Merge "Refactor FileInserter in MediaScanner and adding unit tests for the newly added class."
diff --git a/Android.mk b/Android.mk
index a38723a..f41130b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -402,8 +402,8 @@
resources/samples/AccelerometerPlay "Accelerometer Play" \
-samplecode $(sample_dir)/ActionBarCompat \
resources/samples/ActionBarCompat "Action Bar Compatibility" \
- -samplecode $(sample_dir)/AndroidBeam \
- resources/samples/AndroidBeam "Android Beam" \
+ -samplecode $(sample_dir)/AndroidBeamDemo \
+ resources/samples/AndroidBeamDemo "Android Beam Demo" \
-samplecode $(sample_dir)/ApiDemos \
resources/samples/ApiDemos "API Demos" \
-samplecode $(sample_dir)/Support4Demos \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 9381437..fb334fc 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -116,6 +116,7 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/fonts/DroidSans*)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/fonts/DroidSans*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/api/current.txt b/api/current.txt
index 92969f6..ffa46ec 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6782,6 +6782,13 @@
method public abstract boolean onMove(int, int);
}
+ public class CrossProcessCursorWrapper extends android.database.CursorWrapper implements android.database.CrossProcessCursor {
+ ctor public CrossProcessCursorWrapper(android.database.Cursor);
+ method public void fillWindow(int, android.database.CursorWindow);
+ method public android.database.CursorWindow getWindow();
+ method public boolean onMove(int, int);
+ }
+
public abstract interface Cursor {
method public abstract void close();
method public abstract void copyStringToBuffer(int, android.database.CharArrayBuffer);
@@ -6851,7 +6858,8 @@
}
public class CursorWindow extends android.database.sqlite.SQLiteClosable implements android.os.Parcelable {
- ctor public CursorWindow(boolean);
+ ctor public CursorWindow(java.lang.String);
+ ctor public deprecated CursorWindow(boolean);
method public boolean allocRow();
method public void clear();
method public void close();
@@ -24082,6 +24090,8 @@
method public int getCurrentItemIndex();
method public int getFromIndex();
method public int getItemCount();
+ method public int getMaxScrollX();
+ method public int getMaxScrollY();
method public android.os.Parcelable getParcelableData();
method public int getRemovedCount();
method public int getScrollX();
@@ -24108,6 +24118,8 @@
method public void setFromIndex(int);
method public void setFullScreen(boolean);
method public void setItemCount(int);
+ method public void setMaxScrollX(int);
+ method public void setMaxScrollY(int);
method public void setParcelableData(android.os.Parcelable);
method public void setPassword(boolean);
method public void setRemovedCount(int);
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 528d197..7cb8f62 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -30,7 +30,6 @@
#include <binder/ProcessState.h>
#include <media/IMediaPlayerService.h>
#include <media/stagefright/foundation/ALooper.h>
-#include "include/ARTSPController.h"
#include "include/LiveSession.h"
#include "include/NuCachedSource2.h"
#include <media/stagefright/AudioPlayer.h>
@@ -636,7 +635,6 @@
gDisplayHistogram = false;
sp<ALooper> looper;
- sp<ARTSPController> rtspController;
sp<LiveSession> liveSession;
int res;
@@ -948,7 +946,6 @@
sp<DataSource> dataSource = DataSource::CreateFromURI(filename);
if (strncasecmp(filename, "sine:", 5)
- && strncasecmp(filename, "rtsp://", 7)
&& strncasecmp(filename, "httplive://", 11)
&& dataSource == NULL) {
fprintf(stderr, "Unable to create data source.\n");
@@ -984,23 +981,7 @@
} else {
sp<MediaExtractor> extractor;
- if (!strncasecmp("rtsp://", filename, 7)) {
- if (looper == NULL) {
- looper = new ALooper;
- looper->start();
- }
-
- rtspController = new ARTSPController(looper);
- status_t err = rtspController->connect(filename);
- if (err != OK) {
- fprintf(stderr, "could not connect to rtsp server.\n");
- return -1;
- }
-
- extractor = rtspController.get();
-
- syncInfoPresent = false;
- } else if (!strncasecmp("httplive://", filename, 11)) {
+ if (!strncasecmp("httplive://", filename, 11)) {
String8 uri("http://");
uri.append(filename + 11);
@@ -1021,6 +1002,7 @@
syncInfoPresent = false;
} else {
extractor = MediaExtractor::Create(dataSource);
+
if (extractor == NULL) {
fprintf(stderr, "could not create extractor.\n");
return -1;
@@ -1116,13 +1098,6 @@
} else {
playSource(&client, mediaSource);
}
-
- if (rtspController != NULL) {
- rtspController->disconnect();
- rtspController.clear();
-
- sleep(3);
- }
}
if ((useSurfaceAlloc || useSurfaceTexAlloc) && !audioOnly) {
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 1e238f0..64a2755 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -32,11 +32,9 @@
* when {@link AccessibilityEvent}s are fired. Such events denote some state transition
* in the user interface, for example, the focus has changed, a button has been clicked,
* etc. Such a service can optionally request the capability for querying the content
- * of the active window. Development of an accessibility service requires extends this
- * class and implements its abstract methods.
- * <p>
- * <strong>Lifecycle</strong>
- * </p>
+ * of the active window. Development of an accessibility service requires extending this
+ * class and implementing its abstract methods.
+ * <h3>Lifecycle</h3>
* <p>
* The lifecycle of an accessibility service is managed exclusively by the system and
* follows the established service life cycle. Additionally, starting or stopping an
@@ -45,30 +43,20 @@
* calls {@link AccessibilityService#onServiceConnected()}. This method can be
* overriden by clients that want to perform post binding setup.
* </p>
- * <p>
- * <strong>Declaration</strong>
- * </p>
+ * <h3>Declaration</h3>
* <p>
* An accessibility is declared as any other service in an AndroidManifest.xml but it
* must also specify that it handles the "android.accessibilityservice.AccessibilityService"
* {@link android.content.Intent}. Failure to declare this intent will cause the system to
* ignore the accessibility service. Following is an example declaration:
* </p>
- * <p>
- * <code>
- * <pre>
- * <service android:name=".MyAccessibilityService">
+ * <pre> <service android:name=".MyAccessibilityService">
* <intent-filter>
- * <action android:name="android.accessibilityservice.AccessibilityService" />
+ * <action android:name="android.accessibilityservice.AccessibilityService" />
* </intent-filter>
* . . .
- * </service>
- * </pre>
- * </code>
- * </p>
- * <p>
- * <strong>Configuration</strong>
- * </p>
+ * </service></pre>
+ * <h3>Configuration</h3>
* <p>
* An accessibility service can be configured to receive specific types of accessibility events,
* listen only to specific packages, get events from each type only once in a given time frame,
@@ -81,30 +69,24 @@
* <li>
* Providing a {@link #SERVICE_META_DATA meta-data} entry in the manifest when declaring
* the service. A service declaration with a meta-data tag is presented below:
- * <p>
- * <code>
- * <pre>
- * <service android:name=".MyAccessibilityService">
+ * <pre> <service android:name=".MyAccessibilityService">
* <intent-filter>
- * <action android:name="android.accessibilityservice.AccessibilityService" />
+ * <action android:name="android.accessibilityservice.AccessibilityService" />
* </intent-filter>
* <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibilityservice" />
- * </service>
- * </pre>
- * </code>
- * </p>
- * <p>
- * <strong>Note:</strong>This approach enables setting all properties.
+ * </service></pre>
+ * <p class="note">
+ * <strong>Note:</strong> This approach enables setting all properties.
* </p>
* <p>
* For more details refer to {@link #SERVICE_META_DATA} and
- * <code><{@link android.R.styleable#AccessibilityService accessibility-service}></code>..
+ * <code><{@link android.R.styleable#AccessibilityService accessibility-service}></code>.
* </p>
* </li>
* <li>
* Calling {@link AccessibilityService#setServiceInfo(AccessibilityServiceInfo)}. Note
* that this method can be called any time to dynamically change the service configuration.
- * <p>
+ * <p class="note">
* <strong>Note:</strong> This approach enables setting only dynamically configurable properties:
* {@link AccessibilityServiceInfo#eventTypes},
* {@link AccessibilityServiceInfo#feedbackType},
@@ -117,9 +99,7 @@
* </p>
* </li>
* </ul>
- * <p>
- * <strong>Retrieving window content</strong>
- * </p>
+ * <h3>Retrieving window content</h3>
* <p>
* An service can specify in its declaration that it can retrieve the active window
* content which is represented as a tree of {@link AccessibilityNodeInfo}. Note that
@@ -144,8 +124,8 @@
* this method will return an {@link AccessibilityNodeInfo} that can be used to traverse the
* window content which represented as a tree of such objects.
* </p>
- * <p>
- * <strong>Note</strong>An accessibility service may have requested to be notified for
+ * <p class="note">
+ * <strong>Note</strong> An accessibility service may have requested to be notified for
* a subset of the event types, thus be unaware that the active window has changed. Therefore
* accessibility service that would like to retrieve window content should:
* <ul>
@@ -158,15 +138,13 @@
* <li>
* Prepare that a retrieval method on {@link AccessibilityNodeInfo} may fail since the
* active window has changed and the service did not get the accessibility event yet. Note
- * that it is possible to have a retrieval method failing event adopting the strategy
+ * that it is possible to have a retrieval method failing even adopting the strategy
* specified in the previous bullet because the accessibility event dispatch is asynchronous
* and crosses process boundaries.
* </li>
* </ul>
* </p>
- * <p>
- * <b>Notification strategy</b>
- * </p>
+ * <h3>Notification strategy</h3>
* <p>
* For each feedback type only one accessibility service is notified. Services are notified
* in the order of registration. Hence, if two services are registered for the same
@@ -178,40 +156,39 @@
* well with most applications to coexist with "polished" ones that are targeted for
* specific applications.
* </p>
- * <p>
- * <b>Event types</b>
- * </p>
- * {@link AccessibilityEvent#TYPE_VIEW_CLICKED}
- * {@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}
- * {@link AccessibilityEvent#TYPE_VIEW_FOCUSED}
- * {@link AccessibilityEvent#TYPE_VIEW_SELECTED}
- * {@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}
- * {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}
- * {@link AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED}
- * {@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START}
- * {@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END}
- * {@link AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}
- * {@link AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}
- * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED}
- * {@link AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED}
- * {@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED}
- * <p>
- * <b>Feedback types</b>
- * <p>
- * {@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
- * {@link AccessibilityServiceInfo#FEEDBACK_HAPTIC}
- * {@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
- * {@link AccessibilityServiceInfo#FEEDBACK_VISUAL}
- * {@link AccessibilityServiceInfo#FEEDBACK_GENERIC}
- *
- * @see AccessibilityEvent
- * @see AccessibilityServiceInfo
- * @see android.view.accessibility.AccessibilityManager
- *
+ * <p class="note">
* <strong>Note:</strong> The event notification timeout is useful to avoid propagating
* events to the client too frequently since this is accomplished via an expensive
* interprocess call. One can think of the timeout as a criteria to determine when
- * event generation has settled down.
+ * event generation has settled down.</p>
+ * <h3>Event types</h3>
+ * <ul>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_CLICKED}
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_FOCUSED}
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_SELECTED}
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}
+ * <li>{@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}
+ * <li>{@link AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED}
+ * <li>{@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START}
+ * <li>{@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END}
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_SCROLLED}
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED}
+ * <li>{@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED}
+ * </ul>
+ * <h3>Feedback types</h3>
+ * <ul>
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_HAPTIC}
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_VISUAL}
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_GENERIC}
+ * </ul>
+ * @see AccessibilityEvent
+ * @see AccessibilityServiceInfo
+ * @see android.view.accessibility.AccessibilityManager
*/
public abstract class AccessibilityService extends Service {
/**
@@ -225,10 +202,7 @@
* about itself. This meta-data must reference an XML resource containing an
* <code><{@link android.R.styleable#AccessibilityService accessibility-service}></code>
* tag. This is a a sample XML file configuring an accessibility service:
- * <p>
- * <code>
- * <pre>
- * <accessibility-service
+ * <pre> <accessibility-service
* android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
* android:packageNames="foo.bar, foo.baz"
* android:accessibilityFeedbackType="feedbackSpoken"
@@ -237,10 +211,7 @@
* android:settingsActivity="foo.bar.TestBackActivity"
* android:canRetrieveWindowContent="true"
* . . .
- * />
- * </pre>
- * </code>
- * </p>
+ * /></pre>
*/
public static final String SERVICE_META_DATA = "android.accessibilityservice";
diff --git a/core/java/android/accounts/ChooseAccountTypeActivity.java b/core/java/android/accounts/ChooseAccountTypeActivity.java
index 448b2c0..acc8549 100644
--- a/core/java/android/accounts/ChooseAccountTypeActivity.java
+++ b/core/java/android/accounts/ChooseAccountTypeActivity.java
@@ -43,7 +43,7 @@
* @hide
*/
public class ChooseAccountTypeActivity extends Activity {
- private static final String TAG = "AccountManager";
+ private static final String TAG = "AccountChooser";
private HashMap<String, AuthInfo> mTypeToAuthenticatorInfo = new HashMap<String, AuthInfo>();
private ArrayList<AuthInfo> mAuthenticatorInfosToDisplay;
@@ -52,6 +52,11 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "ChooseAccountTypeActivity.onCreate(savedInstanceState="
+ + savedInstanceState + ")");
+ }
+
// Read the validAccountTypes, if present, and add them to the setOfAllowableAccountTypes
Set<String> setOfAllowableAccountTypes = null;
String[] validAccountTypes = getIntent().getStringArrayExtra(
@@ -111,8 +116,10 @@
Bundle bundle = new Bundle();
bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, type);
setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
- Log.d(TAG, "ChooseAccountTypeActivity.setResultAndFinish: "
- + "selected account type " + type);
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "ChooseAccountTypeActivity.setResultAndFinish: "
+ + "selected account type " + type);
+ }
finish();
}
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index 8cc2002..c3c9d16 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -47,7 +47,7 @@
*/
public class ChooseTypeAndAccountActivity extends Activity
implements AccountManagerCallback<Bundle> {
- private static final String TAG = "AccountManager";
+ private static final String TAG = "AccountChooser";
/**
* A Parcelable ArrayList of Account objects that limits the choosable accounts to those
@@ -72,7 +72,7 @@
* This is passed as the requiredFeatures parameter in AccountManager.addAccount()
* if it is called.
*/
- public static final String EXTRA_ADD_ACCOUNT_REQUIRED_FEATURES_STRING_ARRAY =
+ public static final String EXTRA_ADD_ACCOUNT_REQUIRED_FEATURES_STRING_ARRAY =
"addAccountRequiredFeatures";
/**
@@ -100,13 +100,36 @@
public static final String EXTRA_DESCRIPTION_TEXT_OVERRIDE =
"descriptionTextOverride";
+ public static final int REQUEST_NULL = 0;
+ public static final int REQUEST_CHOOSE_TYPE = 1;
+ public static final int REQUEST_ADD_ACCOUNT = 2;
+
+ private static final String KEY_INSTANCE_STATE_PENDING_REQUEST = "pendingRequest";
+ private static final String KEY_INSTANCE_STATE_EXISTING_ACCOUNTS = "existingAccounts";
+
private ArrayList<AccountInfo> mAccountInfos;
+ private int mPendingRequest = REQUEST_NULL;
+ private Parcelable[] mExistingAccounts = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "ChooseTypeAndAccountActivity.onCreate(savedInstanceState="
+ + savedInstanceState + ")");
+ }
+
setContentView(R.layout.choose_type_and_account);
+ if (savedInstanceState != null) {
+ mPendingRequest = savedInstanceState.getInt(KEY_INSTANCE_STATE_PENDING_REQUEST);
+ mExistingAccounts =
+ savedInstanceState.getParcelableArray(KEY_INSTANCE_STATE_EXISTING_ACCOUNTS);
+ } else {
+ mPendingRequest = REQUEST_NULL;
+ mExistingAccounts = null;
+ }
+
// save some items we use frequently
final AccountManager accountManager = AccountManager.get(this);
final Intent intent = getIntent();
@@ -171,20 +194,6 @@
account.equals(selectedAccount)));
}
- // If there are no allowable accounts go directly to add account
- if (mAccountInfos.isEmpty()) {
- startChooseAccountTypeActivity();
- return;
- }
-
- // if there is only one allowable account return it
- if (!intent.getBooleanExtra(EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT, false)
- && mAccountInfos.size() == 1) {
- Account account = mAccountInfos.get(0).account;
- setResultAndFinish(account.name, account.type);
- return;
- }
-
// there is more than one allowable account. initialize the list adapter to allow
// the user to select an account.
ListView list = (ListView) findViewById(android.R.id.list);
@@ -204,6 +213,39 @@
startChooseAccountTypeActivity();
}
});
+
+ if (mPendingRequest == REQUEST_NULL) {
+ // If there are no allowable accounts go directly to add account
+ if (mAccountInfos.isEmpty()) {
+ startChooseAccountTypeActivity();
+ return;
+ }
+
+ // if there is only one allowable account return it
+ if (!intent.getBooleanExtra(EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT, false)
+ && mAccountInfos.size() == 1) {
+ Account account = mAccountInfos.get(0).account;
+ setResultAndFinish(account.name, account.type);
+ return;
+ }
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "ChooseTypeAndAccountActivity.onDestroy()");
+ }
+ super.onDestroy();
+ }
+
+ @Override
+ protected void onSaveInstanceState(final Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt(KEY_INSTANCE_STATE_PENDING_REQUEST, mPendingRequest);
+ if (mPendingRequest == REQUEST_ADD_ACCOUNT) {
+ outState.putParcelableArray(KEY_INSTANCE_STATE_EXISTING_ACCOUNTS, mExistingAccounts);
+ }
}
// Called when the choose account type activity (for adding an account) returns.
@@ -212,20 +254,74 @@
@Override
protected void onActivityResult(final int requestCode, final int resultCode,
final Intent data) {
- if (resultCode == RESULT_OK && data != null) {
- String accountType = data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE);
- if (accountType != null) {
- runAddAccountForAuthenticator(accountType);
- return;
- }
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ if (data != null && data.getExtras() != null) data.getExtras().keySet();
+ Bundle extras = data != null ? data.getExtras() : null;
+ Log.v(TAG, "ChooseTypeAndAccountActivity.onActivityResult(reqCode=" + requestCode
+ + ", resCode=" + resultCode + ", extras=" + extras + ")");
}
- Log.d(TAG, "ChooseTypeAndAccountActivity.onActivityResult: canceled");
+
+ // we got our result, so clear the fact that we had a pending request
+ mPendingRequest = REQUEST_NULL;
+
+ if (resultCode == RESULT_CANCELED) {
+ return;
+ }
+
+ if (resultCode == RESULT_OK) {
+ if (requestCode == REQUEST_CHOOSE_TYPE) {
+ if (data != null) {
+ String accountType = data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE);
+ if (accountType != null) {
+ runAddAccountForAuthenticator(accountType);
+ return;
+ }
+ }
+ Log.d(TAG, "ChooseTypeAndAccountActivity.onActivityResult: unable to find account "
+ + "type, pretending the request was canceled");
+ } else if (requestCode == REQUEST_ADD_ACCOUNT) {
+ String accountName = null;
+ String accountType = null;
+
+ if (data != null) {
+ accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
+ accountType = data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE);
+ }
+
+ if (accountName == null || accountType == null) {
+ Account[] currentAccounts = AccountManager.get(this).getAccounts();
+ Set<Account> preExistingAccounts = new HashSet<Account>();
+ for (Parcelable accountParcel : mExistingAccounts) {
+ preExistingAccounts.add((Account) accountParcel);
+ }
+ for (Account account : currentAccounts) {
+ if (!preExistingAccounts.contains(account)) {
+ accountName = account.name;
+ accountType = account.type;
+ break;
+ }
+ }
+ }
+
+ if (accountName != null || accountType != null) {
+ setResultAndFinish(accountName, accountType);
+ return;
+ }
+ }
+ Log.d(TAG, "ChooseTypeAndAccountActivity.onActivityResult: unable to find added "
+ + "account, pretending the request was canceled");
+ }
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "ChooseTypeAndAccountActivity.onActivityResult: canceled");
+ }
setResult(Activity.RESULT_CANCELED);
finish();
}
protected void runAddAccountForAuthenticator(String type) {
- Log.d(TAG, "selected account type " + type);
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "runAddAccountForAuthenticator: " + type);
+ }
final Bundle options = getIntent().getBundleExtra(
ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_OPTIONS_BUNDLE);
final String[] requiredFeatures = getIntent().getStringArrayExtra(
@@ -233,20 +329,19 @@
final String authTokenType = getIntent().getStringExtra(
ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING);
AccountManager.get(this).addAccount(type, authTokenType, requiredFeatures,
- options, this, this, null /* Handler */);
+ options, null /* activity */, this /* callback */, null /* Handler */);
}
public void run(final AccountManagerFuture<Bundle> accountManagerFuture) {
try {
final Bundle accountManagerResult = accountManagerFuture.getResult();
- final String name = accountManagerResult.getString(AccountManager.KEY_ACCOUNT_NAME);
- final String type = accountManagerResult.getString(AccountManager.KEY_ACCOUNT_TYPE);
- if (name != null && type != null) {
- final Bundle bundle = new Bundle();
- bundle.putString(AccountManager.KEY_ACCOUNT_NAME, name);
- bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, type);
- setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
- finish();
+ final Intent intent = (Intent)accountManagerResult.getParcelable(
+ AccountManager.KEY_INTENT);
+ if (intent != null) {
+ mPendingRequest = REQUEST_ADD_ACCOUNT;
+ mExistingAccounts = AccountManager.get(this).getAccounts();
+ intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivityForResult(intent, REQUEST_ADD_ACCOUNT);
return;
}
} catch (OperationCanceledException e) {
@@ -297,12 +392,17 @@
bundle.putString(AccountManager.KEY_ACCOUNT_NAME, accountName);
bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, accountType);
setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
- Log.d(TAG, "ChooseTypeAndAccountActivity.setResultAndFinish: "
- + "selected account " + accountName + ", " + accountType);
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "ChooseTypeAndAccountActivity.setResultAndFinish: "
+ + "selected account " + accountName + ", " + accountType);
+ }
finish();
}
private void startChooseAccountTypeActivity() {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "ChooseAccountTypeActivity.startChooseAccountTypeActivity()");
+ }
final Intent intent = new Intent(this, ChooseAccountTypeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
intent.putExtra(EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY,
@@ -313,7 +413,8 @@
getIntent().getStringArrayExtra(EXTRA_ADD_ACCOUNT_REQUIRED_FEATURES_STRING_ARRAY));
intent.putExtra(EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING,
getIntent().getStringExtra(EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING));
- startActivityForResult(intent, 0);
+ startActivityForResult(intent, REQUEST_CHOOSE_TYPE);
+ mPendingRequest = REQUEST_CHOOSE_TYPE;
}
private static class AccountInfo {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d2facdc..8afe9bf 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -490,6 +490,15 @@
// Formatting for checkin service - update version if row format changes
private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1;
+ private void updatePendingConfiguration(Configuration config) {
+ synchronized (mPackages) {
+ if (mPendingConfiguration == null ||
+ mPendingConfiguration.isOtherSeqNewer(config)) {
+ mPendingConfiguration = config;
+ }
+ }
+ }
+
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges) {
queueOrSendMessage(
@@ -530,8 +539,8 @@
// we use token to identify this activity without having to send the
// activity itself back to the activity manager. (matters more with ipc)
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
- ActivityInfo info, CompatibilityInfo compatInfo, Bundle state,
- List<ResultInfo> pendingResults,
+ ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
+ Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
ActivityClientRecord r = new ActivityClientRecord();
@@ -553,6 +562,8 @@
r.profileFd = profileFd;
r.autoStopProfiler = autoStopProfiler;
+ updatePendingConfiguration(curConfig);
+
queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}
@@ -697,12 +708,7 @@
}
public void scheduleConfigurationChanged(Configuration config) {
- synchronized (mPackages) {
- if (mPendingConfiguration == null ||
- mPendingConfiguration.isOtherSeqNewer(config)) {
- mPendingConfiguration = config;
- }
- }
+ updatePendingConfiguration(config);
queueOrSendMessage(H.CONFIGURATION_CHANGED, config);
}
@@ -1966,6 +1972,9 @@
mProfiler.autoStopProfiler = r.autoStopProfiler;
}
+ // Make sure we are running with the most recent config.
+ handleConfigurationChanged(null, null);
+
if (localLOGV) Slog.v(
TAG, "Handling launch of " + r);
Activity a = performLaunchActivity(r, customIntent);
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index c09e87f..e37b3fa 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -54,6 +54,12 @@
* without text editors, so that it will be placed on top of the current
* input method UI. You can modify this behavior by forcing the flag to your
* desired mode after calling {@link #onCreate}.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating dialogs, read the
+ * <a href="{@docRoot}guide/topics/ui/dialogs.html">Dialogs</a> developer guide.</p>
+ * </div>
*/
public class AlertDialog extends Dialog implements DialogInterface {
private AlertController mAlert;
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index cde06cd..c4a4fea 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -132,6 +132,7 @@
IBinder b = data.readStrongBinder();
int ident = data.readInt();
ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
+ Configuration curConfig = Configuration.CREATOR.createFromParcel(data);
CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
Bundle state = data.readBundle();
List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
@@ -142,7 +143,7 @@
ParcelFileDescriptor profileFd = data.readInt() != 0
? data.readFileDescriptor() : null;
boolean autoStopProfiler = data.readInt() != 0;
- scheduleLaunchActivity(intent, b, ident, info, compatInfo, state, ri, pi,
+ scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, state, ri, pi,
notResumed, isForward, profileName, profileFd, autoStopProfiler);
return true;
}
@@ -630,10 +631,10 @@
}
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
- ActivityInfo info, CompatibilityInfo compatInfo, Bundle state,
- List<ResultInfo> pendingResults,
- List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
- String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
+ ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
+ Bundle state, List<ResultInfo> pendingResults,
+ List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
+ String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
@@ -641,6 +642,7 @@
data.writeStrongBinder(token);
data.writeInt(ident);
info.writeToParcel(data, 0);
+ curConfig.writeToParcel(data, 0);
compatInfo.writeToParcel(data, 0);
data.writeBundle(state);
data.writeTypedList(pendingResults);
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 82186dd..7a69419 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -66,9 +66,14 @@
* your Dialog takes input focus, as it the default) with the following code:
*
* <pre>
- * getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
- * WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
- * </pre>
+ * getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+ * WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);</pre>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating dialogs, read the
+ * <a href="{@docRoot}guide/topics/ui/dialogs.html">Dialogs</a> developer guide.</p>
+ * </div>
*/
public class Dialog implements DialogInterface, Window.Callback,
KeyEvent.Callback, OnCreateContextMenuListener {
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 5d200b4..1253fe7 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -53,10 +53,10 @@
void scheduleResumeActivity(IBinder token, boolean isForward) throws RemoteException;
void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
- ActivityInfo info, CompatibilityInfo compatInfo, Bundle state,
- List<ResultInfo> pendingResults,
- List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
- String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
+ ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
+ Bundle state, List<ResultInfo> pendingResults,
+ List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
+ String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
throws RemoteException;
void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, int configChanges,
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 9490b96..f5add25 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -38,9 +38,12 @@
* <p>The {@link Notification.Builder Notification.Builder} has been added to make it
* easier to construct Notifications.</p>
*
- * <p>For a guide to creating notifications, see the
- * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status
- * Bar Notifications</a> document in the Dev Guide.</p>
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For a guide to creating notifications, read the
+ * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
+ * developer guide.</p>
+ * </div>
*/
public class Notification implements Parcelable
{
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 4913e78..bf83f5e 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -55,6 +55,13 @@
* You do not instantiate this class directly; instead, retrieve it through
* {@link android.content.Context#getSystemService}.
*
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For a guide to creating notifications, read the
+ * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
+ * developer guide.</p>
+ * </div>
+ *
* @see android.app.Notification
* @see android.content.Context#getSystemService
*/
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 3290b9d..3aa159e 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -24,6 +24,7 @@
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
+import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -498,8 +499,24 @@
ComponentName launchActivity,
Bundle appSearchData,
boolean globalSearch) {
+ startSearch(initialQuery, selectInitialQuery, launchActivity,
+ appSearchData, globalSearch, null);
+ }
+
+ /**
+ * As {@link #startSearch(String, boolean, ComponentName, Bundle, boolean)} but including
+ * source bounds for the global search intent.
+ *
+ * @hide
+ */
+ public void startSearch(String initialQuery,
+ boolean selectInitialQuery,
+ ComponentName launchActivity,
+ Bundle appSearchData,
+ boolean globalSearch,
+ Rect sourceBounds) {
if (globalSearch) {
- startGlobalSearch(initialQuery, selectInitialQuery, appSearchData);
+ startGlobalSearch(initialQuery, selectInitialQuery, appSearchData, sourceBounds);
return;
}
@@ -520,7 +537,7 @@
* Starts the global search activity.
*/
/* package */ void startGlobalSearch(String initialQuery, boolean selectInitialQuery,
- Bundle appSearchData) {
+ Bundle appSearchData, Rect sourceBounds) {
ComponentName globalSearchActivity = getGlobalSearchActivity();
if (globalSearchActivity == null) {
Log.w(TAG, "No global search activity found.");
@@ -546,6 +563,7 @@
if (selectInitialQuery) {
intent.putExtra(EXTRA_SELECT_QUERY, selectInitialQuery);
}
+ intent.setSourceBounds(sourceBounds);
try {
if (DBG) Log.d(TAG, "Starting global search: " + intent.toUri(0));
mContext.startActivity(intent);
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index 8aee65c..615e8ce 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -29,6 +29,7 @@
import org.xmlpull.v1.XmlPullParserException;
+import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -107,7 +108,8 @@
FileStatus stat = new FileStatus();
if (FileUtils.getFileStatus(mFile.getPath(), stat) && mFile.canRead()) {
try {
- FileInputStream str = new FileInputStream(mFile);
+ BufferedInputStream str = new BufferedInputStream(
+ new FileInputStream(mFile), 16*1024);
map = XmlUtils.readMapXml(str);
str.close();
} catch (XmlPullParserException e) {
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index ca64c88..7863102 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-
+
package android.app;
import android.content.Context;
@@ -40,15 +40,20 @@
public static final int DISABLE_NOTIFICATION_TICKER
= View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER;
public static final int DISABLE_SYSTEM_INFO = View.STATUS_BAR_DISABLE_SYSTEM_INFO;
- public static final int DISABLE_NAVIGATION = View.STATUS_BAR_DISABLE_NAVIGATION;
+ public static final int DISABLE_HOME = View.STATUS_BAR_DISABLE_HOME;
+ public static final int DISABLE_RECENT = View.STATUS_BAR_DISABLE_RECENT;
public static final int DISABLE_BACK = View.STATUS_BAR_DISABLE_BACK;
public static final int DISABLE_CLOCK = View.STATUS_BAR_DISABLE_CLOCK;
+ @Deprecated
+ public static final int DISABLE_NAVIGATION =
+ View.STATUS_BAR_DISABLE_HOME | View.STATUS_BAR_DISABLE_RECENT;
+
public static final int DISABLE_NONE = 0x00000000;
public static final int DISABLE_MASK = DISABLE_EXPAND | DISABLE_NOTIFICATION_ICONS
| DISABLE_NOTIFICATION_ALERTS | DISABLE_NOTIFICATION_TICKER
- | DISABLE_SYSTEM_INFO| DISABLE_NAVIGATION | DISABLE_BACK | DISABLE_CLOCK;
+ | DISABLE_SYSTEM_INFO | DISABLE_RECENT | DISABLE_HOME | DISABLE_BACK | DISABLE_CLOCK;
private Context mContext;
private IStatusBarService mService;
@@ -66,7 +71,9 @@
*/
public void disable(int what) {
try {
- mService.disable(what, mToken, mContext.getPackageName());
+ if (mService != null) {
+ mService.disable(what, mToken, mContext.getPackageName());
+ }
} catch (RemoteException ex) {
// system process is dead anyway.
throw new RuntimeException(ex);
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 8057d4b..092a0c8 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -22,10 +22,6 @@
import android.content.res.AssetFileDescriptor;
import android.content.res.Configuration;
import android.database.Cursor;
-import android.database.CursorToBulkCursorAdaptor;
-import android.database.CursorWindow;
-import android.database.IBulkCursor;
-import android.database.IContentObserver;
import android.database.SQLException;
import android.net.Uri;
import android.os.AsyncTask;
@@ -49,9 +45,6 @@
* multiple applications you can use a database directly via
* {@link android.database.sqlite.SQLiteDatabase}.
*
- * <p>For more information, read <a href="{@docRoot}guide/topics/providers/content-providers.html">Content
- * Providers</a>.</p>
- *
* <p>When a request is made via
* a {@link ContentResolver} the system inspects the authority of the given URI and passes the
* request to the content provider registered with the authority. The content provider can interpret
@@ -77,6 +70,12 @@
* <p>Requests to {@link ContentResolver} are automatically forwarded to the appropriate
* ContentProvider instance, so subclasses don't have to worry about the details of
* cross-process calls.</p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using content providers, read the
+ * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
+ * developer guide.</p>
*/
public abstract class ContentProvider implements ComponentCallbacks2 {
private static final String TAG = "ContentProvider";
@@ -168,22 +167,9 @@
return ContentProvider.this;
}
- /**
- * Remote version of a query, which returns an IBulkCursor. The bulk
- * cursor should be wrapped with BulkCursorToCursorAdaptor before use.
- */
- public IBulkCursor bulkQuery(Uri uri, String[] projection,
- String selection, String[] selectionArgs, String sortOrder,
- IContentObserver observer, CursorWindow window) {
- enforceReadPermission(uri);
- Cursor cursor = ContentProvider.this.query(uri, projection,
- selection, selectionArgs, sortOrder);
- if (cursor == null) {
- return null;
- }
- return new CursorToBulkCursorAdaptor(cursor, observer,
- ContentProvider.this.getClass().getName(),
- hasWritePermission(uri), window);
+ @Override
+ public String getProviderName() {
+ return getContentProvider().getClass().getName();
}
public Cursor query(Uri uri, String[] projection,
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index abeeb74..b089bf2 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -20,6 +20,7 @@
import android.database.BulkCursorNative;
import android.database.BulkCursorToCursorAdaptor;
import android.database.Cursor;
+import android.database.CursorToBulkCursorAdaptor;
import android.database.CursorWindow;
import android.database.DatabaseUtils;
import android.database.IBulkCursor;
@@ -65,6 +66,13 @@
return new ContentProviderProxy(obj);
}
+ /**
+ * Gets the name of the content provider.
+ * Should probably be part of the {@link IContentProvider} interface.
+ * @return The content provider name.
+ */
+ public abstract String getProviderName();
+
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
@@ -98,33 +106,24 @@
}
String sortOrder = data.readString();
- IContentObserver observer = IContentObserver.Stub.
- asInterface(data.readStrongBinder());
- CursorWindow window = CursorWindow.CREATOR.createFromParcel(data);
+ IContentObserver observer = IContentObserver.Stub.asInterface(
+ data.readStrongBinder());
- // Flag for whether caller wants the number of
- // rows in the cursor and the position of the
- // "_id" column index (or -1 if non-existent)
- // Only to be returned if binder != null.
- boolean wantsCursorMetadata = data.readInt() != 0;
+ Cursor cursor = query(url, projection, selection, selectionArgs, sortOrder);
+ if (cursor != null) {
+ CursorToBulkCursorAdaptor adaptor = new CursorToBulkCursorAdaptor(
+ cursor, observer, getProviderName());
+ final IBinder binder = adaptor.asBinder();
+ final int count = adaptor.count();
+ final int index = BulkCursorToCursorAdaptor.findRowIdColumnIndex(
+ adaptor.getColumnNames());
+ final boolean wantsAllOnMoveCalls = adaptor.getWantsAllOnMoveCalls();
- IBulkCursor bulkCursor = bulkQuery(url, projection, selection,
- selectionArgs, sortOrder, observer, window);
- if (bulkCursor != null) {
- final IBinder binder = bulkCursor.asBinder();
- if (wantsCursorMetadata) {
- final int count = bulkCursor.count();
- final int index = BulkCursorToCursorAdaptor.findRowIdColumnIndex(
- bulkCursor.getColumnNames());
-
- reply.writeNoException();
- reply.writeStrongBinder(binder);
- reply.writeInt(count);
- reply.writeInt(index);
- } else {
- reply.writeNoException();
- reply.writeStrongBinder(binder);
- }
+ reply.writeNoException();
+ reply.writeStrongBinder(binder);
+ reply.writeInt(count);
+ reply.writeInt(index);
+ reply.writeInt(wantsAllOnMoveCalls ? 1 : 0);
} else {
reply.writeNoException();
reply.writeStrongBinder(null);
@@ -324,332 +323,301 @@
return mRemote;
}
- // Like bulkQuery() but sets up provided 'adaptor' if not null.
- private IBulkCursor bulkQueryInternal(
- Uri url, String[] projection,
- String selection, String[] selectionArgs, String sortOrder,
- IContentObserver observer, CursorWindow window,
- BulkCursorToCursorAdaptor adaptor) throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IContentProvider.descriptor);
-
- url.writeToParcel(data, 0);
- int length = 0;
- if (projection != null) {
- length = projection.length;
- }
- data.writeInt(length);
- for (int i = 0; i < length; i++) {
- data.writeString(projection[i]);
- }
- data.writeString(selection);
- if (selectionArgs != null) {
- length = selectionArgs.length;
- } else {
- length = 0;
- }
- data.writeInt(length);
- for (int i = 0; i < length; i++) {
- data.writeString(selectionArgs[i]);
- }
- data.writeString(sortOrder);
- data.writeStrongBinder(observer.asBinder());
- window.writeToParcel(data, 0);
-
- // Flag for whether or not we want the number of rows in the
- // cursor and the position of the "_id" column index (or -1 if
- // non-existent). Only to be returned if binder != null.
- final boolean wantsCursorMetadata = (adaptor != null);
- data.writeInt(wantsCursorMetadata ? 1 : 0);
-
- mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- IBulkCursor bulkCursor = null;
- IBinder bulkCursorBinder = reply.readStrongBinder();
- if (bulkCursorBinder != null) {
- bulkCursor = BulkCursorNative.asInterface(bulkCursorBinder);
-
- if (wantsCursorMetadata) {
- int rowCount = reply.readInt();
- int idColumnPosition = reply.readInt();
- if (bulkCursor != null) {
- adaptor.set(bulkCursor, rowCount, idColumnPosition);
- }
- }
- }
-
- data.recycle();
- reply.recycle();
-
- return bulkCursor;
- }
-
- public IBulkCursor bulkQuery(Uri url, String[] projection,
- String selection, String[] selectionArgs, String sortOrder, IContentObserver observer,
- CursorWindow window) throws RemoteException {
- return bulkQueryInternal(
- url, projection, selection, selectionArgs, sortOrder,
- observer, window,
- null /* BulkCursorToCursorAdaptor */);
- }
-
public Cursor query(Uri url, String[] projection, String selection,
String[] selectionArgs, String sortOrder) throws RemoteException {
- //TODO make a pool of windows so we can reuse memory dealers
- CursorWindow window = new CursorWindow(false /* window will be used remotely */);
BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor();
- IBulkCursor bulkCursor = bulkQueryInternal(
- url, projection, selection, selectionArgs, sortOrder,
- adaptor.getObserver(), window,
- adaptor);
- if (bulkCursor == null) {
- return null;
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
+
+ url.writeToParcel(data, 0);
+ int length = 0;
+ if (projection != null) {
+ length = projection.length;
+ }
+ data.writeInt(length);
+ for (int i = 0; i < length; i++) {
+ data.writeString(projection[i]);
+ }
+ data.writeString(selection);
+ if (selectionArgs != null) {
+ length = selectionArgs.length;
+ } else {
+ length = 0;
+ }
+ data.writeInt(length);
+ for (int i = 0; i < length; i++) {
+ data.writeString(selectionArgs[i]);
+ }
+ data.writeString(sortOrder);
+ data.writeStrongBinder(adaptor.getObserver().asBinder());
+
+ mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0);
+
+ DatabaseUtils.readExceptionFromParcel(reply);
+
+ IBulkCursor bulkCursor = BulkCursorNative.asInterface(reply.readStrongBinder());
+ if (bulkCursor != null) {
+ int rowCount = reply.readInt();
+ int idColumnPosition = reply.readInt();
+ boolean wantsAllOnMoveCalls = reply.readInt() != 0;
+ adaptor.initialize(bulkCursor, rowCount, idColumnPosition, wantsAllOnMoveCalls);
+ } else {
+ adaptor.close();
+ adaptor = null;
+ }
+ return adaptor;
+ } catch (RemoteException ex) {
+ adaptor.close();
+ throw ex;
+ } catch (RuntimeException ex) {
+ adaptor.close();
+ throw ex;
+ } finally {
+ data.recycle();
+ reply.recycle();
}
- return adaptor;
}
public String getType(Uri url) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
- url.writeToParcel(data, 0);
+ mRemote.transact(IContentProvider.GET_TYPE_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.GET_TYPE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- String out = reply.readString();
-
- data.recycle();
- reply.recycle();
-
- return out;
+ DatabaseUtils.readExceptionFromParcel(reply);
+ String out = reply.readString();
+ return out;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public Uri insert(Uri url, ContentValues values) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ values.writeToParcel(data, 0);
- url.writeToParcel(data, 0);
- values.writeToParcel(data, 0);
+ mRemote.transact(IContentProvider.INSERT_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.INSERT_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- Uri out = Uri.CREATOR.createFromParcel(reply);
-
- data.recycle();
- reply.recycle();
-
- return out;
+ DatabaseUtils.readExceptionFromParcel(reply);
+ Uri out = Uri.CREATOR.createFromParcel(reply);
+ return out;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public int bulkInsert(Uri url, ContentValues[] values) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ data.writeTypedArray(values, 0);
- url.writeToParcel(data, 0);
- data.writeTypedArray(values, 0);
+ mRemote.transact(IContentProvider.BULK_INSERT_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.BULK_INSERT_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- int count = reply.readInt();
-
- data.recycle();
- reply.recycle();
-
- return count;
+ DatabaseUtils.readExceptionFromParcel(reply);
+ int count = reply.readInt();
+ return count;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
throws RemoteException, OperationApplicationException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
+ data.writeInt(operations.size());
+ for (ContentProviderOperation operation : operations) {
+ operation.writeToParcel(data, 0);
+ }
+ mRemote.transact(IContentProvider.APPLY_BATCH_TRANSACTION, data, reply, 0);
- data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInt(operations.size());
- for (ContentProviderOperation operation : operations) {
- operation.writeToParcel(data, 0);
+ DatabaseUtils.readExceptionWithOperationApplicationExceptionFromParcel(reply);
+ final ContentProviderResult[] results =
+ reply.createTypedArray(ContentProviderResult.CREATOR);
+ return results;
+ } finally {
+ data.recycle();
+ reply.recycle();
}
- mRemote.transact(IContentProvider.APPLY_BATCH_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionWithOperationApplicationExceptionFromParcel(reply);
- final ContentProviderResult[] results =
- reply.createTypedArray(ContentProviderResult.CREATOR);
-
- data.recycle();
- reply.recycle();
-
- return results;
}
public int delete(Uri url, String selection, String[] selectionArgs)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ data.writeString(selection);
+ data.writeStringArray(selectionArgs);
- url.writeToParcel(data, 0);
- data.writeString(selection);
- data.writeStringArray(selectionArgs);
+ mRemote.transact(IContentProvider.DELETE_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.DELETE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- int count = reply.readInt();
-
- data.recycle();
- reply.recycle();
-
- return count;
+ DatabaseUtils.readExceptionFromParcel(reply);
+ int count = reply.readInt();
+ return count;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public int update(Uri url, ContentValues values, String selection,
String[] selectionArgs) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ values.writeToParcel(data, 0);
+ data.writeString(selection);
+ data.writeStringArray(selectionArgs);
- url.writeToParcel(data, 0);
- values.writeToParcel(data, 0);
- data.writeString(selection);
- data.writeStringArray(selectionArgs);
+ mRemote.transact(IContentProvider.UPDATE_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.UPDATE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- int count = reply.readInt();
-
- data.recycle();
- reply.recycle();
-
- return count;
+ DatabaseUtils.readExceptionFromParcel(reply);
+ int count = reply.readInt();
+ return count;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public ParcelFileDescriptor openFile(Uri url, String mode)
throws RemoteException, FileNotFoundException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ data.writeString(mode);
- url.writeToParcel(data, 0);
- data.writeString(mode);
+ mRemote.transact(IContentProvider.OPEN_FILE_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.OPEN_FILE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
- int has = reply.readInt();
- ParcelFileDescriptor fd = has != 0 ? reply.readFileDescriptor() : null;
-
- data.recycle();
- reply.recycle();
-
- return fd;
+ DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
+ int has = reply.readInt();
+ ParcelFileDescriptor fd = has != 0 ? reply.readFileDescriptor() : null;
+ return fd;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public AssetFileDescriptor openAssetFile(Uri url, String mode)
throws RemoteException, FileNotFoundException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ data.writeString(mode);
- url.writeToParcel(data, 0);
- data.writeString(mode);
+ mRemote.transact(IContentProvider.OPEN_ASSET_FILE_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.OPEN_ASSET_FILE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
- int has = reply.readInt();
- AssetFileDescriptor fd = has != 0
- ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null;
-
- data.recycle();
- reply.recycle();
-
- return fd;
+ DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
+ int has = reply.readInt();
+ AssetFileDescriptor fd = has != 0
+ ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null;
+ return fd;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public Bundle call(String method, String request, Bundle args)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ data.writeString(method);
+ data.writeString(request);
+ data.writeBundle(args);
- data.writeString(method);
- data.writeString(request);
- data.writeBundle(args);
+ mRemote.transact(IContentProvider.CALL_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.CALL_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- Bundle bundle = reply.readBundle();
-
- data.recycle();
- reply.recycle();
-
- return bundle;
+ DatabaseUtils.readExceptionFromParcel(reply);
+ Bundle bundle = reply.readBundle();
+ return bundle;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ data.writeString(mimeTypeFilter);
- url.writeToParcel(data, 0);
- data.writeString(mimeTypeFilter);
+ mRemote.transact(IContentProvider.GET_STREAM_TYPES_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.GET_STREAM_TYPES_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- String[] out = reply.createStringArray();
-
- data.recycle();
- reply.recycle();
-
- return out;
+ DatabaseUtils.readExceptionFromParcel(reply);
+ String[] out = reply.createStringArray();
+ return out;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts)
throws RemoteException, FileNotFoundException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ data.writeString(mimeType);
+ data.writeBundle(opts);
- url.writeToParcel(data, 0);
- data.writeString(mimeType);
- data.writeBundle(opts);
+ mRemote.transact(IContentProvider.OPEN_TYPED_ASSET_FILE_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.OPEN_TYPED_ASSET_FILE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
- int has = reply.readInt();
- AssetFileDescriptor fd = has != 0
- ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null;
-
- data.recycle();
- reply.recycle();
-
- return fd;
+ DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
+ int has = reply.readInt();
+ AssetFileDescriptor fd = has != 0
+ ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null;
+ return fd;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
private IBinder mRemote;
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 1e72092..cc3219b 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -16,6 +16,8 @@
package android.content;
+import dalvik.system.CloseGuard;
+
import android.accounts.Account;
import android.app.ActivityManagerNative;
import android.app.ActivityThread;
@@ -24,6 +26,7 @@
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.database.ContentObserver;
+import android.database.CrossProcessCursorWrapper;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.database.IContentObserver;
@@ -33,6 +36,7 @@
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.StrictMode;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.EventLog;
@@ -51,6 +55,12 @@
/**
* This class provides applications access to the content model.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using a ContentResolver with content providers, read the
+ * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
+ * developer guide.</p>
*/
public abstract class ContentResolver {
/**
@@ -1559,30 +1569,42 @@
samplePercent);
}
- private final class CursorWrapperInner extends CursorWrapper {
+ private final class CursorWrapperInner extends CrossProcessCursorWrapper {
private final IContentProvider mContentProvider;
public static final String TAG="CursorWrapperInner";
- private boolean mCloseFlag = false;
+
+ private final CloseGuard mCloseGuard = CloseGuard.get();
+ private boolean mProviderReleased;
CursorWrapperInner(Cursor cursor, IContentProvider icp) {
super(cursor);
mContentProvider = icp;
+ mCloseGuard.open("close");
}
@Override
public void close() {
super.close();
ContentResolver.this.releaseProvider(mContentProvider);
- mCloseFlag = true;
+ mProviderReleased = true;
+
+ if (mCloseGuard != null) {
+ mCloseGuard.close();
+ }
}
@Override
protected void finalize() throws Throwable {
- // TODO: integrate CloseGuard support.
try {
- if(!mCloseFlag) {
+ if (mCloseGuard != null) {
+ mCloseGuard.warnIfOpen();
+ }
+
+ if (!mProviderReleased && mContentProvider != null) {
+ // Even though we are using CloseGuard, log this anyway so that
+ // application developers always see the message in the log.
Log.w(TAG, "Cursor finalized without prior close()");
- close();
+ ContentResolver.this.releaseProvider(mContentProvider);
}
} finally {
super.finalize();
diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java
index 72bc9c2..2a67ff8 100644
--- a/core/java/android/content/IContentProvider.java
+++ b/core/java/android/content/IContentProvider.java
@@ -18,9 +18,6 @@
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
-import android.database.CursorWindow;
-import android.database.IBulkCursor;
-import android.database.IContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
@@ -36,13 +33,6 @@
* @hide
*/
public interface IContentProvider extends IInterface {
- /**
- * @hide - hide this because return type IBulkCursor and parameter
- * IContentObserver are system private classes.
- */
- public IBulkCursor bulkQuery(Uri url, String[] projection,
- String selection, String[] selectionArgs, String sortOrder, IContentObserver observer,
- CursorWindow window) throws RemoteException;
public Cursor query(Uri url, String[] projection, String selection,
String[] selectionArgs, String sortOrder) throws RemoteException;
public String getType(Uri url) throws RemoteException;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 2be5153..45a42e4 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -57,8 +57,8 @@
*
* <p>An Intent provides a facility for performing late runtime binding between the code in
* different applications. Its most significant use is in the launching of activities, where it
- * can be thought of as the glue between activities. It is basically a passive data structure
- * holding an abstract description of an action to be performed.</p>
+ * can be thought of as the glue between activities. It is basically a passive data structure
+ * holding an abstract description of an action to be performed.</p>
*
* <div class="special reference">
* <h3>Developer Guides</h3>
@@ -2566,7 +2566,7 @@
*/
public static final String EXTRA_LOCAL_ONLY =
"android.intent.extra.LOCAL_ONLY";
-
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Intent flags (see mFlags variable).
@@ -5291,7 +5291,7 @@
if (r != null) {
mSourceBounds = new Rect(r);
} else {
- r = null;
+ mSourceBounds = null;
}
}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index a3bcc28..decb974 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -362,4 +362,6 @@
void verifyPendingInstall(int id, int verificationCode);
VerifierDeviceIdentity getVerifierDeviceIdentity();
+
+ boolean isFirstBoot();
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 7a7e4f4..3eb7647 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2124,6 +2124,9 @@
if (pkg == null) {
return null;
}
+ if ((flags & GET_SIGNATURES) != 0) {
+ packageParser.collectCertificates(pkg, 0);
+ }
return PackageParser.generatePackageInfo(pkg, null, flags, 0, 0);
}
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index 3f23b89..74fef29 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -53,7 +53,10 @@
abstract public boolean isNull(int column);
public int getType(int column) {
- throw new UnsupportedOperationException();
+ // Reflects the assumption that all commonly used field types (meaning everything
+ // but blobs) are convertible to strings so it should be safe to call
+ // getString to retrieve them.
+ return FIELD_TYPE_STRING;
}
// TODO implement getBlob in all cursor types
@@ -78,13 +81,11 @@
}
public void deactivate() {
- deactivateInternal();
+ onDeactivateOrClose();
}
- /**
- * @hide
- */
- public void deactivateInternal() {
+ /** @hide */
+ protected void onDeactivateOrClose() {
if (mSelfObserver != null) {
mContentResolver.unregisterContentObserver(mSelfObserver);
mSelfObserverRegistered = false;
@@ -108,7 +109,7 @@
public void close() {
mClosed = true;
mContentObservable.unregisterAll();
- deactivateInternal();
+ onDeactivateOrClose();
}
/**
@@ -187,46 +188,9 @@
return result;
}
- /**
- * Copy data from cursor to CursorWindow
- * @param position start position of data
- * @param window
- */
+ @Override
public void fillWindow(int position, CursorWindow window) {
- if (position < 0 || position >= getCount()) {
- return;
- }
- window.acquireReference();
- try {
- int oldpos = mPos;
- mPos = position - 1;
- window.clear();
- window.setStartPosition(position);
- int columnNum = getColumnCount();
- window.setNumColumns(columnNum);
- while (moveToNext() && window.allocRow()) {
- for (int i = 0; i < columnNum; i++) {
- String field = getString(i);
- if (field != null) {
- if (!window.putString(field, mPos, i)) {
- window.freeLastRow();
- break;
- }
- } else {
- if (!window.putNull(mPos, i)) {
- window.freeLastRow();
- break;
- }
- }
- }
- }
-
- mPos = oldpos;
- } catch (IllegalStateException e){
- // simply ignore it
- } finally {
- window.releaseReference();
- }
+ DatabaseUtils.cursorFillWindow(this, position, window);
}
public final boolean move(int offset) {
diff --git a/core/java/android/database/AbstractWindowedCursor.java b/core/java/android/database/AbstractWindowedCursor.java
index bfc8123..083485f 100644
--- a/core/java/android/database/AbstractWindowedCursor.java
+++ b/core/java/android/database/AbstractWindowedCursor.java
@@ -19,6 +19,11 @@
/**
* A base class for Cursors that store their data in {@link CursorWindow}s.
* <p>
+ * The cursor owns the cursor window it uses. When the cursor is closed,
+ * its window is also closed. Likewise, when the window used by the cursor is
+ * changed, its old window is closed. This policy of strict ownership ensures
+ * that cursor windows are not leaked.
+ * </p><p>
* Subclasses are responsible for filling the cursor window with data during
* {@link #onMove(int, int)}, allocating a new cursor window if necessary.
* During {@link #requery()}, the existing cursor window should be cleared and
@@ -180,4 +185,26 @@
mWindow = null;
}
}
+
+ /**
+ * If there is a window, clear it.
+ * Otherwise, creates a new window.
+ *
+ * @param name The window name.
+ * @hide
+ */
+ protected void clearOrCreateWindow(String name) {
+ if (mWindow == null) {
+ mWindow = new CursorWindow(name);
+ } else {
+ mWindow.clear();
+ }
+ }
+
+ /** @hide */
+ @Override
+ protected void onDeactivateOrClose() {
+ super.onDeactivateOrClose();
+ closeWindow();
+ }
}
diff --git a/core/java/android/database/BulkCursorNative.java b/core/java/android/database/BulkCursorNative.java
index fa62d69..20a9c67 100644
--- a/core/java/android/database/BulkCursorNative.java
+++ b/core/java/android/database/BulkCursorNative.java
@@ -20,12 +20,13 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
+import android.os.Parcelable;
import android.os.RemoteException;
/**
* Native implementation of the bulk cursor. This is only for use in implementing
* IPC, application code should use the Cursor interface.
- *
+ *
* {@hide}
*/
public abstract class BulkCursorNative extends Binder implements IBulkCursor
@@ -61,13 +62,13 @@
data.enforceInterface(IBulkCursor.descriptor);
int startPos = data.readInt();
CursorWindow window = getWindow(startPos);
+ reply.writeNoException();
if (window == null) {
reply.writeInt(0);
- return true;
+ } else {
+ reply.writeInt(1);
+ window.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
- reply.writeNoException();
- reply.writeInt(1);
- window.writeToParcel(reply, 0);
return true;
}
@@ -108,9 +109,8 @@
case REQUERY_TRANSACTION: {
data.enforceInterface(IBulkCursor.descriptor);
IContentObserver observer =
- IContentObserver.Stub.asInterface(data.readStrongBinder());
- CursorWindow window = CursorWindow.CREATOR.createFromParcel(data);
- int count = requery(observer, window);
+ IContentObserver.Stub.asInterface(data.readStrongBinder());
+ int count = requery(observer);
reply.writeNoException();
reply.writeInt(count);
reply.writeBundle(getExtras());
@@ -184,172 +184,171 @@
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
+ data.writeInt(startPos);
- data.writeInterfaceToken(IBulkCursor.descriptor);
+ mRemote.transact(GET_CURSOR_WINDOW_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
- data.writeInt(startPos);
-
- mRemote.transact(GET_CURSOR_WINDOW_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- CursorWindow window = null;
- if (reply.readInt() == 1) {
- window = CursorWindow.newFromParcel(reply);
+ CursorWindow window = null;
+ if (reply.readInt() == 1) {
+ window = CursorWindow.newFromParcel(reply);
+ }
+ return window;
+ } finally {
+ data.recycle();
+ reply.recycle();
}
-
- data.recycle();
- reply.recycle();
-
- return window;
}
public void onMove(int position) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
+ data.writeInt(position);
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- data.writeInt(position);
-
- mRemote.transact(ON_MOVE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- data.recycle();
- reply.recycle();
+ mRemote.transact(ON_MOVE_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public int count() throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
- data.writeInterfaceToken(IBulkCursor.descriptor);
+ boolean result = mRemote.transact(COUNT_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
- boolean result = mRemote.transact(COUNT_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- int count;
- if (result == false) {
- count = -1;
- } else {
- count = reply.readInt();
+ int count;
+ if (result == false) {
+ count = -1;
+ } else {
+ count = reply.readInt();
+ }
+ return count;
+ } finally {
+ data.recycle();
+ reply.recycle();
}
- data.recycle();
- reply.recycle();
- return count;
}
public String[] getColumnNames() throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
- data.writeInterfaceToken(IBulkCursor.descriptor);
+ mRemote.transact(GET_COLUMN_NAMES_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
- mRemote.transact(GET_COLUMN_NAMES_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- String[] columnNames = null;
- int numColumns = reply.readInt();
- columnNames = new String[numColumns];
- for (int i = 0; i < numColumns; i++) {
- columnNames[i] = reply.readString();
+ String[] columnNames = null;
+ int numColumns = reply.readInt();
+ columnNames = new String[numColumns];
+ for (int i = 0; i < numColumns; i++) {
+ columnNames[i] = reply.readString();
+ }
+ return columnNames;
+ } finally {
+ data.recycle();
+ reply.recycle();
}
-
- data.recycle();
- reply.recycle();
- return columnNames;
}
public void deactivate() throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- mRemote.transact(DEACTIVATE_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
-
- data.recycle();
- reply.recycle();
+ mRemote.transact(DEACTIVATE_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public void close() throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- mRemote.transact(CLOSE_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
-
- data.recycle();
- reply.recycle();
+ mRemote.transact(CLOSE_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
- public int requery(IContentObserver observer, CursorWindow window) throws RemoteException {
+ public int requery(IContentObserver observer) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
+ data.writeStrongInterface(observer);
- data.writeInterfaceToken(IBulkCursor.descriptor);
+ boolean result = mRemote.transact(REQUERY_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
- data.writeStrongInterface(observer);
- window.writeToParcel(data, 0);
-
- boolean result = mRemote.transact(REQUERY_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- int count;
- if (!result) {
- count = -1;
- } else {
- count = reply.readInt();
- mExtras = reply.readBundle();
+ int count;
+ if (!result) {
+ count = -1;
+ } else {
+ count = reply.readInt();
+ mExtras = reply.readBundle();
+ }
+ return count;
+ } finally {
+ data.recycle();
+ reply.recycle();
}
-
- data.recycle();
- reply.recycle();
-
- return count;
}
public boolean getWantsAllOnMoveCalls() throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
- data.writeInterfaceToken(IBulkCursor.descriptor);
+ mRemote.transact(WANTS_ON_MOVE_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
- mRemote.transact(WANTS_ON_MOVE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- int result = reply.readInt();
- data.recycle();
- reply.recycle();
- return result != 0;
+ int result = reply.readInt();
+ return result != 0;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public Bundle getExtras() throws RemoteException {
if (mExtras == null) {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
- data.writeInterfaceToken(IBulkCursor.descriptor);
+ mRemote.transact(GET_EXTRAS_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
- mRemote.transact(GET_EXTRAS_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- mExtras = reply.readBundle();
- data.recycle();
- reply.recycle();
+ mExtras = reply.readBundle();
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
return mExtras;
}
@@ -357,19 +356,19 @@
public Bundle respond(Bundle extras) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
+ data.writeBundle(extras);
- data.writeInterfaceToken(IBulkCursor.descriptor);
+ mRemote.transact(RESPOND_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
- data.writeBundle(extras);
-
- mRemote.transact(RESPOND_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- Bundle returnExtras = reply.readBundle();
- data.recycle();
- reply.recycle();
- return returnExtras;
+ Bundle returnExtras = reply.readBundle();
+ return returnExtras;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
}
diff --git a/core/java/android/database/BulkCursorToCursorAdaptor.java b/core/java/android/database/BulkCursorToCursorAdaptor.java
index 9c1b26d..885046b 100644
--- a/core/java/android/database/BulkCursorToCursorAdaptor.java
+++ b/core/java/android/database/BulkCursorToCursorAdaptor.java
@@ -21,44 +21,30 @@
import android.util.Log;
/**
- * Adapts an {@link IBulkCursor} to a {@link Cursor} for use in the local
- * process.
+ * Adapts an {@link IBulkCursor} to a {@link Cursor} for use in the local process.
*
* {@hide}
*/
public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor {
private static final String TAG = "BulkCursor";
- private SelfContentObserver mObserverBridge;
+ private SelfContentObserver mObserverBridge = new SelfContentObserver(this);
private IBulkCursor mBulkCursor;
private int mCount;
private String[] mColumns;
private boolean mWantsAllOnMoveCalls;
- public void set(IBulkCursor bulkCursor) {
- mBulkCursor = bulkCursor;
-
- try {
- mCount = mBulkCursor.count();
- mWantsAllOnMoveCalls = mBulkCursor.getWantsAllOnMoveCalls();
-
- // Search for the rowID column index and set it for our parent
- mColumns = mBulkCursor.getColumnNames();
- mRowIdColumnIndex = findRowIdColumnIndex(mColumns);
- } catch (RemoteException ex) {
- Log.e(TAG, "Setup failed because the remote process is dead");
- }
- }
-
/**
- * Version of set() that does fewer Binder calls if the caller
- * already knows BulkCursorToCursorAdaptor's properties.
+ * Initializes the adaptor.
+ * Must be called before first use.
*/
- public void set(IBulkCursor bulkCursor, int count, int idIndex) {
+ public void initialize(IBulkCursor bulkCursor, int count, int idIndex,
+ boolean wantsAllOnMoveCalls) {
mBulkCursor = bulkCursor;
mColumns = null; // lazily retrieved
mCount = count;
mRowIdColumnIndex = idIndex;
+ mWantsAllOnMoveCalls = wantsAllOnMoveCalls;
}
/**
@@ -80,31 +66,34 @@
*
* @return A SelfContentObserver hooked up to this Cursor
*/
- public synchronized IContentObserver getObserver() {
- if (mObserverBridge == null) {
- mObserverBridge = new SelfContentObserver(this);
- }
+ public IContentObserver getObserver() {
return mObserverBridge.getContentObserver();
}
+ private void throwIfCursorIsClosed() {
+ if (mBulkCursor == null) {
+ throw new StaleDataException("Attempted to access a cursor after it has been closed.");
+ }
+ }
+
@Override
public int getCount() {
+ throwIfCursorIsClosed();
return mCount;
}
@Override
public boolean onMove(int oldPosition, int newPosition) {
+ throwIfCursorIsClosed();
+
try {
// Make sure we have the proper window
- if (mWindow != null) {
- if (newPosition < mWindow.getStartPosition() ||
- newPosition >= (mWindow.getStartPosition() + mWindow.getNumRows())) {
- mWindow = mBulkCursor.getWindow(newPosition);
- } else if (mWantsAllOnMoveCalls) {
- mBulkCursor.onMove(newPosition);
- }
- } else {
- mWindow = mBulkCursor.getWindow(newPosition);
+ if (mWindow == null
+ || newPosition < mWindow.getStartPosition()
+ || newPosition >= mWindow.getStartPosition() + mWindow.getNumRows()) {
+ setWindow(mBulkCursor.getWindow(newPosition));
+ } else if (mWantsAllOnMoveCalls) {
+ mBulkCursor.onMove(newPosition);
}
} catch (RemoteException ex) {
// We tried to get a window and failed
@@ -126,32 +115,36 @@
// which is what actually makes the data set invalid.
super.deactivate();
- try {
- mBulkCursor.deactivate();
- } catch (RemoteException ex) {
- Log.w(TAG, "Remote process exception when deactivating");
+ if (mBulkCursor != null) {
+ try {
+ mBulkCursor.deactivate();
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Remote process exception when deactivating");
+ }
}
- mWindow = null;
}
@Override
public void close() {
super.close();
- try {
- mBulkCursor.close();
- } catch (RemoteException ex) {
- Log.w(TAG, "Remote process exception when closing");
+
+ if (mBulkCursor != null) {
+ try {
+ mBulkCursor.close();
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Remote process exception when closing");
+ } finally {
+ mBulkCursor = null;
+ }
}
- mWindow = null;
}
@Override
public boolean requery() {
+ throwIfCursorIsClosed();
+
try {
- int oldCount = mCount;
- //TODO get the window from a pool somewhere to avoid creating the memory dealer
- mCount = mBulkCursor.requery(getObserver(), new CursorWindow(
- false /* the window will be accessed across processes */));
+ mCount = mBulkCursor.requery(getObserver());
if (mCount != -1) {
mPos = -1;
closeWindow();
@@ -174,6 +167,8 @@
@Override
public String[] getColumnNames() {
+ throwIfCursorIsClosed();
+
if (mColumns == null) {
try {
mColumns = mBulkCursor.getColumnNames();
@@ -187,6 +182,8 @@
@Override
public Bundle getExtras() {
+ throwIfCursorIsClosed();
+
try {
return mBulkCursor.getExtras();
} catch (RemoteException e) {
@@ -198,6 +195,8 @@
@Override
public Bundle respond(Bundle extras) {
+ throwIfCursorIsClosed();
+
try {
return mBulkCursor.respond(extras);
} catch (RemoteException e) {
diff --git a/core/java/android/database/CrossProcessCursor.java b/core/java/android/database/CrossProcessCursor.java
index 77ba3a5..26379cc 100644
--- a/core/java/android/database/CrossProcessCursor.java
+++ b/core/java/android/database/CrossProcessCursor.java
@@ -16,27 +16,63 @@
package android.database;
-public interface CrossProcessCursor extends Cursor{
+/**
+ * A cross process cursor is an extension of a {@link Cursor} that also supports
+ * usage from remote processes.
+ * <p>
+ * The contents of a cross process cursor are marshalled to the remote process by
+ * filling {@link CursorWindow} objects using {@link #fillWindow}. As an optimization,
+ * the cursor can provide a pre-filled window to use via {@link #getWindow} thereby
+ * obviating the need to copy the data to yet another cursor window.
+ */
+public interface CrossProcessCursor extends Cursor {
/**
- * returns a pre-filled window, return NULL if no such window
+ * Returns a pre-filled window that contains the data within this cursor.
+ * <p>
+ * In particular, the window contains the row indicated by {@link Cursor#getPosition}.
+ * The window's contents are automatically scrolled whenever the current
+ * row moved outside the range covered by the window.
+ * </p>
+ *
+ * @return The pre-filled window, or null if none.
*/
CursorWindow getWindow();
/**
- * copies cursor data into the window start at pos
+ * Copies cursor data into the window.
+ * <p>
+ * Clears the window and fills it with data beginning at the requested
+ * row position until all of the data in the cursor is exhausted
+ * or the window runs out of space.
+ * </p><p>
+ * The filled window uses the same row indices as the original cursor.
+ * For example, if you fill a window starting from row 5 from the cursor,
+ * you can query the contents of row 5 from the window just by asking it
+ * for row 5 because there is a direct correspondence between the row indices
+ * used by the cursor and the window.
+ * </p><p>
+ * The current position of the cursor, as returned by {@link #getPosition},
+ * is not changed by this method.
+ * </p>
+ *
+ * @param position The zero-based index of the first row to copy into the window.
+ * @param window The window to fill.
*/
- void fillWindow(int pos, CursorWindow winow);
+ void fillWindow(int position, CursorWindow window);
/**
* This function is called every time the cursor is successfully scrolled
* to a new position, giving the subclass a chance to update any state it
- * may have. If it returns false the move function will also do so and the
+ * may have. If it returns false the move function will also do so and the
* cursor will scroll to the beforeFirst position.
+ * <p>
+ * This function should be called by methods such as {@link #moveToPosition(int)},
+ * so it will typically not be called from outside of the cursor class itself.
+ * </p>
*
- * @param oldPosition the position that we're moving from
- * @param newPosition the position that we're moving to
- * @return true if the move is successful, false otherwise
+ * @param oldPosition The position that we're moving from.
+ * @param newPosition The position that we're moving to.
+ * @return True if the move is successful, false otherwise.
*/
boolean onMove(int oldPosition, int newPosition);
-
}
diff --git a/core/java/android/database/CrossProcessCursorWrapper.java b/core/java/android/database/CrossProcessCursorWrapper.java
new file mode 100644
index 0000000..8c250b8
--- /dev/null
+++ b/core/java/android/database/CrossProcessCursorWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.database;
+
+import android.database.CrossProcessCursor;
+import android.database.Cursor;
+import android.database.CursorWindow;
+import android.database.CursorWrapper;
+
+/**
+ * Cursor wrapper that implements {@link CrossProcessCursor}.
+ * <p>
+ * If the wrapper cursor implemented {@link CrossProcessCursor}, then delegates
+ * {@link #fillWindow}, {@link #getWindow()} and {@link #onMove} to it. Otherwise,
+ * provides default implementations of these methods that traverse the contents
+ * of the cursor similar to {@link AbstractCursor#fillWindow}.
+ * </p><p>
+ * This wrapper can be used to adapt an ordinary {@link Cursor} into a
+ * {@link CrossProcessCursor}.
+ * </p>
+ */
+public class CrossProcessCursorWrapper extends CursorWrapper implements CrossProcessCursor {
+ /**
+ * Creates a cross process cursor wrapper.
+ * @param cursor The underlying cursor to wrap.
+ */
+ public CrossProcessCursorWrapper(Cursor cursor) {
+ super(cursor);
+ }
+
+ @Override
+ public void fillWindow(int position, CursorWindow window) {
+ if (mCursor instanceof CrossProcessCursor) {
+ final CrossProcessCursor crossProcessCursor = (CrossProcessCursor)mCursor;
+ crossProcessCursor.fillWindow(position, window);
+ return;
+ }
+
+ DatabaseUtils.cursorFillWindow(mCursor, position, window);
+ }
+
+ @Override
+ public CursorWindow getWindow() {
+ if (mCursor instanceof CrossProcessCursor) {
+ final CrossProcessCursor crossProcessCursor = (CrossProcessCursor)mCursor;
+ return crossProcessCursor.getWindow();
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean onMove(int oldPosition, int newPosition) {
+ if (mCursor instanceof CrossProcessCursor) {
+ final CrossProcessCursor crossProcessCursor = (CrossProcessCursor)mCursor;
+ return crossProcessCursor.onMove(oldPosition, newPosition);
+ }
+
+ return true;
+ }
+}
diff --git a/core/java/android/database/CursorToBulkCursorAdaptor.java b/core/java/android/database/CursorToBulkCursorAdaptor.java
index 8fa4d3b..215035d 100644
--- a/core/java/android/database/CursorToBulkCursorAdaptor.java
+++ b/core/java/android/database/CursorToBulkCursorAdaptor.java
@@ -24,19 +24,37 @@
/**
* Wraps a BulkCursor around an existing Cursor making it remotable.
+ * <p>
+ * If the wrapped cursor returns non-null from {@link CrossProcessCursor#getWindow}
+ * then it is assumed to own the window. Otherwise, the adaptor provides a
+ * window to be filled and ensures it gets closed as needed during deactivation
+ * and requeries.
+ * </p>
*
* {@hide}
*/
public final class CursorToBulkCursorAdaptor extends BulkCursorNative
implements IBinder.DeathRecipient {
private static final String TAG = "Cursor";
- private final CrossProcessCursor mCursor;
- private CursorWindow mWindow;
+
+ private final Object mLock = new Object();
private final String mProviderName;
private ContentObserverProxy mObserver;
- private static final class ContentObserverProxy extends ContentObserver
- {
+ /**
+ * The cursor that is being adapted.
+ * This field is set to null when the cursor is closed.
+ */
+ private CrossProcessCursor mCursor;
+
+ /**
+ * The cursor window that was filled by the cross process cursor in the
+ * case where the cursor does not support getWindow.
+ * This field is only ever non-null when the window has actually be filled.
+ */
+ private CursorWindow mFilledWindow;
+
+ private static final class ContentObserverProxy extends ContentObserver {
protected IContentObserver mRemote;
public ContentObserverProxy(IContentObserver remoteObserver, DeathRecipient recipient) {
@@ -69,102 +87,163 @@
}
}
- public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer, String providerName,
- boolean allowWrite, CursorWindow window) {
- try {
- mCursor = (CrossProcessCursor) cursor;
- if (mCursor instanceof AbstractWindowedCursor) {
- AbstractWindowedCursor windowedCursor = (AbstractWindowedCursor) cursor;
- if (windowedCursor.hasWindow()) {
- if (Log.isLoggable(TAG, Log.VERBOSE) || false) {
- Log.v(TAG, "Cross process cursor has a local window before setWindow in "
- + providerName, new RuntimeException());
- }
- }
- windowedCursor.setWindow(window);
- } else {
- mWindow = window;
- mCursor.fillWindow(0, window);
- }
- } catch (ClassCastException e) {
- // TODO Implement this case.
- throw new UnsupportedOperationException(
- "Only CrossProcessCursor cursors are supported across process for now", e);
+ public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer,
+ String providerName) {
+ if (cursor instanceof CrossProcessCursor) {
+ mCursor = (CrossProcessCursor)cursor;
+ } else {
+ mCursor = new CrossProcessCursorWrapper(cursor);
}
mProviderName = providerName;
- createAndRegisterObserverProxy(observer);
+ synchronized (mLock) {
+ createAndRegisterObserverProxyLocked(observer);
+ }
}
-
+
+ private void closeFilledWindowLocked() {
+ if (mFilledWindow != null) {
+ mFilledWindow.close();
+ mFilledWindow = null;
+ }
+ }
+
+ private void disposeLocked() {
+ if (mCursor != null) {
+ unregisterObserverProxyLocked();
+ mCursor.close();
+ mCursor = null;
+ }
+
+ closeFilledWindowLocked();
+ }
+
+ private void throwIfCursorIsClosed() {
+ if (mCursor == null) {
+ throw new StaleDataException("Attempted to access a cursor after it has been closed.");
+ }
+ }
+
+ @Override
public void binderDied() {
- mCursor.close();
- if (mWindow != null) {
- mWindow.close();
+ synchronized (mLock) {
+ disposeLocked();
}
}
-
+
+ @Override
public CursorWindow getWindow(int startPos) {
- mCursor.moveToPosition(startPos);
-
- if (mWindow != null) {
- if (startPos < mWindow.getStartPosition() ||
- startPos >= (mWindow.getStartPosition() + mWindow.getNumRows())) {
- mCursor.fillWindow(startPos, mWindow);
- }
- return mWindow;
- } else {
- return ((AbstractWindowedCursor)mCursor).getWindow();
- }
- }
+ synchronized (mLock) {
+ throwIfCursorIsClosed();
- public void onMove(int position) {
- mCursor.onMove(mCursor.getPosition(), position);
- }
-
- public int count() {
- return mCursor.getCount();
- }
-
- public String[] getColumnNames() {
- return mCursor.getColumnNames();
- }
-
- public void deactivate() {
- maybeUnregisterObserverProxy();
- mCursor.deactivate();
- }
-
- public void close() {
- maybeUnregisterObserverProxy();
- mCursor.close();
- }
-
- public int requery(IContentObserver observer, CursorWindow window) {
- if (mWindow == null) {
- ((AbstractWindowedCursor)mCursor).setWindow(window);
- }
- try {
- if (!mCursor.requery()) {
- return -1;
+ if (!mCursor.moveToPosition(startPos)) {
+ closeFilledWindowLocked();
+ return null;
}
- } catch (IllegalStateException e) {
- IllegalStateException leakProgram = new IllegalStateException(
- mProviderName + " Requery misuse db, mCursor isClosed:" +
- mCursor.isClosed(), e);
- throw leakProgram;
+
+ CursorWindow window = mCursor.getWindow();
+ if (window != null) {
+ closeFilledWindowLocked();
+ } else {
+ window = mFilledWindow;
+ if (window == null) {
+ mFilledWindow = new CursorWindow(mProviderName);
+ window = mFilledWindow;
+ mCursor.fillWindow(startPos, window);
+ } else if (startPos < window.getStartPosition()
+ || startPos >= window.getStartPosition() + window.getNumRows()) {
+ window.clear();
+ mCursor.fillWindow(startPos, window);
+ }
+ }
+
+ // Acquire a reference before returning from this RPC.
+ // The Binder proxy will decrement the reference count again as part of writing
+ // the CursorWindow to the reply parcel as a return value.
+ if (window != null) {
+ window.acquireReference();
+ }
+ return window;
}
-
- if (mWindow != null) {
- mCursor.fillWindow(0, window);
- mWindow = window;
- }
- maybeUnregisterObserverProxy();
- createAndRegisterObserverProxy(observer);
- return mCursor.getCount();
}
+ @Override
+ public void onMove(int position) {
+ synchronized (mLock) {
+ throwIfCursorIsClosed();
+
+ mCursor.onMove(mCursor.getPosition(), position);
+ }
+ }
+
+ @Override
+ public int count() {
+ synchronized (mLock) {
+ throwIfCursorIsClosed();
+
+ return mCursor.getCount();
+ }
+ }
+
+ @Override
+ public String[] getColumnNames() {
+ synchronized (mLock) {
+ throwIfCursorIsClosed();
+
+ return mCursor.getColumnNames();
+ }
+ }
+
+ @Override
+ public void deactivate() {
+ synchronized (mLock) {
+ if (mCursor != null) {
+ unregisterObserverProxyLocked();
+ mCursor.deactivate();
+ }
+
+ closeFilledWindowLocked();
+ }
+ }
+
+ @Override
+ public void close() {
+ synchronized (mLock) {
+ disposeLocked();
+ }
+ }
+
+ @Override
+ public int requery(IContentObserver observer) {
+ synchronized (mLock) {
+ throwIfCursorIsClosed();
+
+ closeFilledWindowLocked();
+
+ try {
+ if (!mCursor.requery()) {
+ return -1;
+ }
+ } catch (IllegalStateException e) {
+ IllegalStateException leakProgram = new IllegalStateException(
+ mProviderName + " Requery misuse db, mCursor isClosed:" +
+ mCursor.isClosed(), e);
+ throw leakProgram;
+ }
+
+ unregisterObserverProxyLocked();
+ createAndRegisterObserverProxyLocked(observer);
+ return mCursor.getCount();
+ }
+ }
+
+ @Override
public boolean getWantsAllOnMoveCalls() {
- return mCursor.getWantsAllOnMoveCalls();
+ synchronized (mLock) {
+ throwIfCursorIsClosed();
+
+ return mCursor.getWantsAllOnMoveCalls();
+ }
}
/**
@@ -173,7 +252,7 @@
* @param observer the IContentObserver that wants to monitor the cursor
* @throws IllegalStateException if an observer is already registered
*/
- private void createAndRegisterObserverProxy(IContentObserver observer) {
+ private void createAndRegisterObserverProxyLocked(IContentObserver observer) {
if (mObserver != null) {
throw new IllegalStateException("an observer is already registered");
}
@@ -182,7 +261,7 @@
}
/** Unregister the observer if it is already registered. */
- private void maybeUnregisterObserverProxy() {
+ private void unregisterObserverProxyLocked() {
if (mObserver != null) {
mCursor.unregisterContentObserver(mObserver);
mObserver.unlinkToDeath(this);
@@ -190,11 +269,21 @@
}
}
+ @Override
public Bundle getExtras() {
- return mCursor.getExtras();
+ synchronized (mLock) {
+ throwIfCursorIsClosed();
+
+ return mCursor.getExtras();
+ }
}
+ @Override
public Bundle respond(Bundle extras) {
- return mCursor.respond(extras);
+ synchronized (mLock) {
+ throwIfCursorIsClosed();
+
+ return mCursor.respond(extras);
+ }
}
}
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index 2e3ef28..9c93324 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -16,11 +16,12 @@
package android.database;
+import dalvik.system.CloseGuard;
+
import android.content.res.Resources;
import android.database.sqlite.SQLiteClosable;
import android.database.sqlite.SQLiteException;
import android.os.Binder;
-import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Process;
@@ -29,6 +30,13 @@
/**
* A buffer containing multiple cursor rows.
+ * <p>
+ * A {@link CursorWindow} is read-write when initially created and used locally.
+ * When sent to a remote process (by writing it to a {@link Parcel}), the remote process
+ * receives a read-only view of the cursor window. Typically the cursor window
+ * will be allocated by the producer, filled with data, and then sent to the
+ * consumer for reading.
+ * </p>
*/
public class CursorWindow extends SQLiteClosable implements Parcelable {
private static final String STATS_TAG = "CursorWindowStats";
@@ -48,10 +56,12 @@
private int mStartPos;
- private static native int nativeInitializeEmpty(int cursorWindowSize, boolean localOnly);
- private static native int nativeInitializeFromBinder(IBinder nativeBinder);
+ private final CloseGuard mCloseGuard = CloseGuard.get();
+
+ private static native int nativeCreate(String name, int cursorWindowSize);
+ private static native int nativeCreateFromParcel(Parcel parcel);
private static native void nativeDispose(int windowPtr);
- private static native IBinder nativeGetBinder(int windowPtr);
+ private static native void nativeWriteToParcel(int windowPtr, Parcel parcel);
private static native void nativeClear(int windowPtr);
@@ -75,6 +85,26 @@
private static native boolean nativePutNull(int windowPtr, int row, int column);
/**
+ * Creates a new empty cursor window and gives it a name.
+ * <p>
+ * The cursor initially has no rows or columns. Call {@link #setNumColumns(int)} to
+ * set the number of columns before adding any rows to the cursor.
+ * </p>
+ *
+ * @param name The name of the cursor window, or null if none.
+ */
+ public CursorWindow(String name) {
+ mStartPos = 0;
+ mWindowPtr = nativeCreate(name, sCursorWindowSize);
+ if (mWindowPtr == 0) {
+ throw new CursorWindowAllocationException("Cursor window allocation of " +
+ (sCursorWindowSize / 1024) + " kb failed. " + printStats());
+ }
+ mCloseGuard.open("close");
+ recordNewWindow(Binder.getCallingPid(), mWindowPtr);
+ }
+
+ /**
* Creates a new empty cursor window.
* <p>
* The cursor initially has no rows or columns. Call {@link #setNumColumns(int)} to
@@ -82,31 +112,32 @@
* </p>
*
* @param localWindow True if this window will be used in this process only,
- * false if it might be sent to another processes.
+ * false if it might be sent to another processes. This argument is ignored.
+ *
+ * @deprecated There is no longer a distinction between local and remote
+ * cursor windows. Use the {@link #CursorWindow(String)} constructor instead.
*/
+ @Deprecated
public CursorWindow(boolean localWindow) {
- mStartPos = 0;
- mWindowPtr = nativeInitializeEmpty(sCursorWindowSize, localWindow);
- if (mWindowPtr == 0) {
- throw new CursorWindowAllocationException("Cursor window allocation of " +
- (sCursorWindowSize / 1024) + " kb failed. " + printStats());
- }
- recordNewWindow(Binder.getCallingPid(), mWindowPtr);
+ this((String)null);
}
private CursorWindow(Parcel source) {
- IBinder binder = source.readStrongBinder();
mStartPos = source.readInt();
- mWindowPtr = nativeInitializeFromBinder(binder);
+ mWindowPtr = nativeCreateFromParcel(source);
if (mWindowPtr == 0) {
throw new CursorWindowAllocationException("Cursor window could not be "
+ "created from binder.");
}
+ mCloseGuard.open("close");
}
@Override
protected void finalize() throws Throwable {
try {
+ if (mCloseGuard != null) {
+ mCloseGuard.warnIfOpen();
+ }
dispose();
} finally {
super.finalize();
@@ -114,6 +145,9 @@
}
private void dispose() {
+ if (mCloseGuard != null) {
+ mCloseGuard.close();
+ }
if (mWindowPtr != 0) {
recordClosingOfWindow(mWindowPtr);
nativeDispose(mWindowPtr);
@@ -237,8 +271,7 @@
* Returns true if the field at the specified row and column index
* has type {@link Cursor#FIELD_TYPE_NULL}.
*
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return True if the field has type {@link Cursor#FIELD_TYPE_NULL}.
* @deprecated Use {@link #getType(int, int)} instead.
@@ -252,8 +285,7 @@
* Returns true if the field at the specified row and column index
* has type {@link Cursor#FIELD_TYPE_BLOB} or {@link Cursor#FIELD_TYPE_NULL}.
*
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return True if the field has type {@link Cursor#FIELD_TYPE_BLOB} or
* {@link Cursor#FIELD_TYPE_NULL}.
@@ -269,8 +301,7 @@
* Returns true if the field at the specified row and column index
* has type {@link Cursor#FIELD_TYPE_INTEGER}.
*
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return True if the field has type {@link Cursor#FIELD_TYPE_INTEGER}.
* @deprecated Use {@link #getType(int, int)} instead.
@@ -284,8 +315,7 @@
* Returns true if the field at the specified row and column index
* has type {@link Cursor#FIELD_TYPE_FLOAT}.
*
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return True if the field has type {@link Cursor#FIELD_TYPE_FLOAT}.
* @deprecated Use {@link #getType(int, int)} instead.
@@ -299,8 +329,7 @@
* Returns true if the field at the specified row and column index
* has type {@link Cursor#FIELD_TYPE_STRING} or {@link Cursor#FIELD_TYPE_NULL}.
*
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return True if the field has type {@link Cursor#FIELD_TYPE_STRING}
* or {@link Cursor#FIELD_TYPE_NULL}.
@@ -325,8 +354,7 @@
* </ul>
* </p>
*
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return The field type.
*/
@@ -356,8 +384,7 @@
* </ul>
* </p>
*
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return The value of the field as a byte array.
*/
@@ -392,8 +419,7 @@
* </ul>
* </p>
*
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return The value of the field as a string.
*/
@@ -431,8 +457,7 @@
* </ul>
* </p>
*
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @param buffer The {@link CharArrayBuffer} to hold the string. It is automatically
* resized if the requested string is larger than the buffer's current capacity.
@@ -467,8 +492,7 @@
* </ul>
* </p>
*
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return The value of the field as a <code>long</code>.
*/
@@ -500,8 +524,7 @@
* </ul>
* </p>
*
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return The value of the field as a <code>double</code>.
*/
@@ -522,8 +545,7 @@
* result to <code>short</code>.
* </p>
*
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return The value of the field as a <code>short</code>.
*/
@@ -539,8 +561,7 @@
* result to <code>int</code>.
* </p>
*
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return The value of the field as an <code>int</code>.
*/
@@ -556,8 +577,7 @@
* result to <code>float</code>.
* </p>
*
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return The value of the field as an <code>float</code>.
*/
@@ -569,8 +589,7 @@
* Copies a byte array into the field at the specified row and column index.
*
* @param value The value to store.
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return True if successful.
*/
@@ -587,8 +606,7 @@
* Copies a string into the field at the specified row and column index.
*
* @param value The value to store.
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return True if successful.
*/
@@ -605,8 +623,7 @@
* Puts a long integer into the field at the specified row and column index.
*
* @param value The value to store.
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return True if successful.
*/
@@ -624,8 +641,7 @@
* specified row and column index.
*
* @param value The value to store.
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return True if successful.
*/
@@ -641,8 +657,7 @@
/**
* Puts a null value into the field at the specified row and column index.
*
- * @param row The zero-based row index, relative to the cursor window's
- * start position ({@link #getStartPosition()}).
+ * @param row The zero-based row index.
* @param column The zero-based column index.
* @return True if successful.
*/
@@ -675,8 +690,12 @@
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeStrongBinder(nativeGetBinder(mWindowPtr));
dest.writeInt(mStartPos);
+ nativeWriteToParcel(mWindowPtr, dest);
+
+ if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
+ releaseReference();
+ }
}
@Override
diff --git a/core/java/android/database/CursorWrapper.java b/core/java/android/database/CursorWrapper.java
index 320733e..7baeb8c 100644
--- a/core/java/android/database/CursorWrapper.java
+++ b/core/java/android/database/CursorWrapper.java
@@ -25,9 +25,13 @@
* use for this class is to extend a cursor while overriding only a subset of its methods.
*/
public class CursorWrapper implements Cursor {
+ /** @hide */
+ protected final Cursor mCursor;
- private final Cursor mCursor;
-
+ /**
+ * Creates a cursor wrapper.
+ * @param cursor The underlying cursor to wrap.
+ */
public CursorWrapper(Cursor cursor) {
mCursor = cursor;
}
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
index 8e6f699..a10ca15 100644
--- a/core/java/android/database/DatabaseUtils.java
+++ b/core/java/android/database/DatabaseUtils.java
@@ -237,7 +237,8 @@
return Cursor.FIELD_TYPE_BLOB;
} else if (obj instanceof Float || obj instanceof Double) {
return Cursor.FIELD_TYPE_FLOAT;
- } else if (obj instanceof Long || obj instanceof Integer) {
+ } else if (obj instanceof Long || obj instanceof Integer
+ || obj instanceof Short || obj instanceof Byte) {
return Cursor.FIELD_TYPE_INTEGER;
} else {
return Cursor.FIELD_TYPE_STRING;
@@ -245,6 +246,82 @@
}
/**
+ * Fills the specified cursor window by iterating over the contents of the cursor.
+ * The window is filled until the cursor is exhausted or the window runs out
+ * of space.
+ *
+ * The original position of the cursor is left unchanged by this operation.
+ *
+ * @param cursor The cursor that contains the data to put in the window.
+ * @param position The start position for filling the window.
+ * @param window The window to fill.
+ * @hide
+ */
+ public static void cursorFillWindow(final Cursor cursor,
+ int position, final CursorWindow window) {
+ if (position < 0 || position >= cursor.getCount()) {
+ return;
+ }
+ window.acquireReference();
+ try {
+ final int oldPos = cursor.getPosition();
+ final int numColumns = cursor.getColumnCount();
+ window.clear();
+ window.setStartPosition(position);
+ window.setNumColumns(numColumns);
+ if (cursor.moveToPosition(position)) {
+ do {
+ if (!window.allocRow()) {
+ break;
+ }
+ for (int i = 0; i < numColumns; i++) {
+ final int type = cursor.getType(i);
+ final boolean success;
+ switch (type) {
+ case Cursor.FIELD_TYPE_NULL:
+ success = window.putNull(position, i);
+ break;
+
+ case Cursor.FIELD_TYPE_INTEGER:
+ success = window.putLong(cursor.getLong(i), position, i);
+ break;
+
+ case Cursor.FIELD_TYPE_FLOAT:
+ success = window.putDouble(cursor.getDouble(i), position, i);
+ break;
+
+ case Cursor.FIELD_TYPE_BLOB: {
+ final byte[] value = cursor.getBlob(i);
+ success = value != null ? window.putBlob(value, position, i)
+ : window.putNull(position, i);
+ break;
+ }
+
+ default: // assume value is convertible to String
+ case Cursor.FIELD_TYPE_STRING: {
+ final String value = cursor.getString(i);
+ success = value != null ? window.putString(value, position, i)
+ : window.putNull(position, i);
+ break;
+ }
+ }
+ if (!success) {
+ window.freeLastRow();
+ break;
+ }
+ }
+ position += 1;
+ } while (cursor.moveToNext());
+ }
+ cursor.moveToPosition(oldPos);
+ } catch (IllegalStateException e){
+ // simply ignore it
+ } finally {
+ window.releaseReference();
+ }
+ }
+
+ /**
* Appends an SQL string to the given StringBuilder, including the opening
* and closing single quotes. Any single quotes internal to sqlString will
* be escaped.
diff --git a/core/java/android/database/IBulkCursor.java b/core/java/android/database/IBulkCursor.java
index 244c88f..7c96797 100644
--- a/core/java/android/database/IBulkCursor.java
+++ b/core/java/android/database/IBulkCursor.java
@@ -56,7 +56,7 @@
public void close() throws RemoteException;
- public int requery(IContentObserver observer, CursorWindow window) throws RemoteException;
+ public int requery(IContentObserver observer) throws RemoteException;
boolean getWantsAllOnMoveCalls() throws RemoteException;
diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java
index 81fe824..9574300 100644
--- a/core/java/android/database/sqlite/SQLiteCursor.java
+++ b/core/java/android/database/sqlite/SQLiteCursor.java
@@ -89,8 +89,6 @@
* @param query the {@link SQLiteQuery} object associated with this cursor object.
*/
public SQLiteCursor(SQLiteCursorDriver driver, String editTable, SQLiteQuery query) {
- // The AbstractCursor constructor needs to do some setup.
- super();
if (query == null) {
throw new IllegalArgumentException("query object cannot be null");
}
@@ -157,12 +155,7 @@
}
private void fillWindow(int startPos) {
- if (mWindow == null) {
- // If there isn't a window set already it will only be accessed locally
- mWindow = new CursorWindow(true /* the window is local only */);
- } else {
- mWindow.clear();
- }
+ clearOrCreateWindow(getDatabase().getPath());
mWindow.setStartPosition(startPos);
int count = getQuery().fillWindow(mWindow);
if (startPos == 0) { // fillWindow returns count(*) only for startPos = 0
@@ -214,16 +207,9 @@
return mColumns;
}
- private void deactivateCommon() {
- if (false) Log.v(TAG, "<<< Releasing cursor " + this);
- closeWindow();
- if (false) Log.v("DatabaseWindow", "closing window in release()");
- }
-
@Override
public void deactivate() {
super.deactivate();
- deactivateCommon();
mDriver.cursorDeactivated();
}
@@ -231,7 +217,6 @@
public void close() {
super.close();
synchronized (this) {
- deactivateCommon();
mQuery.close();
mDriver.cursorClosed();
}
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index d65e6df..caad6fd 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -116,6 +116,12 @@
* auto-focus capabilities. In order for your application to be compatible with
* more devices, you should not make assumptions about the device camera
* specifications.</p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using cameras, read the
+ * <a href="{@docRoot}guide/topics/media/camera.html">Camera</a> developer guide.</p>
+ * </div>
*/
public class Camera {
private static final String TAG = "Camera";
@@ -337,7 +343,7 @@
* Camera objects are locked by default unless {@link #unlock()} is
* called. Normally {@link #reconnect()} is used instead.
*
- * <p>Since API level 13, camera is automatically locked for applications in
+ * <p>Since API level 14, camera is automatically locked for applications in
* {@link android.media.MediaRecorder#start()}. Applications can use the
* camera (ex: zoom) after recording starts. There is no need to call this
* after recording starts or stops.
@@ -356,7 +362,7 @@
* which will re-acquire the lock and allow you to continue using the
* camera.
*
- * <p>Since API level 13, camera is automatically locked for applications in
+ * <p>Since API level 14, camera is automatically locked for applications in
* {@link android.media.MediaRecorder#start()}. Applications can use the
* camera (ex: zoom) after recording starts. There is no need to call this
* after recording starts or stops.
@@ -781,7 +787,7 @@
* @see android.hardware.Camera.Parameters#setAutoWhiteBalanceLock(boolean)
*/
void onAutoFocus(boolean success, Camera camera);
- };
+ }
/**
* Starts camera auto-focus and registers a callback function to run when
@@ -804,11 +810,17 @@
* {@link android.hardware.Camera.Parameters#FLASH_MODE_OFF}, flash may be
* fired during auto-focus, depending on the driver and camera hardware.<p>
*
- * Auto-exposure lock {@link android.hardware.Camera.Parameters#getAutoExposureLock()}
+ * <p>Auto-exposure lock {@link android.hardware.Camera.Parameters#getAutoExposureLock()}
* and auto-white balance locks {@link android.hardware.Camera.Parameters#getAutoWhiteBalanceLock()}
* do not change during and after autofocus. But auto-focus routine may stop
* auto-exposure and auto-white balance transiently during focusing.
*
+ * <p>Stopping preview with {@link #stopPreview()}, or triggering still
+ * image capture with {@link #takePicture(Camera.ShutterCallback,
+ * Camera.PictureCallback, Camera.PictureCallback)}, will not change the
+ * the focus position. Applications must call cancelAutoFocus to reset the
+ * focus.</p>
+ *
* @param cb the callback to run
* @see #cancelAutoFocus()
* @see android.hardware.Camera.Parameters#setAutoExposureLock(boolean)
@@ -1059,8 +1071,7 @@
/**
* Notify the listener of the detected faces in the preview frame.
*
- * @param faces The detected faces in a list sorted by the confidence score.
- * The highest scored face is the first element.
+ * @param faces The detected faces in a list
* @param camera The {@link Camera} service object
*/
void onFaceDetection(Face[] faces, Camera camera);
@@ -1121,7 +1132,7 @@
/**
* Information about a face identified through camera face detection.
- *
+ *
* <p>When face detection is used with a camera, the {@link FaceDetectionListener} returns a
* list of face objects for use in focusing and metering.</p>
*
@@ -1140,7 +1151,9 @@
* the field of view. For example, suppose the size of the viewfinder UI
* is 800x480. The rect passed from the driver is (-1000, -1000, 0, 0).
* The corresponding viewfinder rect should be (0, 0, 400, 240). The
- * width and height of the rect will not be 0 or negative.
+ * width and height of the rect will not be 0 or negative. The
+ * coordinates can be smaller than -1000 or bigger than 1000. But at
+ * least one vertex will be within (-1000, -1000) and (1000, 1000).
*
* <p>The direction is relative to the sensor orientation, that is, what
* the sensor sees. The direction is not affected by the rotation or
@@ -1464,6 +1477,8 @@
private static final String KEY_MAX_NUM_DETECTED_FACES_SW = "max-num-detected-faces-sw";
private static final String KEY_RECORDING_HINT = "recording-hint";
private static final String KEY_VIDEO_SNAPSHOT_SUPPORTED = "video-snapshot-supported";
+ private static final String KEY_VIDEO_STABILIZATION = "video-stabilization";
+ private static final String KEY_VIDEO_STABILIZATION_SUPPORTED = "video-stabilization-supported";
// Parameter key suffix for supported values.
private static final String SUPPORTED_VALUES_SUFFIX = "-values";
@@ -1651,9 +1666,18 @@
* call {@link #takePicture(Camera.ShutterCallback,
* Camera.PictureCallback, Camera.PictureCallback)} in this mode but the
* subject may not be in focus. Auto focus starts when the parameter is
- * set. Applications should not call {@link
- * #autoFocus(AutoFocusCallback)} in this mode. To stop continuous
- * focus, applications should change the focus mode to other modes.
+ * set.
+ *
+ * <p>Since API level 14, applications can call {@link
+ * #autoFocus(AutoFocusCallback)} in this mode. The focus callback will
+ * immediately return with a boolean that indicates whether the focus is
+ * sharp or not. The focus position is locked after autoFocus call. If
+ * applications want to resume the continuous focus, cancelAutoFocus
+ * must be called. Restarting the preview will not resume the continuous
+ * autofocus. To stop continuous focus, applications should change the
+ * focus mode to other modes.
+ *
+ * @see #FOCUS_MODE_CONTINUOUS_PICTURE
*/
public static final String FOCUS_MODE_CONTINUOUS_VIDEO = "continuous-video";
@@ -1661,13 +1685,17 @@
* Continuous auto focus mode intended for taking pictures. The camera
* continuously tries to focus. The speed of focus change is more
* aggressive than {@link #FOCUS_MODE_CONTINUOUS_VIDEO}. Auto focus
- * starts when the parameter is set. If applications call {@link
- * #autoFocus(AutoFocusCallback)} in this mode, the focus callback will
- * immediately return with a boolean that indicates whether the focus is
- * sharp or not. The apps can then decide if they want to take a picture
- * immediately or to change the focus mode to auto, and run a full
- * autofocus cycle. To stop continuous focus, applications should change
- * the focus mode to other modes.
+ * starts when the parameter is set.
+ *
+ * <p>If applications call {@link #autoFocus(AutoFocusCallback)} in this
+ * mode, the focus callback will immediately return with a boolean that
+ * indicates whether the focus is sharp or not. The apps can then decide
+ * if they want to take a picture immediately or to change the focus
+ * mode to auto, and run a full autofocus cycle. The focus position is
+ * locked after autoFocus call. If applications want to resume the
+ * continuous focus, cancelAutoFocus must be called. Restarting the
+ * preview will not resume the continuous autofocus. To stop continuous
+ * focus, applications should change the focus mode to other modes.
*
* @see #FOCUS_MODE_CONTINUOUS_VIDEO
*/
@@ -2443,7 +2471,7 @@
*
* @param value new white balance.
* @see #getWhiteBalance()
- * @see #setAutoWhiteBalanceLock()
+ * @see #setAutoWhiteBalanceLock(boolean)
*/
public void setWhiteBalance(String value) {
set(KEY_WHITE_BALANCE, value);
@@ -3059,8 +3087,9 @@
* when using zoom.</p>
*
* <p>Focus area only has effect if the current focus mode is
- * {@link #FOCUS_MODE_AUTO}, {@link #FOCUS_MODE_MACRO}, or
- * {@link #FOCUS_MODE_CONTINUOUS_VIDEO}.</p>
+ * {@link #FOCUS_MODE_AUTO}, {@link #FOCUS_MODE_MACRO},
+ * {@link #FOCUS_MODE_CONTINUOUS_VIDEO}, or
+ * {@link #FOCUS_MODE_CONTINUOUS_PICTURE}.</p>
*
* @return a list of current focus areas
*/
@@ -3208,6 +3237,59 @@
return TRUE.equals(str);
}
+ /**
+ * <p>Enables and disables video stabilization. Use
+ * {@link #isVideoStabilizationSupported} to determine if calling this
+ * method is valid.</p>
+ *
+ * <p>Video stabilization reduces the shaking due to the motion of the
+ * camera in both the preview stream and in recorded videos, including
+ * data received from the preview callback. It does not reduce motion
+ * blur in images captured with
+ * {@link Camera#takePicture takePicture}.</p>
+ *
+ * <p>Video stabilization can be enabled and disabled while preview or
+ * recording is active, but toggling it may cause a jump in the video
+ * stream that may be undesirable in a recorded video.</p>
+ *
+ * @param toggle Set to true to enable video stabilization, and false to
+ * disable video stabilization.
+ * @see #isVideoStabilizationSupported()
+ * @see #getVideoStabilization()
+ * @hide
+ */
+ public void setVideoStabilization(boolean toggle) {
+ set(KEY_VIDEO_STABILIZATION, toggle ? TRUE : FALSE);
+ }
+
+ /**
+ * Get the current state of video stabilization. See
+ * {@link #setVideoStabilization} for details of video stabilization.
+ *
+ * @return true if video stabilization is enabled
+ * @see #isVideoStabilizationSupported()
+ * @see #setVideoStabilization(boolean)
+ * @hide
+ */
+ public boolean getVideoStabilization() {
+ String str = get(KEY_VIDEO_STABILIZATION);
+ return TRUE.equals(str);
+ }
+
+ /**
+ * Returns true if video stabilization is supported. See
+ * {@link #setVideoStabilization} for details of video stabilization.
+ *
+ * @return true if video stabilization is supported
+ * @see #setVideoStabilization(boolean)
+ * @see #getVideoStabilization()
+ * @hide
+ */
+ public boolean isVideoStabilizationSupported() {
+ String str = get(KEY_VIDEO_STABILIZATION_SUPPORTED);
+ return TRUE.equals(str);
+ }
+
// Splits a comma delimited string to an ArrayList of String.
// Return null if the passing string is null or the size is 0.
private ArrayList<String> split(String str) {
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 62bb965..54a89ad 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -197,7 +197,10 @@
String apnName = intent.getStringExtra(Phone.DATA_APN_KEY);
mNetworkInfo.setRoaming(intent.getBooleanExtra(Phone.DATA_NETWORK_ROAMING_KEY,
false));
-
+ if (VDBG) {
+ log(mApnType + " setting isAvailable to " +
+ intent.getBooleanExtra(Phone.NETWORK_UNAVAILABLE_KEY,false));
+ }
mNetworkInfo.setIsAvailable(!intent.getBooleanExtra(Phone.NETWORK_UNAVAILABLE_KEY,
false));
diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java
index aaad8a1..1b24f0c 100644
--- a/core/java/android/net/NetworkPolicy.java
+++ b/core/java/android/net/NetworkPolicy.java
@@ -40,6 +40,8 @@
public long limitBytes;
public long lastSnooze;
+ private static final long DEFAULT_MTU = 1500;
+
public NetworkPolicy(NetworkTemplate template, int cycleDay, long warningBytes, long limitBytes,
long lastSnooze) {
this.template = checkNotNull(template, "missing NetworkTemplate");
@@ -71,6 +73,17 @@
return 0;
}
+ /**
+ * Test if given measurement is near enough to {@link #limitBytes} to be
+ * considered over-limit.
+ */
+ public boolean isOverLimit(long totalBytes) {
+ // over-estimate, since kernel will trigger limit once first packet
+ // trips over limit.
+ totalBytes += 2 * DEFAULT_MTU;
+ return limitBytes != LIMIT_DISABLED && totalBytes >= limitBytes;
+ }
+
/** {@inheritDoc} */
public int compareTo(NetworkPolicy another) {
if (another == null || another.limitBytes == LIMIT_DISABLED) {
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 1735592..7df0193 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -132,6 +132,9 @@
* Returns an indication of whether this network is available for
* connections. A value of {@code false} means that some quasi-permanent
* condition prevents connectivity to this network.
+ *
+ * NOTE that this is broken on multi-connection devices. Should be fixed in J release
+ * TODO - fix on multi-pdp devices
*/
public boolean isAvailable();
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index da878d4..5fe58e9 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -162,6 +162,7 @@
synchronized void maybeRemoveState(Activity activity, NfcActivityState state) {
if (state.ndefMessage == null && state.ndefMessageCallback == null &&
state.onNdefPushCompleteCallback == null) {
+ NfcFragment.remove(activity);
mNfcState.remove(activity);
}
}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index fe0106d..33310df 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -768,61 +768,6 @@
}
/**
- * TODO: Remove this once pre-built apk's (Maps, Youtube etc) are updated
- * @deprecated use {@link CreateNdefMessageCallback} or {@link OnNdefPushCompleteCallback}
- * @hide
- */
- @Deprecated
- public interface NdefPushCallback {
- /**
- * @deprecated use {@link CreateNdefMessageCallback} instead
- */
- @Deprecated
- NdefMessage createMessage();
- /**
- * @deprecated use{@link OnNdefPushCompleteCallback} instead
- */
- @Deprecated
- void onMessagePushed();
- }
-
- /**
- * TODO: Remove this
- * Converts new callbacks to old callbacks.
- */
- static final class LegacyCallbackWrapper implements CreateNdefMessageCallback,
- OnNdefPushCompleteCallback {
- final NdefPushCallback mLegacyCallback;
- LegacyCallbackWrapper(NdefPushCallback legacyCallback) {
- mLegacyCallback = legacyCallback;
- }
- @Override
- public void onNdefPushComplete(NfcEvent event) {
- mLegacyCallback.onMessagePushed();
- }
- @Override
- public NdefMessage createNdefMessage(NfcEvent event) {
- return mLegacyCallback.createMessage();
- }
- }
-
- /**
- * TODO: Remove this once pre-built apk's (Maps, Youtube etc) are updated
- * @deprecated use {@link #setNdefPushMessageCallback} instead
- * @hide
- */
- @Deprecated
- public void enableForegroundNdefPush(Activity activity, final NdefPushCallback callback) {
- if (activity == null || callback == null) {
- throw new NullPointerException();
- }
- enforceResumed(activity);
- LegacyCallbackWrapper callbackWrapper = new LegacyCallbackWrapper(callback);
- mNfcActivityManager.setNdefPushMessageCallback(activity, callbackWrapper);
- mNfcActivityManager.setOnNdefPushCompleteCallback(activity, callbackWrapper);
- }
-
- /**
* Enable NDEF Push feature.
* <p>This API is for the Settings application.
* @hide
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 68385b4..cc2fa85 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -35,7 +35,6 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
@@ -902,6 +901,7 @@
return false;
}
+ // Thread policy controls BlockGuard.
int threadPolicyMask = StrictMode.DETECT_DISK_WRITE |
StrictMode.DETECT_DISK_READ |
StrictMode.DETECT_NETWORK;
@@ -915,10 +915,16 @@
StrictMode.setThreadPolicyMask(threadPolicyMask);
+ // VM Policy controls CloseGuard, detection of Activity leaks,
+ // and instance counting.
if (IS_USER_BUILD) {
setCloseGuardEnabled(false);
} else {
- setVmPolicy(new VmPolicy.Builder().detectAll().penaltyDropBox().build());
+ VmPolicy.Builder policyBuilder = new VmPolicy.Builder().detectAll().penaltyDropBox();
+ if (IS_ENG_BUILD) {
+ policyBuilder.penaltyLog();
+ }
+ setVmPolicy(policyBuilder.build());
setCloseGuardEnabled(vmClosableObjectLeaksEnabled());
}
return true;
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index d1dc6e5..0640d7e 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -658,6 +658,24 @@
return _result;
}
+ @Override
+ public int verifyEncryptionPassword(String password) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(password);
+ mRemote.transact(Stub.TRANSACTION_verifyEncryptionPassword, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
public Parcelable[] getVolumeList() throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
@@ -761,6 +779,8 @@
static final int TRANSACTION_getEncryptionState = IBinder.FIRST_CALL_TRANSACTION + 31;
+ static final int TRANSACTION_verifyEncryptionPassword = IBinder.FIRST_CALL_TRANSACTION + 32;
+
/**
* Cast an IBinder object into an IMountService interface, generating a
* proxy if needed.
@@ -1286,6 +1306,12 @@
public int changeEncryptionPassword(String password) throws RemoteException;
/**
+ * Verify the encryption password against the stored volume. This method
+ * may only be called by the system process.
+ */
+ public int verifyEncryptionPassword(String password) throws RemoteException;
+
+ /**
* Returns list of all mountable volumes.
*/
public Parcelable[] getVolumeList() throws RemoteException;
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 4b4d308..44f259a 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -300,8 +300,25 @@
public static final String CALENDAR_COLOR = "calendar_color";
/**
+ * An index for looking up a color from the {@link Colors} table. NULL
+ * or an empty string are reserved for indicating that the calendar does
+ * not use an index for looking up the color. The provider will update
+ * {@link #CALENDAR_COLOR} automatically when a valid index is written
+ * to this column. @see Colors
+ * <P>
+ * Type: TEXT
+ * </P>
+ * TODO UNHIDE
+ *
+ * @hide
+ */
+ public static final String CALENDAR_COLOR_INDEX = "calendar_color_index";
+
+ /**
* The display name of the calendar. Column name.
- * <P>Type: TEXT</P>
+ * <P>
+ * Type: TEXT
+ * </P>
*/
public static final String CALENDAR_DISPLAY_NAME = "calendar_displayName";
@@ -392,6 +409,34 @@
* <P>Type: TEXT</P>
*/
public static final String ALLOWED_REMINDERS = "allowedReminders";
+
+ /**
+ * A comma separated list of availability types supported for this
+ * calendar in the format "#,#,#". Valid types are
+ * {@link Events#AVAILABILITY_BUSY}, {@link Events#AVAILABILITY_FREE},
+ * {@link Events#AVAILABILITY_TENTATIVE}. Setting this field to only
+ * {@link Events#AVAILABILITY_BUSY} should be used to indicate that
+ * changing the availability is not supported.
+ *
+ * TODO UNHIDE, Update Calendars doc
+ *
+ * @hide
+ */
+ public static final String ALLOWED_AVAILABILITY = "allowedAvailability";
+
+ /**
+ * A comma separated list of attendee types supported for this calendar
+ * in the format "#,#,#". Valid types are {@link Attendees#TYPE_NONE},
+ * {@link Attendees#TYPE_OPTIONAL}, {@link Attendees#TYPE_REQUIRED},
+ * {@link Attendees#TYPE_RESOURCE}. Setting this field to only
+ * {@link Attendees#TYPE_NONE} should be used to indicate that changing
+ * the attendee type is not supported.
+ *
+ * TODO UNHIDE, Update Calendars doc
+ *
+ * @hide
+ */
+ public static final String ALLOWED_ATTENDEE_TYPES = "allowedAttendeeTypes";
}
/**
@@ -688,13 +733,22 @@
/**
* The type of attendee. Column name.
- * <P>Type: Integer (one of {@link #TYPE_REQUIRED}, {@link #TYPE_OPTIONAL})</P>
+ * <P>
+ * Type: Integer (one of {@link #TYPE_REQUIRED}, {@link #TYPE_OPTIONAL}
+ * </P>
*/
public static final String ATTENDEE_TYPE = "attendeeType";
public static final int TYPE_NONE = 0;
public static final int TYPE_REQUIRED = 1;
public static final int TYPE_OPTIONAL = 2;
+ /**
+ * This specifies that an attendee is a resource, such as a room, and
+ * not an actual person. TODO UNHIDE and add to ATTENDEE_TYPE comment
+ *
+ * @hide
+ */
+ public static final int TYPE_RESOURCE = 3;
/**
* The attendance status of the attendee. Column name.
@@ -787,13 +841,26 @@
public static final String EVENT_LOCATION = "eventLocation";
/**
- * A secondary color for the individual event. Reserved for future use.
- * Column name.
+ * A secondary color for the individual event. This should only be
+ * updated by the sync adapter for a given account.
* <P>Type: INTEGER</P>
*/
public static final String EVENT_COLOR = "eventColor";
/**
+ * A secondary color index for the individual event. NULL or an empty
+ * string are reserved for indicating that the event does not use an
+ * index for looking up the color. The provider will update
+ * {@link #EVENT_COLOR} automatically when a valid index is written to
+ * this column. @see Colors
+ * <P>Type: TEXT</P>
+ * TODO UNHIDE
+ *
+ * @hide
+ */
+ public static final String EVENT_COLOR_INDEX = "eventColor_index";
+
+ /**
* The event status. Column name.
* <P>Type: INTEGER (one of {@link #STATUS_TENTATIVE}...)</P>
*/
@@ -964,6 +1031,15 @@
* other events.
*/
public static final int AVAILABILITY_FREE = 1;
+ /**
+ * Indicates that the owner's availability may change, but should be
+ * considered busy time that will conflict.
+ *
+ * TODO UNHIDE
+ *
+ * @hide
+ */
+ public static final int AVAILABILITY_TENTATIVE = 2;
/**
* Whether the event has an alarm or not. Column name.
@@ -1335,7 +1411,9 @@
* <dd>When inserting a new event the following fields must be included:
* <ul>
* <li>dtstart</li>
- * <li>dtend -or- a (rrule or rdate) and a duration</li>
+ * <li>dtend if the event is non-recurring</li>
+ * <li>duration if the event is recurring</li>
+ * <li>rrule or rdate if the event is recurring</li>
* <li>a calendar_id</li>
* </ul>
* There are also further requirements when inserting or updating an event.
@@ -2224,6 +2302,81 @@
}
}
+ /**
+ * @hide
+ * TODO UNHIDE
+ */
+ protected interface ColorsColumns extends SyncStateContract.Columns {
+
+ /**
+ * The type of color, which describes how it should be used. Valid types
+ * are {@link #TYPE_CALENDAR} and {@link #TYPE_EVENT}. Column name.
+ * <P>
+ * Type: INTEGER (NOT NULL)
+ * </P>
+ */
+ public static final String COLOR_TYPE = "color_type";
+
+ /**
+ * This indicateds a color that can be used for calendars.
+ */
+ public static final int TYPE_CALENDAR = 0;
+ /**
+ * This indicates a color that can be used for events.
+ */
+ public static final int TYPE_EVENT = 1;
+
+ /**
+ * The index used to reference this color. This can be any non-empty
+ * string, but must be unique for a given {@link #ACCOUNT_TYPE} and
+ * {@link #ACCOUNT_NAME} . Column name.
+ * <P>
+ * Type: TEXT
+ * </P>
+ */
+ public static final String COLOR_INDEX = "color_index";
+
+ /**
+ * The color as an 8-bit ARGB integer value. Colors should specify alpha
+ * as fully opaque (eg 0xFF993322) as the alpha may be ignored or
+ * modified for display. It is reccomended that colors be usable with
+ * light (near white) text. Apps should not depend on that assumption,
+ * however. Column name.
+ * <P>
+ * Type: INTEGER (NOT NULL)
+ * </P>
+ */
+ public static final String COLOR = "color";
+
+ }
+
+ /**
+ * Fields for accessing colors available for a given account. Colors are
+ * referenced by {@link #COLOR_INDEX} which must be unique for a given
+ * account name/type. These values should only be updated by the sync
+ * adapter.
+ * TODO UNHIDE
+ *
+ * @hide
+ */
+ public static final class Colors implements ColorsColumns {
+ /**
+ * @hide
+ */
+ public static final String TABLE_NAME = "Colors";
+ /**
+ * The Uri for querying color information
+ */
+ @SuppressWarnings("hiding")
+ public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/colors");
+
+ /**
+ * This utility class cannot be instantiated
+ */
+ private Colors() {
+ }
+ }
+
protected interface ExtendedPropertiesColumns {
/**
* The event the extended property belongs to. Column name.
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 8483b4f..4bc0892 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -187,6 +187,59 @@
public static final String DEFERRED_SNIPPETING_QUERY = "deferred_snippeting_query";
/**
+ * <p>
+ * API for obtaining a pre-authorized version of a URI that normally requires special
+ * permission (beyond READ_CONTACTS) to read. The caller obtaining the pre-authorized URI
+ * must already have the necessary permissions to access the URI; otherwise a
+ * {@link SecurityException} will be thrown.
+ * </p>
+ * <p>
+ * The authorized URI returned in the bundle contains an expiring token that allows the
+ * caller to execute the query without having the special permissions that would normally
+ * be required.
+ * </p>
+ * <p>
+ * This API does not access disk, and should be safe to invoke from the UI thread.
+ * </p>
+ * <p>
+ * Example usage:
+ * <pre>
+ * Uri profileUri = ContactsContract.Profile.CONTENT_VCARD_URI;
+ * Bundle uriBundle = new Bundle();
+ * uriBundle.putParcelable(ContactsContract.Authorization.KEY_URI_TO_AUTHORIZE, uri);
+ * Bundle authResponse = getContext().getContentResolver().call(
+ * ContactsContract.AUTHORITY_URI,
+ * ContactsContract.Authorization.AUTHORIZATION_METHOD,
+ * null, // String arg, not used.
+ * uriBundle);
+ * if (authResponse != null) {
+ * Uri preauthorizedProfileUri = (Uri) authResponse.getParcelable(
+ * ContactsContract.Authorization.KEY_AUTHORIZED_URI);
+ * // This pre-authorized URI can be queried by a caller without READ_PROFILE
+ * // permission.
+ * }
+ * </pre>
+ * </p>
+ * @hide
+ */
+ public static final class Authorization {
+ /**
+ * The method to invoke to create a pre-authorized URI out of the input argument.
+ */
+ public static final String AUTHORIZATION_METHOD = "authorize";
+
+ /**
+ * The key to set in the outbound Bundle with the URI that should be authorized.
+ */
+ public static final String KEY_URI_TO_AUTHORIZE = "uri_to_authorize";
+
+ /**
+ * The key to retrieve from the returned Bundle to obtain the pre-authorized URI.
+ */
+ public static final String KEY_AUTHORIZED_URI = "authorized_uri";
+ }
+
+ /**
* @hide
*/
public static final class Preferences {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index bc05078..5754e60 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4053,6 +4053,14 @@
public static final String PACKAGE_VERIFIER_TIMEOUT = "verifier_timeout";
/**
+ * Duration in milliseconds before pre-authorized URIs for the contacts
+ * provider should expire.
+ * @hide
+ */
+ public static final String CONTACTS_PREAUTH_URI_EXPIRATION =
+ "contacts_preauth_uri_expiration";
+
+ /**
* This are the settings to be backed up.
*
* NOTE: Settings are backed up and restored in the order they appear
@@ -4087,7 +4095,9 @@
MOUNT_UMS_AUTOSTART,
MOUNT_UMS_PROMPT,
MOUNT_UMS_NOTIFY_ENABLED,
- UI_NIGHT_MODE
+ UI_NIGHT_MODE,
+ LOCK_SCREEN_OWNER_INFO,
+ LOCK_SCREEN_OWNER_INFO_ENABLED
};
/**
diff --git a/core/java/android/service/textservice/SpellCheckerService.java b/core/java/android/service/textservice/SpellCheckerService.java
index b96099e..2ecf307 100644
--- a/core/java/android/service/textservice/SpellCheckerService.java
+++ b/core/java/android/service/textservice/SpellCheckerService.java
@@ -35,6 +35,28 @@
* SpellCheckerService provides an abstract base class for a spell checker.
* This class combines a service to the system with the spell checker service interface that
* spell checker must implement.
+ *
+ * <p>In addition to the normal Service lifecycle methods, this class
+ * introduces a new specific callback that subclasses should override
+ * {@link #createSession()} to provide a spell checker session that is corresponding
+ * to requested language and so on. The spell checker session returned by this method
+ * should extend {@link SpellCheckerService.Session}.
+ * </p>
+ *
+ * <h3>Returning spell check results</h3>
+ *
+ * <p>{@link SpellCheckerService.Session#onGetSuggestions(TextInfo, int)}
+ * should return spell check results.
+ * It receives {@link android.view.textservice.TextInfo} and returns
+ * {@link android.view.textservice.SuggestionsInfo} for the input.
+ * You may want to override
+ * {@link SpellCheckerService.Session#onGetSuggestionsMultiple(TextInfo[], int, boolean)} for
+ * better performance and quality.
+ * </p>
+ *
+ * <p>Please note that {@link SpellCheckerService.Session#getLocale()} does not return a valid
+ * locale before {@link SpellCheckerService.Session#onCreate()} </p>
+ *
*/
public abstract class SpellCheckerService extends Service {
private static final String TAG = SpellCheckerService.class.getSimpleName();
@@ -89,7 +111,7 @@
* but will be called in series on another thread.
* @param textInfo the text metadata
* @param suggestionsLimit the number of limit of suggestions returned
- * @return SuggestionInfo which contains suggestions for textInfo
+ * @return SuggestionsInfo which contains suggestions for textInfo
*/
public abstract SuggestionsInfo onGetSuggestions(TextInfo textInfo, int suggestionsLimit);
@@ -101,7 +123,7 @@
* @param textInfos an array of the text metadata
* @param suggestionsLimit the number of limit of suggestions returned
* @param sequentialWords true if textInfos can be treated as sequential words.
- * @return an array of SuggestionInfo of onGetSuggestions
+ * @return an array of SuggestionsInfo of onGetSuggestions
*/
public SuggestionsInfo[] onGetSuggestionsMultiple(TextInfo[] textInfos,
int suggestionsLimit, boolean sequentialWords) {
diff --git a/core/java/android/service/textservice/package.html b/core/java/android/service/textservice/package.html
new file mode 100644
index 0000000..89c6dbc
--- /dev/null
+++ b/core/java/android/service/textservice/package.html
@@ -0,0 +1,38 @@
+<HTML>
+<BODY>
+<p>Provides classes that allow you to create spell checkers in a manner similar to the
+input method framework (for IMEs).</p>
+
+<p>To create a new spell checker, you must implement a service that extends {@link
+android.service.textservice.SpellCheckerService} and extend the {@link
+android.service.textservice.SpellCheckerService.Session} class to provide spelling suggestions based
+on text provided by the interface's callback methods. In the {@link
+android.service.textservice.SpellCheckerService.Session} callback methods, you must return the
+spelling suggestions as {@link android.view.textservice.SuggestionsInfo} objects. </p>
+
+<p>Applications with a spell checker service must declare the {@link
+android.Manifest.permission#BIND_TEXT_SERVICE} permission as required by the service. The service
+must also declare an intent filter with {@code <action
+android:name="android.service.textservice.SpellCheckerService" />} as the intent’s action and should
+include a {@code <meta-data>} element that declares configuration information for the spell
+checker. For example:</p>
+
+<pre>
+<service
+ android:label="@string/app_name"
+ android:name=".SampleSpellCheckerService"
+ android:permission="android.permission.BIND_TEXT_SERVICE" >
+ <intent-filter >
+ <action android:name="android.service.textservice.SpellCheckerService" />
+ </intent-filter>
+ <meta-data
+ android:name="android.view.textservice.scs"
+ android:resource="@xml/spellchecker" />
+</service>
+</pre>
+
+<p>For example code, see the <a
+href="{@docRoot}resources/samples/SampleSpellCheckerService/index.html">Spell
+Checker</a> sample app.</p>
+</BODY>
+</HTML>
diff --git a/core/java/android/speech/tts/TtsEngines.java b/core/java/android/speech/tts/TtsEngines.java
index bb72bea..2706bc7 100644
--- a/core/java/android/speech/tts/TtsEngines.java
+++ b/core/java/android/speech/tts/TtsEngines.java
@@ -344,7 +344,10 @@
String v1Locale = lang;
if (!TextUtils.isEmpty(country)) {
v1Locale += LOCALE_DELIMITER + country;
+ } else {
+ return v1Locale;
}
+
if (!TextUtils.isEmpty(variant)) {
v1Locale += LOCALE_DELIMITER + variant;
}
@@ -355,8 +358,28 @@
private String getDefaultLocale() {
final Locale locale = Locale.getDefault();
- return locale.getISO3Language() + LOCALE_DELIMITER + locale.getISO3Country() +
- LOCALE_DELIMITER + locale.getVariant();
+ // Note that the default locale might have an empty variant
+ // or language, and we take care that the construction is
+ // the same as {@link #getV1Locale} i.e no trailing delimiters
+ // or spaces.
+ String defaultLocale = locale.getISO3Language();
+ if (TextUtils.isEmpty(defaultLocale)) {
+ Log.w(TAG, "Default locale is empty.");
+ return "";
+ }
+
+ if (!TextUtils.isEmpty(locale.getISO3Country())) {
+ defaultLocale += LOCALE_DELIMITER + locale.getISO3Country();
+ } else {
+ // Do not allow locales of the form lang--variant with
+ // an empty country.
+ return defaultLocale;
+ }
+ if (!TextUtils.isEmpty(locale.getVariant())) {
+ defaultLocale += LOCALE_DELIMITER + locale.getVariant();
+ }
+
+ return defaultLocale;
}
/**
diff --git a/core/java/android/text/CharSequenceIterator.java b/core/java/android/text/CharSequenceIterator.java
deleted file mode 100644
index 4b8ac10..0000000
--- a/core/java/android/text/CharSequenceIterator.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import java.text.CharacterIterator;
-
-/** {@hide} */
-public class CharSequenceIterator implements CharacterIterator {
- private final CharSequence mValue;
-
- private final int mLength;
- private int mIndex;
-
- public CharSequenceIterator(CharSequence value) {
- mValue = value;
- mLength = value.length();
- mIndex = 0;
- }
-
- @Override
- public Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException e) {
- throw new AssertionError(e);
- }
- }
-
- /** {@inheritDoc} */
- public char current() {
- if (mIndex == mLength) {
- return DONE;
- }
- return mValue.charAt(mIndex);
- }
-
- /** {@inheritDoc} */
- public int getBeginIndex() {
- return 0;
- }
-
- /** {@inheritDoc} */
- public int getEndIndex() {
- return mLength;
- }
-
- /** {@inheritDoc} */
- public int getIndex() {
- return mIndex;
- }
-
- /** {@inheritDoc} */
- public char first() {
- return setIndex(0);
- }
-
- /** {@inheritDoc} */
- public char last() {
- return setIndex(mLength - 1);
- }
-
- /** {@inheritDoc} */
- public char next() {
- if (mIndex == mLength) {
- return DONE;
- }
- return setIndex(mIndex + 1);
- }
-
- /** {@inheritDoc} */
- public char previous() {
- if (mIndex == 0) {
- return DONE;
- }
- return setIndex(mIndex - 1);
- }
-
- /** {@inheritDoc} */
- public char setIndex(int index) {
- if ((index < 0) || (index > mLength)) {
- throw new IllegalArgumentException("Valid range is [" + 0 + "..." + mLength + "]");
- }
- mIndex = index;
- return current();
- }
-}
diff --git a/core/java/android/text/method/ArrowKeyMovementMethod.java b/core/java/android/text/method/ArrowKeyMovementMethod.java
index b8728ee..4ec4bc4 100644
--- a/core/java/android/text/method/ArrowKeyMovementMethod.java
+++ b/core/java/android/text/method/ArrowKeyMovementMethod.java
@@ -35,11 +35,11 @@
(MetaKeyKeyListener.getMetaState(buffer, MetaKeyKeyListener.META_SELECTING) != 0));
}
- private int getCurrentLineTop(Spannable buffer, Layout layout) {
+ private static int getCurrentLineTop(Spannable buffer, Layout layout) {
return layout.getLineTop(layout.getLineForOffset(Selection.getSelectionEnd(buffer)));
}
- private int getPageHeight(TextView widget) {
+ private static int getPageHeight(TextView widget) {
// This calculation does not take into account the view transformations that
// may have been applied to the child or its containers. In case of scaling or
// rotation, the calculated page height may be incorrect.
@@ -196,15 +196,19 @@
/** {@hide} */
@Override
protected boolean leftWord(TextView widget, Spannable buffer) {
- mWordIterator.setCharSequence(buffer);
- return Selection.moveToPreceding(buffer, mWordIterator, isSelecting(buffer));
+ final int selectionEnd = widget.getSelectionEnd();
+ final WordIterator wordIterator = widget.getWordIterator();
+ wordIterator.setCharSequence(buffer, selectionEnd, selectionEnd);
+ return Selection.moveToPreceding(buffer, wordIterator, isSelecting(buffer));
}
/** {@hide} */
@Override
protected boolean rightWord(TextView widget, Spannable buffer) {
- mWordIterator.setCharSequence(buffer);
- return Selection.moveToFollowing(buffer, mWordIterator, isSelecting(buffer));
+ final int selectionEnd = widget.getSelectionEnd();
+ final WordIterator wordIterator = widget.getWordIterator();
+ wordIterator.setCharSequence(buffer, selectionEnd, selectionEnd);
+ return Selection.moveToFollowing(buffer, wordIterator, isSelecting(buffer));
}
@Override
@@ -320,8 +324,6 @@
return sInstance;
}
- private WordIterator mWordIterator = new WordIterator();
-
private static final Object LAST_TAP_DOWN = new Object();
private static ArrowKeyMovementMethod sInstance;
}
diff --git a/core/java/android/text/method/WordIterator.java b/core/java/android/text/method/WordIterator.java
index af524ee..239d9e8 100644
--- a/core/java/android/text/method/WordIterator.java
+++ b/core/java/android/text/method/WordIterator.java
@@ -17,14 +17,9 @@
package android.text.method;
-import android.text.CharSequenceIterator;
-import android.text.Editable;
import android.text.Selection;
-import android.text.Spanned;
-import android.text.TextWatcher;
import java.text.BreakIterator;
-import java.text.CharacterIterator;
import java.util.Locale;
/**
@@ -36,8 +31,11 @@
* {@hide}
*/
public class WordIterator implements Selection.PositionIterator {
- private CharSequence mCurrent;
- private boolean mCurrentDirty = false;
+ // Size of the window for the word iterator, should be greater than the longest word's length
+ private static final int WINDOW_WIDTH = 50;
+
+ private String mString;
+ private int mOffsetShift;
private BreakIterator mIterator;
@@ -56,70 +54,40 @@
mIterator = BreakIterator.getWordInstance(locale);
}
- private final TextWatcher mWatcher = new TextWatcher() {
- /** {@inheritDoc} */
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- // ignored
- }
+ public void setCharSequence(CharSequence charSequence, int start, int end) {
+ mOffsetShift = Math.max(0, start - WINDOW_WIDTH);
+ final int windowEnd = Math.min(charSequence.length(), end + WINDOW_WIDTH);
- /** {@inheritDoc} */
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- mCurrentDirty = true;
- }
-
- /** {@inheritDoc} */
- public void afterTextChanged(Editable s) {
- // ignored
- }
- };
-
- public void setCharSequence(CharSequence incoming) {
- // When incoming is different object, move listeners to new sequence
- // and mark as dirty so we reload contents.
- if (mCurrent != incoming) {
- if (mCurrent instanceof Editable) {
- ((Editable) mCurrent).removeSpan(mWatcher);
- }
-
- if (incoming instanceof Editable) {
- ((Editable) incoming).setSpan(
- mWatcher, 0, incoming.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
- }
-
- mCurrent = incoming;
- mCurrentDirty = true;
- }
-
- if (mCurrentDirty) {
- final CharacterIterator charIterator = new CharSequenceIterator(mCurrent);
- mIterator.setText(charIterator);
-
- mCurrentDirty = false;
- }
+ mString = charSequence.toString().substring(mOffsetShift, windowEnd);
+ mIterator.setText(mString);
}
/** {@inheritDoc} */
public int preceding(int offset) {
+ int shiftedOffset = offset - mOffsetShift;
do {
- offset = mIterator.preceding(offset);
- if (offset == BreakIterator.DONE || isOnLetterOrDigit(offset)) {
- break;
+ shiftedOffset = mIterator.preceding(shiftedOffset);
+ if (shiftedOffset == BreakIterator.DONE) {
+ return BreakIterator.DONE;
+ }
+ if (isOnLetterOrDigit(shiftedOffset)) {
+ return shiftedOffset + mOffsetShift;
}
} while (true);
-
- return offset;
}
/** {@inheritDoc} */
public int following(int offset) {
+ int shiftedOffset = offset - mOffsetShift;
do {
- offset = mIterator.following(offset);
- if (offset == BreakIterator.DONE || isAfterLetterOrDigit(offset)) {
- break;
+ shiftedOffset = mIterator.following(shiftedOffset);
+ if (shiftedOffset == BreakIterator.DONE) {
+ return BreakIterator.DONE;
+ }
+ if (isAfterLetterOrDigit(shiftedOffset)) {
+ return shiftedOffset + mOffsetShift;
}
} while (true);
-
- return offset;
}
/** If <code>offset</code> is within a word, returns the index of the first character of that
@@ -135,17 +103,18 @@
* @throws IllegalArgumentException is offset is not valid.
*/
public int getBeginning(int offset) {
- checkOffsetIsValid(offset);
+ final int shiftedOffset = offset - mOffsetShift;
+ checkOffsetIsValid(shiftedOffset);
- if (isOnLetterOrDigit(offset)) {
- if (mIterator.isBoundary(offset)) {
- return offset;
+ if (isOnLetterOrDigit(shiftedOffset)) {
+ if (mIterator.isBoundary(shiftedOffset)) {
+ return shiftedOffset + mOffsetShift;
} else {
- return mIterator.preceding(offset);
+ return mIterator.preceding(shiftedOffset) + mOffsetShift;
}
} else {
- if (isAfterLetterOrDigit(offset)) {
- return mIterator.preceding(offset);
+ if (isAfterLetterOrDigit(shiftedOffset)) {
+ return mIterator.preceding(shiftedOffset) + mOffsetShift;
}
}
return BreakIterator.DONE;
@@ -164,58 +133,44 @@
* @throws IllegalArgumentException is offset is not valid.
*/
public int getEnd(int offset) {
- checkOffsetIsValid(offset);
+ final int shiftedOffset = offset - mOffsetShift;
+ checkOffsetIsValid(shiftedOffset);
- if (isAfterLetterOrDigit(offset)) {
- if (mIterator.isBoundary(offset)) {
- return offset;
+ if (isAfterLetterOrDigit(shiftedOffset)) {
+ if (mIterator.isBoundary(shiftedOffset)) {
+ return shiftedOffset + mOffsetShift;
} else {
- return mIterator.following(offset);
+ return mIterator.following(shiftedOffset) + mOffsetShift;
}
} else {
- if (isOnLetterOrDigit(offset)) {
- return mIterator.following(offset);
+ if (isOnLetterOrDigit(shiftedOffset)) {
+ return mIterator.following(shiftedOffset) + mOffsetShift;
}
}
return BreakIterator.DONE;
}
- private boolean isAfterLetterOrDigit(int offset) {
- if (offset - 1 >= 0) {
- final char previousChar = mCurrent.charAt(offset - 1);
- if (Character.isLetterOrDigit(previousChar)) return true;
- if (offset - 2 >= 0) {
- final char previousPreviousChar = mCurrent.charAt(offset - 2);
- if (Character.isSurrogatePair(previousPreviousChar, previousChar)) {
- final int codePoint = Character.toCodePoint(previousPreviousChar, previousChar);
- return Character.isLetterOrDigit(codePoint);
- }
- }
+ private boolean isAfterLetterOrDigit(int shiftedOffset) {
+ if (shiftedOffset >= 1 && shiftedOffset <= mString.length()) {
+ final int codePoint = mString.codePointBefore(shiftedOffset);
+ if (Character.isLetterOrDigit(codePoint)) return true;
}
return false;
}
- private boolean isOnLetterOrDigit(int offset) {
- final int length = mCurrent.length();
- if (offset < length) {
- final char currentChar = mCurrent.charAt(offset);
- if (Character.isLetterOrDigit(currentChar)) return true;
- if (offset + 1 < length) {
- final char nextChar = mCurrent.charAt(offset + 1);
- if (Character.isSurrogatePair(currentChar, nextChar)) {
- final int codePoint = Character.toCodePoint(currentChar, nextChar);
- return Character.isLetterOrDigit(codePoint);
- }
- }
+ private boolean isOnLetterOrDigit(int shiftedOffset) {
+ if (shiftedOffset >= 0 && shiftedOffset < mString.length()) {
+ final int codePoint = mString.codePointAt(shiftedOffset);
+ if (Character.isLetterOrDigit(codePoint)) return true;
}
return false;
}
- private void checkOffsetIsValid(int offset) {
- if (offset < 0 || offset > mCurrent.length()) {
- final String message = "Invalid offset: " + offset +
- ". Valid range is [0, " + mCurrent.length() + "]";
- throw new IllegalArgumentException(message);
+ private void checkOffsetIsValid(int shiftedOffset) {
+ if (shiftedOffset < 0 || shiftedOffset > mString.length()) {
+ throw new IllegalArgumentException("Invalid offset: " + (shiftedOffset + mOffsetShift) +
+ ". Valid range is [" + mOffsetShift + ", " + (mString.length() + mOffsetShift) +
+ "]");
}
}
}
diff --git a/core/java/android/view/ContextMenu.java b/core/java/android/view/ContextMenu.java
index dd1d7db..decabcb 100644
--- a/core/java/android/view/ContextMenu.java
+++ b/core/java/android/view/ContextMenu.java
@@ -29,6 +29,12 @@
* To show a context menu on long click, most clients will want to call
* {@link Activity#registerForContextMenu} and override
* {@link Activity#onCreateContextMenu}.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about creating menus, read the
+ * <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guide.</p>
+ * </div>
*/
public interface ContextMenu extends Menu {
/**
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 3bd0f76..ad2283e 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -117,6 +117,11 @@
outSize.x = getRawWidth();
outSize.y = getRawHeight();
}
+ if (false) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.v(TAG, "Returning display size: " + outSize, here);
+ }
if (DEBUG_DISPLAY_SIZE && doCompat) Slog.v(
TAG, "Returning display size: " + outSize);
} catch (RemoteException e) {
diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java
index 8f491ef..f559e21 100644
--- a/core/java/android/view/DragEvent.java
+++ b/core/java/android/view/DragEvent.java
@@ -114,6 +114,12 @@
* {@link android.view.DragEvent#writeToParcel(Parcel,int)}, and
* {@link android.view.DragEvent#toString()} methods always return valid data.
* </p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For a guide to implementing drag and drop features, read the
+ * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
+ * </div>
*/
public class DragEvent implements Parcelable {
private static final boolean TRACK_RECYCLED_LOCATION = false;
diff --git a/core/java/android/view/Menu.java b/core/java/android/view/Menu.java
index 97825e6..7157bc5 100644
--- a/core/java/android/view/Menu.java
+++ b/core/java/android/view/Menu.java
@@ -41,6 +41,12 @@
* item check marks are discouraged.
* <li><b>Sub menus</b>: Do not support item icons, or nested sub menus.
* </ol>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating menus, read the
+ * <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guide.</p>
+ * </div>
*/
public interface Menu {
diff --git a/core/java/android/view/MenuItem.java b/core/java/android/view/MenuItem.java
index ccd8353..2dfbcb5 100644
--- a/core/java/android/view/MenuItem.java
+++ b/core/java/android/view/MenuItem.java
@@ -29,6 +29,12 @@
* methods.
* <p>
* For a feature set of specific menu types, see {@link Menu}.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about creating menus, read the
+ * <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guide.</p>
+ * </div>
*/
public interface MenuItem {
/*
diff --git a/core/java/android/view/SubMenu.java b/core/java/android/view/SubMenu.java
index e981486..196a183 100644
--- a/core/java/android/view/SubMenu.java
+++ b/core/java/android/view/SubMenu.java
@@ -22,6 +22,12 @@
* Subclass of {@link Menu} for sub menus.
* <p>
* Sub menus do not support item icons, or nested sub menus.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about creating menus, read the
+ * <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guide.</p>
+ * </div>
*/
public interface SubMenu extends Menu {
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 64d3d31..2b254af 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -194,6 +194,9 @@
*/
public static final int FX_SURFACE_DIM = 0x00020000;
+ /** @hide */
+ public static final int FX_SURFACE_SCREENSHOT = 0x00030000;
+
/** Mask used for FX values above @hide */
public static final int FX_SURFACE_MASK = 0x000F0000;
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index d57132a..1697382 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -502,9 +502,23 @@
* @see #isAvailable()
* @see #getBitmap(int, int)
* @see #getBitmap()
+ *
+ * @throws IllegalStateException if the hardware rendering context cannot be
+ * acquired to capture the bitmap
*/
public Bitmap getBitmap(Bitmap bitmap) {
if (bitmap != null && isAvailable()) {
+ AttachInfo info = mAttachInfo;
+ if (info != null && info.mHardwareRenderer != null &&
+ info.mHardwareRenderer.isEnabled()) {
+ if (!info.mHardwareRenderer.validate()) {
+ throw new IllegalStateException("Could not acquire hardware rendering context");
+ }
+ }
+
+ applyUpdate();
+ applyTransformMatrix();
+
mLayer.copyInto(bitmap);
}
return bitmap;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 15544cc..a2f9b36 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -418,7 +418,7 @@
* <h3>Drawing</h3>
* <p>
* Drawing is handled by walking the tree and rendering each view that
- * intersects the the invalid region. Because the tree is traversed in-order,
+ * intersects the invalid region. Because the tree is traversed in-order,
* this means that parents will draw before (i.e., behind) their children, with
* siblings drawn in the order they appear in the tree.
* If you set a background drawable for a View, then the View will draw it for you
@@ -1486,7 +1486,8 @@
| AccessibilityEvent.TYPE_VIEW_FOCUSED
| AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
| AccessibilityEvent.TYPE_VIEW_HOVER_ENTER
- | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT;
+ | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT
+ | AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED;
/**
* Temporary Rect currently for use in setBackground(). This will probably
@@ -1890,12 +1891,10 @@
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
- * Flag to hide only the navigation buttons. Don't use this
+ * Flag to hide only the home button. Don't use this
* unless you're a special part of the system UI (i.e., setup wizard, keyguard).
- *
- * THIS DOES NOT DISABLE THE BACK BUTTON
*/
- public static final int STATUS_BAR_DISABLE_NAVIGATION = 0x00200000;
+ public static final int STATUS_BAR_DISABLE_HOME = 0x00200000;
/**
* @hide
@@ -1903,7 +1902,7 @@
* NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
* out of the public fields to keep the undefined bits out of the developer's way.
*
- * Flag to hide only the back button. Don't use this
+ * Flag to hide only the back button. Don't use this
* unless you're a special part of the system UI (i.e., setup wizard, keyguard).
*/
public static final int STATUS_BAR_DISABLE_BACK = 0x00400000;
@@ -1921,6 +1920,28 @@
/**
* @hide
+ *
+ * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+ * out of the public fields to keep the undefined bits out of the developer's way.
+ *
+ * Flag to hide only the recent apps button. Don't use this
+ * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
+ */
+ public static final int STATUS_BAR_DISABLE_RECENT = 0x01000000;
+
+ /**
+ * @hide
+ *
+ * NOTE: This flag may only be used in subtreeSystemUiVisibility, etc. etc.
+ *
+ * This hides HOME and RECENT and is provided for compatibility with interim implementations.
+ */
+ @Deprecated
+ public static final int STATUS_BAR_DISABLE_NAVIGATION =
+ STATUS_BAR_DISABLE_HOME | STATUS_BAR_DISABLE_RECENT;
+
+ /**
+ * @hide
*/
public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x0000FFFF;
@@ -3809,7 +3830,10 @@
* responsible for handling this call.
* </p>
*
- * @param eventType The type of the event to send.
+ * @param eventType The type of the event to send, as defined by several types from
+ * {@link android.view.accessibility.AccessibilityEvent}, such as
+ * {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED} or
+ * {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}.
*
* @see #onInitializeAccessibilityEvent(AccessibilityEvent)
* @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
@@ -3922,27 +3946,28 @@
/**
* Called from {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
* giving a chance to this View to populate the accessibility event with its
- * text content. While the implementation is free to modify other event
- * attributes this should be performed in
+ * text content. While this method is free to modify event
+ * attributes other than text content, doing so should normally be performed in
* {@link #onInitializeAccessibilityEvent(AccessibilityEvent)}.
* <p>
* Example: Adding formatted date string to an accessibility event in addition
- * to the text added by the super implementation.
- * </p><p><pre><code>
- * public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+ * to the text added by the super implementation:
+ * <pre> public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
* super.onPopulateAccessibilityEvent(event);
* final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY;
* String selectedDateUtterance = DateUtils.formatDateTime(mContext,
* mCurrentDate.getTimeInMillis(), flags);
* event.getText().add(selectedDateUtterance);
- * }
- * </code></pre></p>
+ * }</pre>
* <p>
* If an {@link AccessibilityDelegate} has been specified via calling
* {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
* {@link AccessibilityDelegate#onPopulateAccessibilityEvent(View, AccessibilityEvent)}
* is responsible for handling this call.
* </p>
+ * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
+ * information to the event, in case the default implementation has basic information to add.
+ * </p>
*
* @param event The accessibility event which to populate.
*
@@ -3973,20 +3998,20 @@
* the event.
* <p>
* Example: Setting the password property of an event in addition
- * to properties set by the super implementation.
- * </p><p><pre><code>
- * public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
- * super.onInitializeAccessibilityEvent(event);
- * event.setPassword(true);
- * }
- * </code></pre></p>
+ * to properties set by the super implementation:
+ * <pre> public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+ * super.onInitializeAccessibilityEvent(event);
+ * event.setPassword(true);
+ * }</pre>
* <p>
* If an {@link AccessibilityDelegate} has been specified via calling
* {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
* {@link AccessibilityDelegate#onInitializeAccessibilityEvent(View, AccessibilityEvent)}
* is responsible for handling this call.
* </p>
- *
+ * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
+ * information to the event, in case the default implementation has basic information to add.
+ * </p>
* @param event The event to initialize.
*
* @see #sendAccessibilityEvent(int)
@@ -6158,8 +6183,7 @@
* are delivered to the view under the pointer. All other generic motion events are
* delivered to the focused view.
* </p>
- * <code>
- * public boolean onGenericMotionEvent(MotionEvent event) {
+ * <pre> public boolean onGenericMotionEvent(MotionEvent event) {
* if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
* if (event.getAction() == MotionEvent.ACTION_MOVE) {
* // process the joystick movement...
@@ -6177,8 +6201,7 @@
* }
* }
* return super.onGenericMotionEvent(event);
- * }
- * </code>
+ * }</pre>
*
* @param event The generic motion event being processed.
* @return True if the event was handled, false otherwise.
@@ -8343,7 +8366,7 @@
!((ViewGroup) mParent).isViewTransitioning(this));
}
/**
- * Mark the the area defined by dirty as needing to be drawn. If the view is
+ * Mark the area defined by dirty as needing to be drawn. If the view is
* visible, {@link #onDraw(android.graphics.Canvas)} will be called at some point
* in the future. This must be called from a UI thread. To call from a non-UI
* thread, call {@link #postInvalidate()}.
@@ -8388,7 +8411,7 @@
}
/**
- * Mark the the area defined by the rect (l,t,r,b) as needing to be drawn.
+ * Mark the area defined by the rect (l,t,r,b) as needing to be drawn.
* The coordinates of the dirty rect are relative to the view.
* If the view is visible, {@link #onDraw(android.graphics.Canvas)}
* will be called at some point in the future. This must be called from
@@ -10091,8 +10114,20 @@
mLocalDirtyRect.setEmpty();
}
+ // The layer is not valid if the underlying GPU resources cannot be allocated
+ if (!mHardwareLayer.isValid()) {
+ return null;
+ }
+
HardwareCanvas currentCanvas = mAttachInfo.mHardwareCanvas;
final HardwareCanvas canvas = mHardwareLayer.start(currentCanvas);
+
+ // Make sure all the GPU resources have been properly allocated
+ if (canvas == null) {
+ mHardwareLayer.end(currentCanvas);
+ return null;
+ }
+
mAttachInfo.mHardwareCanvas = canvas;
try {
canvas.setViewport(width, height);
@@ -10125,6 +10160,14 @@
return mHardwareLayer;
}
+ /**
+ * Destroys this View's hardware layer if possible.
+ *
+ * @return True if the layer was destroyed, false otherwise.
+ *
+ * @see #setLayerType(int, android.graphics.Paint)
+ * @see #LAYER_TYPE_HARDWARE
+ */
boolean destroyLayer() {
if (mHardwareLayer != null) {
mHardwareLayer.destroy();
@@ -13066,6 +13109,12 @@
* {@link android.graphics.Canvas} object, then it calls {@link #onDrawShadow(Canvas) onDrawShadow()}
* so that your application can draw the shadow image in the Canvas.
* </p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For a guide to implementing drag and drop features, read the
+ * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
+ * </div>
*/
public static class DragShadowBuilder {
private final WeakReference<View> mView;
@@ -14057,6 +14106,12 @@
* to this view. The callback will be invoked before the hosting view's own
* onDrag(event) method. If the listener wants to fall back to the hosting view's
* onDrag(event) behavior, it should return 'false' from this callback.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For a guide to implementing drag and drop features, read the
+ * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
+ * </div>
*/
public interface OnDragListener {
/**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 9266ae2..62b20b3 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -60,6 +60,12 @@
* Also see {@link LayoutParams} for layout attributes.
* </p>
*
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating user interface layouts, read the
+ * <a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a> developer
+ * guide.</p></div>
+ *
* @attr ref android.R.styleable#ViewGroup_clipChildren
* @attr ref android.R.styleable#ViewGroup_clipToPadding
* @attr ref android.R.styleable#ViewGroup_layoutAnimation
@@ -5158,7 +5164,13 @@
* </ul>
* There are subclasses of LayoutParams for different subclasses of
* ViewGroup. For example, AbsoluteLayout has its own subclass of
- * LayoutParams which adds an X and Y value.
+ * LayoutParams which adds an X and Y value.</p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating user interface layouts, read the
+ * <a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a> developer
+ * guide.</p></div>
*
* @attr ref android.R.styleable#ViewGroup_Layout_layout_height
* @attr ref android.R.styleable#ViewGroup_Layout_layout_width
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 7eae739..abb5bc8 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -108,6 +108,7 @@
private static final boolean DEBUG_TRACKBALL = false || LOCAL_LOGV;
private static final boolean DEBUG_IMF = false || LOCAL_LOGV;
private static final boolean DEBUG_CONFIGURATION = false || LOCAL_LOGV;
+ private static final boolean DEBUG_FPS = false;
private static final boolean WATCH_POINTER = false;
/**
@@ -274,6 +275,11 @@
private Thread mRenderProfiler;
private volatile boolean mRenderProfilingEnabled;
+ // Variables to track frames per second, enabled via DEBUG_FPS flag
+ private long mFpsStartTime = -1;
+ private long mFpsPrevTime = -1;
+ private int mFpsNumFrames;
+
/**
* see {@link #playSoundEffect(int)}
*/
@@ -425,20 +431,17 @@
}
}
+ CompatibilityInfo compatibilityInfo = mCompatibilityInfo.get();
+ mTranslator = compatibilityInfo.getTranslator();
+
// If the application owns the surface, don't enable hardware acceleration
if (mSurfaceHolder == null) {
enableHardwareAcceleration(attrs);
}
- CompatibilityInfo compatibilityInfo = mCompatibilityInfo.get();
- mTranslator = compatibilityInfo.getTranslator();
-
- if (mTranslator != null) {
- mSurface.setCompatibilityTranslator(mTranslator);
- }
-
boolean restore = false;
if (mTranslator != null) {
+ mSurface.setCompatibilityTranslator(mTranslator);
restore = true;
attrs.backup();
mTranslator.translateWindowLayout(attrs);
@@ -590,6 +593,9 @@
mAttachInfo.mHardwareAccelerated = false;
mAttachInfo.mHardwareAccelerationRequested = false;
+ // Don't enable hardware acceleration when the application is in compatibility mode
+ if (mTranslator != null) return;
+
// Try to enable hardware acceleration if requested
final boolean hardwareAccelerated =
(attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
@@ -1766,12 +1772,42 @@
}
}
+ /**
+ * Called from draw() when DEBUG_FPS is enabled
+ */
+ private void trackFPS() {
+ // Tracks frames per second drawn. First value in a series of draws may be bogus
+ // because it down not account for the intervening idle time
+ long nowTime = System.currentTimeMillis();
+ if (mFpsStartTime < 0) {
+ mFpsStartTime = mFpsPrevTime = nowTime;
+ mFpsNumFrames = 0;
+ } else {
+ ++mFpsNumFrames;
+ String thisHash = Integer.toHexString(System.identityHashCode(this));
+ long frameTime = nowTime - mFpsPrevTime;
+ long totalTime = nowTime - mFpsStartTime;
+ Log.v(TAG, "0x" + thisHash + "\tFrame time:\t" + frameTime);
+ mFpsPrevTime = nowTime;
+ if (totalTime > 1000) {
+ float fps = (float) mFpsNumFrames * 1000 / totalTime;
+ Log.v(TAG, "0x" + thisHash + "\tFPS:\t" + fps);
+ mFpsStartTime = nowTime;
+ mFpsNumFrames = 0;
+ }
+ }
+ }
+
private void draw(boolean fullRedrawNeeded) {
Surface surface = mSurface;
if (surface == null || !surface.isValid()) {
return;
}
+ if (DEBUG_FPS) {
+ trackFPS();
+ }
+
if (!sFirstDrawComplete) {
synchronized (sFirstDrawHandlers) {
sFirstDrawComplete = true;
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index 122865e..83df8a5 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -97,6 +97,7 @@
protected AudioService mAudioService;
private boolean mRingIsSilent;
private boolean mShowCombinedVolumes;
+ private boolean mVoiceCapable;
/** Dialog containing all the sliders */
private final Dialog mDialog;
@@ -117,40 +118,62 @@
/** All the slider controls mapped by stream type */
private HashMap<Integer,StreamControl> mStreamControls;
+ private enum StreamResources {
+ BluetoothSCOStream(AudioManager.STREAM_BLUETOOTH_SCO,
+ R.string.volume_icon_description_bluetooth,
+ R.drawable.ic_audio_bt,
+ R.drawable.ic_audio_bt,
+ false),
+ RingerStream(AudioManager.STREAM_RING,
+ R.string.volume_icon_description_ringer,
+ R.drawable.ic_audio_ring_notif,
+ R.drawable.ic_audio_ring_notif_mute,
+ false),
+ VoiceStream(AudioManager.STREAM_VOICE_CALL,
+ R.string.volume_icon_description_incall,
+ R.drawable.ic_audio_phone,
+ R.drawable.ic_audio_phone,
+ false),
+ AlarmStream(AudioManager.STREAM_ALARM,
+ R.string.volume_alarm,
+ R.drawable.ic_audio_alarm,
+ R.drawable.ic_audio_alarm_mute,
+ false),
+ MediaStream(AudioManager.STREAM_MUSIC,
+ R.string.volume_icon_description_media,
+ R.drawable.ic_audio_vol,
+ R.drawable.ic_audio_vol_mute,
+ true),
+ NotificationStream(AudioManager.STREAM_NOTIFICATION,
+ R.string.volume_icon_description_notification,
+ R.drawable.ic_audio_notification,
+ R.drawable.ic_audio_notification_mute,
+ true);
+
+ int streamType;
+ int descRes;
+ int iconRes;
+ int iconMuteRes;
+ // RING, VOICE_CALL & BLUETOOTH_SCO are hidden unless explicitly requested
+ boolean show;
+
+ StreamResources(int streamType, int descRes, int iconRes, int iconMuteRes, boolean show) {
+ this.streamType = streamType;
+ this.descRes = descRes;
+ this.iconRes = iconRes;
+ this.iconMuteRes = iconMuteRes;
+ this.show = show;
+ }
+ };
+
// List of stream types and their order
- // RING, VOICE_CALL & BLUETOOTH_SCO are hidden unless explicitly requested
- private static final int [] STREAM_TYPES = {
- AudioManager.STREAM_BLUETOOTH_SCO,
- AudioManager.STREAM_RING,
- AudioManager.STREAM_VOICE_CALL,
- AudioManager.STREAM_MUSIC,
- AudioManager.STREAM_NOTIFICATION
- };
-
- private static final int [] CONTENT_DESCRIPTIONS = {
- R.string.volume_icon_description_bluetooth,
- R.string.volume_icon_description_ringer,
- R.string.volume_icon_description_incall,
- R.string.volume_icon_description_media,
- R.string.volume_icon_description_notification
- };
-
- // These icons need to correspond to the ones above.
- private static final int [] STREAM_ICONS_NORMAL = {
- R.drawable.ic_audio_bt,
- R.drawable.ic_audio_ring_notif,
- R.drawable.ic_audio_phone,
- R.drawable.ic_audio_vol,
- R.drawable.ic_audio_notification,
- };
-
- // These icons need to correspond to the ones above.
- private static final int [] STREAM_ICONS_MUTED = {
- R.drawable.ic_audio_bt,
- R.drawable.ic_audio_ring_notif_mute,
- R.drawable.ic_audio_phone,
- R.drawable.ic_audio_vol_mute,
- R.drawable.ic_audio_notification_mute,
+ private static final StreamResources[] STREAMS = {
+ StreamResources.BluetoothSCOStream,
+ StreamResources.RingerStream,
+ StreamResources.VoiceStream,
+ StreamResources.MediaStream,
+ StreamResources.NotificationStream,
+ StreamResources.AlarmStream
};
/** Object that contains data for each slider */
@@ -221,7 +244,8 @@
mToneGenerators = new ToneGenerator[AudioSystem.getNumStreamTypes()];
mVibrator = new Vibrator();
- mShowCombinedVolumes = !context.getResources().getBoolean(R.bool.config_voice_capable);
+ mVoiceCapable = context.getResources().getBoolean(R.bool.config_voice_capable);
+ mShowCombinedVolumes = !mVoiceCapable;
// If we don't want to show multiple volumes, hide the settings button and divider
if (!mShowCombinedVolumes) {
mMoreButton.setVisibility(View.GONE);
@@ -260,10 +284,14 @@
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mStreamControls = new HashMap<Integer,StreamControl>(STREAM_TYPES.length);
+ mStreamControls = new HashMap<Integer, StreamControl>(STREAMS.length);
Resources res = mContext.getResources();
- for (int i = 0; i < STREAM_TYPES.length; i++) {
- final int streamType = STREAM_TYPES[i];
+ for (int i = 0; i < STREAMS.length; i++) {
+ StreamResources streamRes = STREAMS[i];
+ int streamType = streamRes.streamType;
+ if (mVoiceCapable && streamRes == StreamResources.NotificationStream) {
+ streamRes = StreamResources.RingerStream;
+ }
StreamControl sc = new StreamControl();
sc.streamType = streamType;
sc.group = (ViewGroup) inflater.inflate(R.layout.volume_adjust_item, null);
@@ -273,9 +301,9 @@
sc.icon.setOnClickListener(this);
}
sc.icon.setTag(sc);
- sc.icon.setContentDescription(res.getString(CONTENT_DESCRIPTIONS[i]));
- sc.iconRes = STREAM_ICONS_NORMAL[i];
- sc.iconMuteRes = STREAM_ICONS_MUTED[i];
+ sc.icon.setContentDescription(res.getString(streamRes.descRes));
+ sc.iconRes = streamRes.iconRes;
+ sc.iconMuteRes = streamRes.iconMuteRes;
sc.icon.setImageResource(sc.iconRes);
sc.seekbarView = (SeekBar) sc.group.findViewById(R.id.seekbar);
int plusOne = (streamType == AudioSystem.STREAM_BLUETOOTH_SCO ||
@@ -307,13 +335,10 @@
private void addOtherVolumes() {
if (!mShowCombinedVolumes) return;
- for (int i = 0; i < STREAM_TYPES.length; i++) {
+ for (int i = 0; i < STREAMS.length; i++) {
// Skip the phone specific ones and the active one
- final int streamType = STREAM_TYPES[i];
- if (streamType == AudioManager.STREAM_RING
- || streamType == AudioManager.STREAM_VOICE_CALL
- || streamType == AudioManager.STREAM_BLUETOOTH_SCO
- || streamType == mActiveStreamType) {
+ final int streamType = STREAMS[i].streamType;
+ if (!STREAMS[i].show || streamType == mActiveStreamType) {
continue;
}
StreamControl sc = mStreamControls.get(streamType);
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index bfd2959..17bdff2 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -104,23 +104,23 @@
*/
public final static String EXTRA_HDMI_PLUGGED_STATE = "state";
- // flags for interceptKeyTq
/**
- * Pass this event to the user / app. To be returned from {@link #interceptKeyTq}.
+ * Pass this event to the user / app. To be returned from
+ * {@link #interceptKeyBeforeQueueing}.
*/
public final static int ACTION_PASS_TO_USER = 0x00000001;
/**
* This key event should extend the user activity timeout and turn the lights on.
- * To be returned from {@link #interceptKeyTq}. Do not return this and
- * {@link #ACTION_GO_TO_SLEEP} or {@link #ACTION_PASS_TO_USER}.
+ * To be returned from {@link #interceptKeyBeforeQueueing}.
+ * Do not return this and {@link #ACTION_GO_TO_SLEEP} or {@link #ACTION_PASS_TO_USER}.
*/
public final static int ACTION_POKE_USER_ACTIVITY = 0x00000002;
/**
* This key event should put the device to sleep (and engage keyguard if necessary)
- * To be returned from {@link #interceptKeyTq}. Do not return this and
- * {@link #ACTION_POKE_USER_ACTIVITY} or {@link #ACTION_PASS_TO_USER}.
+ * To be returned from {@link #interceptKeyBeforeQueueing}.
+ * Do not return this and {@link #ACTION_POKE_USER_ACTIVITY} or {@link #ACTION_PASS_TO_USER}.
*/
public final static int ACTION_GO_TO_SLEEP = 0x00000004;
@@ -677,10 +677,12 @@
* event will normally go.
* @param event The key event.
* @param policyFlags The policy flags associated with the key.
- * @return Returns true if the policy consumed the event and it should
- * not be further dispatched.
+ * @return 0 if the key should be dispatched immediately, -1 if the key should
+ * not be dispatched ever, or a positive value indicating the number of
+ * milliseconds by which the key dispatch should be delayed before trying
+ * again.
*/
- public boolean interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags);
+ public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags);
/**
* Called from the input dispatcher thread when an application did not handle
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 25bc559..86dd9df 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -200,15 +200,6 @@
* <li>{@link #getBeforeText()} - The text of the source before the change.</li>
* <li>{@link #getContentDescription()} - The content description of the source.</li>
* </ul>
- * <em>Note:</em> This event type is not dispatched to descendants though
- * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
- * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
- * source {@link android.view.View} and the sub-tree rooted at it will not receive
- * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
- * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
- * text content to such events is by setting the
- * {@link android.R.styleable#View_contentDescription contentDescription} of the source
- * view.</br>
* </p>
* <p>
* <b>View text selection changed</b> - represents the event of changing the text
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index a80c2a7..e37de6f 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -49,10 +49,8 @@
* </p>
* <p>
* <code>
- * <pre>
- * AccessibilityManager accessibilityManager =
- * (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
- * </pre>
+ * <pre>AccessibilityManager accessibilityManager =
+ * (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);</pre>
* </code>
* </p>
*
@@ -91,7 +89,10 @@
new CopyOnWriteArrayList<AccessibilityStateChangeListener>();
/**
- * Listener for the accessibility state.
+ * Listener for the system accessibility state. To listen for changes to the accessibility
+ * state on the device, implement this interface and register it with the system by
+ * calling {@link AccessibilityManager#addAccessibilityStateChangeListener
+ * addAccessibilityStateChangeListener()}.
*/
public interface AccessibilityStateChangeListener {
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index fe06d98..a4e0688 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -391,8 +391,6 @@
* Gets the max scroll offset of the source left edge in pixels.
*
* @return The max scroll.
- *
- * @hide
*/
public int getMaxScrollX() {
return mMaxScrollX;
@@ -401,8 +399,6 @@
* Sets the max scroll offset of the source left edge in pixels.
*
* @param maxScrollX The max scroll.
- *
- * @hide
*/
public void setMaxScrollX(int maxScrollX) {
enforceNotSealed();
@@ -413,8 +409,6 @@
* Gets the max scroll offset of the source top edge in pixels.
*
* @return The max scroll.
- *
- * @hide
*/
public int getMaxScrollY() {
return mMaxScrollY;
@@ -424,8 +418,6 @@
* Sets the max scroll offset of the source top edge in pixels.
*
* @param maxScrollY The max scroll.
- *
- * @hide
*/
public void setMaxScrollY(int maxScrollY) {
enforceNotSealed();
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index 34c9c29..93caabe 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -35,6 +35,13 @@
* Subtype can describe locale (e.g. en_US, fr_FR...) and mode (e.g. voice, keyboard...), and is
* used for IME switch and settings. The input method subtype allows the system to bring up the
* specified subtype of the designated input method directly.
+ *
+ * <p>It should be defined in an XML resource file of the input method
+ * with the <code><subtype></code> element.
+ * For more information, see the guide to
+ * <a href="{@docRoot}resources/articles/creating-input-method.html">
+ * Creating an Input Method</a>.</p>
+ *
*/
public final class InputMethodSubtype implements Parcelable {
private static final String TAG = InputMethodSubtype.class.getSimpleName();
diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java
index b940b80..793f514 100644
--- a/core/java/android/view/textservice/SpellCheckerSession.java
+++ b/core/java/android/view/textservice/SpellCheckerSession.java
@@ -34,6 +34,51 @@
/**
* The SpellCheckerSession interface provides the per client functionality of SpellCheckerService.
+ *
+ *
+ * <a name="Applications"></a>
+ * <h3>Applications</h3>
+ *
+ * <p>In most cases, applications that are using the standard
+ * {@link android.widget.TextView} or its subclasses will have little they need
+ * to do to work well with spell checker services. The main things you need to
+ * be aware of are:</p>
+ *
+ * <ul>
+ * <li> Properly set the {@link android.R.attr#inputType} in your editable
+ * text views, so that the spell checker will have enough context to help the
+ * user in editing text in them.
+ * </ul>
+ *
+ * <p>For the rare people amongst us writing client applications that use the spell checker service
+ * directly, you will need to use {@link #getSuggestions(TextInfo, int)} or
+ * {@link #getSuggestions(TextInfo[], int, boolean)} for obtaining results from the spell checker
+ * service by yourself.</p>
+ *
+ * <h3>Security</h3>
+ *
+ * <p>There are a lot of security issues associated with spell checkers,
+ * since they could monitor all the text being sent to them
+ * through, for instance, {@link android.widget.TextView}.
+ * The Android spell checker framework also allows
+ * arbitrary third party spell checkers, so care must be taken to restrict their
+ * selection and interactions.</p>
+ *
+ * <p>Here are some key points about the security architecture behind the
+ * spell checker framework:</p>
+ *
+ * <ul>
+ * <li>Only the system is allowed to directly access a spell checker framework's
+ * {@link android.service.textservice.SpellCheckerService} interface, via the
+ * {@link android.Manifest.permission#BIND_TEXT_SERVICE} permission. This is
+ * enforced in the system by not binding to a spell checker service that does
+ * not require this permission.
+ *
+ * <li>The user must explicitly enable a new spell checker in settings before
+ * they can be enabled, to confirm with the system that they know about it
+ * and want to make it available for use.
+ * </ul>
+ *
*/
public class SpellCheckerSession {
private static final String TAG = SpellCheckerSession.class.getSimpleName();
diff --git a/core/java/android/view/textservice/TextServicesManager.java b/core/java/android/view/textservice/TextServicesManager.java
index b06c112..69f88a5 100644
--- a/core/java/android/view/textservice/TextServicesManager.java
+++ b/core/java/android/view/textservice/TextServicesManager.java
@@ -35,6 +35,31 @@
*
* The user can change the current text services in Settings. And also applications can specify
* the target text services.
+ *
+ * <h3>Architecture Overview</h3>
+ *
+ * <p>There are three primary parties involved in the text services
+ * framework (TSF) architecture:</p>
+ *
+ * <ul>
+ * <li> The <strong>text services manager</strong> as expressed by this class
+ * is the central point of the system that manages interaction between all
+ * other parts. It is expressed as the client-side API here which exists
+ * in each application context and communicates with a global system service
+ * that manages the interaction across all processes.
+ * <li> A <strong>text service</strong> implements a particular
+ * interaction model allowing the client application to retrieve information of text.
+ * The system binds to the current text service that is in use, causing it to be created and run.
+ * <li> Multiple <strong>client applications</strong> arbitrate with the text service
+ * manager for connections to text services.
+ * </ul>
+ *
+ * <h3>Text services sessions</h3>
+ * <ul>
+ * <li>The <strong>spell checker session</strong> is one of the text services.
+ * {@link android.view.textservice.SpellCheckerSession}</li>
+ * </ul>
+ *
*/
public final class TextServicesManager {
private static final String TAG = TextServicesManager.class.getSimpleName();
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index c8b67a8..2cc928f 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -1204,22 +1204,20 @@
* We delegate the request to CallbackProxy, and route its response to
* {@link #nativeSslClientCert(int, X509Certificate)}.
*/
- private void requestClientCert(int handle, byte[] host_and_port_bytes) {
- String host_and_port = new String(host_and_port_bytes, Charsets.UTF_8);
+ private void requestClientCert(int handle, String hostAndPort) {
SslClientCertLookupTable table = SslClientCertLookupTable.getInstance();
- if (table.IsAllowed(host_and_port)) {
+ if (table.IsAllowed(hostAndPort)) {
// previously allowed
nativeSslClientCert(handle,
- table.PrivateKey(host_and_port),
- table.CertificateChain(host_and_port));
- } else if (table.IsDenied(host_and_port)) {
+ table.PrivateKey(hostAndPort),
+ table.CertificateChain(hostAndPort));
+ } else if (table.IsDenied(hostAndPort)) {
// previously denied
nativeSslClientCert(handle, null, null);
} else {
// previously ignored or new
mCallbackProxy.onReceivedClientCertRequest(
- new ClientCertRequestHandler(this, handle, host_and_port, table),
- host_and_port);
+ new ClientCertRequestHandler(this, handle, hostAndPort, table), hostAndPort);
}
}
diff --git a/core/java/android/webkit/HTML5Audio.java b/core/java/android/webkit/HTML5Audio.java
index 9fc48a1..97d61ba 100644
--- a/core/java/android/webkit/HTML5Audio.java
+++ b/core/java/android/webkit/HTML5Audio.java
@@ -238,24 +238,27 @@
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
// resume playback
- if (mMediaPlayer == null) resetMediaPlayer();
- else if (!mMediaPlayer.isPlaying()) mMediaPlayer.start();
- mState = STARTED;
+ if (mMediaPlayer == null) {
+ resetMediaPlayer();
+ } else if (mState != ERROR && !mMediaPlayer.isPlaying()) {
+ mMediaPlayer.start();
+ mState = STARTED;
+ }
break;
case AudioManager.AUDIOFOCUS_LOSS:
- // Lost focus for an unbounded amount of time: stop playback and release media player
- if (mMediaPlayer.isPlaying()) mMediaPlayer.stop();
- mMediaPlayer.release();
- mMediaPlayer = null;
+ // Lost focus for an unbounded amount of time: stop playback.
+ if (mState != ERROR && mMediaPlayer.isPlaying()) {
+ mMediaPlayer.stop();
+ mState = STOPPED;
+ }
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// Lost focus for a short time, but we have to stop
- // playback. We don't release the media player because playback
- // is likely to resume
- if (mMediaPlayer.isPlaying()) mMediaPlayer.pause();
+ // playback.
+ if (mState != ERROR && mMediaPlayer.isPlaying()) pause();
break;
}
}
@@ -273,10 +276,7 @@
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
- if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
- // could not get audio focus.
- teardown();
- } else {
+ if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mMediaPlayer.start();
mState = STARTED;
}
@@ -299,8 +299,13 @@
}
}
+ /**
+ * Called only over JNI when WebKit is happy to
+ * destroy the media player.
+ */
private void teardown() {
mMediaPlayer.release();
+ mMediaPlayer = null;
mState = ERROR;
mNativePointer = 0;
}
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index ae40ded..3d129f7 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -95,27 +95,33 @@
public void onHideCustomView() {}
/**
- * Request the host application to create a new Webview. The host
- * application should handle placement of the new WebView in the view
- * system. The default behavior returns null.
- * @param view The WebView that initiated the callback.
- * @param dialog True if the new window is meant to be a small dialog
- * window.
- * @param userGesture True if the request was initiated by a user gesture
- * such as clicking a link.
- * @param resultMsg The message to send when done creating a new WebView.
- * Set the new WebView through resultMsg.obj which is
- * WebView.WebViewTransport() and then call
- * resultMsg.sendToTarget();
- * @return Similar to javscript dialogs, this method should return true if
- * the client is going to handle creating a new WebView. Note that
- * the WebView will halt processing if this method returns true so
- * make sure to call resultMsg.sendToTarget(). It is undefined
- * behavior to call resultMsg.sendToTarget() after returning false
- * from this method.
+ * Request the host application to create a new window. If the host
+ * application chooses to honor this request, it should return true from
+ * this method, create a new WebView to host the window, insert it into the
+ * View system and send the supplied resultMsg message to its target with
+ * the new WebView as an argument. If the host application chooses not to
+ * honor the request, it should return false from this method. The default
+ * implementation of this method does nothing and hence returns false.
+ * @param view The WebView from which the request for a new window
+ * originated.
+ * @param isDialog True if the new window should be a dialog, rather than
+ * a full-size window.
+ * @param isUserGesture True if the request was initiated by a user gesture,
+ * such as the user clicking a link.
+ * @param resultMsg The message to send when once a new WebView has been
+ * created. resultMsg.obj is a
+ * {@link WebView.WebViewTransport} object. This should be
+ * used to transport the new WebView, by calling
+ * {@link WebView.WebViewTransport#setWebView(WebView)
+ * WebView.WebViewTransport.setWebView(WebView)}.
+ * @return This method should return true if the host application will
+ * create a new window, in which case resultMsg should be sent to
+ * its target. Otherwise, this method should return false. Returning
+ * false from this method but also sending resultMsg will result in
+ * undefined behavior.
*/
- public boolean onCreateWindow(WebView view, boolean dialog,
- boolean userGesture, Message resultMsg) {
+ public boolean onCreateWindow(WebView view, boolean isDialog,
+ boolean isUserGesture, Message resultMsg) {
return false;
}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 9c44138..f1c2bde 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -211,6 +211,7 @@
private ZoomDensity mDefaultZoom = ZoomDensity.MEDIUM;
private RenderPriority mRenderPriority = RenderPriority.NORMAL;
private int mOverrideCacheMode = LOAD_DEFAULT;
+ private int mDoubleTapZoom = 100;
private boolean mSaveFormData = true;
private boolean mAutoFillEnabled = false;
private boolean mSavePassword = true;
@@ -769,6 +770,27 @@
}
/**
+ * Set the double-tap zoom of the page in percent. Default is 100.
+ * @param doubleTapZoom A percent value for increasing or decreasing the double-tap zoom.
+ * @hide
+ */
+ public void setDoubleTapZoom(int doubleTapZoom) {
+ if (mDoubleTapZoom != doubleTapZoom) {
+ mDoubleTapZoom = doubleTapZoom;
+ mWebView.updateDoubleTapZoom();
+ }
+ }
+
+ /**
+ * Get the double-tap zoom of the page in percent.
+ * @return A percent value describing the double-tap zoom.
+ * @hide
+ */
+ public int getDoubleTapZoom() {
+ return mDoubleTapZoom;
+ }
+
+ /**
* Set the default zoom density of the page. This should be called from UI
* thread.
* @param zoom A ZoomDensity value
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 66371f5..b0ecf09 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -1002,6 +1002,9 @@
| InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT;
int imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
| EditorInfo.IME_FLAG_NO_FULLSCREEN;
+ if (!mWebView.nativeFocusCandidateIsSpellcheck()) {
+ inputType |= InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
+ }
if (TEXT_AREA != type
&& mWebView.nativeFocusCandidateHasNextTextfield()) {
imeOptions |= EditorInfo.IME_FLAG_NAVIGATE_NEXT;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index f46af51..71ba7eb 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1917,6 +1917,7 @@
mLoadedPicture = ViewStateSerializer.deserializeViewState(stream, this);
mBlockWebkitViewMessages = true;
setNewPicture(mLoadedPicture, true);
+ mLoadedPicture.mViewState = null;
return true;
} catch (IOException e) {
Log.w(LOGTAG, "Failed to loadViewState", e);
@@ -2003,15 +2004,18 @@
}
/**
- * Load the given url with the extra headers.
- * @param url The url of the resource to load.
- * @param extraHeaders The extra headers sent with this url. This should not
- * include the common headers like "user-agent". If it does, it
- * will be replaced by the intrinsic value of the WebView.
+ * Load the given URL with the specified additional HTTP headers.
+ * @param url The URL of the resource to load.
+ * @param additionalHttpHeaders The additional headers to be used in the
+ * HTTP request for this URL, specified as a map from name to
+ * value. Note that if this map contains any of the headers
+ * that are set by default by the WebView, such as those
+ * controlling caching, accept types or the User-Agent, their
+ * values may be overriden by the WebView's defaults.
*/
- public void loadUrl(String url, Map<String, String> extraHeaders) {
+ public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
checkThread();
- loadUrlImpl(url, extraHeaders);
+ loadUrlImpl(url, additionalHttpHeaders);
}
private void loadUrlImpl(String url, Map<String, String> extraHeaders) {
@@ -2024,8 +2028,8 @@
}
/**
- * Load the given url.
- * @param url The url of the resource to load.
+ * Load the given URL.
+ * @param url The URL of the resource to load.
*/
public void loadUrl(String url) {
checkThread();
@@ -2074,14 +2078,17 @@
* If the value of the encoding parameter is 'base64', then the data must
* be encoded as base64. Otherwise, the data must use ASCII encoding for
* octets inside the range of safe URL characters and use the standard %xx
- * hex encoding of URLs for octets outside that range.
+ * hex encoding of URLs for octets outside that range. For example,
+ * '#', '%', '\', '?' should be replaced by %23, %25, %27, %3f respectively.
* <p>
* The 'data' scheme URL formed by this method uses the default US-ASCII
* charset. If you need need to set a different charset, you should form a
- * 'data' scheme URL which specifies a charset parameter and call
- * {@link #loadUrl(String)} instead.
+ * 'data' scheme URL which explicitly specifies a charset parameter in the
+ * mediatype portion of the URL and call {@link #loadUrl(String)} instead.
+ * Note that the charset obtained from the mediatype portion of a data URL
+ * always overrides that specified in the HTML or XML document itself.
* @param data A String of data in the given encoding.
- * @param mimeType The MIMEType of the data, e.g. 'text/html'.
+ * @param mimeType The MIME type of the data, e.g. 'text/html'.
* @param encoding The encoding of the data.
*/
public void loadData(String data, String mimeType, String encoding) {
@@ -2985,6 +2992,13 @@
return false;
}
+ /**
+ * Update the double-tap zoom.
+ */
+ /* package */ void updateDoubleTapZoom() {
+ mZoomManager.updateDoubleTapZoom();
+ }
+
private int computeRealHorizontalScrollRange() {
if (mDrawHistory) {
return mHistoryWidth;
@@ -4345,7 +4359,9 @@
selectionDone();
}
mOrientation = newConfig.orientation;
- mWebViewCore.sendMessage(EventHub.CLEAR_CONTENT);
+ if (mWebViewCore != null && !mBlockWebkitViewMessages) {
+ mWebViewCore.sendMessage(EventHub.CLEAR_CONTENT);
+ }
}
/**
@@ -4491,6 +4507,9 @@
if (mHeldMotionless == MOTIONLESS_FALSE) {
mPrivateHandler.sendMessageDelayed(mPrivateHandler
.obtainMessage(DRAG_HELD_MOTIONLESS), MOTIONLESS_TIME);
+ mPrivateHandler.sendMessageDelayed(mPrivateHandler
+ .obtainMessage(AWAKEN_SCROLL_BARS),
+ ViewConfiguration.getScrollDefaultDelay());
mHeldMotionless = MOTIONLESS_PENDING;
}
}
@@ -4504,7 +4523,7 @@
boolean UIAnimationsRunning = false;
// Currently for each draw we compute the animation values;
// We may in the future decide to do that independently.
- if (mNativeClass != 0 && nativeEvaluateLayersAnimations()) {
+ if (mNativeClass != 0 && nativeEvaluateLayersAnimations(mNativeClass)) {
UIAnimationsRunning = true;
// If we have unfinished (or unstarted) animations,
// we ask for a repaint. We only need to do this in software
@@ -4520,9 +4539,9 @@
extras = DRAW_EXTRAS_FIND;
} else if (mSelectingText && !USE_JAVA_TEXT_SELECTION) {
extras = DRAW_EXTRAS_SELECTION;
- nativeSetSelectionPointer(mDrawSelectionPointer,
- mZoomManager.getInvScale(),
- mSelectX, mSelectY - getTitleHeight());
+ nativeSetSelectionPointer(mNativeClass,
+ mDrawSelectionPointer,
+ mZoomManager.getInvScale(), mSelectX, mSelectY - getTitleHeight());
} else if (drawCursorRing) {
extras = DRAW_EXTRAS_CURSOR_RING;
}
@@ -4536,8 +4555,8 @@
}
if (canvas.isHardwareAccelerated()) {
- int functor = nativeGetDrawGLFunction(mGLViewportEmpty ? null : mGLRectViewport,
- mGLViewportEmpty ? null : mViewRectViewport, getScale(), extras);
+ int functor = nativeGetDrawGLFunction(mNativeClass,
+ mGLViewportEmpty ? null : mGLRectViewport, mGLViewportEmpty ? null : mViewRectViewport, getScale(), extras);
((HardwareCanvas) canvas).callDrawGLFunction(functor);
if (mHardwareAccelSkia != getSettings().getHardwareAccelSkiaEnabled()) {
@@ -5988,6 +6007,7 @@
mTouchMode = TOUCH_DRAG_START_MODE;
mConfirmMove = true;
mPrivateHandler.removeMessages(RESUME_WEBCORE_PRIORITY);
+ nativeSetIsScrolling(false);
} else if (mPrivateHandler.hasMessages(RELEASE_SINGLE_TAP)) {
mPrivateHandler.removeMessages(RELEASE_SINGLE_TAP);
if (USE_WEBKIT_RINGS || getSettings().supportTouchOnly()) {
@@ -6270,9 +6290,16 @@
}
mLastTouchX = x;
mLastTouchY = y;
- if ((deltaX | deltaY) != 0) {
+
+ if (deltaX * deltaX + deltaY * deltaY > mTouchSlopSquare) {
mHeldMotionless = MOTIONLESS_FALSE;
+ nativeSetIsScrolling(true);
+ } else {
+ mHeldMotionless = MOTIONLESS_TRUE;
+ nativeSetIsScrolling(false);
+ keepScrollBarsVisible = true;
}
+
mLastTouchTime = eventTime;
}
@@ -6288,9 +6315,15 @@
// keep the scrollbar on the screen even there is no scroll
awakenScrollBars(ViewConfiguration.getScrollDefaultDelay(),
false);
+ // Post a message so that we'll keep them alive while we're not scrolling.
+ mPrivateHandler.sendMessageDelayed(mPrivateHandler
+ .obtainMessage(AWAKEN_SCROLL_BARS),
+ ViewConfiguration.getScrollDefaultDelay());
// return false to indicate that we can't pan out of the
// view space
return !done;
+ } else {
+ mPrivateHandler.removeMessages(AWAKEN_SCROLL_BARS);
}
break;
}
@@ -7415,6 +7448,10 @@
}
}
+ void sendPluginDrawMsg() {
+ mWebViewCore.sendMessage(EventHub.PLUGIN_SURFACE_READY);
+ }
+
/**
* Returns plugin bounds if x/y in content coordinates corresponds to a
* plugin. Otherwise a NULL rectangle is returned.
@@ -9402,9 +9439,9 @@
// We never want to change button state if we are hardware accelerated,
// but we DO want to invalidate as necessary so that the GL ring
// can be drawn
- nativeRecordButtons(false, false, inval);
+ nativeRecordButtons(mNativeClass, false, false, inval);
} else {
- nativeRecordButtons(focus, pressed, inval);
+ nativeRecordButtons(mNativeClass, focus, pressed, inval);
}
}
@@ -9439,9 +9476,9 @@
private native int nativeDraw(Canvas canvas, int color, int extra,
boolean splitIfNeeded);
private native void nativeDumpDisplayTree(String urlOrNull);
- private native boolean nativeEvaluateLayersAnimations();
- private native int nativeGetDrawGLFunction(Rect rect, Rect viewRect,
- float scale, int extras);
+ private native boolean nativeEvaluateLayersAnimations(int nativeInstance);
+ private native int nativeGetDrawGLFunction(int nativeInstance, Rect rect,
+ Rect viewRect, float scale, int extras);
private native void nativeUpdateDrawGLFunction(Rect rect, Rect viewRect);
private native void nativeExtendSelection(int x, int y);
private native int nativeFindAll(String findLower, String findUpper,
@@ -9454,6 +9491,7 @@
private native boolean nativeFocusCandidateIsTextInput();
/* package */ native int nativeFocusCandidateMaxLength();
/* package */ native boolean nativeFocusCandidateIsAutoComplete();
+ /* package */ native boolean nativeFocusCandidateIsSpellcheck();
/* package */ native String nativeFocusCandidateName();
private native Rect nativeFocusCandidateNodeBounds();
/**
@@ -9503,8 +9541,8 @@
private native boolean nativePointInNavCache(int x, int y, int slop);
// Like many other of our native methods, you must make sure that
// mNativeClass is not null before calling this method.
- private native void nativeRecordButtons(boolean focused,
- boolean pressed, boolean invalidate);
+ private native void nativeRecordButtons(int nativeInstance,
+ boolean focused, boolean pressed, boolean invalidate);
private native void nativeResetSelection();
private native Point nativeSelectableText();
private native void nativeSelectAll();
@@ -9525,8 +9563,8 @@
private native void nativeReplaceBaseContent(int content);
private native void nativeCopyBaseContentToPicture(Picture pict);
private native boolean nativeHasContent();
- private native void nativeSetSelectionPointer(boolean set,
- float scale, int x, int y);
+ private native void nativeSetSelectionPointer(int nativeInstance,
+ boolean set, float scale, int x, int y);
private native boolean nativeStartSelection(int x, int y);
private native void nativeStopGL();
private native Rect nativeSubtractLayers(Rect content);
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 44688b8..1294a28 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1032,6 +1032,8 @@
static final int EXECUTE_JS = 194;
+ static final int PLUGIN_SURFACE_READY = 195;
+
// private message ids
private static final int DESTROY = 200;
@@ -1587,6 +1589,10 @@
nativeFullScreenPluginHidden(msg.arg1);
break;
+ case PLUGIN_SURFACE_READY:
+ nativePluginSurfaceReady();
+ break;
+
case ADD_PACKAGE_NAMES:
if (BrowserFrame.sJavaBridge == null) {
throw new IllegalStateException("No WebView " +
@@ -2826,6 +2832,7 @@
private native void nativeResume();
private native void nativeFreeMemory();
private native void nativeFullScreenPluginHidden(int npp);
+ private native void nativePluginSurfaceReady();
private native boolean nativeValidNodeAndBounds(int frame, int node,
Rect bounds);
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 7f526e7..9151fdd 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -145,11 +145,11 @@
private float mInvDefaultScale;
/*
- * The scale factor that is used to determine the zoom level for reading text.
- * The value is initially set to equal the display density.
- * TODO: Support changing this in WebSettings
+ * The logical density of the display. This is a scaling factor for the
+ * Density Independent Pixel unit, where one DIP is one pixel on an
+ * approximately 160 dpi screen (see android.util.DisplayMetrics.density)
*/
- private float mReadingLevelScale;
+ private float mDisplayDensity;
/*
* The scale factor that is used as the minimum increment when going from
@@ -233,11 +233,11 @@
public void init(float density) {
assert density > 0;
+ mDisplayDensity = density;
setDefaultZoomScale(density);
mActualScale = density;
mInvActualScale = 1 / density;
- mReadingLevelScale = density;
- mTextWrapScale = density;
+ mTextWrapScale = getReadingLevelScale();
}
/**
@@ -310,8 +310,14 @@
return mInitialScale > 0 ? mInitialScale : mDefaultScale;
}
+ /**
+ * Returns the zoom scale used for reading text on a double-tap.
+ */
public final float getReadingLevelScale() {
- return mReadingLevelScale;
+ WebSettings settings = mWebView.getSettings();
+ final float doubleTapZoomFactor = settings != null
+ ? settings.getDoubleTapZoom() / 100.f : 1.0f;
+ return mDisplayDensity * doubleTapZoomFactor;
}
public final float getInvDefaultScale() {
@@ -510,6 +516,13 @@
return mZoomScale != 0 || mInHWAcceleratedZoom;
}
+ public void updateDoubleTapZoom() {
+ if (mInZoomOverview) {
+ mTextWrapScale = getReadingLevelScale();
+ refreshZoomScale(true);
+ }
+ }
+
public void refreshZoomScale(boolean reflowText) {
setZoomScale(mActualScale, reflowText, true);
}
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index df8eb05..bdaf89e 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -335,6 +335,9 @@
mTouchDownX = event.getX();
} else {
setPressed(true);
+ if (mThumb != null) {
+ invalidate(mThumb.getBounds()); // This may be within the padding region
+ }
onStartTrackingTouch();
trackTouchEvent(event);
attemptClaimDrag();
@@ -348,6 +351,9 @@
final float x = event.getX();
if (Math.abs(x - mTouchDownX) > mScaledTouchSlop) {
setPressed(true);
+ if (mThumb != null) {
+ invalidate(mThumb.getBounds()); // This may be within the padding region
+ }
onStartTrackingTouch();
trackTouchEvent(event);
attemptClaimDrag();
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index fd19b5f..e16a8bd 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -922,15 +922,20 @@
if (selectedView != null) {
event.setEnabled(selectedView.isEnabled());
}
+ event.setCurrentItemIndex(getSelectedItemPosition());
event.setFromIndex(getFirstVisiblePosition());
event.setToIndex(getLastVisiblePosition());
event.setItemCount(getAdapter().getCount());
}
private boolean isScrollableForAccessibility() {
- final int itemCount = getAdapter().getCount();
- return itemCount > 0
- && (getFirstVisiblePosition() > 0 || getLastVisiblePosition() < itemCount - 1);
+ T adapter = getAdapter();
+ if (adapter != null) {
+ final int itemCount = adapter.getCount();
+ return itemCount > 0
+ && (getFirstVisiblePosition() > 0 || getLastVisiblePosition() < itemCount - 1);
+ }
+ return false;
}
@Override
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 51506e8..083a952 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -29,12 +29,14 @@
import android.os.SystemClock;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewConfiguration;
import android.widget.AbsListView.OnScrollListener;
/**
* Helper class for AbsListView to draw and control the Fast Scroll thumb
*/
class FastScroller {
+ private static final String TAG = "FastScroller";
// Minimum number of pages to justify showing a fast scroll thumb
private static int MIN_PAGES = 4;
@@ -81,15 +83,15 @@
private Drawable mOverlayDrawableLeft;
private Drawable mOverlayDrawableRight;
- private int mThumbH;
- private int mThumbW;
- private int mThumbY;
+ int mThumbH;
+ int mThumbW;
+ int mThumbY;
private RectF mOverlayPos;
private int mOverlaySize;
- private AbsListView mList;
- private boolean mScrollCompleted;
+ AbsListView mList;
+ boolean mScrollCompleted;
private int mVisibleItem;
private Paint mPaint;
private int mListOffset;
@@ -105,7 +107,7 @@
private Handler mHandler = new Handler();
- private BaseAdapter mListAdapter;
+ BaseAdapter mListAdapter;
private SectionIndexer mSectionIndexer;
private boolean mChangedBounds;
@@ -118,10 +120,36 @@
private boolean mMatchDragPosition;
+ float mInitialTouchY;
+ boolean mPendingDrag;
+ private int mScaledTouchSlop;
+
private static final int FADE_TIMEOUT = 1500;
+ private static final int PENDING_DRAG_DELAY = 180;
private final Rect mTmpRect = new Rect();
+ private final Runnable mDeferStartDrag = new Runnable() {
+ public void run() {
+ if (mList.mIsAttached) {
+ beginDrag();
+
+ final int viewHeight = mList.getHeight();
+ // Jitter
+ int newThumbY = (int) mInitialTouchY - mThumbH + 10;
+ if (newThumbY < 0) {
+ newThumbY = 0;
+ } else if (newThumbY + mThumbH > viewHeight) {
+ newThumbY = viewHeight - mThumbH;
+ }
+ mThumbY = newThumbY;
+ scrollTo((float) mThumbY / (viewHeight - mThumbH));
+ }
+
+ mPendingDrag = false;
+ }
+ };
+
public FastScroller(Context context, AbsListView listView) {
mList = listView;
init(context);
@@ -264,6 +292,8 @@
ta.recycle();
+ mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+
mMatchDragPosition = context.getApplicationInfo().targetSdkVersion >=
android.os.Build.VERSION_CODES.HONEYCOMB;
@@ -456,7 +486,7 @@
return mSections;
}
- private void getSectionsFromIndexer() {
+ void getSectionsFromIndexer() {
Adapter adapter = mList.getAdapter();
mSectionIndexer = null;
if (adapter instanceof HeaderViewListAdapter) {
@@ -489,7 +519,7 @@
mListAdapter = null;
}
- private void scrollTo(float position) {
+ void scrollTo(float position) {
int count = mList.getCount();
mScrollCompleted = false;
float fThreshold = (1.0f / count) / 8;
@@ -647,12 +677,45 @@
cancelFling.recycle();
}
+ void cancelPendingDrag() {
+ mList.removeCallbacks(mDeferStartDrag);
+ mPendingDrag = false;
+ }
+
+ void startPendingDrag() {
+ mPendingDrag = true;
+ mList.postDelayed(mDeferStartDrag, PENDING_DRAG_DELAY);
+ }
+
+ void beginDrag() {
+ setState(STATE_DRAGGING);
+ if (mListAdapter == null && mList != null) {
+ getSectionsFromIndexer();
+ }
+ if (mList != null) {
+ mList.requestDisallowInterceptTouchEvent(true);
+ mList.reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+ }
+
+ cancelFling();
+ }
+
boolean onInterceptTouchEvent(MotionEvent ev) {
- if (mState > STATE_NONE && ev.getAction() == MotionEvent.ACTION_DOWN) {
- if (isPointInside(ev.getX(), ev.getY())) {
- setState(STATE_DRAGGING);
- return true;
- }
+ switch (ev.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ if (mState > STATE_NONE && isPointInside(ev.getX(), ev.getY())) {
+ if (!mList.isInScrollingContainer()) {
+ beginDrag();
+ return true;
+ }
+ mInitialTouchY = ev.getY();
+ startPendingDrag();
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ cancelPendingDrag();
+ break;
}
return false;
}
@@ -666,19 +729,32 @@
if (action == MotionEvent.ACTION_DOWN) {
if (isPointInside(me.getX(), me.getY())) {
- setState(STATE_DRAGGING);
- if (mListAdapter == null && mList != null) {
- getSectionsFromIndexer();
+ if (!mList.isInScrollingContainer()) {
+ beginDrag();
+ return true;
}
- if (mList != null) {
- mList.requestDisallowInterceptTouchEvent(true);
- mList.reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
- }
-
- cancelFling();
- return true;
+ mInitialTouchY = me.getY();
+ startPendingDrag();
}
} else if (action == MotionEvent.ACTION_UP) { // don't add ACTION_CANCEL here
+ if (mPendingDrag) {
+ // Allow a tap to scroll.
+ beginDrag();
+
+ final int viewHeight = mList.getHeight();
+ // Jitter
+ int newThumbY = (int) me.getY() - mThumbH + 10;
+ if (newThumbY < 0) {
+ newThumbY = 0;
+ } else if (newThumbY + mThumbH > viewHeight) {
+ newThumbY = viewHeight - mThumbH;
+ }
+ mThumbY = newThumbY;
+ scrollTo((float) mThumbY / (viewHeight - mThumbH));
+
+ cancelPendingDrag();
+ // Will hit the STATE_DRAGGING check below
+ }
if (mState == STATE_DRAGGING) {
if (mList != null) {
// ViewGroup does the right thing already, but there might
@@ -698,6 +774,23 @@
return true;
}
} else if (action == MotionEvent.ACTION_MOVE) {
+ if (mPendingDrag) {
+ final float y = me.getY();
+ if (Math.abs(y - mInitialTouchY) > mScaledTouchSlop) {
+ setState(STATE_DRAGGING);
+ if (mListAdapter == null && mList != null) {
+ getSectionsFromIndexer();
+ }
+ if (mList != null) {
+ mList.requestDisallowInterceptTouchEvent(true);
+ mList.reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+ }
+
+ cancelFling();
+ cancelPendingDrag();
+ // Will hit the STATE_DRAGGING check below
+ }
+ }
if (mState == STATE_DRAGGING) {
final int viewHeight = mList.getHeight();
// Jitter
@@ -717,6 +810,8 @@
}
return true;
}
+ } else if (action == MotionEvent.ACTION_CANCEL) {
+ cancelPendingDrag();
}
return false;
}
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index a5d6c9a..b24dd69 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -147,6 +147,11 @@
setColorFilter(tint);
}
+ int alpha = a.getInt(com.android.internal.R.styleable.ImageView_drawableAlpha, 255);
+ if (alpha != 255) {
+ setAlpha(alpha);
+ }
+
mCropToPadding = a.getBoolean(
com.android.internal.R.styleable.ImageView_cropToPadding, false);
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index ce17184..5fbbe4d 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -20,6 +20,7 @@
import android.text.Editable;
import android.text.Selection;
import android.text.Spanned;
+import android.text.method.WordIterator;
import android.text.style.SpellCheckSpan;
import android.text.style.SuggestionSpan;
import android.view.textservice.SpellCheckerSession;
@@ -30,6 +31,9 @@
import com.android.internal.util.ArrayUtils;
+import java.text.BreakIterator;
+import java.util.Locale;
+
/**
* Helper class for TextView. Bridge between the TextView and the Dictionnary service.
@@ -38,45 +42,81 @@
*/
public class SpellChecker implements SpellCheckerSessionListener {
+ private final static int MAX_SPELL_BATCH_SIZE = 50;
+
private final TextView mTextView;
- final SpellCheckerSession mSpellCheckerSession;
+ SpellCheckerSession mSpellCheckerSession;
final int mCookie;
// Paired arrays for the (id, spellCheckSpan) pair. A negative id means the associated
// SpellCheckSpan has been recycled and can be-reused.
- // May contain null SpellCheckSpans after a given index.
+ // Contains null SpellCheckSpans after index mLength.
private int[] mIds;
private SpellCheckSpan[] mSpellCheckSpans;
// The mLength first elements of the above arrays have been initialized
private int mLength;
+ // Parsers on chunck of text, cutting text into words that will be checked
+ private SpellParser[] mSpellParsers = new SpellParser[0];
+
private int mSpanSequenceCounter = 0;
+ private Locale mCurrentLocale;
+
+ // Shared by all SpellParsers. Cannot be shared with TextView since it may be used
+ // concurrently due to the asynchronous nature of onGetSuggestions.
+ private WordIterator mWordIterator;
+
public SpellChecker(TextView textView) {
mTextView = textView;
- final TextServicesManager textServicesManager = (TextServicesManager) textView.getContext().
- getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE);
- mSpellCheckerSession = textServicesManager.newSpellCheckerSession(
- null /* not currently used by the textServicesManager */,
- null /* null locale means use the languages defined in Settings
- if referToSpellCheckerLanguageSettings is true */,
- this, true /* means use the languages defined in Settings */);
- mCookie = hashCode();
-
- // Arbitrary: 4 simultaneous spell check spans. Will automatically double size on demand
+ // Arbitrary: these arrays will automatically double their sizes on demand
final int size = ArrayUtils.idealObjectArraySize(1);
mIds = new int[size];
mSpellCheckSpans = new SpellCheckSpan[size];
+
+ setLocale(mTextView.getLocale());
+
+ mCookie = hashCode();
+ }
+
+ private void setLocale(Locale locale) {
+ final TextServicesManager textServicesManager = (TextServicesManager)
+ mTextView.getContext().getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE);
+ mSpellCheckerSession = textServicesManager.newSpellCheckerSession(
+ null /* Bundle not currently used by the textServicesManager */,
+ locale, this, false /* means any available languages from current spell checker */);
+ mCurrentLocale = locale;
+
+ // Restore SpellCheckSpans in pool
+ for (int i = 0; i < mLength; i++) {
+ mSpellCheckSpans[i].setSpellCheckInProgress(false);
+ mIds[i] = -1;
+ }
mLength = 0;
+
+ // Change SpellParsers' wordIterator locale
+ mWordIterator = new WordIterator(locale);
+
+ // Stop all SpellParsers
+ final int length = mSpellParsers.length;
+ for (int i = 0; i < length; i++) {
+ mSpellParsers[i].finish();
+ }
+
+ // Remove existing misspelled SuggestionSpans
+ mTextView.removeMisspelledSpans((Editable) mTextView.getText());
+
+ // This class is the listener for locale change: warn other locale-aware objects
+ mTextView.onLocaleChanged();
}
/**
* @return true if a spell checker session has successfully been created. Returns false if not,
* for instance when spell checking has been disabled in settings.
*/
- public boolean isSessionActive() {
+ private boolean isSessionActive() {
return mSpellCheckerSession != null;
}
@@ -84,6 +124,11 @@
if (mSpellCheckerSession != null) {
mSpellCheckerSession.close();
}
+
+ final int length = mSpellParsers.length;
+ for (int i = 0; i < length; i++) {
+ mSpellParsers[i].finish();
+ }
}
private int nextSpellCheckSpanIndex() {
@@ -106,10 +151,9 @@
return mLength - 1;
}
- public void addSpellCheckSpan(int wordStart, int wordEnd) {
+ private void addSpellCheckSpan(Editable editable, int start, int end) {
final int index = nextSpellCheckSpanIndex();
- ((Editable) mTextView.getText()).setSpan(mSpellCheckSpans[index], wordStart, wordEnd,
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ editable.setSpan(mSpellCheckSpans[index], start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mIds[index] = mSpanSequenceCounter++;
}
@@ -127,10 +171,42 @@
spellCheck();
}
- public void spellCheck() {
+ public void spellCheck(int start, int end) {
+ final Locale locale = mTextView.getLocale();
+ if (mCurrentLocale == null || (!(mCurrentLocale.equals(locale)))) {
+ setLocale(locale);
+ // Re-check the entire text
+ start = 0;
+ end = mTextView.getText().length();
+ }
+
+ if (!isSessionActive()) return;
+
+ final int length = mSpellParsers.length;
+ for (int i = 0; i < length; i++) {
+ final SpellParser spellParser = mSpellParsers[i];
+ if (spellParser.isFinished()) {
+ spellParser.init(start, end);
+ spellParser.parse();
+ return;
+ }
+ }
+
+ // No available parser found in pool, create a new one
+ SpellParser[] newSpellParsers = new SpellParser[length + 1];
+ System.arraycopy(mSpellParsers, 0, newSpellParsers, 0, length);
+ mSpellParsers = newSpellParsers;
+
+ SpellParser spellParser = new SpellParser();
+ mSpellParsers[length] = spellParser;
+ spellParser.init(start, end);
+ spellParser.parse();
+ }
+
+ private void spellCheck() {
if (mSpellCheckerSession == null) return;
- final Editable editable = (Editable) mTextView.getText();
+ Editable editable = (Editable) mTextView.getText();
final int selectionStart = Selection.getSelectionStart(editable);
final int selectionEnd = Selection.getSelectionEnd(editable);
@@ -153,7 +229,7 @@
}
if (textInfosCount > 0) {
- if (textInfosCount < mLength) {
+ if (textInfosCount < textInfos.length) {
TextInfo[] textInfosCopy = new TextInfo[textInfosCount];
System.arraycopy(textInfos, 0, textInfosCopy, 0, textInfosCount);
textInfos = textInfosCopy;
@@ -165,7 +241,8 @@
@Override
public void onGetSuggestions(SuggestionsInfo[] results) {
- final Editable editable = (Editable) mTextView.getText();
+ Editable editable = (Editable) mTextView.getText();
+
for (int i = 0; i < results.length; i++) {
SuggestionsInfo suggestionsInfo = results[i];
if (suggestionsInfo.getCookie() != mCookie) continue;
@@ -188,12 +265,21 @@
}
}
}
+
+ final int length = mSpellParsers.length;
+ for (int i = 0; i < length; i++) {
+ final SpellParser spellParser = mSpellParsers[i];
+ if (!spellParser.isFinished()) {
+ spellParser.parse();
+ }
+ }
}
- private void createMisspelledSuggestionSpan(Editable editable, SuggestionsInfo suggestionsInfo,
- SpellCheckSpan spellCheckSpan) {
+ private void createMisspelledSuggestionSpan(Editable editable,
+ SuggestionsInfo suggestionsInfo, SpellCheckSpan spellCheckSpan) {
final int start = editable.getSpanStart(spellCheckSpan);
final int end = editable.getSpanEnd(spellCheckSpan);
+ if (start < 0 || end < 0) return; // span was removed in the meantime
// Other suggestion spans may exist on that region, with identical suggestions, filter
// them out to avoid duplicates. First, filter suggestion spans on that exact region.
@@ -204,7 +290,6 @@
final int spanEnd = editable.getSpanEnd(suggestionSpans[i]);
if (spanStart != start || spanEnd != end) {
suggestionSpans[i] = null;
- break;
}
}
@@ -254,4 +339,130 @@
// TODO limit to the word rectangle region
mTextView.invalidate();
}
+
+ private class SpellParser {
+ private Object mRange = new Object();
+
+ public void init(int start, int end) {
+ ((Editable) mTextView.getText()).setSpan(mRange, start, end,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+
+ public void finish() {
+ ((Editable) mTextView.getText()).removeSpan(mRange);
+ }
+
+ public boolean isFinished() {
+ return ((Editable) mTextView.getText()).getSpanStart(mRange) < 0;
+ }
+
+ public void parse() {
+ Editable editable = (Editable) mTextView.getText();
+ // Iterate over the newly added text and schedule new SpellCheckSpans
+ final int start = editable.getSpanStart(mRange);
+ final int end = editable.getSpanEnd(mRange);
+ mWordIterator.setCharSequence(editable, start, end);
+
+ // Move back to the beginning of the current word, if any
+ int wordStart = mWordIterator.preceding(start);
+ int wordEnd;
+ if (wordStart == BreakIterator.DONE) {
+ wordEnd = mWordIterator.following(start);
+ if (wordEnd != BreakIterator.DONE) {
+ wordStart = mWordIterator.getBeginning(wordEnd);
+ }
+ } else {
+ wordEnd = mWordIterator.getEnd(wordStart);
+ }
+ if (wordEnd == BreakIterator.DONE) {
+ editable.removeSpan(mRange);
+ return;
+ }
+
+ // We need to expand by one character because we want to include the spans that
+ // end/start at position start/end respectively.
+ SpellCheckSpan[] spellCheckSpans = editable.getSpans(start - 1, end + 1,
+ SpellCheckSpan.class);
+ SuggestionSpan[] suggestionSpans = editable.getSpans(start - 1, end + 1,
+ SuggestionSpan.class);
+
+ int nbWordsChecked = 0;
+ boolean scheduleOtherSpellCheck = false;
+
+ while (wordStart <= end) {
+ if (wordEnd >= start && wordEnd > wordStart) {
+ // A new word has been created across the interval boundaries with this edit.
+ // Previous spans (ended on start / started on end) removed, not valid anymore
+ if (wordStart < start && wordEnd > start) {
+ removeSpansAt(editable, start, spellCheckSpans);
+ removeSpansAt(editable, start, suggestionSpans);
+ }
+
+ if (wordStart < end && wordEnd > end) {
+ removeSpansAt(editable, end, spellCheckSpans);
+ removeSpansAt(editable, end, suggestionSpans);
+ }
+
+ // Do not create new boundary spans if they already exist
+ boolean createSpellCheckSpan = true;
+ if (wordEnd == start) {
+ for (int i = 0; i < spellCheckSpans.length; i++) {
+ final int spanEnd = editable.getSpanEnd(spellCheckSpans[i]);
+ if (spanEnd == start) {
+ createSpellCheckSpan = false;
+ break;
+ }
+ }
+ }
+
+ if (wordStart == end) {
+ for (int i = 0; i < spellCheckSpans.length; i++) {
+ final int spanStart = editable.getSpanStart(spellCheckSpans[i]);
+ if (spanStart == end) {
+ createSpellCheckSpan = false;
+ break;
+ }
+ }
+ }
+
+ if (createSpellCheckSpan) {
+ if (nbWordsChecked == MAX_SPELL_BATCH_SIZE) {
+ scheduleOtherSpellCheck = true;
+ break;
+ }
+ addSpellCheckSpan(editable, wordStart, wordEnd);
+ nbWordsChecked++;
+ }
+ }
+
+ // iterate word by word
+ wordEnd = mWordIterator.following(wordEnd);
+ if (wordEnd == BreakIterator.DONE) break;
+ wordStart = mWordIterator.getBeginning(wordEnd);
+ if (wordStart == BreakIterator.DONE) {
+ break;
+ }
+ }
+
+ if (scheduleOtherSpellCheck) {
+ editable.setSpan(mRange, wordStart, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ } else {
+ editable.removeSpan(mRange);
+ }
+
+ spellCheck();
+ }
+
+ private <T> void removeSpansAt(Editable editable, int offset, T[] spans) {
+ final int length = spans.length;
+ for (int i = 0; i < length; i++) {
+ final T span = spans[i];
+ final int start = editable.getSpanStart(span);
+ if (start > offset) continue;
+ final int end = editable.getSpanEnd(span);
+ if (end < offset) continue;
+ editable.removeSpan(span);
+ }
+ }
+ }
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 68de2e9..55e49ea 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -132,6 +132,7 @@
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethodSubtype;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.RemoteViews.RemoteView;
@@ -147,6 +148,7 @@
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.Locale;
/**
* Displays text to the user and optionally allows them to edit it. A TextView
@@ -353,12 +355,12 @@
// Set when this TextView gained focus with some text selected. Will start selection mode.
private boolean mCreatedWithASelection = false;
- // Size of the window for the word iterator, should be greater than the longest word's length
- private static final int WORD_ITERATOR_WINDOW_WIDTH = 50;
private WordIterator mWordIterator;
private SpellChecker mSpellChecker;
+ private boolean mShowSoftInputOnFocus = true;
+
// The alignment to pass to Layout, or null if not resolved.
private Layout.Alignment mLayoutAlignment;
@@ -607,6 +609,12 @@
mLinksClickable = a.getBoolean(attr, true);
break;
+// TODO uncomment when this attribute is made public in the next release
+// also add TextView_showSoftInputOnFocus to the list of attributes above
+// case com.android.internal.R.styleable.TextView_showSoftInputOnFocus:
+// setShowSoftInputOnFocus(a.getBoolean(attr, true));
+// break;
+
case com.android.internal.R.styleable.TextView_drawableLeft:
drawableLeft = a.getDrawable(attr);
break;
@@ -2370,6 +2378,29 @@
}
/**
+ * Sets whether the soft input method will be made visible when this
+ * TextView gets focused. The default is true.
+ *
+ * @attr ref android.R.styleable#TextView_showSoftInputOnFocus
+ * @hide
+ */
+ @android.view.RemotableViewMethod
+ public final void setShowSoftInputOnFocus(boolean show) {
+ mShowSoftInputOnFocus = show;
+ }
+
+ /**
+ * Returns whether the soft input method will be made visible when this
+ * TextView gets focused. The default is true.
+ *
+ * @attr ref android.R.styleable#TextView_showSoftInputOnFocus
+ * @hide
+ */
+ public final boolean getShowSoftInputOnFocus() {
+ return mShowSoftInputOnFocus;
+ }
+
+ /**
* Returns the list of URLSpans attached to the text
* (by {@link Linkify} or otherwise) if any. You can call
* {@link URLSpan#getURL} on them to find where they link to
@@ -2478,6 +2509,7 @@
if (gravity != mGravity) {
invalidate();
+ mLayoutAlignment = null;
}
mGravity = gravity;
@@ -2943,15 +2975,7 @@
sp.removeSpan(cw);
}
- SuggestionSpan[] suggestionSpans = sp.getSpans(0, sp.length(), SuggestionSpan.class);
- for (int i = 0; i < suggestionSpans.length; i++) {
- int flags = suggestionSpans[i].getFlags();
- if ((flags & SuggestionSpan.FLAG_EASY_CORRECT) != 0
- && (flags & SuggestionSpan.FLAG_MISSPELLED) != 0) {
- sp.removeSpan(suggestionSpans[i]);
- }
- }
-
+ removeMisspelledSpans(sp);
sp.removeSpan(mSuggestionRangeSpan);
ss.text = sp;
@@ -2971,6 +2995,18 @@
return superState;
}
+ void removeMisspelledSpans(Spannable spannable) {
+ SuggestionSpan[] suggestionSpans = spannable.getSpans(0, spannable.length(),
+ SuggestionSpan.class);
+ for (int i = 0; i < suggestionSpans.length; i++) {
+ int flags = suggestionSpans[i].getFlags();
+ if ((flags & SuggestionSpan.FLAG_EASY_CORRECT) != 0
+ && (flags & SuggestionSpan.FLAG_MISSPELLED) != 0) {
+ spannable.removeSpan(suggestionSpans[i]);
+ }
+ }
+ }
+
@Override
public void onRestoreInstanceState(Parcelable state) {
if (!(state instanceof SavedState)) {
@@ -5466,7 +5502,7 @@
&& mLayout != null && onCheckIsTextEditor()) {
InputMethodManager imm = InputMethodManager.peekInstance();
viewClicked(imm);
- if (imm != null) {
+ if (imm != null && mShowSoftInputOnFocus) {
imm.showSoftInput(this, 0);
}
}
@@ -6124,7 +6160,7 @@
* not the full view width with padding.
* {@hide}
*/
- protected void makeNewLayout(int w, int hintWidth,
+ protected void makeNewLayout(int wantWidth, int hintWidth,
BoringLayout.Metrics boring,
BoringLayout.Metrics hintBoring,
int ellipsisWidth, boolean bringIntoView) {
@@ -6136,8 +6172,8 @@
mHighlightPathBogus = true;
- if (w < 0) {
- w = 0;
+ if (wantWidth < 0) {
+ wantWidth = 0;
}
if (hintWidth < 0) {
hintWidth = 0;
@@ -6157,12 +6193,12 @@
resolveTextDirection();
}
- mLayout = makeSingleLayout(w, boring, ellipsisWidth, alignment, shouldEllipsize,
+ mLayout = makeSingleLayout(wantWidth, boring, ellipsisWidth, alignment, shouldEllipsize,
effectiveEllipsize, effectiveEllipsize == mEllipsize);
if (switchEllipsize) {
TruncateAt oppositeEllipsize = effectiveEllipsize == TruncateAt.MARQUEE ?
TruncateAt.END : TruncateAt.MARQUEE;
- mSavedMarqueeModeLayout = makeSingleLayout(w, boring, ellipsisWidth, alignment,
+ mSavedMarqueeModeLayout = makeSingleLayout(wantWidth, boring, ellipsisWidth, alignment,
shouldEllipsize, oppositeEllipsize, effectiveEllipsize != mEllipsize);
}
@@ -6170,7 +6206,7 @@
mHintLayout = null;
if (mHint != null) {
- if (shouldEllipsize) hintWidth = w;
+ if (shouldEllipsize) hintWidth = wantWidth;
if (hintBoring == UNKNOWN_BORING) {
hintBoring = BoringLayout.isBoring(mHint, mTextPaint, mTextDir,
@@ -6254,12 +6290,12 @@
prepareCursorControllers();
}
- private Layout makeSingleLayout(int w, BoringLayout.Metrics boring, int ellipsisWidth,
+ private Layout makeSingleLayout(int wantWidth, BoringLayout.Metrics boring, int ellipsisWidth,
Layout.Alignment alignment, boolean shouldEllipsize, TruncateAt effectiveEllipsize,
boolean useSaved) {
Layout result = null;
if (mText instanceof Spannable) {
- result = new DynamicLayout(mText, mTransformed, mTextPaint, w,
+ result = new DynamicLayout(mText, mTransformed, mTextPaint, wantWidth,
alignment, mTextDir, mSpacingMult,
mSpacingAdd, mIncludePad, mInput == null ? effectiveEllipsize : null,
ellipsisWidth);
@@ -6272,53 +6308,53 @@
}
if (boring != null) {
- if (boring.width <= w &&
+ if (boring.width <= wantWidth &&
(effectiveEllipsize == null || boring.width <= ellipsisWidth)) {
if (useSaved && mSavedLayout != null) {
result = mSavedLayout.replaceOrMake(mTransformed, mTextPaint,
- w, alignment, mSpacingMult, mSpacingAdd,
+ wantWidth, alignment, mSpacingMult, mSpacingAdd,
boring, mIncludePad);
} else {
result = BoringLayout.make(mTransformed, mTextPaint,
- w, alignment, mSpacingMult, mSpacingAdd,
+ wantWidth, alignment, mSpacingMult, mSpacingAdd,
boring, mIncludePad);
}
if (useSaved) {
mSavedLayout = (BoringLayout) result;
}
- } else if (shouldEllipsize && boring.width <= w) {
+ } else if (shouldEllipsize && boring.width <= wantWidth) {
if (useSaved && mSavedLayout != null) {
result = mSavedLayout.replaceOrMake(mTransformed, mTextPaint,
- w, alignment, mSpacingMult, mSpacingAdd,
+ wantWidth, alignment, mSpacingMult, mSpacingAdd,
boring, mIncludePad, effectiveEllipsize,
ellipsisWidth);
} else {
result = BoringLayout.make(mTransformed, mTextPaint,
- w, alignment, mSpacingMult, mSpacingAdd,
+ wantWidth, alignment, mSpacingMult, mSpacingAdd,
boring, mIncludePad, effectiveEllipsize,
ellipsisWidth);
}
} else if (shouldEllipsize) {
result = new StaticLayout(mTransformed,
0, mTransformed.length(),
- mTextPaint, w, alignment, mTextDir, mSpacingMult,
+ mTextPaint, wantWidth, alignment, mTextDir, mSpacingMult,
mSpacingAdd, mIncludePad, effectiveEllipsize,
ellipsisWidth, mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
} else {
result = new StaticLayout(mTransformed, mTextPaint,
- w, alignment, mTextDir, mSpacingMult, mSpacingAdd,
+ wantWidth, alignment, mTextDir, mSpacingMult, mSpacingAdd,
mIncludePad);
}
} else if (shouldEllipsize) {
result = new StaticLayout(mTransformed,
0, mTransformed.length(),
- mTextPaint, w, alignment, mTextDir, mSpacingMult,
+ mTextPaint, wantWidth, alignment, mTextDir, mSpacingMult,
mSpacingAdd, mIncludePad, effectiveEllipsize,
ellipsisWidth, mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
} else {
result = new StaticLayout(mTransformed, mTextPaint,
- w, alignment, mTextDir, mSpacingMult, mSpacingAdd,
+ wantWidth, alignment, mTextDir, mSpacingMult, mSpacingAdd,
mIncludePad);
}
}
@@ -7684,8 +7720,9 @@
}
}
- if (what instanceof UpdateAppearance ||
- what instanceof ParagraphStyle) {
+ if (what instanceof UpdateAppearance || what instanceof ParagraphStyle
+ || (what instanceof SuggestionSpan && (((SuggestionSpan)what).getFlags()
+ & SuggestionSpan.FLAG_AUTO_CORRECTION) != 0)) {
if (ims == null || ims.mBatchEditNesting == 0) {
invalidate();
mHighlightPathBogus = true;
@@ -7749,98 +7786,8 @@
* Create new SpellCheckSpans on the modified region.
*/
private void updateSpellCheckSpans(int start, int end) {
- if (!isTextEditable() || !isSuggestionsEnabled() || !getSpellChecker().isSessionActive())
- return;
- Editable text = (Editable) mText;
-
- final int shift = prepareWordIterator(start, end);
- final int shiftedStart = start - shift;
- final int shiftedEnd = end - shift;
-
- // Move back to the beginning of the current word, if any
- int wordStart = mWordIterator.preceding(shiftedStart);
- int wordEnd;
- if (wordStart == BreakIterator.DONE) {
- wordEnd = mWordIterator.following(shiftedStart);
- if (wordEnd != BreakIterator.DONE) {
- wordStart = mWordIterator.getBeginning(wordEnd);
- }
- } else {
- wordEnd = mWordIterator.getEnd(wordStart);
- }
- if (wordEnd == BreakIterator.DONE) {
- return;
- }
-
- // We need to expand by one character because we want to include the spans that end/start
- // at position start/end respectively.
- SpellCheckSpan[] spellCheckSpans = text.getSpans(start - 1, end + 1, SpellCheckSpan.class);
- SuggestionSpan[] suggestionSpans = text.getSpans(start - 1, end + 1, SuggestionSpan.class);
- final int numberOfSpellCheckSpans = spellCheckSpans.length;
-
- // Iterate over the newly added text and schedule new SpellCheckSpans
- while (wordStart <= shiftedEnd) {
- if (wordEnd >= shiftedStart && wordEnd > wordStart) {
- // A new word has been created across the interval boundaries. Remove previous spans
- if (wordStart < shiftedStart && wordEnd > shiftedStart) {
- removeSpansAt(start, spellCheckSpans, text);
- removeSpansAt(start, suggestionSpans, text);
- }
-
- if (wordStart < shiftedEnd && wordEnd > shiftedEnd) {
- removeSpansAt(end, spellCheckSpans, text);
- removeSpansAt(end, suggestionSpans, text);
- }
-
- // Do not create new boundary spans if they already exist
- boolean createSpellCheckSpan = true;
- if (wordEnd == shiftedStart) {
- for (int i = 0; i < numberOfSpellCheckSpans; i++) {
- final int spanEnd = text.getSpanEnd(spellCheckSpans[i]);
- if (spanEnd == start) {
- createSpellCheckSpan = false;
- break;
- }
- }
- }
-
- if (wordStart == shiftedEnd) {
- for (int i = 0; i < numberOfSpellCheckSpans; i++) {
- final int spanStart = text.getSpanStart(spellCheckSpans[i]);
- if (spanStart == end) {
- createSpellCheckSpan = false;
- break;
- }
- }
- }
-
- if (createSpellCheckSpan) {
- mSpellChecker.addSpellCheckSpan(wordStart + shift, wordEnd + shift);
- }
- }
-
- // iterate word by word
- wordEnd = mWordIterator.following(wordEnd);
- if (wordEnd == BreakIterator.DONE) break;
- wordStart = mWordIterator.getBeginning(wordEnd);
- if (wordStart == BreakIterator.DONE) {
- Log.e(LOG_TAG, "No word beginning from " + (wordEnd + shift) + "in " + mText);
- break;
- }
- }
-
- mSpellChecker.spellCheck();
- }
-
- private static <T> void removeSpansAt(int offset, T[] spans, Editable text) {
- final int length = spans.length;
- for (int i = 0; i < length; i++) {
- final T span = spans[i];
- final int start = text.getSpanStart(span);
- if (start > offset) continue;
- final int end = text.getSpanEnd(span);
- if (end < offset) continue;
- text.removeSpan(span);
+ if (isTextEditable() && isSuggestionsEnabled()) {
+ getSpellChecker().spellCheck(start, end);
}
}
@@ -8297,6 +8244,9 @@
}
hideControllers();
+ if (mSuggestionsPopupWindow != null) {
+ mSuggestionsPopupWindow.onParentLostFocus();
+ }
}
startStopMarquee(hasWindowFocus);
@@ -8394,7 +8344,7 @@
// Show the IME, except when selecting in read-only text.
final InputMethodManager imm = InputMethodManager.peekInstance();
viewClicked(imm);
- if (!mTextIsSelectable) {
+ if (!mTextIsSelectable && mShowSoftInputOnFocus) {
handled |= imm != null && imm.showSoftInput(this, 0);
}
@@ -8930,15 +8880,14 @@
selectionStart = ((Spanned) mText).getSpanStart(urlSpan);
selectionEnd = ((Spanned) mText).getSpanEnd(urlSpan);
} else {
- final int shift = prepareWordIterator(minOffset, maxOffset);
+ final WordIterator wordIterator = getWordIterator();
+ wordIterator.setCharSequence(mText, minOffset, maxOffset);
- selectionStart = mWordIterator.getBeginning(minOffset - shift);
+ selectionStart = wordIterator.getBeginning(minOffset);
if (selectionStart == BreakIterator.DONE) return false;
- selectionStart += shift;
- selectionEnd = mWordIterator.getEnd(maxOffset - shift);
+ selectionEnd = wordIterator.getEnd(maxOffset);
if (selectionEnd == BreakIterator.DONE) return false;
- selectionEnd += shift;
if (selectionStart == selectionEnd) {
// Possible when the word iterator does not properly handle the text's language
@@ -8952,6 +8901,43 @@
return selectionEnd > selectionStart;
}
+ /**
+ * This is a temporary method. Future versions may support multi-locale text.
+ *
+ * @return The current locale used in this TextView, based on the current IME's locale,
+ * or the system default locale if this is not defined.
+ * @hide
+ */
+ public Locale getLocale() {
+ Locale locale = Locale.getDefault();
+ final InputMethodManager imm = InputMethodManager.peekInstance();
+ if (imm != null) {
+ final InputMethodSubtype currentInputMethodSubtype = imm.getCurrentInputMethodSubtype();
+ if (currentInputMethodSubtype != null) {
+ String localeString = currentInputMethodSubtype.getLocale();
+ if (!TextUtils.isEmpty(localeString)) {
+ locale = new Locale(localeString);
+ }
+ }
+ }
+ return locale;
+ }
+
+ void onLocaleChanged() {
+ // Will be re-created on demand in getWordIterator with the proper new locale
+ mWordIterator = null;
+ }
+
+ /**
+ * @hide
+ */
+ public WordIterator getWordIterator() {
+ if (mWordIterator == null) {
+ mWordIterator = new WordIterator(getLocale());
+ }
+ return mWordIterator;
+ }
+
private long getCharRange(int offset) {
final int textLength = mText.length();
if (offset + 1 < textLength) {
@@ -8977,18 +8963,6 @@
return packRangeInLong(offset, offset);
}
- int prepareWordIterator(int start, int end) {
- if (mWordIterator == null) {
- mWordIterator = new WordIterator();
- }
-
- final int windowStart = Math.max(0, start - WORD_ITERATOR_WINDOW_WIDTH);
- final int windowEnd = Math.min(mText.length(), end + WORD_ITERATOR_WINDOW_WIDTH);
- mWordIterator.setCharSequence(mText.subSequence(windowStart, windowEnd));
-
- return windowStart;
- }
-
private SpellChecker getSpellChecker() {
if (mSpellChecker == null) {
mSpellChecker = new SpellChecker(this);
@@ -9648,6 +9622,7 @@
private SuggestionInfo[] mSuggestionInfos;
private int mNumberOfSuggestions;
private boolean mCursorWasVisibleBeforeSuggestions;
+ private boolean mIsShowingUp = false;
private SuggestionAdapter mSuggestionsAdapter;
private final Comparator<SuggestionSpan> mSuggestionSpanComparator;
private final HashMap<SuggestionSpan, Integer> mSpansLengths;
@@ -9703,6 +9678,14 @@
}
}
+ public boolean isShowingUp() {
+ return mIsShowingUp;
+ }
+
+ public void onParentLostFocus() {
+ mIsShowingUp = false;
+ }
+
private class SuggestionInfo {
int suggestionStart, suggestionEnd; // range of actual suggestion within text
SuggestionSpan suggestionSpan; // the SuggestionSpan that this TextView represents
@@ -9710,15 +9693,6 @@
SpannableStringBuilder text = new SpannableStringBuilder();
TextAppearanceSpan highlightSpan = new TextAppearanceSpan(mContext,
android.R.style.TextAppearance_SuggestionHighlight);
-
- void removeMisspelledFlag() {
- int suggestionSpanFlags = suggestionSpan.getFlags();
- if ((suggestionSpanFlags & SuggestionSpan.FLAG_MISSPELLED) > 0) {
- suggestionSpanFlags &= ~SuggestionSpan.FLAG_MISSPELLED;
- suggestionSpanFlags &= ~SuggestionSpan.FLAG_EASY_CORRECT;
- suggestionSpan.setFlags(suggestionSpanFlags);
- }
- }
}
private class SuggestionAdapter extends BaseAdapter {
@@ -9815,6 +9789,7 @@
updateSuggestions();
mCursorWasVisibleBeforeSuggestions = mCursorVisible;
setCursorVisible(false);
+ mIsShowingUp = true;
super.show();
}
@@ -9992,14 +9967,16 @@
if (suggestionInfo.suggestionIndex == DELETE_TEXT) {
final int spanUnionStart = editable.getSpanStart(mSuggestionRangeSpan);
int spanUnionEnd = editable.getSpanEnd(mSuggestionRangeSpan);
- // Do not leave two adjacent spaces after deletion, or one at beginning of text
- if (spanUnionEnd < editable.length() &&
- Character.isSpaceChar(editable.charAt(spanUnionEnd)) &&
- (spanUnionStart == 0 ||
- Character.isSpaceChar(editable.charAt(spanUnionStart - 1)))) {
+ if (spanUnionStart >= 0 && spanUnionEnd > spanUnionStart) {
+ // Do not leave two adjacent spaces after deletion, or one at beginning of text
+ if (spanUnionEnd < editable.length() &&
+ Character.isSpaceChar(editable.charAt(spanUnionEnd)) &&
+ (spanUnionStart == 0 ||
+ Character.isSpaceChar(editable.charAt(spanUnionStart - 1)))) {
spanUnionEnd = spanUnionEnd + 1;
+ }
+ editable.replace(spanUnionStart, spanUnionEnd, "");
}
- editable.replace(spanUnionStart, spanUnionEnd, "");
hide();
return;
}
@@ -10034,6 +10011,14 @@
suggestionSpansStarts[i] = editable.getSpanStart(suggestionSpan);
suggestionSpansEnds[i] = editable.getSpanEnd(suggestionSpan);
suggestionSpansFlags[i] = editable.getSpanFlags(suggestionSpan);
+
+ // Remove potential misspelled flags
+ int suggestionSpanFlags = suggestionSpan.getFlags();
+ if ((suggestionSpanFlags & SuggestionSpan.FLAG_MISSPELLED) > 0) {
+ suggestionSpanFlags &= ~SuggestionSpan.FLAG_MISSPELLED;
+ suggestionSpanFlags &= ~SuggestionSpan.FLAG_EASY_CORRECT;
+ suggestionSpan.setFlags(suggestionSpanFlags);
+ }
}
final int suggestionStart = suggestionInfo.suggestionStart;
@@ -10042,8 +10027,6 @@
suggestionStart, suggestionEnd).toString();
editable.replace(spanStart, spanEnd, suggestion);
- suggestionInfo.removeMisspelledFlag();
-
// Notify source IME of the suggestion pick. Do this before swaping texts.
if (!TextUtils.isEmpty(
suggestionInfo.suggestionSpan.getNotificationTargetClassName())) {
@@ -10219,7 +10202,7 @@
final boolean selectionStarted = mSelectionActionMode != null ||
extractedTextModeWillBeStartedFullScreen;
- if (selectionStarted && !mTextIsSelectable && imm != null) {
+ if (selectionStarted && !mTextIsSelectable && imm != null && mShowSoftInputOnFocus) {
// Show the IME to be able to replace text, except when selecting non editable text.
imm.showSoftInput(this, 0, null);
}
@@ -11219,6 +11202,10 @@
}
private void hideCursorControllers() {
+ if (mSuggestionsPopupWindow != null && !mSuggestionsPopupWindow.isShowingUp()) {
+ // Should be done before hide insertion point controller since it triggers a show of it
+ mSuggestionsPopupWindow.hide();
+ }
hideInsertionPointCursorController();
stopSelectionActionMode();
}
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index bb23173..88d7e05 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -48,6 +48,13 @@
* <p>
* The easiest way to use this class is to call one of the static methods that constructs
* everything you need and returns a new Toast object.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about creating Toast notifications, read the
+ * <a href="{@docRoot}guide/topics/ui/notifiers/toasts.html">Toast Notifications</a> developer
+ * guide.</p>
+ * </div>
*/
public class Toast {
static final String TAG = "Toast";
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 9fbbb3d..a0e125a 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -17,32 +17,79 @@
package com.android.internal.app;
import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Vibrator;
import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
import android.widget.ImageView;
import android.widget.Toast;
public class PlatLogoActivity extends Activity {
Toast mToast;
+ ImageView mContent;
+ Vibrator mZzz = new Vibrator();
+ int mCount;
+ final Handler mHandler = new Handler();
+
+ Runnable mSuperLongPress = new Runnable() {
+ public void run() {
+ mCount++;
+ mZzz.vibrate(50 * mCount);
+ final float scale = 1f + 0.25f * mCount * mCount;
+ mContent.setScaleX(scale);
+ mContent.setScaleY(scale);
+
+ if (mCount <= 3) {
+ mHandler.postDelayed(mSuperLongPress, ViewConfiguration.getLongPressTimeout());
+ } else {
+ try {
+ startActivity(new Intent(Intent.ACTION_MAIN)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_CLEAR_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+ .setClassName("com.android.systemui","com.android.systemui.Nyandroid"));
+ } catch (ActivityNotFoundException ex) {
+ android.util.Log.e("PlatLogoActivity", "Couldn't find platlogo screensaver.");
+ }
+ finish();
+ }
+ }
+ };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mToast = Toast.makeText(this, "REZZZZZZZ...", Toast.LENGTH_SHORT);
+ mToast = Toast.makeText(this, "Android 4.0: Ice Cream Sandwich", Toast.LENGTH_SHORT);
- ImageView content = new ImageView(this);
- content.setImageResource(com.android.internal.R.drawable.platlogo);
- content.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+ mContent = new ImageView(this);
+ mContent.setImageResource(com.android.internal.R.drawable.platlogo);
+ mContent.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+
+ mContent.setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ final int action = event.getAction();
+ if (action == MotionEvent.ACTION_DOWN) {
+ mContent.setPressed(true);
+ mHandler.removeCallbacks(mSuperLongPress);
+ mCount = 0;
+ mHandler.postDelayed(mSuperLongPress, 2*ViewConfiguration.getLongPressTimeout());
+ } else if (action == MotionEvent.ACTION_UP) {
+ if (mContent.isPressed()) {
+ mContent.setPressed(false);
+ mHandler.removeCallbacks(mSuperLongPress);
+ mToast.show();
+ }
+ }
+ return true;
+ }
+ });
- setContentView(content);
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_UP) {
- mToast.show();
- }
- return super.dispatchTouchEvent(ev);
+ setContentView(mContent);
}
}
diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
index daabf42..77d0c97 100644
--- a/core/java/com/android/internal/app/ShutdownThread.java
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -109,7 +109,6 @@
if (confirm) {
final CloseDialogReceiver closer = new CloseDialogReceiver(context);
final AlertDialog dialog = new AlertDialog.Builder(context)
- .setIconAttribute(android.R.attr.alertDialogIcon)
.setTitle(com.android.internal.R.string.power_off)
.setMessage(resourceId)
.setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
diff --git a/core/java/com/android/internal/policy/IFaceLockCallback.aidl b/core/java/com/android/internal/policy/IFaceLockCallback.aidl
index add3f1c..25adbb6 100644
--- a/core/java/com/android/internal/policy/IFaceLockCallback.aidl
+++ b/core/java/com/android/internal/policy/IFaceLockCallback.aidl
@@ -21,5 +21,6 @@
oneway interface IFaceLockCallback {
void unlock();
void cancel();
+ void reportFailedAttempt();
void pokeWakelock();
}
diff --git a/core/java/com/android/internal/policy/IFaceLockInterface.aidl b/core/java/com/android/internal/policy/IFaceLockInterface.aidl
index 921b8c7..3958cda 100644
--- a/core/java/com/android/internal/policy/IFaceLockInterface.aidl
+++ b/core/java/com/android/internal/policy/IFaceLockInterface.aidl
@@ -23,4 +23,5 @@
void startUi(IBinder containingWindowToken, int x, int y, int width, int height);
void stopUi();
void registerCallback(IFaceLockCallback cb);
+ void unregisterCallback(IFaceLockCallback cb);
}
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index aabea2c..f25d65f 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -31,9 +31,6 @@
import android.view.View.MeasureSpec;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ImageButton;
import java.util.ArrayList;
@@ -71,8 +68,8 @@
final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback();
int mOpenSubMenuId;
- public ActionMenuPresenter() {
- super(com.android.internal.R.layout.action_menu_layout,
+ public ActionMenuPresenter(Context context) {
+ super(context, com.android.internal.R.layout.action_menu_layout,
com.android.internal.R.layout.action_menu_item_layout);
}
@@ -98,7 +95,7 @@
int width = mWidthLimit;
if (mReserveOverflow) {
if (mOverflowButton == null) {
- mOverflowButton = new OverflowMenuButton(mContext);
+ mOverflowButton = new OverflowMenuButton(mSystemContext);
final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
mOverflowButton.measure(spec, spec);
}
@@ -215,7 +212,7 @@
if (hasOverflow) {
if (mOverflowButton == null) {
- mOverflowButton = new OverflowMenuButton(mContext);
+ mOverflowButton = new OverflowMenuButton(mSystemContext);
}
ViewGroup parent = (ViewGroup) mOverflowButton.getParent();
if (parent != mMenuView) {
diff --git a/core/java/com/android/internal/view/menu/BaseMenuPresenter.java b/core/java/com/android/internal/view/menu/BaseMenuPresenter.java
index bec437a..1e06b5a 100644
--- a/core/java/com/android/internal/view/menu/BaseMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/BaseMenuPresenter.java
@@ -29,8 +29,10 @@
* be reused if possible when items change.
*/
public abstract class BaseMenuPresenter implements MenuPresenter {
+ protected Context mSystemContext;
protected Context mContext;
protected MenuBuilder mMenu;
+ protected LayoutInflater mSystemInflater;
protected LayoutInflater mInflater;
private Callback mCallback;
@@ -44,10 +46,13 @@
/**
* Construct a new BaseMenuPresenter.
*
+ * @param context Context for generating system-supplied views
* @param menuLayoutRes Layout resource ID for the menu container view
* @param itemLayoutRes Layout resource ID for a single item view
*/
- public BaseMenuPresenter(int menuLayoutRes, int itemLayoutRes) {
+ public BaseMenuPresenter(Context context, int menuLayoutRes, int itemLayoutRes) {
+ mSystemContext = context;
+ mSystemInflater = LayoutInflater.from(context);
mMenuLayoutRes = menuLayoutRes;
mItemLayoutRes = itemLayoutRes;
}
@@ -62,7 +67,7 @@
@Override
public MenuView getMenuView(ViewGroup root) {
if (mMenuView == null) {
- mMenuView = (MenuView) mInflater.inflate(mMenuLayoutRes, root, false);
+ mMenuView = (MenuView) mSystemInflater.inflate(mMenuLayoutRes, root, false);
mMenuView.initialize(mMenu);
updateMenuView(true);
}
@@ -138,7 +143,7 @@
* @return The new item view
*/
public MenuView.ItemView createItemView(ViewGroup parent) {
- return (MenuView.ItemView) mInflater.inflate(mItemLayoutRes, parent, false);
+ return (MenuView.ItemView) mSystemInflater.inflate(mItemLayoutRes, parent, false);
}
/**
diff --git a/core/java/com/android/internal/view/menu/ExpandedMenuView.java b/core/java/com/android/internal/view/menu/ExpandedMenuView.java
index 723ece4..47058ad 100644
--- a/core/java/com/android/internal/view/menu/ExpandedMenuView.java
+++ b/core/java/com/android/internal/view/menu/ExpandedMenuView.java
@@ -63,11 +63,6 @@
setChildrenDrawingCacheEnabled(false);
}
- @Override
- protected boolean recycleOnMeasure() {
- return false;
- }
-
public boolean invokeItem(MenuItemImpl item) {
return mMenu.performItemAction(item, 0);
}
diff --git a/core/java/com/android/internal/view/menu/IconMenuPresenter.java b/core/java/com/android/internal/view/menu/IconMenuPresenter.java
index 24ddad6..2439b5d 100644
--- a/core/java/com/android/internal/view/menu/IconMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/IconMenuPresenter.java
@@ -22,7 +22,6 @@
import android.os.Parcelable;
import android.util.SparseArray;
import android.view.ContextThemeWrapper;
-import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@@ -43,16 +42,15 @@
private static final String VIEWS_TAG = "android:menu:icon";
private static final String OPEN_SUBMENU_KEY = "android:menu:icon:submenu";
- public IconMenuPresenter() {
- super(com.android.internal.R.layout.icon_menu_layout,
+ public IconMenuPresenter(Context context) {
+ super(new ContextThemeWrapper(context, com.android.internal.R.style.Theme_IconMenu),
+ com.android.internal.R.layout.icon_menu_layout,
com.android.internal.R.layout.icon_menu_item_layout);
}
@Override
public void initForMenu(Context context, MenuBuilder menu) {
- mContext = new ContextThemeWrapper(context, com.android.internal.R.style.Theme_IconMenu);
- mInflater = LayoutInflater.from(mContext);
- mMenu = menu;
+ super.initForMenu(context, menu);
mMaxItems = -1;
}
diff --git a/core/java/com/android/internal/view/menu/ListMenuItemView.java b/core/java/com/android/internal/view/menu/ListMenuItemView.java
index a1e16d4..df579c69 100644
--- a/core/java/com/android/internal/view/menu/ListMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ListMenuItemView.java
@@ -34,6 +34,7 @@
* The item view for each item in the ListView-based MenuViews.
*/
public class ListMenuItemView extends LinearLayout implements MenuView.ItemView {
+ private static final String TAG = "ListMenuItemView";
private MenuItemImpl mItemData;
private ImageView mIconView;
@@ -121,27 +122,25 @@
}
public void setCheckable(boolean checkable) {
-
if (!checkable && mRadioButton == null && mCheckBox == null) {
return;
}
- if (mRadioButton == null) {
- insertRadioButton();
- }
- if (mCheckBox == null) {
- insertCheckBox();
- }
-
// Depending on whether its exclusive check or not, the checkbox or
// radio button will be the one in use (and the other will be otherCompoundButton)
final CompoundButton compoundButton;
final CompoundButton otherCompoundButton;
if (mItemData.isExclusiveCheckable()) {
+ if (mRadioButton == null) {
+ insertRadioButton();
+ }
compoundButton = mRadioButton;
otherCompoundButton = mCheckBox;
} else {
+ if (mCheckBox == null) {
+ insertCheckBox();
+ }
compoundButton = mCheckBox;
otherCompoundButton = mRadioButton;
}
@@ -155,12 +154,12 @@
}
// Make sure the other compound button isn't visible
- if (otherCompoundButton.getVisibility() != GONE) {
+ if (otherCompoundButton != null && otherCompoundButton.getVisibility() != GONE) {
otherCompoundButton.setVisibility(GONE);
}
} else {
- mCheckBox.setVisibility(GONE);
- mRadioButton.setVisibility(GONE);
+ if (mCheckBox != null) mCheckBox.setVisibility(GONE);
+ if (mRadioButton != null) mRadioButton.setVisibility(GONE);
}
}
diff --git a/core/java/com/android/internal/widget/ActionBarContainer.java b/core/java/com/android/internal/widget/ActionBarContainer.java
index f95de62..0c572705 100644
--- a/core/java/com/android/internal/widget/ActionBarContainer.java
+++ b/core/java/com/android/internal/widget/ActionBarContainer.java
@@ -118,6 +118,14 @@
return true;
}
+ @Override
+ public boolean onHoverEvent(MotionEvent ev) {
+ super.onHoverEvent(ev);
+
+ // An action bar always eats hover events.
+ return true;
+ }
+
public void setTabContainer(ScrollingTabContainerView tabView) {
if (mTabContainer != null) {
removeView(mTabContainer);
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index acffa5c..446dab1 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -207,7 +207,7 @@
});
final MenuBuilder menu = (MenuBuilder) mode.getMenu();
- mActionMenuPresenter = new ActionMenuPresenter();
+ mActionMenuPresenter = new ActionMenuPresenter(mContext);
mActionMenuPresenter.setReserveOverflow(true);
final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 6d2e823..61bce60 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -373,7 +373,7 @@
}
}
if (mActionMenuPresenter == null) {
- mActionMenuPresenter = new ActionMenuPresenter();
+ mActionMenuPresenter = new ActionMenuPresenter(mContext);
mActionMenuPresenter.setCallback(cb);
mActionMenuPresenter.setId(com.android.internal.R.id.action_menu_presenter);
mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter();
diff --git a/core/java/com/android/internal/widget/DigitalClock.java b/core/java/com/android/internal/widget/DigitalClock.java
index ac0dc35..18a4794 100644
--- a/core/java/com/android/internal/widget/DigitalClock.java
+++ b/core/java/com/android/internal/widget/DigitalClock.java
@@ -22,8 +22,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.res.AssetManager;
-import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Typeface;
import android.os.Handler;
@@ -61,6 +59,14 @@
private final Handler mHandler = new Handler();
private BroadcastReceiver mIntentReceiver;
+ private static final Typeface sBackgroundFont;
+ private static final Typeface sForegroundFont;
+
+ static {
+ sBackgroundFont = Typeface.createFromFile(SYSTEM_FONT_TIME_BACKGROUND);
+ sForegroundFont = Typeface.createFromFile(SYSTEM_FONT_TIME_FOREGROUND);
+ }
+
private static class TimeChangedReceiver extends BroadcastReceiver {
private WeakReference<DigitalClock> mClock;
private Context mContext;
@@ -159,13 +165,11 @@
protected void onFinishInflate() {
super.onFinishInflate();
- AssetManager assets = mContext.getAssets();
-
/* The time display consists of two tones. That's why we have two overlapping text views. */
mTimeDisplayBackground = (TextView) findViewById(R.id.timeDisplayBackground);
- mTimeDisplayBackground.setTypeface(Typeface.createFromFile(SYSTEM_FONT_TIME_BACKGROUND));
+ mTimeDisplayBackground.setTypeface(sBackgroundFont);
mTimeDisplayForeground = (TextView) findViewById(R.id.timeDisplayForeground);
- mTimeDisplayForeground.setTypeface(Typeface.createFromFile(SYSTEM_FONT_TIME_FOREGROUND));
+ mTimeDisplayForeground.setTypeface(sForegroundFont);
mAmPm = new AmPm(this, null);
mCalendar = Calendar.getInstance();
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 97bbe52..a2fc6e2 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -17,8 +17,6 @@
package com.android.internal.widget;
-import com.android.internal.R;
-
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -34,11 +32,15 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
-import android.os.Vibrator;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+
+import com.android.internal.R;
import java.util.ArrayList;
import java.util.List;
@@ -57,9 +59,6 @@
private static final int ASPECT_LOCK_WIDTH = 1; // Fixed width; height will be minimum of (w,h)
private static final int ASPECT_LOCK_HEIGHT = 2; // Fixed height; width will be minimum of (w,h)
- // Vibrator pattern for creating a tactile bump
- private static final long[] DEFAULT_VIBE_PATTERN = {0, 1, 40, 41};
-
private static final boolean PROFILE_DRAWING = false;
private boolean mDrawingProfilingStarted = false;
@@ -100,7 +99,7 @@
private DisplayMode mPatternDisplayMode = DisplayMode.Correct;
private boolean mInputEnabled = true;
private boolean mInStealthMode = false;
- private boolean mTactileFeedbackEnabled = true;
+ private boolean mEnableHapticFeedback = true;
private boolean mPatternInProgress = false;
private float mDiameterFactor = 0.10f; // TODO: move to attrs
@@ -125,11 +124,6 @@
private int mBitmapWidth;
private int mBitmapHeight;
-
- private Vibrator vibe; // Vibrator for creating tactile feedback
-
- private long[] mVibePattern;
-
private int mAspect;
private final Matrix mArrowMatrix = new Matrix();
private final Matrix mCircleMatrix = new Matrix();
@@ -248,7 +242,6 @@
public LockPatternView(Context context, AttributeSet attrs) {
super(context, attrs);
- vibe = new Vibrator();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LockPatternView);
@@ -293,26 +286,6 @@
mBitmapHeight = Math.max(mBitmapHeight, bitmap.getHeight());
}
- // allow vibration pattern to be customized
- mVibePattern = loadVibratePattern(com.android.internal.R.array.config_virtualKeyVibePattern);
- }
-
- private long[] loadVibratePattern(int id) {
- int[] pattern = null;
- try {
- pattern = getResources().getIntArray(id);
- } catch (Resources.NotFoundException e) {
- Log.e(TAG, "Vibrate pattern missing, using default", e);
- }
- if (pattern == null) {
- return DEFAULT_VIBE_PATTERN;
- }
-
- long[] tmpPattern = new long[pattern.length];
- for (int i = 0; i < pattern.length; i++) {
- tmpPattern[i] = pattern[i];
- }
- return tmpPattern;
}
private Bitmap getBitmapFor(int resId) {
@@ -330,7 +303,7 @@
* @return Whether the view has tactile feedback enabled.
*/
public boolean isTactileFeedbackEnabled() {
- return mTactileFeedbackEnabled;
+ return mEnableHapticFeedback;
}
/**
@@ -350,7 +323,7 @@
* @param tactileFeedbackEnabled Whether tactile feedback is enabled
*/
public void setTactileFeedbackEnabled(boolean tactileFeedbackEnabled) {
- mTactileFeedbackEnabled = tactileFeedbackEnabled;
+ mEnableHapticFeedback = tactileFeedbackEnabled;
}
/**
@@ -401,6 +374,34 @@
invalidate();
}
+ private void notifyCellAdded() {
+ if (mOnPatternListener != null) {
+ mOnPatternListener.onPatternCellAdded(mPattern);
+ }
+ sendAccessEvent(R.string.lockscreen_access_pattern_cell_added);
+ }
+
+ private void notifyPatternStarted() {
+ if (mOnPatternListener != null) {
+ mOnPatternListener.onPatternStart();
+ }
+ sendAccessEvent(R.string.lockscreen_access_pattern_start);
+ }
+
+ private void notifyPatternDetected() {
+ if (mOnPatternListener != null) {
+ mOnPatternListener.onPatternDetected(mPattern);
+ }
+ sendAccessEvent(R.string.lockscreen_access_pattern_detected);
+ }
+
+ private void notifyPatternCleared() {
+ if (mOnPatternListener != null) {
+ mOnPatternListener.onPatternCleared();
+ }
+ sendAccessEvent(R.string.lockscreen_access_pattern_cleared);
+ }
+
/**
* Clear the pattern.
*/
@@ -543,8 +544,10 @@
addCellToPattern(fillInGapCell);
}
addCellToPattern(cell);
- if (mTactileFeedbackEnabled){
- vibe.vibrate(mVibePattern, -1); // Generate tactile feedback
+ if (mEnableHapticFeedback) {
+ performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
+ HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
+ | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
}
return cell;
}
@@ -554,9 +557,7 @@
private void addCellToPattern(Cell newCell) {
mPatternDrawLookup[newCell.getRow()][newCell.getColumn()] = true;
mPattern.add(newCell);
- if (mOnPatternListener != null) {
- mOnPatternListener.onPatternCellAdded(mPattern);
- }
+ notifyCellAdded();
}
// helper method to find which cell a point maps to
@@ -619,6 +620,27 @@
}
@Override
+ public boolean onHoverEvent(MotionEvent event) {
+ if (AccessibilityManager.getInstance(mContext).isTouchExplorationEnabled()) {
+ final int action = event.getAction();
+ switch (action) {
+ case MotionEvent.ACTION_HOVER_ENTER:
+ event.setAction(MotionEvent.ACTION_DOWN);
+ break;
+ case MotionEvent.ACTION_HOVER_MOVE:
+ event.setAction(MotionEvent.ACTION_MOVE);
+ break;
+ case MotionEvent.ACTION_HOVER_EXIT:
+ event.setAction(MotionEvent.ACTION_UP);
+ break;
+ }
+ onTouchEvent(event);
+ event.setAction(action);
+ }
+ return super.onHoverEvent(event);
+ }
+
+ @Override
public boolean onTouchEvent(MotionEvent event) {
if (!mInputEnabled || !isEnabled()) {
return false;
@@ -636,10 +658,8 @@
return true;
case MotionEvent.ACTION_CANCEL:
resetPattern();
- if (mOnPatternListener != null) {
- mPatternInProgress = false;
- mOnPatternListener.onPatternCleared();
- }
+ mPatternInProgress = false;
+ notifyPatternCleared();
if (PROFILE_DRAWING) {
if (mDrawingProfilingStarted) {
Debug.stopMethodTracing();
@@ -661,9 +681,9 @@
final int patternSizePreHitDetect = mPattern.size();
Cell hitCell = detectAndAddHit(x, y);
final int patternSize = mPattern.size();
- if (hitCell != null && (mOnPatternListener != null) && (patternSize == 1)) {
+ if (hitCell != null && patternSize == 1) {
mPatternInProgress = true;
- mOnPatternListener.onPatternStart();
+ notifyPatternStarted();
}
// note current x and y for rubber banding of in progress patterns
final float dx = Math.abs(x - mInProgressX);
@@ -778,11 +798,17 @@
}
}
+ private void sendAccessEvent(int resId) {
+ setContentDescription(mContext.getString(resId));
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+ setContentDescription(null);
+ }
+
private void handleActionUp(MotionEvent event) {
// report pattern detected
- if (!mPattern.isEmpty() && mOnPatternListener != null) {
+ if (!mPattern.isEmpty()) {
mPatternInProgress = false;
- mOnPatternListener.onPatternDetected(mPattern);
+ notifyPatternDetected();
invalidate();
}
if (PROFILE_DRAWING) {
@@ -798,13 +824,13 @@
final float x = event.getX();
final float y = event.getY();
final Cell hitCell = detectAndAddHit(x, y);
- if (hitCell != null && mOnPatternListener != null) {
+ if (hitCell != null) {
mPatternInProgress = true;
mPatternDisplayMode = DisplayMode.Correct;
- mOnPatternListener.onPatternStart();
- } else if (mOnPatternListener != null) {
+ notifyPatternStarted();
+ } else {
mPatternInProgress = false;
- mOnPatternListener.onPatternCleared();
+ notifyPatternCleared();
}
if (hitCell != null) {
final float startX = getCenterXForColumn(hitCell.column);
@@ -1061,7 +1087,7 @@
return new SavedState(superState,
LockPatternUtils.patternToString(mPattern),
mPatternDisplayMode.ordinal(),
- mInputEnabled, mInStealthMode, mTactileFeedbackEnabled);
+ mInputEnabled, mInStealthMode, mEnableHapticFeedback);
}
@Override
@@ -1074,7 +1100,7 @@
mPatternDisplayMode = DisplayMode.values()[ss.getDisplayMode()];
mInputEnabled = ss.isInputEnabled();
mInStealthMode = ss.isInStealthMode();
- mTactileFeedbackEnabled = ss.isTactileFeedbackEnabled();
+ mEnableHapticFeedback = ss.isTactileFeedbackEnabled();
}
/**
diff --git a/core/java/com/android/internal/widget/LockScreenWidgetCallback.java b/core/java/com/android/internal/widget/LockScreenWidgetCallback.java
index d6403e9f..d7ad6c0 100644
--- a/core/java/com/android/internal/widget/LockScreenWidgetCallback.java
+++ b/core/java/com/android/internal/widget/LockScreenWidgetCallback.java
@@ -29,6 +29,9 @@
// Sends a message to lock screen requesting the view to be hidden.
public void requestHide(View self);
+ // Whether or not this view is currently visible on LockScreen
+ public boolean isVisible(View self);
+
// Sends a message to lock screen that user has interacted with widget. This should be used
// exclusively in response to user activity, i.e. user hits a button in the view.
public void userActivity(View self);
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
index 01df48a..2e7810f 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
@@ -26,6 +26,7 @@
import android.os.Vibrator;
import android.provider.Settings;
import android.util.Log;
+import android.view.HapticFeedbackConstants;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
@@ -52,7 +53,7 @@
private final View mTargetView;
private final KeyboardView mKeyboardView;
private long[] mVibratePattern;
- private final Vibrator mVibrator;
+ private boolean mEnableHaptics = false;
public PasswordEntryKeyboardHelper(Context context, KeyboardView keyboardView, View targetView) {
this(context, keyboardView, targetView, true);
@@ -71,7 +72,10 @@
mKeyboardView.getLayoutParams().height);
}
mKeyboardView.setOnKeyboardActionListener(this);
- mVibrator = new Vibrator();
+ }
+
+ public void setEnableHaptics(boolean enabled) {
+ mEnableHaptics = enabled;
}
public boolean isAlpha() {
@@ -230,6 +234,7 @@
public void handleBackspace() {
sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
+ performHapticFeedback();
}
private void handleShift() {
@@ -272,8 +277,14 @@
}
public void onPress(int primaryCode) {
- if (mVibratePattern != null) {
- mVibrator.vibrate(mVibratePattern, -1);
+ performHapticFeedback();
+ }
+
+ private void performHapticFeedback() {
+ if (mEnableHaptics) {
+ mKeyboardView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
+ HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
+ | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
}
}
diff --git a/core/java/com/android/internal/widget/TransportControlView.java b/core/java/com/android/internal/widget/TransportControlView.java
index 1042a59..63a3aa5 100644
--- a/core/java/com/android/internal/widget/TransportControlView.java
+++ b/core/java/com/android/internal/widget/TransportControlView.java
@@ -34,6 +34,8 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.os.RemoteException;
import android.os.SystemClock;
import android.text.Spannable;
@@ -61,7 +63,7 @@
private static final int MSG_SET_GENERATION_ID = 104;
private static final int MAXDIM = 512;
private static final int DISPLAY_TIMEOUT_MS = 5000; // 5s
- protected static final boolean DEBUG = true;
+ protected static final boolean DEBUG = false;
protected static final String TAG = "TransportControlView";
private ImageView mAlbumArt;
@@ -74,7 +76,7 @@
private boolean mAttached;
private PendingIntent mClientIntent;
private int mTransportControlFlags;
- private int mPlayState;
+ private int mCurrentPlayState;
private AudioManager mAudioManager;
private LockScreenWidgetCallback mWidgetCallbacks;
private IRemoteControlDisplayWeak mIRCD;
@@ -84,6 +86,11 @@
*/
private Bundle mPopulateMetadataWhenAttached = null;
+ /**
+ * Whether to clear the interface next time it is shown (i.e. the generation id changed)
+ */
+ private boolean mClearOnNextShow;
+
// This handler is required to ensure messages from IRCD are handled in sequence and on
// the UI thread.
private Handler mHandler = new Handler() {
@@ -113,15 +120,10 @@
break;
case MSG_SET_GENERATION_ID:
- if (mWidgetCallbacks != null) {
- boolean clearing = msg.arg2 != 0;
- if (DEBUG) Log.v(TAG, "New genId = " + msg.arg1 + ", clearing = " + clearing);
- if (!clearing) {
- mWidgetCallbacks.requestShow(TransportControlView.this);
- } else {
- mWidgetCallbacks.requestHide(TransportControlView.this);
- }
+ if (msg.arg2 != 0) {
+ mClearOnNextShow = true; // TODO: handle this
}
+ if (DEBUG) Log.v(TAG, "New genId = " + msg.arg1 + ", clearing = " + msg.arg2);
mClientGeneration = msg.arg1;
mClientIntent = (PendingIntent) msg.obj;
break;
@@ -195,6 +197,7 @@
super(context, attrs);
Log.v(TAG, "Create TCV " + this);
mAudioManager = new AudioManager(mContext);
+ mCurrentPlayState = RemoteControlClient.PLAYSTATE_NONE; // until we get a callback
mIRCD = new IRemoteControlDisplayWeak(mHandler);
}
@@ -319,7 +322,7 @@
| RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE
| RemoteControlClient.FLAG_KEY_MEDIA_STOP);
- updatePlayPauseState(mPlayState);
+ updatePlayPauseState(mCurrentPlayState);
}
private static void setVisibilityBasedOnFlag(View view, int flags, int flag) {
@@ -332,25 +335,99 @@
private void updatePlayPauseState(int state) {
if (DEBUG) Log.v(TAG,
- "updatePlayPauseState(), old=" + mPlayState + ", state=" + state);
- if (state == mPlayState) {
+ "updatePlayPauseState(), old=" + mCurrentPlayState + ", state=" + state);
+ if (state == mCurrentPlayState) {
return;
}
+ final int imageResId;
+ final int imageDescId;
+ boolean showIfHidden = false;
switch (state) {
+ case RemoteControlClient.PLAYSTATE_ERROR:
+ imageResId = com.android.internal.R.drawable.stat_sys_warning;
+ // TODO use more specific image description string for warning, but here the "play"
+ // message is still valid because this button triggers a play command.
+ imageDescId = com.android.internal.R.string.lockscreen_transport_play_description;
+ break;
+
case RemoteControlClient.PLAYSTATE_PLAYING:
- mBtnPlay.setImageResource(com.android.internal.R.drawable.ic_media_pause);
+ imageResId = com.android.internal.R.drawable.ic_media_pause;
+ imageDescId = com.android.internal.R.string.lockscreen_transport_pause_description;
+ showIfHidden = true;
break;
case RemoteControlClient.PLAYSTATE_BUFFERING:
- mBtnPlay.setImageResource(com.android.internal.R.drawable.ic_media_stop);
+ imageResId = com.android.internal.R.drawable.ic_media_stop;
+ imageDescId = com.android.internal.R.string.lockscreen_transport_stop_description;
+ showIfHidden = true;
break;
case RemoteControlClient.PLAYSTATE_PAUSED:
default:
- mBtnPlay.setImageResource(com.android.internal.R.drawable.ic_media_play);
+ imageResId = com.android.internal.R.drawable.ic_media_play;
+ imageDescId = com.android.internal.R.string.lockscreen_transport_play_description;
+ showIfHidden = false;
break;
}
- mPlayState = state;
+ mBtnPlay.setImageResource(imageResId);
+ mBtnPlay.setContentDescription(getResources().getString(imageDescId));
+ if (showIfHidden && mWidgetCallbacks != null && !mWidgetCallbacks.isVisible(this)) {
+ mWidgetCallbacks.requestShow(this);
+ }
+ mCurrentPlayState = state;
+ }
+
+ static class SavedState extends BaseSavedState {
+ boolean wasShowing;
+
+ SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ private SavedState(Parcel in) {
+ super(in);
+ this.wasShowing = in.readInt() != 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ super.writeToParcel(out, flags);
+ out.writeInt(this.wasShowing ? 1 : 0);
+ }
+
+ public static final Parcelable.Creator<SavedState> CREATOR
+ = new Parcelable.Creator<SavedState>() {
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
+
+ @Override
+ public Parcelable onSaveInstanceState() {
+ if (DEBUG) Log.v(TAG, "onSaveInstanceState()");
+ Parcelable superState = super.onSaveInstanceState();
+ SavedState ss = new SavedState(superState);
+ ss.wasShowing = mWidgetCallbacks.isVisible(this);
+ return ss;
+ }
+
+ @Override
+ public void onRestoreInstanceState(Parcelable state) {
+ if (DEBUG) Log.v(TAG, "onRestoreInstanceState()");
+ if (!(state instanceof SavedState)) {
+ super.onRestoreInstanceState(state);
+ return;
+ }
+ SavedState ss = (SavedState) state;
+ super.onRestoreInstanceState(ss.getSuperState());
+ if (ss.wasShowing) {
+ mWidgetCallbacks.requestShow(this);
+ }
}
public void onClick(View v) {
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index da055fc..d1d3b78 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -579,6 +579,7 @@
android::AutoBufferPointer abp(env, jbuffer, JNI_FALSE);
// the java side has already checked that buffer is large enough
memcpy(dst, abp.pointer(), bitmap->getSize());
+ bitmap->notifyPixelsChanged();
}
}
diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp
index fe1aca0..4a9fcf2 100644
--- a/core/jni/android_database_CursorWindow.cpp
+++ b/core/jni/android_database_CursorWindow.cpp
@@ -57,14 +57,22 @@
jniThrowException(env, "java/lang/IllegalStateException", msg.string());
}
-static jint nativeInitializeEmpty(JNIEnv* env, jclass clazz,
- jint cursorWindowSize, jboolean localOnly) {
- CursorWindow* window = new CursorWindow(cursorWindowSize);
- if (!window) {
- return 0;
+static jint nativeCreate(JNIEnv* env, jclass clazz, jstring nameObj, jint cursorWindowSize) {
+ String8 name;
+ if (nameObj) {
+ const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
+ name.setTo(nameStr);
+ env->ReleaseStringUTFChars(nameObj, nameStr);
}
- if (!window->initBuffer(localOnly)) {
- delete window;
+ if (name.size() == 0) {
+ name.setTo("<unnamed>");
+ }
+
+ CursorWindow* window;
+ status_t status = CursorWindow::create(name, cursorWindowSize, &window);
+ if (status || !window) {
+ LOGE("Could not allocate CursorWindow '%s' of size %d due to error %d.",
+ name.string(), cursorWindowSize, status);
return 0;
}
@@ -72,19 +80,13 @@
return reinterpret_cast<jint>(window);
}
-static jint nativeInitializeFromBinder(JNIEnv* env, jclass clazz, jobject binderObj) {
- sp<IMemory> memory = interface_cast<IMemory>(ibinderForJavaObject(env, binderObj));
- if (memory == NULL) {
- jniThrowException(env, "java/lang/IllegalStateException", "Couldn't get native binder");
- return 0;
- }
+static jint nativeCreateFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) {
+ Parcel* parcel = parcelForJavaObject(env, parcelObj);
- CursorWindow* window = new CursorWindow();
- if (!window) {
- return 0;
- }
- if (!window->setMemory(memory)) {
- delete window;
+ CursorWindow* window;
+ status_t status = CursorWindow::createFromParcel(parcel, &window);
+ if (status || !window) {
+ LOGE("Could not create CursorWindow from Parcel due to error %d.", status);
return 0;
}
@@ -101,22 +103,26 @@
}
}
-static jobject nativeGetBinder(JNIEnv * env, jclass clazz, jint windowPtr) {
+static void nativeWriteToParcel(JNIEnv * env, jclass clazz, jint windowPtr,
+ jobject parcelObj) {
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
- if (window) {
- sp<IMemory> memory = window->getMemory();
- if (memory != NULL) {
- sp<IBinder> binder = memory->asBinder();
- return javaObjectForIBinder(env, binder);
- }
+ Parcel* parcel = parcelForJavaObject(env, parcelObj);
+
+ status_t status = window->writeToParcel(parcel);
+ if (status) {
+ String8 msg;
+ msg.appendFormat("Could not write CursorWindow to Parcel due to error %d.", status);
+ jniThrowRuntimeException(env, msg.string());
}
- return NULL;
}
static void nativeClear(JNIEnv * env, jclass clazz, jint windowPtr) {
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
LOG_WINDOW("Clearing window %p", window);
- window->clear();
+ status_t status = window->clear();
+ if (status) {
+ LOG_WINDOW("Could not clear window. error=%d", status);
+ }
}
static jint nativeGetNumRows(JNIEnv* env, jclass clazz, jint windowPtr) {
@@ -127,12 +133,14 @@
static jboolean nativeSetNumColumns(JNIEnv* env, jclass clazz, jint windowPtr,
jint columnNum) {
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
- return window->setNumColumns(columnNum);
+ status_t status = window->setNumColumns(columnNum);
+ return status == OK;
}
static jboolean nativeAllocRow(JNIEnv* env, jclass clazz, jint windowPtr) {
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
- return window->allocRow() != NULL;
+ status_t status = window->allocRow();
+ return status == OK;
}
static void nativeFreeLastRow(JNIEnv* env, jclass clazz, jint windowPtr) {
@@ -145,14 +153,14 @@
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
LOG_WINDOW("returning column type affinity for %d,%d from %p", row, column, window);
- field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column);
+ CursorWindow::FieldSlot* fieldSlot = window->getFieldSlot(row, column);
if (!fieldSlot) {
// FIXME: This is really broken but we have CTS tests that depend
// on this legacy behavior.
//throwExceptionWithRowCol(env, row, column);
- return FIELD_TYPE_NULL;
+ return CursorWindow::FIELD_TYPE_NULL;
}
- return fieldSlot->type;
+ return window->getFieldSlotType(fieldSlot);
}
static jbyteArray nativeGetBlob(JNIEnv* env, jclass clazz, jint windowPtr,
@@ -160,29 +168,29 @@
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
LOG_WINDOW("Getting blob for %d,%d from %p", row, column, window);
- field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column);
+ CursorWindow::FieldSlot* fieldSlot = window->getFieldSlot(row, column);
if (!fieldSlot) {
throwExceptionWithRowCol(env, row, column);
return NULL;
}
- uint8_t type = fieldSlot->type;
- if (type == FIELD_TYPE_BLOB || type == FIELD_TYPE_STRING) {
- uint32_t size = fieldSlot->data.buffer.size;
+ int32_t type = window->getFieldSlotType(fieldSlot);
+ if (type == CursorWindow::FIELD_TYPE_BLOB || type == CursorWindow::FIELD_TYPE_STRING) {
+ size_t size;
+ const void* value = window->getFieldSlotValueBlob(fieldSlot, &size);
jbyteArray byteArray = env->NewByteArray(size);
if (!byteArray) {
env->ExceptionClear();
throw_sqlite3_exception(env, "Native could not create new byte[]");
return NULL;
}
- env->SetByteArrayRegion(byteArray, 0, size,
- reinterpret_cast<jbyte*>(window->offsetToPtr(fieldSlot->data.buffer.offset)));
+ env->SetByteArrayRegion(byteArray, 0, size, static_cast<const jbyte*>(value));
return byteArray;
- } else if (type == FIELD_TYPE_INTEGER) {
+ } else if (type == CursorWindow::FIELD_TYPE_INTEGER) {
throw_sqlite3_exception(env, "INTEGER data in nativeGetBlob ");
- } else if (type == FIELD_TYPE_FLOAT) {
+ } else if (type == CursorWindow::FIELD_TYPE_FLOAT) {
throw_sqlite3_exception(env, "FLOAT data in nativeGetBlob ");
- } else if (type == FIELD_TYPE_NULL) {
+ } else if (type == CursorWindow::FIELD_TYPE_NULL) {
// do nothing
} else {
throwUnknownTypeException(env, type);
@@ -195,43 +203,37 @@
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
LOG_WINDOW("Getting string for %d,%d from %p", row, column, window);
- field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column);
+ CursorWindow::FieldSlot* fieldSlot = window->getFieldSlot(row, column);
if (!fieldSlot) {
throwExceptionWithRowCol(env, row, column);
return NULL;
}
- uint8_t type = fieldSlot->type;
- if (type == FIELD_TYPE_STRING) {
- uint32_t size = fieldSlot->data.buffer.size;
-#if WINDOW_STORAGE_UTF8
- if (size <= 1) {
+ int32_t type = window->getFieldSlotType(fieldSlot);
+ if (type == CursorWindow::FIELD_TYPE_STRING) {
+ size_t sizeIncludingNull;
+ const char* value = window->getFieldSlotValueString(fieldSlot, &sizeIncludingNull);
+ if (sizeIncludingNull <= 1) {
return gEmptyString;
}
// Convert to UTF-16 here instead of calling NewStringUTF. NewStringUTF
// doesn't like UTF-8 strings with high codepoints. It actually expects
// Modified UTF-8 with encoded surrogate pairs.
- String16 utf16(window->getFieldSlotValueString(fieldSlot), size - 1);
+ String16 utf16(value, sizeIncludingNull - 1);
return env->NewString(reinterpret_cast<const jchar*>(utf16.string()), utf16.size());
-#else
- size_t chars = size / sizeof(char16_t);
- return chars ? env->NewString(reinterpret_cast<jchar*>(
- window->getFieldSlotValueString(fieldSlot)), chars)
- : gEmptyString;
-#endif
- } else if (type == FIELD_TYPE_INTEGER) {
+ } else if (type == CursorWindow::FIELD_TYPE_INTEGER) {
int64_t value = window->getFieldSlotValueLong(fieldSlot);
char buf[32];
snprintf(buf, sizeof(buf), "%lld", value);
return env->NewStringUTF(buf);
- } else if (type == FIELD_TYPE_FLOAT) {
+ } else if (type == CursorWindow::FIELD_TYPE_FLOAT) {
double value = window->getFieldSlotValueDouble(fieldSlot);
char buf[32];
snprintf(buf, sizeof(buf), "%g", value);
return env->NewStringUTF(buf);
- } else if (type == FIELD_TYPE_NULL) {
+ } else if (type == CursorWindow::FIELD_TYPE_NULL) {
return NULL;
- } else if (type == FIELD_TYPE_BLOB) {
+ } else if (type == CursorWindow::FIELD_TYPE_BLOB) {
throw_sqlite3_exception(env, "Unable to convert BLOB to string");
return NULL;
} else {
@@ -281,21 +283,6 @@
}
}
-#if !WINDOW_STORAGE_UTF8
-static void fillCharArrayBuffer(JNIEnv* env, jobject bufferObj,
- const char16_t* str, size_t len) {
- jcharArray dataObj = allocCharArrayBuffer(env, bufferObj, len);
- if (dataObj) {
- if (len) {
- jchar* data = static_cast<jchar*>(env->GetPrimitiveArrayCritical(dataObj, NULL));
- memcpy(data, str, len * sizeof(jchar));
- env->ReleasePrimitiveArrayCritical(dataObj, data, 0);
- }
- env->SetIntField(bufferObj, gCharArrayBufferClassInfo.sizeCopied, len);
- }
-}
-#endif
-
static void clearCharArrayBuffer(JNIEnv* env, jobject bufferObj) {
jcharArray dataObj = allocCharArrayBuffer(env, bufferObj, 0);
if (dataObj) {
@@ -308,44 +295,34 @@
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
LOG_WINDOW("Copying string for %d,%d from %p", row, column, window);
- field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column);
+ CursorWindow::FieldSlot* fieldSlot = window->getFieldSlot(row, column);
if (!fieldSlot) {
throwExceptionWithRowCol(env, row, column);
return;
}
- uint8_t type = fieldSlot->type;
- if (type == FIELD_TYPE_STRING) {
- uint32_t size = fieldSlot->data.buffer.size;
-#if WINDOW_STORAGE_UTF8
- if (size > 1) {
- fillCharArrayBufferUTF(env, bufferObj,
- window->getFieldSlotValueString(fieldSlot), size - 1);
+ int32_t type = window->getFieldSlotType(fieldSlot);
+ if (type == CursorWindow::FIELD_TYPE_STRING) {
+ size_t sizeIncludingNull;
+ const char* value = window->getFieldSlotValueString(fieldSlot, &sizeIncludingNull);
+ if (sizeIncludingNull > 1) {
+ fillCharArrayBufferUTF(env, bufferObj, value, sizeIncludingNull - 1);
} else {
clearCharArrayBuffer(env, bufferObj);
}
-#else
- size_t chars = size / sizeof(char16_t);
- if (chars) {
- fillCharArrayBuffer(env, bufferObj,
- window->getFieldSlotValueString(fieldSlot), chars);
- } else {
- clearCharArrayBuffer(env, bufferObj);
- }
-#endif
- } else if (type == FIELD_TYPE_INTEGER) {
+ } else if (type == CursorWindow::FIELD_TYPE_INTEGER) {
int64_t value = window->getFieldSlotValueLong(fieldSlot);
char buf[32];
snprintf(buf, sizeof(buf), "%lld", value);
fillCharArrayBufferUTF(env, bufferObj, buf, strlen(buf));
- } else if (type == FIELD_TYPE_FLOAT) {
+ } else if (type == CursorWindow::FIELD_TYPE_FLOAT) {
double value = window->getFieldSlotValueDouble(fieldSlot);
char buf[32];
snprintf(buf, sizeof(buf), "%g", value);
fillCharArrayBufferUTF(env, bufferObj, buf, strlen(buf));
- } else if (type == FIELD_TYPE_NULL) {
+ } else if (type == CursorWindow::FIELD_TYPE_NULL) {
clearCharArrayBuffer(env, bufferObj);
- } else if (type == FIELD_TYPE_BLOB) {
+ } else if (type == CursorWindow::FIELD_TYPE_BLOB) {
throw_sqlite3_exception(env, "Unable to convert BLOB to string");
} else {
throwUnknownTypeException(env, type);
@@ -357,29 +334,24 @@
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
LOG_WINDOW("Getting long for %d,%d from %p", row, column, window);
- field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column);
+ CursorWindow::FieldSlot* fieldSlot = window->getFieldSlot(row, column);
if (!fieldSlot) {
throwExceptionWithRowCol(env, row, column);
return 0;
}
- uint8_t type = fieldSlot->type;
- if (type == FIELD_TYPE_INTEGER) {
+ int32_t type = window->getFieldSlotType(fieldSlot);
+ if (type == CursorWindow::FIELD_TYPE_INTEGER) {
return window->getFieldSlotValueLong(fieldSlot);
- } else if (type == FIELD_TYPE_STRING) {
- uint32_t size = fieldSlot->data.buffer.size;
-#if WINDOW_STORAGE_UTF8
- return size > 1 ? strtoll(window->getFieldSlotValueString(fieldSlot), NULL, 0) : 0L;
-#else
- size_t chars = size / sizeof(char16_t);
- return chars ? strtoll(String8(window->getFieldSlotValueString(fieldSlot), chars)
- .string(), NULL, 0) : 0L;
-#endif
- } else if (type == FIELD_TYPE_FLOAT) {
+ } else if (type == CursorWindow::FIELD_TYPE_STRING) {
+ size_t sizeIncludingNull;
+ const char* value = window->getFieldSlotValueString(fieldSlot, &sizeIncludingNull);
+ return sizeIncludingNull > 1 ? strtoll(value, NULL, 0) : 0L;
+ } else if (type == CursorWindow::FIELD_TYPE_FLOAT) {
return jlong(window->getFieldSlotValueDouble(fieldSlot));
- } else if (type == FIELD_TYPE_NULL) {
+ } else if (type == CursorWindow::FIELD_TYPE_NULL) {
return 0;
- } else if (type == FIELD_TYPE_BLOB) {
+ } else if (type == CursorWindow::FIELD_TYPE_BLOB) {
throw_sqlite3_exception(env, "Unable to convert BLOB to long");
return 0;
} else {
@@ -393,29 +365,24 @@
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
LOG_WINDOW("Getting double for %d,%d from %p", row, column, window);
- field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column);
+ CursorWindow::FieldSlot* fieldSlot = window->getFieldSlot(row, column);
if (!fieldSlot) {
throwExceptionWithRowCol(env, row, column);
return 0.0;
}
- uint8_t type = fieldSlot->type;
- if (type == FIELD_TYPE_FLOAT) {
+ int32_t type = window->getFieldSlotType(fieldSlot);
+ if (type == CursorWindow::FIELD_TYPE_FLOAT) {
return window->getFieldSlotValueDouble(fieldSlot);
- } else if (type == FIELD_TYPE_STRING) {
- uint32_t size = fieldSlot->data.buffer.size;
-#if WINDOW_STORAGE_UTF8
- return size > 1 ? strtod(window->getFieldSlotValueString(fieldSlot), NULL) : 0.0;
-#else
- size_t chars = size / sizeof(char16_t);
- return chars ? strtod(String8(window->getFieldSlotValueString(fieldSlot), chars)
- .string(), NULL) : 0.0;
-#endif
- } else if (type == FIELD_TYPE_INTEGER) {
+ } else if (type == CursorWindow::FIELD_TYPE_STRING) {
+ size_t sizeIncludingNull;
+ const char* value = window->getFieldSlotValueString(fieldSlot, &sizeIncludingNull);
+ return sizeIncludingNull > 1 ? strtod(value, NULL) : 0.0;
+ } else if (type == CursorWindow::FIELD_TYPE_INTEGER) {
return jdouble(window->getFieldSlotValueLong(fieldSlot));
- } else if (type == FIELD_TYPE_NULL) {
+ } else if (type == CursorWindow::FIELD_TYPE_NULL) {
return 0.0;
- } else if (type == FIELD_TYPE_BLOB) {
+ } else if (type == CursorWindow::FIELD_TYPE_BLOB) {
throw_sqlite3_exception(env, "Unable to convert BLOB to double");
return 0.0;
} else {
@@ -427,82 +394,50 @@
static jboolean nativePutBlob(JNIEnv* env, jclass clazz, jint windowPtr,
jbyteArray valueObj, jint row, jint column) {
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
- field_slot_t * fieldSlot = window->getFieldSlotWithCheck(row, column);
- if (fieldSlot == NULL) {
- LOG_WINDOW(" getFieldSlotWithCheck error ");
- return false;
- }
-
jsize len = env->GetArrayLength(valueObj);
- uint32_t offset = window->alloc(len);
- if (!offset) {
- LOG_WINDOW("Failed allocating %u bytes", len);
- return false;
- }
void* value = env->GetPrimitiveArrayCritical(valueObj, NULL);
- window->copyIn(offset, static_cast<const uint8_t*>(value), len);
+ status_t status = window->putBlob(row, column, value, len);
env->ReleasePrimitiveArrayCritical(valueObj, value, JNI_ABORT);
- fieldSlot->type = FIELD_TYPE_BLOB;
- fieldSlot->data.buffer.offset = offset;
- fieldSlot->data.buffer.size = len;
- LOG_WINDOW("%d,%d is BLOB with %u bytes @ %d", row, column, len, offset);
+ if (status) {
+ LOG_WINDOW("Failed to put blob. error=%d", status);
+ return false;
+ }
+
+ LOG_WINDOW("%d,%d is BLOB with %u bytes", row, column, len);
return true;
}
static jboolean nativePutString(JNIEnv* env, jclass clazz, jint windowPtr,
jstring valueObj, jint row, jint column) {
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
- field_slot_t * fieldSlot = window->getFieldSlotWithCheck(row, column);
- if (fieldSlot == NULL) {
- LOG_WINDOW(" getFieldSlotWithCheck error ");
- return false;
- }
-#if WINDOW_STORAGE_UTF8
- size_t size = env->GetStringUTFLength(valueObj) + 1;
+ size_t sizeIncludingNull = env->GetStringUTFLength(valueObj) + 1;
const char* valueStr = env->GetStringUTFChars(valueObj, NULL);
-#else
- size_t size = env->GetStringLength(valueObj) * sizeof(jchar);
- const jchar* valueStr = env->GetStringChars(valueObj, NULL);
-#endif
if (!valueStr) {
- LOG_WINDOW("value can't be transfer to UTFChars");
+ LOG_WINDOW("value can't be transferred to UTFChars");
return false;
}
-
- uint32_t offset = window->alloc(size);
- if (!offset) {
- LOG_WINDOW("Failed allocating %u bytes", size);
-#if WINDOW_STORAGE_UTF8
- env->ReleaseStringUTFChars(valueObj, valueStr);
-#else
- env->ReleaseStringChars(valueObj, valueStr);
-#endif
- return false;
- }
-
- window->copyIn(offset, reinterpret_cast<const uint8_t*>(valueStr), size);
-
-#if WINDOW_STORAGE_UTF8
+ status_t status = window->putString(row, column, valueStr, sizeIncludingNull);
env->ReleaseStringUTFChars(valueObj, valueStr);
-#else
- env->ReleaseStringChars(valueObj, valueStr);
-#endif
- fieldSlot->type = FIELD_TYPE_STRING;
- fieldSlot->data.buffer.offset = offset;
- fieldSlot->data.buffer.size = size;
- LOG_WINDOW("%d,%d is TEXT with %u bytes @ %d", row, column, size, offset);
+ if (status) {
+ LOG_WINDOW("Failed to put string. error=%d", status);
+ return false;
+ }
+
+ LOG_WINDOW("%d,%d is TEXT with %u bytes", row, column, sizeIncludingNull);
return true;
}
static jboolean nativePutLong(JNIEnv* env, jclass clazz, jint windowPtr,
jlong value, jint row, jint column) {
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
- if (!window->putLong(row, column, value)) {
- LOG_WINDOW(" getFieldSlotWithCheck error ");
+ status_t status = window->putLong(row, column, value);
+
+ if (status) {
+ LOG_WINDOW("Failed to put long. error=%d", status);
return false;
}
@@ -513,8 +448,10 @@
static jboolean nativePutDouble(JNIEnv* env, jclass clazz, jint windowPtr,
jdouble value, jint row, jint column) {
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
- if (!window->putDouble(row, column, value)) {
- LOG_WINDOW(" getFieldSlotWithCheck error ");
+ status_t status = window->putDouble(row, column, value);
+
+ if (status) {
+ LOG_WINDOW("Failed to put double. error=%d", status);
return false;
}
@@ -525,8 +462,10 @@
static jboolean nativePutNull(JNIEnv* env, jclass clazz, jint windowPtr,
jint row, jint column) {
CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
- if (!window->putNull(row, column)) {
- LOG_WINDOW(" getFieldSlotWithCheck error ");
+ status_t status = window->putNull(row, column);
+
+ if (status) {
+ LOG_WINDOW("Failed to put null. error=%d", status);
return false;
}
@@ -537,14 +476,14 @@
static JNINativeMethod sMethods[] =
{
/* name, signature, funcPtr */
- { "nativeInitializeEmpty", "(IZ)I",
- (void*)nativeInitializeEmpty },
- { "nativeInitializeFromBinder", "(Landroid/os/IBinder;)I",
- (void*)nativeInitializeFromBinder },
+ { "nativeCreate", "(Ljava/lang/String;I)I",
+ (void*)nativeCreate },
+ { "nativeCreateFromParcel", "(Landroid/os/Parcel;)I",
+ (void*)nativeCreateFromParcel },
{ "nativeDispose", "(I)V",
(void*)nativeDispose },
- { "nativeGetBinder", "(I)Landroid/os/IBinder;",
- (void*)nativeGetBinder },
+ { "nativeWriteToParcel", "(ILandroid/os/Parcel;)V",
+ (void*)nativeWriteToParcel },
{ "nativeClear", "(I)V",
(void*)nativeClear },
{ "nativeGetNumRows", "(I)I",
diff --git a/core/jni/android_database_SQLiteQuery.cpp b/core/jni/android_database_SQLiteQuery.cpp
index 022a64c..8170f46 100644
--- a/core/jni/android_database_SQLiteQuery.cpp
+++ b/core/jni/android_database_SQLiteQuery.cpp
@@ -61,7 +61,8 @@
window->getNumRows(), window->size(), window->freeSpace());
int numColumns = sqlite3_column_count(statement);
- if (!window->setNumColumns(numColumns)) {
+ status_t status = window->setNumColumns(numColumns);
+ if (status) {
LOGE("Failed to change column count from %d to %d", window->getNumColumns(), numColumns);
jniThrowException(env, "java/lang/IllegalStateException", "numColumns mismatch");
return 0;
@@ -88,10 +89,10 @@
// Allocate a new field directory for the row. This pointer is not reused
// since it may be possible for it to be relocated on a call to alloc() when
// the field data is being allocated.
- field_slot_t* fieldDir = window->allocRow();
- if (!fieldDir) {
- LOG_WINDOW("Failed allocating fieldDir at startPos %d row %d",
- startPos, addedRows);
+ status = window->allocRow();
+ if (status) {
+ LOG_WINDOW("Failed allocating fieldDir at startPos %d row %d, error=%d",
+ startPos, addedRows, status);
windowFull = true;
continue;
}
@@ -101,37 +102,28 @@
int type = sqlite3_column_type(statement, i);
if (type == SQLITE_TEXT) {
// TEXT data
-#if WINDOW_STORAGE_UTF8
- const uint8_t* text = reinterpret_cast<const uint8_t*>(
+ const char* text = reinterpret_cast<const char*>(
sqlite3_column_text(statement, i));
// SQLite does not include the NULL terminator in size, but does
// ensure all strings are NULL terminated, so increase size by
// one to make sure we store the terminator.
- size_t size = sqlite3_column_bytes(statement, i) + 1;
-#else
- const uint8_t* text = reinterpret_cast<const uint8_t*>(
- sqlite3_column_text16(statement, i));
- size_t size = sqlite3_column_bytes16(statement, i);
-#endif
- int offset = window->alloc(size);
- if (!offset) {
- LOG_WINDOW("Failed allocating %u bytes for text/blob at %d,%d", size,
- startPos + addedRows, i);
+ size_t sizeIncludingNull = sqlite3_column_bytes(statement, i) + 1;
+ status = window->putString(addedRows, i, text, sizeIncludingNull);
+ if (status) {
+ LOG_WINDOW("Failed allocating %u bytes for text at %d,%d, error=%d",
+ sizeIncludingNull, startPos + addedRows, i, status);
windowFull = true;
break;
}
- window->copyIn(offset, text, size);
-
- field_slot_t* fieldSlot = window->getFieldSlot(addedRows, i);
- fieldSlot->type = FIELD_TYPE_STRING;
- fieldSlot->data.buffer.offset = offset;
- fieldSlot->data.buffer.size = size;
- LOG_WINDOW("%d,%d is TEXT with %u bytes", startPos + addedRows, i, size);
+ LOG_WINDOW("%d,%d is TEXT with %u bytes",
+ startPos + addedRows, i, sizeIncludingNull);
} else if (type == SQLITE_INTEGER) {
// INTEGER data
int64_t value = sqlite3_column_int64(statement, i);
- if (!window->putLong(addedRows, i, value)) {
- LOG_WINDOW("Failed allocating space for a long in column %d", i);
+ status = window->putLong(addedRows, i, value);
+ if (status) {
+ LOG_WINDOW("Failed allocating space for a long in column %d, error=%d",
+ i, status);
windowFull = true;
break;
}
@@ -139,35 +131,33 @@
} else if (type == SQLITE_FLOAT) {
// FLOAT data
double value = sqlite3_column_double(statement, i);
- if (!window->putDouble(addedRows, i, value)) {
- LOG_WINDOW("Failed allocating space for a double in column %d", i);
+ status = window->putDouble(addedRows, i, value);
+ if (status) {
+ LOG_WINDOW("Failed allocating space for a double in column %d, error=%d",
+ i, status);
windowFull = true;
break;
}
LOG_WINDOW("%d,%d is FLOAT %lf", startPos + addedRows, i, value);
} else if (type == SQLITE_BLOB) {
// BLOB data
- uint8_t const * blob = (uint8_t const *)sqlite3_column_blob(statement, i);
- size_t size = sqlite3_column_bytes16(statement, i);
- int offset = window->alloc(size);
- if (!offset) {
- LOG_WINDOW("Failed allocating %u bytes for blob at %d,%d", size,
- startPos + addedRows, i);
+ const void* blob = sqlite3_column_blob(statement, i);
+ size_t size = sqlite3_column_bytes(statement, i);
+ status = window->putBlob(addedRows, i, blob, size);
+ if (status) {
+ LOG_WINDOW("Failed allocating %u bytes for blob at %d,%d, error=%d",
+ size, startPos + addedRows, i, status);
windowFull = true;
break;
}
- window->copyIn(offset, blob, size);
-
- field_slot_t* fieldSlot = window->getFieldSlot(addedRows, i);
- fieldSlot->type = FIELD_TYPE_BLOB;
- fieldSlot->data.buffer.offset = offset;
- fieldSlot->data.buffer.size = size;
- LOG_WINDOW("%d,%d is Blob with %u bytes @ %d",
- startPos + addedRows, i, size, offset);
+ LOG_WINDOW("%d,%d is Blob with %u bytes",
+ startPos + addedRows, i, size);
} else if (type == SQLITE_NULL) {
// NULL field
- if (!window->putNull(addedRows, i)) {
- LOG_WINDOW("Failed allocating space for a null in column %d", i);
+ status = window->putNull(addedRows, i);
+ if (status) {
+ LOG_WINDOW("Failed allocating space for a null in column %d, error=%d",
+ i, status);
windowFull = true;
break;
}
diff --git a/core/res/res/drawable-hdpi/btn_check_on_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/btn_check_on_disabled_focused_holo_dark.png
index 52a9800..bf2cf8d 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/btn_check_on_disabled_focused_holo_light.png
index 49a2aeb..00427a1 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_disabled_holo_dark.png b/core/res/res/drawable-hdpi/btn_check_on_disabled_holo_dark.png
index e6ebb43..0ee10ac 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_disabled_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_disabled_holo_light.png b/core/res/res/drawable-hdpi/btn_check_on_disabled_holo_light.png
index 7069fc5..e07be7c 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_disabled_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_focused_holo_dark.png b/core/res/res/drawable-hdpi/btn_check_on_focused_holo_dark.png
index ec2a7e3..fcea3b4 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_focused_holo_light.png b/core/res/res/drawable-hdpi/btn_check_on_focused_holo_light.png
index 486334f..4006bd4 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_holo.png b/core/res/res/drawable-hdpi/btn_check_on_holo.png
index 1f11a78..7c1bab0 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_holo.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_holo_dark.png b/core/res/res/drawable-hdpi/btn_check_on_holo_dark.png
index a17100c..c69bcf8 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_holo_light.png b/core/res/res/drawable-hdpi/btn_check_on_holo_light.png
index 130ab4f..a8cedd1 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_dark.png b/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_dark.png
index 96abcda..bc57f7a 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_light.png b/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_light.png
index 0a22f02..34209c0 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_code_lock_default_holo.png b/core/res/res/drawable-hdpi/btn_code_lock_default_holo.png
index 28b2578..e77921c 100644
--- a/core/res/res/drawable-hdpi/btn_code_lock_default_holo.png
+++ b/core/res/res/drawable-hdpi/btn_code_lock_default_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_off_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/btn_star_off_disabled_focused_holo_dark.png
index 8906c4d..61f9e6b 100644
--- a/core/res/res/drawable-hdpi/btn_star_off_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_star_off_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_off_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/btn_star_off_disabled_focused_holo_light.png
index 2bcb98e..62ac7f9 100644
--- a/core/res/res/drawable-hdpi/btn_star_off_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_star_off_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_off_disabled_holo_dark.png b/core/res/res/drawable-hdpi/btn_star_off_disabled_holo_dark.png
index 2e36821..e10d5d1 100644
--- a/core/res/res/drawable-hdpi/btn_star_off_disabled_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_star_off_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_off_disabled_holo_light.png b/core/res/res/drawable-hdpi/btn_star_off_disabled_holo_light.png
index 6a50bd8..685f8b5 100644
--- a/core/res/res/drawable-hdpi/btn_star_off_disabled_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_star_off_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_off_focused_holo_dark.png b/core/res/res/drawable-hdpi/btn_star_off_focused_holo_dark.png
index 8595dd0..d7ef1a6 100644
--- a/core/res/res/drawable-hdpi/btn_star_off_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_star_off_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_off_focused_holo_light.png b/core/res/res/drawable-hdpi/btn_star_off_focused_holo_light.png
index 1dda090..fcf4623 100644
--- a/core/res/res/drawable-hdpi/btn_star_off_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_star_off_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_off_normal_holo_dark.png b/core/res/res/drawable-hdpi/btn_star_off_normal_holo_dark.png
index 942722e..9a6fc4d 100644
--- a/core/res/res/drawable-hdpi/btn_star_off_normal_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_star_off_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_off_normal_holo_light.png b/core/res/res/drawable-hdpi/btn_star_off_normal_holo_light.png
index e46f035..3875ac3 100644
--- a/core/res/res/drawable-hdpi/btn_star_off_normal_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_star_off_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_off_pressed_holo_dark.png b/core/res/res/drawable-hdpi/btn_star_off_pressed_holo_dark.png
index 5cfe146..a929e09 100644
--- a/core/res/res/drawable-hdpi/btn_star_off_pressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_star_off_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_off_pressed_holo_light.png b/core/res/res/drawable-hdpi/btn_star_off_pressed_holo_light.png
index 20d0eb3..013ca85 100644
--- a/core/res/res/drawable-hdpi/btn_star_off_pressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_star_off_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_on_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/btn_star_on_disabled_focused_holo_dark.png
index 3b478d6..57cfa4d 100644
--- a/core/res/res/drawable-hdpi/btn_star_on_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_star_on_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_on_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/btn_star_on_disabled_focused_holo_light.png
index 52a9f44..1a37993 100644
--- a/core/res/res/drawable-hdpi/btn_star_on_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_star_on_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_on_disabled_holo_dark.png b/core/res/res/drawable-hdpi/btn_star_on_disabled_holo_dark.png
index 9810029..5694cf7 100644
--- a/core/res/res/drawable-hdpi/btn_star_on_disabled_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_star_on_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_on_disabled_holo_light.png b/core/res/res/drawable-hdpi/btn_star_on_disabled_holo_light.png
index 445af7b..6406c06 100644
--- a/core/res/res/drawable-hdpi/btn_star_on_disabled_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_star_on_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_on_focused_holo_dark.png b/core/res/res/drawable-hdpi/btn_star_on_focused_holo_dark.png
index d3884f6..c50efaf 100644
--- a/core/res/res/drawable-hdpi/btn_star_on_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_star_on_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_on_focused_holo_light.png b/core/res/res/drawable-hdpi/btn_star_on_focused_holo_light.png
index eea174a..1a899c9e 100644
--- a/core/res/res/drawable-hdpi/btn_star_on_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_star_on_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_on_normal_holo_light.png b/core/res/res/drawable-hdpi/btn_star_on_normal_holo_light.png
index 58b2b09..37547d2 100644
--- a/core/res/res/drawable-hdpi/btn_star_on_normal_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_star_on_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_on_pressed_holo_dark.png b/core/res/res/drawable-hdpi/btn_star_on_pressed_holo_dark.png
index a39a620..7b0e089 100644
--- a/core/res/res/drawable-hdpi/btn_star_on_pressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/btn_star_on_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_on_pressed_holo_light.png b/core/res/res/drawable-hdpi/btn_star_on_pressed_holo_light.png
index 1ffe7fe..692d705 100644
--- a/core/res/res/drawable-hdpi/btn_star_on_pressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/btn_star_on_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_btn_find_next.png b/core/res/res/drawable-hdpi/ic_btn_find_next.png
deleted file mode 100644
index b696a6b..0000000
--- a/core/res/res/drawable-hdpi/ic_btn_find_next.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_btn_find_prev.png b/core/res/res/drawable-hdpi/ic_btn_find_prev.png
deleted file mode 100644
index 5550c5a..0000000
--- a/core/res/res/drawable-hdpi/ic_btn_find_prev.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_bullet_key_permission.png b/core/res/res/drawable-hdpi/ic_bullet_key_permission.png
index a7eaec5..4cf50ad 100644
--- a/core/res/res/drawable-hdpi/ic_bullet_key_permission.png
+++ b/core/res/res/drawable-hdpi/ic_bullet_key_permission.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_find_next_holo_dark.png b/core/res/res/drawable-hdpi/ic_find_next_holo_dark.png
new file mode 100644
index 0000000..2fe4f81
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_find_next_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_find_previous_holo_dark.png b/core/res/res/drawable-hdpi/ic_find_previous_holo_dark.png
new file mode 100644
index 0000000..d4e9bd1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_find_previous_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_answer_active.png b/core/res/res/drawable-hdpi/ic_lockscreen_answer_active.png
index 683a575..d201bfb7 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_answer_active.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_answer_active.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_answer_focused.png b/core/res/res/drawable-hdpi/ic_lockscreen_answer_focused.png
index bdece9f..efb29f1 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_answer_focused.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_answer_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_answer_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_answer_normal.png
index 6a8ab24..176d448 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_answer_normal.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_answer_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_decline_focused.png b/core/res/res/drawable-hdpi/ic_lockscreen_decline_focused.png
index f2fceaa..f37b16a 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_decline_focused.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_decline_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_decline_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_decline_normal.png
index e005ffc..d88087b 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_decline_normal.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_decline_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png
index f41ad95..1780ec0 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_handle_pressed.png b/core/res/res/drawable-hdpi/ic_lockscreen_handle_pressed.png
index 98ab6e9..58a5f16 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_handle_pressed.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_player_background.9.png b/core/res/res/drawable-hdpi/ic_lockscreen_player_background.9.png
index b187358..fbb75b5 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_player_background.9.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_player_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_silent_focused.png b/core/res/res/drawable-hdpi/ic_lockscreen_silent_focused.png
index 651b837..f9a8c7c 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_silent_focused.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_silent_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_silent_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_silent_normal.png
index babab1d..b47cd08 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_silent_normal.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_silent_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_focused.png b/core/res/res/drawable-hdpi/ic_lockscreen_soundon_focused.png
index d000866..6e16e40 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_focused.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_soundon_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png
index 82133d0..0dd81c0 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_text_focusde.png b/core/res/res/drawable-hdpi/ic_lockscreen_text_focusde.png
index 26df6b2..5f1b881 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_text_focusde.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_text_focusde.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png
index 9e36918..374a62a 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_next.png b/core/res/res/drawable-hdpi/ic_media_next.png
index c74703e..f5ba824 100644
--- a/core/res/res/drawable-hdpi/ic_media_next.png
+++ b/core/res/res/drawable-hdpi/ic_media_next.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_previous.png b/core/res/res/drawable-hdpi/ic_media_previous.png
index 15dc390..40ecb00 100644
--- a/core/res/res/drawable-hdpi/ic_media_previous.png
+++ b/core/res/res/drawable-hdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png
index 81c52b0..3e00747 100644
--- a/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png
index 15500c3..c760936 100644
--- a/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_text_dot.png b/core/res/res/drawable-hdpi/ic_text_dot.png
index a7eaec5..fa69c69 100644
--- a/core/res/res/drawable-hdpi/ic_text_dot.png
+++ b/core/res/res/drawable-hdpi/ic_text_dot.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_default_holo.png b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_default_holo.png
index 28b2578..449d427 100644
--- a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_default_holo.png
+++ b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_default_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green_holo.png b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green_holo.png
index 545cc09..14f4ff8 100644
--- a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green_holo.png
+++ b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red_holo.png b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red_holo.png
index 9176b33..5cf9086 100644
--- a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red_holo.png
+++ b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_selector_background_disabled.9.png b/core/res/res/drawable-hdpi/list_selector_background_disabled.9.png
old mode 100755
new mode 100644
index 9e1c42a..05b1419
--- a/core/res/res/drawable-hdpi/list_selector_background_disabled.9.png
+++ b/core/res/res/drawable-hdpi/list_selector_background_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_selector_background_focus.9.png b/core/res/res/drawable-hdpi/list_selector_background_focus.9.png
old mode 100755
new mode 100644
index 5563c80..3a21d35
--- a/core/res/res/drawable-hdpi/list_selector_background_focus.9.png
+++ b/core/res/res/drawable-hdpi/list_selector_background_focus.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_selector_background_longpress.9.png b/core/res/res/drawable-hdpi/list_selector_background_longpress.9.png
old mode 100755
new mode 100644
index 72d3a08..19558e9
--- a/core/res/res/drawable-hdpi/list_selector_background_longpress.9.png
+++ b/core/res/res/drawable-hdpi/list_selector_background_longpress.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_selector_background_pressed.9.png b/core/res/res/drawable-hdpi/list_selector_background_pressed.9.png
old mode 100755
new mode 100644
index 7568b30..0f3b444
--- a/core/res/res/drawable-hdpi/list_selector_background_pressed.9.png
+++ b/core/res/res/drawable-hdpi/list_selector_background_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_dark.png
index fb34a6d..9584649 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_light.png
index 87b2ad67..5c37873 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_dark.png
index 1655fea..b5faf6f 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_light.png
index 61cfe7a..041412b 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png
index 43e2e89..9ff4cce 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png
index 7d80ff6..a556e00 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png
index cc21a1c..9353511 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png
index cc21a1c..9353511 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png
index 3c9c192..2ca591f 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png
index 6511cd2..1275a2f 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_dark.png
index 7b135ea..9c23a18 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_light.png
index 7b135ea..9c23a18 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_dark.png
index b6a85a2..159913c 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_light.png
index 50d979e..cfee4b7 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_dark.png
index 608dd52..e5f0430 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_light.png
index 96ff781..7e4ec4a 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png
index a48bf2e..df374c4 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png
index b69589b..d6b9c67 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png
index 5adfb04..69474e3 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png
index 5adfb04..69474e3 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png
index ff34463..a2fc32a 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png
index 0bcfd67..c4b58b7 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_dark.png
index 00092cc..358a13f 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_light.png
index 00092cc..358a13f 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/presence_away.png b/core/res/res/drawable-hdpi/presence_away.png
index fe5b880..455fec1 100644
--- a/core/res/res/drawable-hdpi/presence_away.png
+++ b/core/res/res/drawable-hdpi/presence_away.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_big_half_holo_dark.png b/core/res/res/drawable-hdpi/rate_star_big_half_holo_dark.png
index e3131b1..67890f0 100644
--- a/core/res/res/drawable-hdpi/rate_star_big_half_holo_dark.png
+++ b/core/res/res/drawable-hdpi/rate_star_big_half_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_big_half_holo_light.png b/core/res/res/drawable-hdpi/rate_star_big_half_holo_light.png
index cdc94a1..e9ffa5b 100644
--- a/core/res/res/drawable-hdpi/rate_star_big_half_holo_light.png
+++ b/core/res/res/drawable-hdpi/rate_star_big_half_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_big_off_holo_dark.png b/core/res/res/drawable-hdpi/rate_star_big_off_holo_dark.png
index d83522a..cc08f88 100644
--- a/core/res/res/drawable-hdpi/rate_star_big_off_holo_dark.png
+++ b/core/res/res/drawable-hdpi/rate_star_big_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_big_off_holo_light.png b/core/res/res/drawable-hdpi/rate_star_big_off_holo_light.png
index 2af7814..ebdb47b 100644
--- a/core/res/res/drawable-hdpi/rate_star_big_off_holo_light.png
+++ b/core/res/res/drawable-hdpi/rate_star_big_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_big_on_holo_dark.png b/core/res/res/drawable-hdpi/rate_star_big_on_holo_dark.png
index e4b766d..d594c46 100644
--- a/core/res/res/drawable-hdpi/rate_star_big_on_holo_dark.png
+++ b/core/res/res/drawable-hdpi/rate_star_big_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_big_on_holo_light.png b/core/res/res/drawable-hdpi/rate_star_big_on_holo_light.png
index edd264a..b4fd29b 100644
--- a/core/res/res/drawable-hdpi/rate_star_big_on_holo_light.png
+++ b/core/res/res/drawable-hdpi/rate_star_big_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_med_half_holo_light.png b/core/res/res/drawable-hdpi/rate_star_med_half_holo_light.png
index 3ff3bbd..d1756c7 100644
--- a/core/res/res/drawable-hdpi/rate_star_med_half_holo_light.png
+++ b/core/res/res/drawable-hdpi/rate_star_med_half_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_med_off_holo_light.png b/core/res/res/drawable-hdpi/rate_star_med_off_holo_light.png
index ce9fc25..4605a42 100644
--- a/core/res/res/drawable-hdpi/rate_star_med_off_holo_light.png
+++ b/core/res/res/drawable-hdpi/rate_star_med_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_med_on_holo_light.png b/core/res/res/drawable-hdpi/rate_star_med_on_holo_light.png
index a6fdcff..41f33a8 100644
--- a/core/res/res/drawable-hdpi/rate_star_med_on_holo_light.png
+++ b/core/res/res/drawable-hdpi/rate_star_med_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_small_half_holo_dark.png b/core/res/res/drawable-hdpi/rate_star_small_half_holo_dark.png
index 4fb14f9..6cd59ea 100644
--- a/core/res/res/drawable-hdpi/rate_star_small_half_holo_dark.png
+++ b/core/res/res/drawable-hdpi/rate_star_small_half_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_small_half_holo_light.png b/core/res/res/drawable-hdpi/rate_star_small_half_holo_light.png
index 667b8e2..e03711e 100644
--- a/core/res/res/drawable-hdpi/rate_star_small_half_holo_light.png
+++ b/core/res/res/drawable-hdpi/rate_star_small_half_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_small_off_holo_dark.png b/core/res/res/drawable-hdpi/rate_star_small_off_holo_dark.png
index e19cf7a..a5ee171 100644
--- a/core/res/res/drawable-hdpi/rate_star_small_off_holo_dark.png
+++ b/core/res/res/drawable-hdpi/rate_star_small_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_small_off_holo_light.png b/core/res/res/drawable-hdpi/rate_star_small_off_holo_light.png
index 8886006..c7fb673 100644
--- a/core/res/res/drawable-hdpi/rate_star_small_off_holo_light.png
+++ b/core/res/res/drawable-hdpi/rate_star_small_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_small_on_holo_dark.png b/core/res/res/drawable-hdpi/rate_star_small_on_holo_dark.png
index bc5d3db..134a38b 100644
--- a/core/res/res/drawable-hdpi/rate_star_small_on_holo_dark.png
+++ b/core/res/res/drawable-hdpi/rate_star_small_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_small_on_holo_light.png b/core/res/res/drawable-hdpi/rate_star_small_on_holo_light.png
index 1041008..0e7c8a9 100644
--- a/core/res/res/drawable-hdpi/rate_star_small_on_holo_light.png
+++ b/core/res/res/drawable-hdpi/rate_star_small_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_16_inner_holo.png b/core/res/res/drawable-hdpi/spinner_16_inner_holo.png
index 0166938..383543a 100644
--- a/core/res/res/drawable-hdpi/spinner_16_inner_holo.png
+++ b/core/res/res/drawable-hdpi/spinner_16_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_20_inner_holo.png b/core/res/res/drawable-hdpi/spinner_20_inner_holo.png
index ffad720..49841ea 100644
--- a/core/res/res/drawable-hdpi/spinner_20_inner_holo.png
+++ b/core/res/res/drawable-hdpi/spinner_20_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_20_outer_holo.png b/core/res/res/drawable-hdpi/spinner_20_outer_holo.png
index f2523f4..69f0070 100644
--- a/core/res/res/drawable-hdpi/spinner_20_outer_holo.png
+++ b/core/res/res/drawable-hdpi/spinner_20_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_48_inner_holo.png b/core/res/res/drawable-hdpi/spinner_48_inner_holo.png
index f8e3fef..c8358e9 100644
--- a/core/res/res/drawable-hdpi/spinner_48_inner_holo.png
+++ b/core/res/res/drawable-hdpi/spinner_48_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_48_outer_holo.png b/core/res/res/drawable-hdpi/spinner_48_outer_holo.png
index 04c5fb5..f62f74b 100644
--- a/core/res/res/drawable-hdpi/spinner_48_outer_holo.png
+++ b/core/res/res/drawable-hdpi/spinner_48_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_76_inner_holo.png b/core/res/res/drawable-hdpi/spinner_76_inner_holo.png
index a28a6d1..c29ab07 100644
--- a/core/res/res/drawable-hdpi/spinner_76_inner_holo.png
+++ b/core/res/res/drawable-hdpi/spinner_76_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_76_outer_holo.png b/core/res/res/drawable-hdpi/spinner_76_outer_holo.png
index 3d5aa46..287afc6 100644
--- a/core/res/res/drawable-hdpi/spinner_76_outer_holo.png
+++ b/core/res/res/drawable-hdpi/spinner_76_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_call_mute.png b/core/res/res/drawable-hdpi/stat_notify_call_mute.png
index 1446fa7..7f87ee7 100644
--- a/core/res/res/drawable-hdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-hdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_disabled.png b/core/res/res/drawable-hdpi/stat_notify_disabled.png
new file mode 100644
index 0000000..5b5a7dc
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_notify_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png
index f3aaa27..8148ab8 100644
--- a/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png
+++ b/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim1.png b/core/res/res/drawable-hdpi/stat_sys_download_anim1.png
index 3e27c52..0b1aa34 100644
--- a/core/res/res/drawable-hdpi/stat_sys_download_anim1.png
+++ b/core/res/res/drawable-hdpi/stat_sys_download_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_speakerphone.png b/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
index a9af4a8..765be61 100644
--- a/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_tether_wifi.png b/core/res/res/drawable-hdpi/stat_sys_tether_wifi.png
index 0b8dbf5..7d4df50 100644
--- a/core/res/res/drawable-hdpi/stat_sys_tether_wifi.png
+++ b/core/res/res/drawable-hdpi/stat_sys_tether_wifi.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png
index 2754428..39d2c95f 100644
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim3.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim3.png
index 3590062..937720f 100644
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim3.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_def_app_icon.png b/core/res/res/drawable-hdpi/sym_def_app_icon.png
index c8a38ed..96a442e 100644
--- a/core/res/res/drawable-hdpi/sym_def_app_icon.png
+++ b/core/res/res/drawable-hdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_cursor_holo_dark.9.png b/core/res/res/drawable-hdpi/text_cursor_holo_dark.9.png
deleted file mode 100644
index ae77fa0..0000000
--- a/core/res/res/drawable-hdpi/text_cursor_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_cursor_holo_light.9.png b/core/res/res/drawable-hdpi/text_cursor_holo_light.9.png
deleted file mode 100644
index c6bdfcc..0000000
--- a/core/res/res/drawable-hdpi/text_cursor_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_select_handle_left.png b/core/res/res/drawable-hdpi/text_select_handle_left.png
index 5adc2e1..d2ed06d 100644
--- a/core/res/res/drawable-hdpi/text_select_handle_left.png
+++ b/core/res/res/drawable-hdpi/text_select_handle_left.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_select_handle_middle.png b/core/res/res/drawable-hdpi/text_select_handle_middle.png
index b7a472a..be2dc68 100644
--- a/core/res/res/drawable-hdpi/text_select_handle_middle.png
+++ b/core/res/res/drawable-hdpi/text_select_handle_middle.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_select_handle_right.png b/core/res/res/drawable-hdpi/text_select_handle_right.png
index cf94179..e419249 100644
--- a/core/res/res/drawable-hdpi/text_select_handle_right.png
+++ b/core/res/res/drawable-hdpi/text_select_handle_right.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_adb.png b/core/res/res/drawable-ldpi/stat_sys_adb.png
index aec8d90..86b945b 100644
--- a/core/res/res/drawable-ldpi/stat_sys_adb.png
+++ b/core/res/res/drawable-ldpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_share_pack_holo_light.9.png b/core/res/res/drawable-mdpi/ab_share_pack_holo_light.9.png
index 1983c68..8f10bd5 100644
--- a/core/res/res/drawable-mdpi/ab_share_pack_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/ab_share_pack_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_pressed_holo_dark.png b/core/res/res/drawable-mdpi/btn_check_on_pressed_holo_dark.png
index b70db89..06f0518 100644
--- a/core/res/res/drawable-mdpi/btn_check_on_pressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/btn_check_on_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_code_lock_touched.png b/core/res/res/drawable-mdpi/btn_code_lock_touched.png
index 98a3b6d..2dfe0f6 100644
--- a/core/res/res/drawable-mdpi/btn_code_lock_touched.png
+++ b/core/res/res/drawable-mdpi/btn_code_lock_touched.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_rating_star_on_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/btn_rating_star_on_disabled_focused_holo_light.png
index 816e146..26841bd 100644
--- a/core/res/res/drawable-mdpi/btn_rating_star_on_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/btn_rating_star_on_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_rating_star_on_disabled_holo_light.png b/core/res/res/drawable-mdpi/btn_rating_star_on_disabled_holo_light.png
index 4f4eff2..4fe7483 100644
--- a/core/res/res/drawable-mdpi/btn_rating_star_on_disabled_holo_light.png
+++ b/core/res/res/drawable-mdpi/btn_rating_star_on_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_rating_star_on_focused_holo_light.png b/core/res/res/drawable-mdpi/btn_rating_star_on_focused_holo_light.png
index afaa8ca..ec3b84d 100644
--- a/core/res/res/drawable-mdpi/btn_rating_star_on_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/btn_rating_star_on_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_rating_star_on_normal_holo_light.png b/core/res/res/drawable-mdpi/btn_rating_star_on_normal_holo_light.png
index b7d9079..537f4f0 100644
--- a/core/res/res/drawable-mdpi/btn_rating_star_on_normal_holo_light.png
+++ b/core/res/res/drawable-mdpi/btn_rating_star_on_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_rating_star_on_pressed_holo_light.png b/core/res/res/drawable-mdpi/btn_rating_star_on_pressed_holo_light.png
index 994eb0c..0409d4b 100644
--- a/core/res/res/drawable-mdpi/btn_rating_star_on_pressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/btn_rating_star_on_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_btn_find_next.png b/core/res/res/drawable-mdpi/ic_btn_find_next.png
deleted file mode 100644
index abdc247..0000000
--- a/core/res/res/drawable-mdpi/ic_btn_find_next.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_btn_find_prev.png b/core/res/res/drawable-mdpi/ic_btn_find_prev.png
deleted file mode 100644
index 4e3da1d..0000000
--- a/core/res/res/drawable-mdpi/ic_btn_find_prev.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_bullet_key_permission.png b/core/res/res/drawable-mdpi/ic_bullet_key_permission.png
index 47913f6..7fee560 100644
--- a/core/res/res/drawable-mdpi/ic_bullet_key_permission.png
+++ b/core/res/res/drawable-mdpi/ic_bullet_key_permission.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_find_next_holo_dark.png b/core/res/res/drawable-mdpi/ic_find_next_holo_dark.png
new file mode 100644
index 0000000..c138916
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_find_next_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_find_previous_holo_dark.png b/core/res/res/drawable-mdpi/ic_find_previous_holo_dark.png
new file mode 100644
index 0000000..d239274
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_find_previous_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_player_background.9.png b/core/res/res/drawable-mdpi/ic_lockscreen_player_background.9.png
index 8cfd1af..17d97c4 100644
--- a/core/res/res/drawable-mdpi/ic_lockscreen_player_background.9.png
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_player_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_next.png b/core/res/res/drawable-mdpi/ic_media_next.png
index a6feed0..acef506 100644
--- a/core/res/res/drawable-mdpi/ic_media_next.png
+++ b/core/res/res/drawable-mdpi/ic_media_next.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_previous.png b/core/res/res/drawable-mdpi/ic_media_previous.png
index 0163d0945..940d6a4 100644
--- a/core/res/res/drawable-mdpi/ic_media_previous.png
+++ b/core/res/res/drawable-mdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png
index 85f3cb2..baa5427 100644
--- a/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png
index 77f92fb..8e6a93f 100644
--- a/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_text_dot.png b/core/res/res/drawable-mdpi/ic_text_dot.png
index 47913f6..2225bd5 100644
--- a/core/res/res/drawable-mdpi/ic_text_dot.png
+++ b/core/res/res/drawable-mdpi/ic_text_dot.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_red_holo.png b/core/res/res/drawable-mdpi/indicator_code_lock_point_area_red_holo.png
index 8434741..52c9e3a 100644
--- a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_red_holo.png
+++ b/core/res/res/drawable-mdpi/indicator_code_lock_point_area_red_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_selector_background_disabled.9.png b/core/res/res/drawable-mdpi/list_selector_background_disabled.9.png
index 43c36cb..8ad0b32 100644
--- a/core/res/res/drawable-mdpi/list_selector_background_disabled.9.png
+++ b/core/res/res/drawable-mdpi/list_selector_background_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_selector_background_focus.9.png b/core/res/res/drawable-mdpi/list_selector_background_focus.9.png
index 53a7eac..da625af 100644
--- a/core/res/res/drawable-mdpi/list_selector_background_focus.9.png
+++ b/core/res/res/drawable-mdpi/list_selector_background_focus.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_selector_background_longpress.9.png b/core/res/res/drawable-mdpi/list_selector_background_longpress.9.png
index 0818761..fbf7ef0 100644
--- a/core/res/res/drawable-mdpi/list_selector_background_longpress.9.png
+++ b/core/res/res/drawable-mdpi/list_selector_background_longpress.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_selector_background_pressed.9.png b/core/res/res/drawable-mdpi/list_selector_background_pressed.9.png
index 8bd86b2..dd2a024 100644
--- a/core/res/res/drawable-mdpi/list_selector_background_pressed.9.png
+++ b/core/res/res/drawable-mdpi/list_selector_background_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png
index 1f29da2..7d9637a 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png
index a27f5aa..f7409e4 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_dark.png
index 34268af..9c2b833 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_light.png
index 304f800..dcf2fb7 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_dark.png
index 583542b..b63c510d 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_light.png
index d15bd16..55312a1 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_dark.png
index 9a5d79f..48e300c 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_light.png
index 9a5d79f..48e300c 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_dark.png
index 8051d64..1558d3d 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_light.png
index bcd34e9..6b6e7e1 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png
index cf4bdb6..081ea4e 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png
index cf4bdb6..081ea4e 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png
index 0535ff7..739a8d7 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png
index 360284d..bd440f2 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_dark.png
index 1e0e92c..cf856a1 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_light.png
index 14bcce9..6665953 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_dark.png
index 6ed2cf0..d63d797 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_light.png
index 015a8cf..22b6dbd 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_dark.png
index 8bb44f2..4bcce98 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_light.png
index 8bb44f2..4bcce98 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_dark.png
index 6ab5f23..12ba823 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_light.png
index 65ec302..d841f5a 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png
index 34d3228..0318c5f 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png
index 34d3228..0318c5f 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_call_mute.png b/core/res/res/drawable-mdpi/stat_notify_call_mute.png
index 8797a09..58e0cbc 100644
--- a/core/res/res/drawable-mdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-mdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_disabled.png b/core/res/res/drawable-mdpi/stat_notify_disabled.png
new file mode 100644
index 0000000..9661d31
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_notify_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png
index 747cb97..b7e2a6a 100644
--- a/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png
+++ b/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_speakerphone.png b/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
index e8c6374..d82704e 100644
--- a/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_def_app_icon.png b/core/res/res/drawable-mdpi/sym_def_app_icon.png
index b3e10f6..359047d 100644
--- a/core/res/res/drawable-mdpi/sym_def_app_icon.png
+++ b/core/res/res/drawable-mdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_cursor_holo_dark.9.png b/core/res/res/drawable-mdpi/text_cursor_holo_dark.9.png
deleted file mode 100644
index ae77fa0..0000000
--- a/core/res/res/drawable-mdpi/text_cursor_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_cursor_holo_light.9.png b/core/res/res/drawable-mdpi/text_cursor_holo_light.9.png
deleted file mode 100644
index c6bdfcc..0000000
--- a/core/res/res/drawable-mdpi/text_cursor_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-nodpi/indicator_code_lock_drag_direction_red_up.png b/core/res/res/drawable-nodpi/indicator_code_lock_drag_direction_red_up.png
new file mode 100644
index 0000000..cc46f19
--- /dev/null
+++ b/core/res/res/drawable-nodpi/indicator_code_lock_drag_direction_red_up.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/platlogo.png b/core/res/res/drawable-nodpi/platlogo.png
index e619ed5..8aa3b9e 100644
--- a/core/res/res/drawable-nodpi/platlogo.png
+++ b/core/res/res/drawable-nodpi/platlogo.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/text_cursor_holo_dark.9.png b/core/res/res/drawable-nodpi/text_cursor_holo_dark.9.png
new file mode 100644
index 0000000..450c486
--- /dev/null
+++ b/core/res/res/drawable-nodpi/text_cursor_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/text_cursor_holo_light.9.png b/core/res/res/drawable-nodpi/text_cursor_holo_light.9.png
new file mode 100644
index 0000000..22633eb0
--- /dev/null
+++ b/core/res/res/drawable-nodpi/text_cursor_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-hdpi/stat_notify_call_mute.png b/core/res/res/drawable-sw600dp-hdpi/stat_notify_call_mute.png
new file mode 100644
index 0000000..b753764
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-hdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-hdpi/stat_sys_speakerphone.png b/core/res/res/drawable-sw600dp-hdpi/stat_sys_speakerphone.png
new file mode 100644
index 0000000..b47a9f6
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-hdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-mdpi/stat_notify_call_mute.png b/core/res/res/drawable-sw600dp-mdpi/stat_notify_call_mute.png
new file mode 100644
index 0000000..951197c
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-mdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-mdpi/stat_sys_speakerphone.png b/core/res/res/drawable-sw600dp-mdpi/stat_sys_speakerphone.png
new file mode 100644
index 0000000..5893db9
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-mdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-mdpi/unlock_halo.png b/core/res/res/drawable-sw600dp-mdpi/unlock_halo.png
index c9ed4c7..96891ce 100644
--- a/core/res/res/drawable-sw600dp-mdpi/unlock_halo.png
+++ b/core/res/res/drawable-sw600dp-mdpi/unlock_halo.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xhdpi/stat_notify_call_mute.png b/core/res/res/drawable-sw600dp-xhdpi/stat_notify_call_mute.png
new file mode 100644
index 0000000..1d72243
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-xhdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xhdpi/stat_sys_speakerphone.png b/core/res/res/drawable-sw600dp-xhdpi/stat_sys_speakerphone.png
new file mode 100644
index 0000000..76dee9e
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-xhdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_btn_find_next.png b/core/res/res/drawable-xhdpi/ic_btn_find_next.png
deleted file mode 100644
index a334a5d..0000000
--- a/core/res/res/drawable-xhdpi/ic_btn_find_next.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_btn_find_prev.png b/core/res/res/drawable-xhdpi/ic_btn_find_prev.png
deleted file mode 100644
index d7b3177..0000000
--- a/core/res/res/drawable-xhdpi/ic_btn_find_prev.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_bullet_key_permission.png b/core/res/res/drawable-xhdpi/ic_bullet_key_permission.png
index b2db65c..6a0bdfc 100644
--- a/core/res/res/drawable-xhdpi/ic_bullet_key_permission.png
+++ b/core/res/res/drawable-xhdpi/ic_bullet_key_permission.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_find_next_holo_dark.png b/core/res/res/drawable-xhdpi/ic_find_next_holo_dark.png
new file mode 100644
index 0000000..e8226053
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_find_next_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_find_previous_holo_dark.png b/core/res/res/drawable-xhdpi/ic_find_previous_holo_dark.png
new file mode 100644
index 0000000..0ba45876c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_find_previous_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_player_background.9.png b/core/res/res/drawable-xhdpi/ic_lockscreen_player_background.9.png
index 7fb0cbc..393bca6 100644
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_player_background.9.png
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_player_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_next.png b/core/res/res/drawable-xhdpi/ic_media_next.png
index 9835c63..726fee7 100644
--- a/core/res/res/drawable-xhdpi/ic_media_next.png
+++ b/core/res/res/drawable-xhdpi/ic_media_next.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_previous.png b/core/res/res/drawable-xhdpi/ic_media_previous.png
index 5df5987..59f994d 100644
--- a/core/res/res/drawable-xhdpi/ic_media_previous.png
+++ b/core/res/res/drawable-xhdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.png b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.png
index 16632b1..7aa8750 100644
--- a/core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.png b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.png
index 6e007c7..d4e4d81 100644
--- a/core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.png
+++ b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_text_dot.png b/core/res/res/drawable-xhdpi/ic_text_dot.png
index d316f9a..869dd95 100644
--- a/core/res/res/drawable-xhdpi/ic_text_dot.png
+++ b/core/res/res/drawable-xhdpi/ic_text_dot.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/list_selector_background_disabled.9.png b/core/res/res/drawable-xhdpi/list_selector_background_disabled.9.png
index d599976..f039081 100644
--- a/core/res/res/drawable-xhdpi/list_selector_background_disabled.9.png
+++ b/core/res/res/drawable-xhdpi/list_selector_background_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/list_selector_background_focus.9.png b/core/res/res/drawable-xhdpi/list_selector_background_focus.9.png
index 17987f3..79c4577 100644
--- a/core/res/res/drawable-xhdpi/list_selector_background_focus.9.png
+++ b/core/res/res/drawable-xhdpi/list_selector_background_focus.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/list_selector_background_longpress.9.png b/core/res/res/drawable-xhdpi/list_selector_background_longpress.9.png
index 5a64592..73fc783 100644
--- a/core/res/res/drawable-xhdpi/list_selector_background_longpress.9.png
+++ b/core/res/res/drawable-xhdpi/list_selector_background_longpress.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/list_selector_background_pressed.9.png b/core/res/res/drawable-xhdpi/list_selector_background_pressed.9.png
index 1593577..5b3ebe1 100644
--- a/core/res/res/drawable-xhdpi/list_selector_background_pressed.9.png
+++ b/core/res/res/drawable-xhdpi/list_selector_background_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_disabled.9.png b/core/res/res/drawable-xhdpi/numberpicker_down_disabled.9.png
index 62b267e..ec92ea5 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_disabled.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused.9.png b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused.9.png
index 5f38c35..03c020d 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_dark.png
index 1c2f33e..111f57e 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_light.png
index 4e688bc..d0ef05b 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_dark.png
index dc422f2..ff21941 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_light.png
index afc02db..3e9bdda 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_light.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_dark.png
index 3604013..0462fca 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_light.png
index a16cd38..a488e8e 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_light.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_dark.png
index b975b63..f61b076 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_light.png
index b975b63..f61b076 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_light.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_normal.9.png b/core/res/res/drawable-xhdpi/numberpicker_down_normal.9.png
index b1d3e7b..8637414 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_normal.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_dark.png
index 39cdb93..211944e 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_light.png
index 2a14ac5..12bc11a 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_light.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_pressed.9.png b/core/res/res/drawable-xhdpi/numberpicker_down_pressed.9.png
index e61c469..bb56365 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_pressed.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_dark.png
index 4827377..635184c 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_light.png
index 4827377..635184c 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_light.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_selected.9.png b/core/res/res/drawable-xhdpi/numberpicker_down_selected.9.png
index ed0c016..4a076f6 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_down_selected.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_down_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_input_disabled.9.png b/core/res/res/drawable-xhdpi/numberpicker_input_disabled.9.png
index 279087c..d176022 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_input_disabled.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_input_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_input_normal.9.png b/core/res/res/drawable-xhdpi/numberpicker_input_normal.9.png
index 1b3467a..dcacfcf 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_input_normal.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_input_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_input_pressed.9.png b/core/res/res/drawable-xhdpi/numberpicker_input_pressed.9.png
index 930415e..f8cb9e5 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_input_pressed.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_input_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_input_selected.9.png b/core/res/res/drawable-xhdpi/numberpicker_input_selected.9.png
index 5240d08..38c429f 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_input_selected.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_input_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_disabled.9.png b/core/res/res/drawable-xhdpi/numberpicker_up_disabled.9.png
index 4b79112..a1d8ae1 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_disabled.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused.9.png b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused.9.png
index 6c2f397..0256f32a 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_dark.png
index 97ea0b5..470e569 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_light.png
index e59e2a7..16df74d 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_dark.png
index 3b8fa7f..edd4c04 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_light.png
index 77a1dd4..d8f459a 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_light.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_dark.png
index 24c2d84..08bf241 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_light.png
index b2566dc3..b2c40f1 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_light.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_dark.png
index 7075af7..f4f7331 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_light.png
index 7075af7..f4f7331 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_light.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_normal.9.png b/core/res/res/drawable-xhdpi/numberpicker_up_normal.9.png
index 699a9f5..f6746a6 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_normal.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_dark.png
index 11b60a9..83650b1 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_light.png
index 074fae5..78085d3 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_light.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_pressed.9.png b/core/res/res/drawable-xhdpi/numberpicker_up_pressed.9.png
index 5504fee..1071c73 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_pressed.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_dark.png
index 2310f83..b8f6849 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_light.png
index 2310f83..b8f6849 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_light.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_selected.9.png b/core/res/res/drawable-xhdpi/numberpicker_up_selected.9.png
index 585cf30..f446d48 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_up_selected.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_up_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_16_inner_holo.png b/core/res/res/drawable-xhdpi/spinner_16_inner_holo.png
index 9afd52f..55e2329 100644
--- a/core/res/res/drawable-xhdpi/spinner_16_inner_holo.png
+++ b/core/res/res/drawable-xhdpi/spinner_16_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_notify_call_mute.png b/core/res/res/drawable-xhdpi/stat_notify_call_mute.png
index 4135fea..adbd7b1 100644
--- a/core/res/res/drawable-xhdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-xhdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_notify_disabled.png b/core/res/res/drawable-xhdpi/stat_notify_disabled.png
new file mode 100644
index 0000000..0a003af
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/stat_notify_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-xhdpi/stat_notify_wifi_in_range.png
index 6bb7512..0dbae57 100644
--- a/core/res/res/drawable-xhdpi/stat_notify_wifi_in_range.png
+++ b/core/res/res/drawable-xhdpi/stat_notify_wifi_in_range.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png b/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
index 3ac1b88..51e648c 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/sym_def_app_icon.png b/core/res/res/drawable-xhdpi/sym_def_app_icon.png
index f381f86..71c6d76 100644
--- a/core/res/res/drawable-xhdpi/sym_def_app_icon.png
+++ b/core/res/res/drawable-xhdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/text_cursor_holo_dark.9.png b/core/res/res/drawable-xhdpi/text_cursor_holo_dark.9.png
deleted file mode 100644
index e7bb0d4..0000000
--- a/core/res/res/drawable-xhdpi/text_cursor_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/text_cursor_holo_light.9.png b/core/res/res/drawable-xhdpi/text_cursor_holo_light.9.png
deleted file mode 100644
index f429785..0000000
--- a/core/res/res/drawable-xhdpi/text_cursor_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/layout/grant_credentials_permission.xml b/core/res/res/layout/grant_credentials_permission.xml
index 3313590..dd85b33 100644
--- a/core/res/res/layout/grant_credentials_permission.xml
+++ b/core/res/res/layout/grant_credentials_permission.xml
@@ -77,7 +77,7 @@
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/perms_dangerous_perm_color"
android:textStyle="bold"
- android:paddingLeft="6dip"
+ android:paddingLeft="16dip"
android:layout_toRightOf="@id/permission_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
@@ -88,7 +88,7 @@
android:textColor="@color/perms_dangerous_perm_color"
android:layout_marginTop="-4dip"
android:paddingBottom="8dip"
- android:paddingLeft="6dip"
+ android:paddingLeft="16dip"
android:layout_below="@id/account_type"
android:layout_toRightOf="@id/permission_icon"
android:layout_width="wrap_content"
@@ -101,7 +101,7 @@
android:textStyle="bold"
android:layout_marginTop="-4dip"
android:paddingBottom="8dip"
- android:paddingLeft="6dip"
+ android:paddingLeft="16dip"
android:layout_below="@id/account_name"
android:layout_toRightOf="@id/permission_icon"
android:layout_width="wrap_content"
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index e34822d..803047e 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -206,7 +206,7 @@
<!-- Area to overlay FaceLock -->
<TextView android:id="@+id/faceLockAreaView"
- android:visibility="gone"
+ android:visibility="invisible"
android:layout_row="0"
android:layout_column="2"
android:layout_rowSpan="8"
diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml
index e1280ba..6b03359 100644
--- a/core/res/res/layout/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_password_portrait.xml
@@ -195,7 +195,7 @@
<!-- Area to overlay FaceLock -->
<TextView android:id="@+id/faceLockAreaView"
- android:visibility="gone"
+ android:visibility="invisible"
android:layout_row="3"
android:layout_column="0"
android:layout_rowSpan="2"
diff --git a/core/res/res/layout/keyguard_screen_unlock_landscape.xml b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
index 2778f4e..1038657 100644
--- a/core/res/res/layout/keyguard_screen_unlock_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
@@ -162,7 +162,7 @@
<!-- Area to overlay FaceLock -->
<TextView android:id="@+id/faceLockAreaView"
- android:visibility="gone"
+ android:visibility="invisible"
android:layout_row="0"
android:layout_column="1"
android:layout_rowSpan="7"
diff --git a/core/res/res/layout/keyguard_screen_unlock_portrait.xml b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
index 03fc79e..f286ccd 100644
--- a/core/res/res/layout/keyguard_screen_unlock_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
@@ -174,7 +174,7 @@
<!-- Area to overlay FaceLock -->
<TextView android:id="@+id/faceLockAreaView"
- android:visibility="gone"
+ android:visibility="invisible"
android:layout_row="4"
android:layout_column="0"
android:layout_rowSpan="1"
diff --git a/core/res/res/layout/keyguard_transport_control.xml b/core/res/res/layout/keyguard_transport_control.xml
index 2ebe5fc..7e2a31c 100644
--- a/core/res/res/layout/keyguard_transport_control.xml
+++ b/core/res/res/layout/keyguard_transport_control.xml
@@ -19,23 +19,28 @@
but rather as include tags for this file or the layout will break. -->
<com.android.internal.widget.TransportControlView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/transport_controls"
- android:background="@drawable/ic_lockscreen_player_background">
+ android:id="@+id/transport_controls">
- <ImageView
- android:id="@+id/albumart"
+ <!-- FrameLayout used as scrim to show between album art and buttons -->
+ <FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_gravity="fill"
- android:scaleType="centerCrop"
- android:adjustViewBounds="false"
+ android:foreground="@drawable/ic_lockscreen_player_background">
+ <!-- We use ImageView for its cropping features, otherwise could be android:background -->
+ <ImageView
+ android:id="@+id/albumart"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="fill"
+ android:scaleType="centerCrop"
+ android:adjustViewBounds="false"
/>
+ </FrameLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="#c8000000"
android:layout_gravity="bottom">
<TextView
android:id="@+id/title"
@@ -63,10 +68,11 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:src="@drawable/ic_media_rew"
+ android:src="@drawable/ic_media_previous"
android:clickable="true"
android:background="?android:attr/selectableItemBackground"
- android:padding="10dip"/>
+ android:padding="10dip"
+ android:contentDescription="@string/lockscreen_transport_prev_description"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
@@ -80,7 +86,8 @@
android:clickable="true"
android:src="@drawable/ic_media_play"
android:background="?android:attr/selectableItemBackground"
- android:padding="10dip"/>
+ android:padding="10dip"
+ android:contentDescription="@string/lockscreen_transport_play_description"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
@@ -92,9 +99,10 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:clickable="true"
- android:src="@drawable/ic_media_ff"
+ android:src="@drawable/ic_media_next"
android:background="?android:attr/selectableItemBackground"
- android:padding="10dip"/>
+ android:padding="10dip"
+ android:contentDescription="@string/lockscreen_transport_next_description"/>
</FrameLayout>
</LinearLayout>
</LinearLayout>
diff --git a/core/res/res/layout/status_bar_latest_event_content_large_icon.xml b/core/res/res/layout/status_bar_latest_event_content_large_icon.xml
index f3f1957..6e8c921 100644
--- a/core/res/res/layout/status_bar_latest_event_content_large_icon.xml
+++ b/core/res/res/layout/status_bar_latest_event_content_large_icon.xml
@@ -25,14 +25,12 @@
android:fadingEdge="horizontal"
android:ellipsize="marquee"
android:visibility="gone"
- android:alpha="0.7"
/>
<LinearLayout
android:id="@+id/line3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
- android:alpha="0.7"
>
<TextView android:id="@+id/text"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
@@ -62,6 +60,7 @@
android:scaleType="center"
android:paddingLeft="8dp"
android:visibility="gone"
+ android:drawableAlpha="180"
/>
</LinearLayout>
<ProgressBar
diff --git a/core/res/res/layout/volume_adjust_item.xml b/core/res/res/layout/volume_adjust_item.xml
index fb900f7..d3fa7e9 100644
--- a/core/res/res/layout/volume_adjust_item.xml
+++ b/core/res/res/layout/volume_adjust_item.xml
@@ -27,7 +27,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dip"
- android:layout_marginLeft="8dip"
android:background="?attr/selectableItemBackground"
/>
@@ -38,8 +37,6 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="16dip"
- android:layout_marginRight="8dip" />
+ android:layout_marginRight="16dip" />
</LinearLayout>
-
-
diff --git a/core/res/res/menu/webview_find.xml b/core/res/res/menu/webview_find.xml
index 74a40aa..526b346 100644
--- a/core/res/res/menu/webview_find.xml
+++ b/core/res/res/menu/webview_find.xml
@@ -16,11 +16,11 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/find_prev"
- android:icon="@drawable/ic_btn_find_prev"
+ android:icon="@drawable/ic_find_previous_holo_dark"
android:showAsAction="always"
/>
<item android:id="@+id/find_next"
- android:icon="@drawable/ic_btn_find_next"
+ android:icon="@drawable/ic_find_next_holo_dark"
android:showAsAction="always"
/>
</menu>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index c977bea..3ad01a5 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Laat die program toe om persoonlike profielinligting gestoor op jou selfoon, soos jou naam en kontakbesonderhede, te lees. Dit beteken dat die program jou kan identifiseer en jou profielinligting aan ander kan stuur."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"skryf na jou profieldata"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Laat die program toe om te verander of by te voeg tot die persoonlike profielinligting gestoor op jou selfoon, soos jou naam en kontakbesonderhede. Dit beteken dat ander programme jou kan identifiseer en jou profielinligting aan ander kan stuur."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lees jou sosiale stroom"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Stel die app in staat om toegang te verkry tot en sosiale bywerkings tussen jou en jou vriende te sinch. Kwaadwillige apps kan dit gebruik om private kommunikasie tussen jou en jou vriende op sosiale netwerke te lees."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skryf aan jou sosiale stroom"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Stel die app in staat om jou vriende se sosiale bywerkings te vertoon. Kwaadwillige apps kan dit gebruik om via sosiale netwerke toegang tot private kommunikasie tussen jou en jou vriende te verkry."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"lees kalenderafsprake plus vertroulike inligting"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Laat \'n program toe om alle kalenderafsprake te lees wat op jou tablet gestoor is, insluitend dié van vriende of kollegas. \'n Kwaadwillige program met dié toestemming kan persoonlike inligting uit hierdie kalenders uithaal sonder die eienaars se medewete."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Laat \'n program toe om alle kalendergebeure wat op jou foon gestoor is, insluitend dié van vriende of kollega\'s, te lees. \'n Kwaadwillige program met dié toestemming kan persoonlike inligting uit hierdie kalenders uithaal, sonder die eienaars se medewete."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Sit asseblief \'n SIM-kaart in."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Die SIM-kaart is weg of onleesbaar. Steek asseblief \'n SIM-kaart in."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Jou SIM-kaart is permanent gedeaktiveer."\n" Kontak asseblief jou draadlosediens-verskaffer om \'n ander SIM-kaart te kry."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Vorigesnit-knoppie"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Volgendesnit-knoppie"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Laatwag-knoppie"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Speel-knoppie"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Stop-knoppie"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Net noodoproepe"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Netwerk gesluit"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-kaart is PUK-geslote."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Ontsluit"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Klank aan"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Klank af"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Patroon begin"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Patroon uitgevee"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Sel bygevoeg"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Patroon klaar"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"Sny"</string>
<string name="copy" msgid="2681946229533511987">"Kopieer"</string>
<string name="paste" msgid="5629880836805036433">"Plak"</string>
- <string name="replace" msgid="5781686059063148930">"Vervang???"</string>
+ <string name="replace" msgid="5781686059063148930">"Vervang..."</string>
<string name="delete" msgid="6098684844021697789">"Vee uit"</string>
<string name="copyUrl" msgid="2538211579596067402">"Kopieer URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Kies teks..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modus verander"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Invoersleutel"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Kies \'n app"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Deel met"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Deel met <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Glyhandvatsel. Tik en hou."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Op na <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Af vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Stil"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Klank aan"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Sleutel. Kopstuk nodig om sleutels te hoor, tydens tik van \'n wagwoord."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Koppel \'n kopstuk om te hoor hoe wagwoordsleutels hardop gesê word."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punt."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Navigeer tuis"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navigeer op"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Meer opsies"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 892939f..f23e9e7 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -63,7 +63,7 @@
<string name="RuacMmi" msgid="7827887459138308886">"የሚያበሳጭ የማይፈለጉ ጥሪዎች አለመቀበል።"</string>
<string name="CndMmi" msgid="3116446237081575808">"መደወያ ቁጥር አስረከበ"</string>
<string name="DndMmi" msgid="1265478932418334331">"አትረብሽ"</string>
- <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"የደዋይ ID ወደ ተከልክሏል ነባሪዎች። ቀጥሎ ጥሪ፡ ተከልክሏል"</string>
+ <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"የደዋይID ወደ ተከልክሏል ነባሪዎች።ጥሪ ቀጥሎ ተከልክሏል፡"</string>
<string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"የደዋይ ID ወደ ተከልክሏል ነባሪዎች።ቀጥሎ ጥሪ፡ አልተከለከለም"</string>
<string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"የደዋይ ID ወደ አልተከለከለም ነባሪዎች።ቀጥሎ ጥሪ፡ ተከልክሏል"</string>
<string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"የደዋይ ID ነባሪዎች ወደአልተከለከለም። ቀጥሎ ጥሪ፡አልተከለከለም"</string>
@@ -83,7 +83,7 @@
<string name="serviceClassFAX" msgid="5566624998840486475">"ፋክስ"</string>
<string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
<string name="serviceClassDataAsync" msgid="4523454783498551468">"በተለያየ ጊዜ"</string>
- <string name="serviceClassDataSync" msgid="7530000519646054776">"አሳምር"</string>
+ <string name="serviceClassDataSync" msgid="7530000519646054776">"ሥምሪያ"</string>
<string name="serviceClassPacket" msgid="6991006557993423453">"ፓኬት"</string>
<string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
<string name="roamingText0" msgid="7170335472198694945">"በዝውውር ላይ አመላካች በርቷል"</string>
@@ -124,8 +124,8 @@
<string name="httpErrorFileNotFound" msgid="5588380756326017105">"የተጠየቀው ፋይል አልተገኘም ነበር።"</string>
<string name="httpErrorTooManyRequests" msgid="1235396927087188253">"እጅግ ብዙ ጥየቃዎች ተካሂደዋል። ትንሽ ቆይተው እንደገና ይሞክሩ።"</string>
<string name="notification_title" msgid="1259940370369187045">"ለ<xliff:g id="ACCOUNT">%1$s</xliff:g> ስህተት ግባ"</string>
- <string name="contentServiceSync" msgid="8353523060269335667">"አሳምር"</string>
- <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"አሳምር"</string>
+ <string name="contentServiceSync" msgid="8353523060269335667">"ሥምሪያ"</string>
+ <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"ሥምሪያ"</string>
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"በጣም ብዙ <xliff:g id="CONTENT_TYPE">%s</xliff:g> ስርዞች።"</string>
<string name="low_memory" product="tablet" msgid="2292820184396262278">"የጡባዊ ማከማቻ ሙሉ ነው! ቦታ ነፃ ለማድረግ አንዳንድ ፋይሎች ሰርዝ።"</string>
<string name="low_memory" product="default" msgid="6632412458436461203">"የስልክ ማከማቻ ሙሉ ነው! ቦታ ነፃ ለማድረግ አንዳንድ ፋይሎች ሰርዝ።"</string>
@@ -222,7 +222,7 @@
<string name="permdesc_killBackgroundProcesses" msgid="2908829602869383753">"ትግበራ ምንም እንኳ ማህደረ ትውስታ አነስተኛ ባይሆንም ሌላ ትግበራዎች የዳራ ሂደታቸውን ለማቆም ይፈቅዳል።"</string>
<string name="permlab_forceStopPackages" msgid="1447830113260156236">"ሌላ ትግበራዎችን በኃይል አቁም"</string>
<string name="permdesc_forceStopPackages" msgid="7263036616161367402">"ትግበራ ሌሎች ትግበራዎችን በኃይል ለማስቆም ይፈቅዳል።"</string>
- <string name="permlab_forceBack" msgid="1804196839880393631">"ትግበራ እንዲዘጋ አስገድድ"</string>
+ <string name="permlab_forceBack" msgid="1804196839880393631">"ትግበራ እንዲዘጋ አስገድድ"</string>
<string name="permdesc_forceBack" msgid="6534109744159919013">"ትግበራ ማንኛውም ቅድመገፅ እንቅስቃሴ በግድ ለመዝጋት እና ለመመለስ ይፈቅዳል። ለመደበኛ ትግበራዎች በፍፁም አያስፈልግም።"</string>
<string name="permlab_dump" msgid="1681799862438954752">"የስርዓት የውስጥ ሁኔታን ሰርስረህ አውጣ"</string>
<string name="permdesc_dump" msgid="2198776174276275220">"ትግበራ የስረዓት ውስጣዊ ሁኔታ ሰርስረው ሊያወጡ ይፈቅዳል። ተንኮል አዘል ትግበራዎች በፍፁም የማያስፈልጋቸውን የተለያዩ ሰፋ ያለ የግል እና የተጠበቀ መረጃ ሰርስረ ው ሊያወጡይችላሉ።"</string>
@@ -250,7 +250,7 @@
<string name="permdesc_backup" msgid="4837493065154256525">"ትግበራው በስርዓተ መጠባበቅ እና እነበረበት መልስ አሰራር ለመቆጣጠር ይፈቅዳል።ለመደበኛ ትግበራዎች ጥቅም አይደለም።"</string>
<string name="permlab_confirm_full_backup" msgid="5557071325804469102">"የሙሉ መጠበቂያ ወይም እነበረበት መልስ ከዋኝ አረጋግጥ"</string>
<string name="permdesc_confirm_full_backup" msgid="9005017754175897954">"ትግበራ ሙሉ የመጠባበቂያ ማረጋገጫ UI ለማስነሳት ይፈቅዳል። በሌላ በማንኛውም እንዳይገለገል።"</string>
- <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"ያልተፈቀደ ዊንዶውዝ አሳይ"</string>
+ <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"ያልተፈቀደ Windows አሳይ"</string>
<string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"በውስጥ ስርዓት ተጠቃሚ በየነገፅ ለመጠቀም የሚታሰብ ዊንዶውዝ መፍጠር ይፈቅዳል። ለመደበኛ ትግበራዎች ጥቅም አይደለም።"</string>
<string name="permlab_systemAlertWindow" msgid="3372321942941168324">"የስርዓት-ደረጃ ማንቂያ አሳይ"</string>
<string name="permdesc_systemAlertWindow" msgid="2884149573672821318">"ትግበ ራ የስርዓት ማንቂያ ዊንዶውዝ ለማሳየት ይፈቅዳል። ተንኮል አዘል ትግበራዎች የስልኩን ጠቅላላ ማያ ሊቆጣጠሩት ይችላሉ።"</string>
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"ትግበራ በመሣሪያዎ ላይ የተከማቸውን የግል የመገለጫ መረጃ፣ እንደ ስምዎ እና የዕውቂያ መረጃ ለማንበብ ይፈቅዳል። ይህ ማለት ትግበራው እርስዎን ለይቶ የመገለጫ መረጃዎን ለሌሎች መላክ ይችላል።"</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"የአርስዎ መገለጫ ውሂብ ላይ ይፃፉ"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"ትግበራ በመሣሪያዎ ላይ የተከማቸውን የግል የመገለጫ መረጃ፣ እንደ ስምዎ እና የዕውቂያ መረጃ ለመለወጥ እና ለማከል ይፈቅዳል። ይህ ማለት ትግበራው እርስዎን ለይቶ የመገለጫ መረጃዎን ለሌሎች መላክ ይችላል።"</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ያንተን ማህበራዊ የውይይት ክፍሎች አንብብ"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"መተግበሪያው ካንተ ጓደኞች ማህበራዊ ዝማኔዎችን እንዲደርስባቸው እና እንዲያመሳስል ይፈቅዳል፡፡ ተንኮል አዘል መተግበሪያዎች ይህን መዳረሻ ባንተና በጓደኞችህ መካከል በማህበራዊ አውታረመረቦች ያሉ የግል ተግባቦቶችን ለመዳረስ ሊጠቀሙበት ይችላሉ፡፡"</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ወደ ያንተ ማህበራዊ የውይይት ክፍሎች ጻፍ"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"መተግበሪያው የጓደኞችህን ማህበራዊ ዝማኔዎችን ለማሳየት ይፈቅዳል፡፡ ተንኮል አዘል መተግበሪያዎች ይህን መዳረሻ ጓደኛ መስለው ለመቅረብ እና የይለፍ ቃልና ሌላ ምስጢራዊ መረጃ እንድትሰጡ ለማድረግ ሊጠቀሙበት ይችላሉ፡፡"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"የቀን መቁጠሪያ ክስተቶች ተጨማሪ ሚስጥራዊ መረጃ አንብብ"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"ትግበራ በጡባዊዎ ላይ የተከማቸውን የቀን መቁጠሪያ ክስተቶች በሙሉ አብረው የሚሰሩትንም ሆነ የጓደኞችዎን ጨምሮ ለማንበብ ይፈቅዳል። ይህን ፈቃድ የያዘ ተንኮል አዘል ትግበራ ከባለቤቱ ዕውቅና ውጪ ከቀን አቆጣጠር ላይ የግል መረጃ ማውጣት ይችላል።\'"</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"ትግበራ በስልክዎ ላይ የተከማቸውን የቀን መቁጠሪያ ክስተቶች በሙሉ አብረው የሚሰሩትንም ሆነ የጓደኞችዎን ጨምሮ ለማንበብ ይፈቅዳል። ይህን ፈቃድ የያዘ ተንኮል አዘል ትግበራ ከባለቤቱ ዕውቅና ውጪ ከቀን አቆጣጠር ላይ የግል መረጃ ማውጣት ይችላል።\'"</string>
@@ -468,14 +472,14 @@
<string name="permdesc_nfc" msgid="9171401851954407226">"ትግበራ የቅርብ ግኑኙነትመስክ (NFC) መለያዎች፣ ካርዶች እና አንባቢ ጋር ለማገናኘትይፈቅዳል።"</string>
<string name="permlab_disableKeyguard" msgid="4977406164311535092">"ቁልፍመቆለፊያአቦዝን"</string>
<string name="permdesc_disableKeyguard" msgid="3189763479326302017">"ትግበራ የቁልፍሽንጉር እና ማንኛውም ተያያዥ የይለፍ ቃል ደህንነት ላለማስቻል ይፈቅዳል። ለዚህ ህጋዊ ምሳሌ የገቢ ስልክ ጥሪ ሲቀበሉ የቁልፍሽንጉርአለማስቻል፣ ከዛም ጥሪው ሲጨርስ የቁልፍሽንጉሩን ድጋሚ ማስቻል።"</string>
- <string name="permlab_readSyncSettings" msgid="6201810008230503052">"የአሳምር ቅንብሮች አንብብ"</string>
+ <string name="permlab_readSyncSettings" msgid="6201810008230503052">"የሥምሪያ ቅንብሮች አንብብ"</string>
<string name="permdesc_readSyncSettings" msgid="5315925706353341823">"ትግበራ የአሳምር ቅንብሮች እንደ አየር ሁኔታ አሳምር ለዕውቆች መንቃቱን ለማንበብ ይፈቅዳል።"</string>
- <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"የአሳምር ቅንብሮች ፃፍ"</string>
+ <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"የሥምሪያ ቅንብሮችን ፃፍ"</string>
<string name="permdesc_writeSyncSettings" msgid="2498201614431360044">"ትግበራ የአሳምር ቅንብሮች እንደ አየር ሁኔታ አሳምር ለዕውቆች መንቃቱን ለመቀየር ይፈቅዳል።"</string>
- <string name="permlab_readSyncStats" msgid="7396577451360202448">"የአሳምር ስታስቲክስ አንብብ"</string>
+ <string name="permlab_readSyncStats" msgid="7396577451360202448">"የሥምሪያ ስታስቲክስ አንብብ"</string>
<string name="permdesc_readSyncStats" msgid="7511448343374465000">"ትግበራ የአሳምር ስታስቲክ ለምሳሌ የተከሰተ የአሳምር ታሪክ ለማንበብ ይፈቅዳል።"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"የምዝገባ መግቦች አንበብ"</string>
- <string name="permdesc_subscribedFeedsRead" msgid="3622200625634207660">"ትግበራ ስለ አሁኑጊዜ አሳምርምላሾች ዝርዝሮች ለማግኘት ይፈቅዳል።"</string>
+ <string name="permdesc_subscribedFeedsRead" msgid="3622200625634207660">"ትግበራ ስለ አሁኑጊዜ ሥምሪያምላሾች ዝርዝሮች ለማግኘት ይፈቅዳል።"</string>
<string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"የተመዝጋቢዎች ምላሾች ፃፍ"</string>
<string name="permdesc_subscribedFeedsWrite" msgid="8121607099326533878">"ትግበራ በአሁን ጊዜ የእርስዎን አሳምር ምገባዎች ለመቀየር ይፈቅዳል።ይህ ለተንኮል አዘል ትግበራ የእርስዎን አሳምር ምገባ ዎች ለመለወጥ መፍቀድ ይችላል።"</string>
<string name="permlab_readDictionary" msgid="432535716804748781">"በተጠቃሚ የተበየኑ መዝገበ ቃላት አንብብ"</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"እባክዎ SIM ካርድ ያስገቡ"</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"SIM ካርዱ ጠፍቷል ወይም መነበብ አይችልም።እባክዎ SIM ካርድ ያስገቡ።"</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"SIM ካርድዎ በቋሚነት ቦዝኗል።"\n" እባክዎ ሌላ SIM ካርድ ለማግኘት የገመድ አልባ አገልግሎት አቅራቢዎን ያግኙ።"</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"የቀድሞ ዝርዝር አዝራር"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"ቀጣይ ዝርዝር አዝራር"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"ለአፍታ አቁም አዝራር"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"ማጫወቻ አዝራር።"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"አቁም አዝራር"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"የአደጋ ጊዜ ጥሪ ብቻ"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"አውታረመረብ ተሸንጉሯል"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM ካርድበPUK ተዘግቷል።"</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"ክፈት"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"ድምፅ አብራ"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"ድምፅ አጥፋ"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"ንድፍ ተጀምሯል"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"ንድፍ ጸድቷል"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"ሕዋስ ታክሏል"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ንድፍ ተጠናቋል"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"ቁረጥ"</string>
<string name="copy" msgid="2681946229533511987">"ግላባጭ"</string>
<string name="paste" msgid="5629880836805036433">"ለጥፍ"</string>
- <string name="replace" msgid="5781686059063148930">"ተካ???"</string>
+ <string name="replace" msgid="5781686059063148930">"ተካ..."</string>
<string name="delete" msgid="6098684844021697789">"ሰርዝ"</string>
<string name="copyUrl" msgid="2538211579596067402">"የURL ቅጂ"</string>
<string name="selectTextMode" msgid="6738556348861347240">"ፅሁፍ ምረጥ"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ሞድ ለውጥ"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"ቀይር"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"አስገባ"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"መተግበሪያ ምረጥ"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"ተጋራ ከ"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"ከ <xliff:g id="APPLICATION_NAME">%s</xliff:g> ጋር ተጋራ"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Sliding handle. Tap and hold."</string>
<string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደላይ።"</string>
<string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደታች።"</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"ካሜራ"</string>
<string name="description_target_silent" msgid="893551287746522182">"ፀጥታ"</string>
<string name="description_target_soundon" msgid="30052466675500172">"ድምፅ አብራ"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"አዝራር፡፡ ይለፍቃል እየተየብክ አዝራሮችን ለመስማት ማዳመጫ መሳሪያ ያስፈልጋል፡፡"</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"የይለፍቃል ቁልፎች ጮክ በለው ሲነገሩ ለመስማት የጆሮ ማዳመጫ ሰካ::"</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"ነጥብ."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"መነሻ ዳስስ"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"አስስ"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"ተጨማሪ አማራጮች"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index fcba14e..1d65c4f 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"للسماح للتطبيق بقراءة معلومات الملف الشخصي الشخصية المخزنة على الجهاز، مثل الاسم ومعلومات الاتصال. يعني ذلك أن التطبيق يمكنه التعرف عليك وإرسال معلومات ملفك الشخصي إلى الآخرين."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"الكتابة إلى بيانات ملفك الشخصي"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"للسماح للتطبيق بتغيير أو إضافة معلومات الملف الشخصي الشخصية المخزنة على الجهاز، مثل الاسم ومعلومات الاتصال. يعني ذلك أن التطبيقات الأخرى يمكنها التعرف عليك وإرسال معلومات ملفك الشخصي إلى الآخرين."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"قراءة المشاركات الاجتماعية"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"للسماح للتطبيق بالدخول إلى التحديثات الاجتماعية منك ومن أصدقائك ومزامنتها. يمكن أن تستخدم التطبيقات الضارة هذا لقراءة الاتصالات الخاصة بينك وبين أصدقائك على الشبكات الاجتماعية."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"كتابة إلى المشاركات الاجتماعية"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"للسماح للتطبيق بعرض التحديثات الاجتماعية من أصدقائك. يمكن أن تستخدم التطبيقات الضارة هذا للتظاهر بأنها صديق وتخدعك لكشف كلمات المرور أو المعلومات السرية الأخرى."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"قراءة أحداث التقويم بالإضافة إلى المعلومات السرية"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"للسماح لأحد التطبيقات بقراءة جميع أحداث التقويم المخزّنة في الجهاز اللوحي، بما في ذلك أحداث التقويم الخاصة بالأصدقاء وزملاء العمل. يمكن لأحد التطبيقات الضارة باستخدام هذا الإذن استخراج المعلومات الشخصية من هذه التقاويم بدون معرفة المالكين."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"للسماح لأحد التطبيقات بقراءة جميع أحداث التقويم المخزّنة في هاتفك، بما في ذلك أحداث التقويم الخاصة بالأصدقاء وزملاء العمل. يمكن لأحد التطبيقات الضارة باستخدام هذا الإذن استخراج المعلومات الشخصية من هذه التقاويم بدون معرفة المالكين."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"الرجاء إدخال بطاقة SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"بطاقة SIM مفقودة أو غير قابلة للقراءة. الرجاء إدراج بطاقة SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"بطاقة SIM معطلة دومًا."\n" يرجى الاتصال بمقدم الخدمة اللاسلكية للحصول على بطاقة SIM أخرى."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"زر المقطع الصوتي السابق"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"زر المقطع الصوتي التالي"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"زر الإيقاف المؤقت"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"زر التشغيل"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"زر الإيقاف"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"مكالمات الطوارئ فقط"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"الشبكة مؤمّنة"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"بطاقة SIM مؤمّنة بكود PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"إلغاء تأمين"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"تشغيل الصوت"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"الصوت متوقف"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"بدأ النمط"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"تم محو النمط"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"تمت إضافة الخلية"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"اكتمل النمط"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ب ت ث"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"قص"</string>
<string name="copy" msgid="2681946229533511987">"نسخ"</string>
<string name="paste" msgid="5629880836805036433">"لصق"</string>
- <string name="replace" msgid="5781686059063148930">"استبدال???"</string>
+ <string name="replace" msgid="5781686059063148930">"استبدال..."</string>
<string name="delete" msgid="6098684844021697789">"حذف"</string>
<string name="copyUrl" msgid="2538211579596067402">"نسخ عنوان URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"تحديد نص..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"تغيير الوضع"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"العالي"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"اختيار تطبيق"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"مشاركة مع"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"مشاركة مع <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"مقبض التمرير. انقر وامسك."</string>
<string name="description_direction_up" msgid="1983114130441878529">"أعلى إلى <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"أسفل إلى <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"الكاميرا"</string>
<string name="description_target_silent" msgid="893551287746522182">"صامت"</string>
<string name="description_target_soundon" msgid="30052466675500172">"تشغيل الصوت"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"سماعة رأس مطلوبة لسماع المفاتيح أثناء كتابة كلمة مرور."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"يمكنك توصيل سماعة رأس لسماع مفاتيح كلمة المرور منطوقة بصوت عالٍ."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"نقطة"</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"التنقل إلى الشاشة الرئيسية"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"التنقل إلى أعلى"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"المزيد من الخيارات"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 9599028..45834a0 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Разрешава на приложението да чете информацията от личния потребителски профил, съхранена на устройството ви, например вашето име и данни за връзка. Това означава, че приложението може да ви идентифицира и да изпраща информацията за потребителския ви профил на други хора."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"запис в потр. ви профил"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Разрешава на приложението да променя или добавя към личния потребителски профил информация, съхранена на устройството ви, като например вашето име и данни за връзка. Това означава, че приложението може да ви идентифицира и да изпраща информацията за потребителския ви профил на други хора."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"четене на социалния ви поток"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Разрешава на приложението да осъществява достъп и да синхронизира социални актуализации от вас и приятелите ви. Злонамерените приложения могат да използват това, за да четат частни съобщения помежду ви в социалните мрежи."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"писане в социалния ви поток"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Разрешава на приложението да показва социални актуализации от приятелите ви. Злонамерените приложения могат да използват това, за да се представят за приятел и да ви подмамят да разкриете пароли или друга поверителна информация."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"четене на събития от календари плюс поверителна информация"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Разрешава на приложението да чете всички събития от календари, съхранявани на таблета ви, включително тези на приятели или колеги. Злонамерено приложение с това разрешение може да извлича лична информация от тези календари без знанието на собствениците."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Разрешава на приложението да чете всички събития от календари, съхранявани на телефона ви, включително тези на приятели или колеги. Злонамерено приложение с това разрешение може да извлича лична информация от тези календари без знанието на собствениците."</string>
@@ -661,6 +665,16 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Моля, поставете SIM карта."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"SIM картата липсва или е нечетима. Моля, поставете SIM карта."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"SIM картата ви е деактивирана за постоянно."\n" Моля, свържете се с оператора на безжичната си връзка, за да получите друга."</string>
+ <!-- no translation found for lockscreen_transport_prev_description (201594905152746886) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_next_description (6089297650481292363) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_pause_description (7659088786780128001) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_play_description (5888422938351019426) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_stop_description (4562318378766987601) -->
+ <skip />
<string name="emergency_calls_only" msgid="6733978304386365407">"Само спешни обаждания"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Мрежата е заключена"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM картата е заключена с PUK."</string>
@@ -690,6 +704,14 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Отключване"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Включване на звука"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Изключване на звука"</string>
+ <!-- no translation found for lockscreen_access_pattern_start (3941045502933142847) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_cleared (5583479721001639579) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_cell_added (6756031208359292487) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_detected (4988730895554057058) -->
+ <skip />
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"АБВ"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +877,7 @@
<string name="cut" msgid="3092569408438626261">"Изрязване"</string>
<string name="copy" msgid="2681946229533511987">"Копиране"</string>
<string name="paste" msgid="5629880836805036433">"Поставяне"</string>
- <string name="replace" msgid="5781686059063148930">"Замяна???"</string>
+ <string name="replace" msgid="5781686059063148930">"Замяна..."</string>
<string name="delete" msgid="6098684844021697789">"Изтриване"</string>
<string name="copyUrl" msgid="2538211579596067402">"Копиране на URL адреса"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Избиране на текст..."</string>
@@ -1144,6 +1166,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Промяна на режима"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Избор на приложение"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Споделяне със"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Споделяне със: <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Плъзгаща се дръжка. Докоснете и задръжте."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Надолу за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1178,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
<string name="description_target_silent" msgid="893551287746522182">"Тих режим"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Включване на звука"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Клавиш. Необходими са слушалки, за да чуете клавишите при въвеждането на парола."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Включете слушалки, за да чуете клавишите за паролата на висок глас."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Точка."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Придвижване към „Начало“"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Придвижване нагоре"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Още опции"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index c25fc30..ec454a7 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -158,16 +158,16 @@
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Serveis de pagament"</string>
<string name="permgroupdesc_costMoney" msgid="8193824940620517189">"Permet a les aplicacions dur a terme activitats de pagament."</string>
- <string name="permgrouplab_messages" msgid="7521249148445456662">"Els vostres missatges"</string>
+ <string name="permgrouplab_messages" msgid="7521249148445456662">"Missatges"</string>
<string name="permgroupdesc_messages" msgid="7045736972019211994">"Llegeix i escriu SMS, correu electrònic i altres missatges."</string>
- <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"La vostra informació personal"</string>
+ <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Informació personal"</string>
<string name="permgroupdesc_personalInfo" product="tablet" msgid="6975389054186265786">"Accés directe als contactes i al calendari emmagatzemat a la tauleta."</string>
<string name="permgroupdesc_personalInfo" product="default" msgid="5488050357388806068">"Accés directe als contactes i al calendari emmagatzemats al telèfon."</string>
- <string name="permgrouplab_location" msgid="635149742436692049">"La vostra ubicació"</string>
+ <string name="permgrouplab_location" msgid="635149742436692049">"Ubicació"</string>
<string name="permgroupdesc_location" msgid="2430258821648348660">"Supervisa la ubicació física"</string>
<string name="permgrouplab_network" msgid="5808983377727109831">"Comunicació de xarxa"</string>
<string name="permgroupdesc_network" msgid="5035763698958415998">"Permet a les aplicacions accedir a diverses funcions de xarxa."</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Els vostres comptes"</string>
+ <string name="permgrouplab_accounts" msgid="3359646291125325519">"Comptes"</string>
<string name="permgroupdesc_accounts" msgid="4948732641827091312">"Accedeix als comptes disponibles."</string>
<string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Controls de maquinari"</string>
<string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Accés directe al maquinari del telèfon."</string>
@@ -252,7 +252,7 @@
<string name="permdesc_confirm_full_backup" msgid="9005017754175897954">"Permet que l\'aplicació iniciï la IU de confirmació de còpia de seguretat completa. No pot utilitzar-ho qualsevol aplicació."</string>
<string name="permlab_internalSystemWindow" msgid="2148563628140193231">"visualitzar finestres no autoritzades"</string>
<string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Permet la creació de finestres que utilitzarà la interfície d\'usuari del sistema interna. No indicat per a les aplicacions normals."</string>
- <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"visualitzar les alertes del sistema"</string>
+ <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"mostrar les alertes del sistema"</string>
<string name="permdesc_systemAlertWindow" msgid="2884149573672821318">"Permet que una aplicació mostri finestres d\'alertes del sistema. Les aplicacions malicioses poden ocupar tota la pantalla."</string>
<string name="permlab_setAnimationScale" msgid="2805103241153907174">"modificar la velocitat d\'animacions global"</string>
<string name="permdesc_setAnimationScale" msgid="7181522138912391988">"Permet a una aplicació canviar la velocitat global d\'animació (animacions més ràpides o lentes) en qualsevol moment."</string>
@@ -293,12 +293,12 @@
<string name="permdesc_getPackageSize" msgid="5557253039670753437">"Permet a una aplicació recuperar les mides del codi, de les dades i de la memòria cau"</string>
<string name="permlab_installPackages" msgid="335800214119051089">"instal·lar aplicacions directament"</string>
<string name="permdesc_installPackages" msgid="526669220850066132">"Permet a una aplicació instal·lar paquets d\'Android nous o actualitzats. Les aplicacions malicioses poden utilitzar-ho per afegir aplicacions noves amb permisos arbitràriament potents."</string>
- <string name="permlab_clearAppCache" msgid="4747698311163766540">"suprimir totes les dades de memòria cau d\'aplicacions"</string>
+ <string name="permlab_clearAppCache" msgid="4747698311163766540">"eliminar totes les dades de memòria cau d\'aplicacions"</string>
<string name="permdesc_clearAppCache" product="tablet" msgid="3097119797652477973">"Permet que una aplicació alliberi emmagatzematge de la tauleta suprimint fitxers al directori de la memòria cau de l\'aplicació. Habitualment, l\'accés és molt restringit a processos del sistema."</string>
<string name="permdesc_clearAppCache" product="default" msgid="7740465694193671402">"Permet a una aplicació alliberar emmagatzematge al telèfon suprimint fitxers del directori de la memòria cau d\'aplicacions. Normalment l\'accés es restringeix als processos del sistema."</string>
<string name="permlab_movePackage" msgid="728454979946503926">"Desplaça els recursos de les aplicacions"</string>
<string name="permdesc_movePackage" msgid="6323049291923925277">"Permet a una aplicació desplaçar els recursos d\'aplicació de suports interns a externs i viceversa."</string>
- <string name="permlab_readLogs" msgid="6615778543198967614">"llegeix les dades sensibles del registre"</string>
+ <string name="permlab_readLogs" msgid="6615778543198967614">"llegir dades de registre personals"</string>
<string name="permdesc_readLogs" product="tablet" msgid="4077356893924755294">"Permet que una aplicació llegeixi els diversos fitxers de registre del sistema. Això li permet descobrir informació general sobre què estàs fent amb la tauleta, i pot incloure informació personal o privada."</string>
<string name="permdesc_readLogs" product="default" msgid="8896449437464867766">"Permet que una aplicació llegeixi els diversos fitxers de registre del sistema. Això li permet descobrir informació general sobre què estàs fent amb el telèfon i, potencialment, pot incloure informació personal o privada."</string>
<string name="permlab_diagnostic" msgid="8076743953908000342">"llegir/escriure recursos propietat de diag"</string>
@@ -307,7 +307,7 @@
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Permet que una aplicació canviï si un component d\'una altra aplicació està activat o no. Les aplicacions malicioses poden utilitzar aquesta funció per desactivar funcions importants de la tauleta. Cal anar amb compte amb aquest permís, ja que és possible que els components d\'una aplicació esdevinguin inutilitzables, incoherents o inestables."</string>
<string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Permet que una aplicació canviï si un component d\'una altra aplicació està activat o no. Les aplicacions malicioses poden utilitzar aquesta funció per desactivar funcions importants del telèfon. Cal anar amb compte amb aquest permís, ja que és possible que els components d\'una aplicació esdevinguin inutilitzables, incoherents o inestables."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"definir les aplicacions preferides"</string>
- <string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Permet a una aplicació modificar les aplicacions preferides. Això pot permetre a les aplicacions malicioses canviar silenciosament les aplicacions que s\'executen, falsejar les aplicacions existents o recollir dades privades vostres."</string>
+ <string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Permet a una aplicació modificar les aplicacions preferides. Això pot permetre a les aplicacions malicioses canviar silenciosament les aplicacions que s\'executen, falsejar les aplicacions existents o recollir dades privades de l\'usuari."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modificar la configuració global del sistema"</string>
<string name="permdesc_writeSettings" msgid="838789419871034696">"Permet a una aplicació modificar les dades de configuració del sistema. Les aplicacions malicioses poden malmetre la configuració del sistema."</string>
<string name="permlab_writeSecureSettings" msgid="204676251876718288">"modificar la configuració de seguretat del sistema"</string>
@@ -320,9 +320,9 @@
<string name="permlab_broadcastSticky" msgid="7919126372606881614">"enviar difusió permanent"</string>
<string name="permdesc_broadcastSticky" product="tablet" msgid="6322249605930062595">"Permet que una aplicació enviï transmissions \"enganxoses\" que es queden al sistema un cop finalitzada la transmissió. Les aplicacions malicioses poden alentir la tauleta o fer-la inestable en provocar que utilitzi massa memòria."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="1920045289234052219">"Permet a una aplicació enviar difusions permanents, que es conserven després de finalitzar la difusió. Les aplicacions malicioses poden alentir o desestabilitzar el telèfon en fer-li utilitzar massa memòria."</string>
- <string name="permlab_readContacts" msgid="6219652189510218240">"llegir les dades de contacte"</string>
+ <string name="permlab_readContacts" msgid="6219652189510218240">"llegir dades de contacte"</string>
<string name="permdesc_readContacts" product="tablet" msgid="7596158687301157686">"Permet que una aplicació llegeixi totes les dades dels contactes (adreces) de la tauleta. Les aplicacions malicioses poden utilitzar aquesta funció per enviar dades a altres persones."</string>
- <string name="permdesc_readContacts" product="default" msgid="3371591512896545975">"Permet a una aplicació llegir totes les dades de contacte (adreces) emmagatzemades al telèfon. Les aplicacions malicioses poden utilitzar-ho per enviar les vostres dades a altres persones."</string>
+ <string name="permdesc_readContacts" product="default" msgid="3371591512896545975">"Permet a una aplicació llegir totes les dades de contacte (adreces) emmagatzemades al telèfon. Les aplicacions malicioses poden utilitzar-ho per enviar les teves dades a altres persones."</string>
<string name="permlab_writeContacts" msgid="644616215860933284">"escriure dades de contacte"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="7782689510038568495">"Permet que una aplicació modifiqui les dades de contactes (adreces) emmagatzemades a la tauleta. Les aplicacions malicioses poden utilitzar aquesta funció per esborrar o per modificar les teves dades de contactes."</string>
<string name="permdesc_writeContacts" product="default" msgid="3924383579108183601">"Permet a una aplicació modificar les dades de contacte (adreça) emmagatzemades al telèfon. Les aplicacions malicioses poden utilitzar-ho per esborrar o modificar les dades de contacte."</string>
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Permet que l\'aplicació pugui llegir la informació del perfil personal emmagatzemada al dispositiu, com ara el teu nom i la teva informació de contacte. Això significa que l\'aplicació et pot identificar i enviar la informació del teu perfil a altres persones."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"escriptura a les teves dades del perfil"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Permet que l\'aplicació pugui canviar o afegir a la informació del perfil personal emmagatzemada al dispositiu, com ara el teu nom i la teva informació de contacte. Això significa que altres aplicacions et poden identificar i enviar la informació del teu perfil a altres persones."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"llegeix el teu tauler d\'activitat social"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Permet que l\'aplicació accedeixi a les teves actualitzacions socials i a les dels teus amics i que les sincronitzi. Les aplicacions malicioses poden fer servir aquesta funció per llegir comunicacions privades entre tu i els teus amics a les xarxes socials."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"escriu al tauler d\'activitat social"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Permet que l\'aplicació mostri actualitzacions socials dels teus amics. Les aplicacions malicioses poden fer servir aquesta funció per fer-se passar per amics teus i per enganyar-te per tal que els revelis contrasenyes o altra informació confidencial."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"llegeix els esdeveniments del calendari més informació confidencial"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Permet que una aplicació llegeixi tots els esdeveniments de calendari emmagatzemats a la tauleta, inclosos els dels seus amics o els seus companys de feina. Una aplicació maliciosa amb aquest permís pot extreure informació personal d\'aquests calendaris sense el coneixement dels propietaris."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Permet que una aplicació llegeixi tots els esdeveniments de calendari emmagatzemats al telèfon, inclosos els dels seus amics o els teus companys de feina. Una aplicació maliciosa amb aquest permís pot extreure informació personal d\'aquests calendaris sense que ho sàpiguen els propietaris."</string>
@@ -365,7 +369,7 @@
<string name="permlab_reboot" product="default" msgid="2898560872462638242">"forçar el reinici del telèfon"</string>
<string name="permdesc_reboot" product="tablet" msgid="4555793623560701557">"Permet que l\'aplicació faci que es reiniciï la tauleta."</string>
<string name="permdesc_reboot" product="default" msgid="7914933292815491782">"Permet a l\'aplicació forçar el reinici del telèfon."</string>
- <string name="permlab_mount_unmount_filesystems" msgid="1761023272170956541">"muntar i desmuntar sistemes de fitxers"</string>
+ <string name="permlab_mount_unmount_filesystems" msgid="1761023272170956541">"activar i desactivar sistemes de fitxers"</string>
<string name="permdesc_mount_unmount_filesystems" msgid="6253263792535859767">"Permet a l\'aplicació muntar i desmuntar sistemes de fitxers per a l\'emmagatzematge extraïble."</string>
<string name="permlab_mount_format_filesystems" msgid="5523285143576718981">"formatar l\'emmagatzematge extern"</string>
<string name="permdesc_mount_format_filesystems" msgid="574060044906047386">"Permet a l\'aplicació formatar l\'emmagatzematge extraïble."</string>
@@ -417,7 +421,7 @@
<string name="permlab_factoryTest" msgid="3715225492696416187">"executar en mode de proves de fàbrica"</string>
<string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Executa com a prova de perfil baix del fabricant que permet accés complet al maquinari de la tauleta. Només està disponible quan la tauleta s\'executa en mode de prova del fabricant."</string>
<string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"S\'executa com a prova del fabricant de baix nivell, cosa que permet l\'accés total al maquinari del telèfon. Només està disponible quan un telèfon s\'executa en mode de proves del fabricant."</string>
- <string name="permlab_setWallpaper" msgid="6627192333373465143">"definir l\'empaperat"</string>
+ <string name="permlab_setWallpaper" msgid="6627192333373465143">"definir fons de pantalla"</string>
<string name="permdesc_setWallpaper" msgid="6417041752170585837">"Permet l\'aplicació definir l\'empaperat del sistema."</string>
<string name="permlab_setWallpaperHints" msgid="3600721069353106851">"definir els suggeriments de mida de l\'empaperat"</string>
<string name="permdesc_setWallpaperHints" msgid="6019479164008079626">"Permet a l\'aplicació definir els suggeriments de mida del l\'empaperat del sistema."</string>
@@ -431,7 +435,7 @@
<string name="permdesc_setTimeZone" product="default" msgid="1902540227418179364">"Permet a una aplicació canviar el fus horari del telèfon."</string>
<string name="permlab_accountManagerService" msgid="4829262349691386986">"actuar com a AccountManagerService"</string>
<string name="permdesc_accountManagerService" msgid="6056903274106394752">"Permet a una aplicació fer trucades a autenticadors de comptes"</string>
- <string name="permlab_getAccounts" msgid="4549918644233460103">"descobrir comptes coneguts"</string>
+ <string name="permlab_getAccounts" msgid="4549918644233460103">"detectar comptes coneguts"</string>
<string name="permdesc_getAccounts" product="tablet" msgid="857622793935544694">"Permet que una aplicació obtingui la llista de comptes coneguts per la tauleta."</string>
<string name="permdesc_getAccounts" product="default" msgid="6839262446413155394">"Permet a una aplicació obtenir la llista de comptes que coneix el telèfon."</string>
<string name="permlab_authenticateAccounts" msgid="3940505577982882450">"fer d\'autenticador de comptes"</string>
@@ -450,8 +454,8 @@
<string name="permdesc_changeNetworkState" msgid="4199958910396387075">"Permet a una aplicació canviar l\'estat de la connectivitat de xarxa."</string>
<string name="permlab_changeTetherState" msgid="2702121155761140799">"Canvia la connectivitat ancorada a la xarxa"</string>
<string name="permdesc_changeTetherState" msgid="8905815579146349568">"Permet a una aplicació canviar l\'estat de la connectivitat de xarxa d\'ancoratge."</string>
- <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"canviar la configuració d\'ús de dades en segon terme"</string>
- <string name="permdesc_changeBackgroundDataSetting" msgid="1001482853266638864">"Permet a una aplicació canviar la configuració d\'ús de les dades en segon terme."</string>
+ <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"canviar la configuració d\'ús de dades de referència"</string>
+ <string name="permdesc_changeBackgroundDataSetting" msgid="1001482853266638864">"Permet a una aplicació canviar la configuració d\'ús de les dades de referència."</string>
<string name="permlab_accessWifiState" msgid="8100926650211034400">"visualitzar l\'estat de la Wi-fi"</string>
<string name="permdesc_accessWifiState" msgid="485796529139236346">"Permet a una aplicació visualitzar la informació de l\'estat de la Wi-fi."</string>
<string name="permlab_changeWifiState" msgid="7280632711057112137">"canviar l\'estat de la Wi-fi"</string>
@@ -482,15 +486,15 @@
<string name="permdesc_readDictionary" msgid="1082972603576360690">"Permet a una aplicació llegir les paraules, els noms i les frases privats que l\'usuari pot haver emmagatzemat al diccionari de l\'usuari."</string>
<string name="permlab_writeDictionary" msgid="6703109511836343341">"escriure al diccionari definit per l\'usuari"</string>
<string name="permdesc_writeDictionary" msgid="2241256206524082880">"Permet a una aplicació escriure paraules noves al diccionari de l\'usuari."</string>
- <string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"modifica/suprimeix el contingut de l\'emmagatzematge USB"</string>
- <string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"modificar/suprimir el contingut de les targetes SD"</string>
+ <string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"modificar/esborrar contingut USB"</string>
+ <string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"modificar/esborrar contingut de la targeta SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Permet que una aplicació gravii a l\'emmagatzematge USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Permet a una aplicació escriure a la targeta SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Canvia/esborra emmagatz. intern"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Permet que una aplicació modifiqui el contingut de l\'emmagatzematge multimèdia intern."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"accedir al sistema de fitxers de la memòria cau"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Permet a una aplicació llegir el sistema de fitxers de la memòria cau i escriure-hi."</string>
- <string name="permlab_use_sip" msgid="5986952362795870502">"fes/rep trucades per Internet"</string>
+ <string name="permlab_use_sip" msgid="5986952362795870502">"fer/rebre trucades per Internet"</string>
<string name="permdesc_use_sip" msgid="6320376185606661843">"Permet que una aplicació utilitzi el servei SIP per fer i rebre trucades per Internet."</string>
<string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"lectura de l\'ús històric de la xarxa"</string>
<string name="permdesc_readNetworkUsageHistory" msgid="6040738474779135653">"Permet que una aplicació llegeixi l\'ús històric de la xarxa per a xarxes i aplicacions específiques."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Inseriu una targeta SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Falta la targeta SIM o no es pot llegir. Insereix-ne una."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"La targeta SIM està desactivada permanentment. "\n" Contacta amb el teu proveïdor de serveis sense fil per obtenir-ne una altra."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Botó de pista anterior"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Botó de pista següent"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Botó de pausa"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Botó de reproducció"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Botó de parada"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Només trucades d\'emergència"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Xarxa bloquejada"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"La targeta SIM està bloquejada pel PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloqueja"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"So activat"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"So desactivat"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Patró iniciat"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Patró esborrat"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"S\'ha afegit una cel·la"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Patró completat"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"Retalla"</string>
<string name="copy" msgid="2681946229533511987">"Copia"</string>
<string name="paste" msgid="5629880836805036433">"Enganxa"</string>
- <string name="replace" msgid="5781686059063148930">"Vols substituir?"</string>
+ <string name="replace" msgid="5781686059063148930">"Vols substituir..."</string>
<string name="delete" msgid="6098684844021697789">"Suprimeix"</string>
<string name="copyUrl" msgid="2538211579596067402">"Copia l\'URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Selecciona el text..."</string>
@@ -967,7 +980,7 @@
<string name="date_time_set" msgid="5777075614321087758">"Defineix"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predeterminat"</string>
<string name="no_permissions" msgid="7283357728219338112">"No cal cap permís"</string>
- <string name="perms_hide" msgid="7283915391320676226"><b>"Oamaga"</b></string>
+ <string name="perms_hide" msgid="7283915391320676226"><b>"Amaga"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mostra\'ls tots"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"Emmagatzematge massiu USB"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB connectat"</string>
@@ -1055,7 +1068,7 @@
<string name="input_method_binding_label" msgid="1283557179944992649">"Mètode d\'entrada"</string>
<string name="sync_binding_label" msgid="3687969138375092423">"Sincronització"</string>
<string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibilitat"</string>
- <string name="wallpaper_binding_label" msgid="1240087844304687662">"Empaperat"</string>
+ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fons de pantalla"</string>
<string name="chooser_wallpaper" msgid="7873476199295190279">"Canvi de l\'empaperat"</string>
<string name="vpn_title" msgid="8219003246858087489">"VPN activada."</string>
<string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> ha activat VPN"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Canvi de mode"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Maj"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Retorn"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Selecciona una aplicació"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Comparteix amb"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Comparteix amb <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Llisca el dit. Mantén premut."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Cap amunt per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Cap avall per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Càmera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Silenci"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Activa el so"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Tecles. Es necessiten auriculars per escoltar les tecles en escriure una contrasenya."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Connecta un auricular per escoltar les claus de la contrasenya en veu alta."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punt."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Torna a la pàgina d\'inici"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Mou cap a dalt"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Més opcions"</string>
@@ -1173,7 +1190,7 @@
<string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"S\'ha superat el límit de dades mòbils"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"S\'ha superat el límit de dades Wi-Fi"</string>
<string name="data_usage_limit_snoozed_body" msgid="2932736326652880660">"<xliff:g id="SIZE">%s</xliff:g> per sobre del límit especificat"</string>
- <string name="data_usage_restricted_title" msgid="5965157361036321914">"S\'han restringit dades de fons"</string>
+ <string name="data_usage_restricted_title" msgid="5965157361036321914">"Dades de referència restringides"</string>
<string name="data_usage_restricted_body" msgid="5087354814839059798">"Toca per eliminar la restricció"</string>
<string name="ssl_certificate" msgid="6510040486049237639">"Certificat de seguretat"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Aquest certificat és vàlid."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 1ee3bfc..f3aa280 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Umožňuje aplikaci číst osobní informace o profilu uložené ve vašem zařízení, jako je jméno a kontaktní informace. To znamená, že vás aplikace může identifikovat a odesílat informace o profilu ostatním."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"zapisovat do údajů o profilu"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Umožňuje aplikaci měnit a přidávat osobní informace o profilu uložené ve vašem zařízení, jako je jméno a kontaktní informace. To znamená, že vás aplikace může identifikovat a odesílat informace o profilu ostatním."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"číst váš sociální stream"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Umožňuje aplikaci přístup k sociálním aktualizacím od vás a vašich přátel a synchronizaci těchto aktualizací. Škodlivé aplikace toho mohou využít ke čtení soukromé komunikace mezi vámi a vašimi přáteli v sociálních sítích."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"zapisovat do vašeho sociálního streamu"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Umožňuje aplikaci zobrazit sociální aktualizace od vašich přátel. Škodlivé aplikace toho mohou využít k předstírání, že jsou vašimi přáteli, a snažit se vás tak přimět k prozrazení hesel nebo jiných důvěrných informací."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"číst události kalendáře a důvěrné informace"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Povolí aplikaci číst všechny události kalendáře uložené ve vašem tabletu, včetně událostí vašich přátel a spolupracovníků. Škodlivá aplikace s tímto oprávněním může z těchto kalendářů extrahovat osobní údaje, aniž by o tom vlastník věděl."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Povolí aplikaci číst všechny události kalendáře uložené ve vašem telefonu, včetně událostí vašich přátel a spolupracovníků. Škodlivá aplikace s tímto oprávněním může z těchto kalendářů extrahovat osobní údaje, aniž by o tom vlastník věděl."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Prosím vložte kartu SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Karta SIM chybí nebo je nečitelná. Vložte prosím kartu SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Vaše karta SIM byla natrvalo zablokována."\n" Další kartu SIM obdržíte u svého poskytovatele bezdrátových služeb."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Tlačítko Předchozí stopa"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Tlačítko Další stopa"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Tlačítko Pozastavit"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Tlačítko Přehrát"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Tlačítko Zastavit"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Pouze tísňová volání"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Síť je blokována"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Karta SIM je zablokována pomocí kódu PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Odemknout"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Zapnout zvuk"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Vypnout zvuk"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Bezpečnostní gesto zahájeno"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Bzpečnostní gesto vymazáno"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Buňka přidána"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Bezpečnostní gesto dokončeno"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"Alt"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"Vyjmout"</string>
<string name="copy" msgid="2681946229533511987">"Kopírovat"</string>
<string name="paste" msgid="5629880836805036433">"Vložit"</string>
- <string name="replace" msgid="5781686059063148930">"Nahradit???"</string>
+ <string name="replace" msgid="5781686059063148930">"Nahradit•"</string>
<string name="delete" msgid="6098684844021697789">"Smazat"</string>
<string name="copyUrl" msgid="2538211579596067402">"Kopírovat adresu URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Vybrat text..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Změna režimu"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Zvolit aplikaci"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Sdílet s"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Sdílet s aplikací <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Posuvník. Klepněte a podržte."</string>
<string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> – nahoru."</string>
<string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> – dolů."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Fotoaparát"</string>
<string name="description_target_silent" msgid="893551287746522182">"Tichý"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Zapnout zvuk"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Klávesa. Při zadávání hesla je potřeba použít náhlavní soupravu."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Chcete-li slyšet, které klávesy jste při zadávání hesla stiskli, připojte sluchátka."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Tečka."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Přejít na plochu"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Přejít nahoru"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Další možnosti"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index a4efb61..4e98da8 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Tillader programmet at læse personlige profiloplysninger, som er gemt på din enhed. Disse kan f.eks. være dit navn og dine kontaktoplysninger. Dette betyder, at applikationen kan identificere dig og sende dine profiloplysninger til andre."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"skrive til dine profildata"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Tillader programmet at ændre eller føje til personlige profiloplysninger, som er gemt på din enhed. Disse kan f.eks. være dit navn og dine kontaktoplysninger. Dette betyder, at andre applikationer kan identificere dig og sende dine profiloplysninger til andre."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"læs din sociale strøm"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Tillader, at applikationen får adgang til og synkroniserer sociale opdateringer fra dig og dine venner. Ondsindede apps kan bruge dette til at læse privat kommunikation mellem dig og dine venner på sociale netværk."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skriv i din sociale strøm"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Tillader, at applikationen viser sociale opdateringer fra dine venner. Ondsindede apps kan bruge dette til at foregive at være en ven og narre dig til at afsløre adgangskoder eller andre fortrolige oplysninger."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"læs kalenderbegivenheder plus fortrolige oplysninger"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Tillader, at en applikation kan læse alle kalenderbegivenheder, der er gemt på din tablet, herunder dem venners eller kollegers. En ondsindet applikation med denne tilladelse kan udtrække personlige oplysninger fra disse kalendere uden ejernes viden."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Tillader, at en applikation kan læse alle kalenderbegivenheder gemt på din telefon, herunder dem af venner eller kolleger. En ondsindet applikation med denne tilladelse kan udtrække personlige oplysninger fra disse kalendere uden ejernes viden."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Indsæt et SIM-kort."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"SIM-kortet mangler eller kan ikke læses. Indsæt et SIM-kort."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Dit SIM-kort er permanent deaktiveret."\n"Kontakt dit mobilselskab for at få et nyt SIM-kort."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Knap til forrige nummer"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Knap til næste nummer"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pause-knap"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Afspil-knappen"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Stop-knap"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Kun nødopkald"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Netværket er låst"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-kortet er låst med PUK-koden."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Lås op"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Lyd slået til"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Lyd slået fra"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Mønster er begyndt"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Mønster er ryddet"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Celle er tilføjet"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Mønster er afsluttet"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Ændring af tilstand"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Angiv"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Vælg en applikation"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Del med"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Del med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Glidende håndtag. Tryk og hold nede."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Op for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Ned for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Lydløs"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Lyd slået til"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Tast. Du skal bruge et headset for at høre tastelyde, når du indtaster en adgangskode."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Tilslut et headset for at få læst taster højt, når du indtaster en adgangskode."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punktum."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Naviger hjem"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Naviger op"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Flere valgmuligheder"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index f33e2f4..4a83ae8 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -160,14 +160,14 @@
<string name="permgroupdesc_costMoney" msgid="8193824940620517189">"Ermöglicht Anwendungen die Ausführung eventuell kostenpflichtiger Aktionen"</string>
<string name="permgrouplab_messages" msgid="7521249148445456662">"Ihre Nachrichten"</string>
<string name="permgroupdesc_messages" msgid="7045736972019211994">"Lesen und schreiben Sie Ihre SMS, E-Mails und anderen Nachrichten."</string>
- <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Ihre persönlichen Informationen"</string>
+ <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Meine persönlichen Informationen"</string>
<string name="permgroupdesc_personalInfo" product="tablet" msgid="6975389054186265786">"Direkter Zugriff auf die Kontakte und den Kalender Ihres Tablets"</string>
<string name="permgroupdesc_personalInfo" product="default" msgid="5488050357388806068">"Direkter Zugriff auf die Kontakte und den Kalender Ihres Telefons"</string>
<string name="permgrouplab_location" msgid="635149742436692049">"Meinen Standort"</string>
<string name="permgroupdesc_location" msgid="2430258821648348660">"Ihren physischen Standort überwachen"</string>
<string name="permgrouplab_network" msgid="5808983377727109831">"Netzwerkkommunikation"</string>
<string name="permgroupdesc_network" msgid="5035763698958415998">"Ermöglicht Anwendungen den Zugriff auf verschiedene Netzwerkfunktionen"</string>
- <string name="permgrouplab_accounts" msgid="3359646291125325519">"Ihre Konten"</string>
+ <string name="permgrouplab_accounts" msgid="3359646291125325519">"Meine Konten"</string>
<string name="permgroupdesc_accounts" msgid="4948732641827091312">"Zugriff auf verfügbare Konten"</string>
<string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Hardware-Steuerelemente"</string>
<string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Direkter Zugriff auf Hardware über Headset"</string>
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Ermöglicht der App, auf Ihrem Gerät gespeicherte persönliche Profilinformationen einzusehen, darunter Ihren Namen und Ihre Kontaktinformationen. Die App kann Sie somit identifizieren und Ihre Profilinformationen an andere senden."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"In Ihre Profildaten schreiben"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Ermöglicht der App, auf Ihrem Gerät gespeicherte persönliche Profilinformationen zu ändern, darunter Ihren Namen und Ihre Kontaktinformationen, sowie Informationen hinzuzufügen. Andere Apps können Sie somit identifizieren und Ihre Profilinformationen an andere senden."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"In sozialem Stream lesen"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Diese Berechtigung ermöglicht der App, auf soziale Updates von Ihnen und Ihren Freunden zuzugreifen und diese zu synchronisieren. Schädliche Apps können mithilfe dieser Berechtigung private Kommunikationen zwischen Ihnen und Ihren Freunden in sozialen Netzwerken lesen."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"In sozialem Stream schreiben"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Diese Berechtigung ermöglicht der App, soziale Updates Ihrer Freunde anzuzeigen. Schädliche Apps können sich mithilfe dieser Berechtigung als Freund von Ihnen ausgeben, um an Ihre Passwörter oder andere vertrauliche Informationen zu gelangen."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"Kalendertermine sowie vertrauliche Informationen lesen"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Ermöglicht einer App das Lesen aller Kalendertermine, die auf Ihrem Tablet gespeichert sind, einschließlich der Termine von Freunden oder Kollegen. Schädliche Apps mit dieser Berechtigung können aus diesen Kalendern ohne das Wissen der Eigentümer persönliche Informationen extrahieren."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Ermöglicht einer App das Lesen aller Kalendertermine, die auf Ihrem Telefon gespeichert sind, einschließlich der Termine von Freunden oder Kollegen. Schädliche Apps mit dieser Berechtigung können aus diesen Kalendern ohne das Wissen der Eigentümer persönliche Informationen extrahieren."</string>
@@ -341,7 +345,7 @@
<string name="permdesc_accessLocationExtraCommands" msgid="1948144701382451721">"Zugriff auf zusätzliche Dienstanbieterbefehle für Standort. Schädliche Anwendungen könnten so die Funktionsweise von GPS oder anderen Standortquellen beeinträchtigen."</string>
<string name="permlab_installLocationProvider" msgid="6578101199825193873">"Berechtigung zur Installation eines Standortanbieters"</string>
<string name="permdesc_installLocationProvider" msgid="5449175116732002106">"Erstellt falsche Standortquellen für Testzwecke. Schädliche Anwendungen können so den von den echten Standortquellen wie GPS oder Netzwerkanbieter zurückgegebenen Standort und/oder Status überschreiben oder Ihren Standort überwachen und an eine externe Quelle weitergeben."</string>
- <string name="permlab_accessFineLocation" msgid="8116127007541369477">"genauer (GPS-) Standort"</string>
+ <string name="permlab_accessFineLocation" msgid="8116127007541369477">"Genauer (GPS-) Standort"</string>
<string name="permdesc_accessFineLocation" product="tablet" msgid="243973693233359681">"Zugriff auf genaue Standortquellen wie GPS auf dem Tablet (falls verfügbar). Schädliche Anwendungen können damit bestimmen, wo Sie sich befinden und so Ihren Akku zusätzlich belasten."</string>
<string name="permdesc_accessFineLocation" product="default" msgid="7411213317434337331">"Zugriff auf genaue Standortquellen wie GPS auf dem Telefon (falls verfügbar). Schädliche Anwendungen können damit bestimmen, so Sie sich befinden und so Ihren Akku zusätzlich belasten."</string>
<string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"ungefährer (netzwerkbasierter) Standort"</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Bitte legen Sie eine SIM-Karte ein."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"SIM-Karte fehlt oder ist nicht lesbar. Bitte legen Sie eine SIM-Karte ein."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Ihre SIM-Karte wurde dauerhaft deaktiviert."\n" Bitte wenden Sie sich an Ihren Mobilfunkanbieter, um eine andere SIM-Karte zu erhalten."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Schaltfläche für vorherigen Track"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Schaltfläche für nächsten Track"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Schaltfläche für Pause"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Schaltfläche für Wiedergabe"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Schaltfläche für Stopp"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Nur Notrufe"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Netzwerk gesperrt"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"PUK-Sperre auf SIM"</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Entsperren"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ton ein"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Ton aus"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Muster gestartet"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Muster gelöscht"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Zelle hinzugefügt"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Muster abgeschlossen"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -705,7 +718,7 @@
<string name="save_password_label" msgid="6860261758665825069">"Bestätigen"</string>
<string name="double_tap_toast" msgid="1068216937244567247">"Tipp: Zum Heranzoomen und Vergrößern zweimal tippen"</string>
<string name="autofill_this_form" msgid="1272247532604569872">"AutoFill"</string>
- <string name="setup_autofill" msgid="8154593408885654044">"AutoFill-Setup"</string>
+ <string name="setup_autofill" msgid="8154593408885654044">"AutoFill-Einrichtung"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -873,7 +886,7 @@
<string name="no" msgid="5141531044935541497">"Abbrechen"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Achtung"</string>
<string name="loading" msgid="1760724998928255250">"Wird geladen..."</string>
- <string name="capital_on" msgid="1544682755514494298">"EIN"</string>
+ <string name="capital_on" msgid="1544682755514494298">"AN"</string>
<string name="capital_off" msgid="6815870386972805832">"AUS"</string>
<string name="whichApplication" msgid="4533185947064773386">"Aktion durchführen mit"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Standardmäßig für diese Aktion verwenden"</string>
@@ -1096,7 +1109,7 @@
<string name="media_shared" product="nosdcard" msgid="5830814349250834225">"Der USB-Speicher wird zurzeit von einem Computer verwendet."</string>
<string name="media_shared" product="default" msgid="5706130568133540435">"Die SD-Karte wird zurzeit von einem Computer verwendet."</string>
<string name="media_unknown_state" msgid="729192782197290385">"Unbekannter Status des externen Speichermediums"</string>
- <string name="share" msgid="1778686618230011964">"Weitergeben"</string>
+ <string name="share" msgid="1778686618230011964">"Teilen"</string>
<string name="find" msgid="4808270900322985960">"Suchen"</string>
<string name="websearch" msgid="4337157977400211589">"Websuche"</string>
<string name="gpsNotifTicker" msgid="5622683912616496172">"Standortabfrage von <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1133,7 +1146,7 @@
<string name="checkbox_not_checked" msgid="5174639551134444056">"Nicht aktiviert"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"Ausgewählt"</string>
<string name="radiobutton_not_selected" msgid="2908760184307722393">"Nicht ausgewählt"</string>
- <string name="switch_on" msgid="551417728476977311">"Ein"</string>
+ <string name="switch_on" msgid="551417728476977311">"An"</string>
<string name="switch_off" msgid="7249798614327155088">"Aus"</string>
<string name="togglebutton_pressed" msgid="4180411746647422233">"Gedrückt"</string>
<string name="togglebutton_not_pressed" msgid="4495147725636134425">"Nicht gedrückt"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modusänderung"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Umschalttaste"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Eingabetaste"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"App wählen"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Teilen mit"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Mit <xliff:g id="APPLICATION_NAME">%s</xliff:g> teilen"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Schieberegler: Tippen und halten"</string>
<string name="description_direction_up" msgid="1983114130441878529">"Für <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach oben"</string>
<string name="description_direction_down" msgid="4294993639091088240">"Für <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach unten"</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Lautlos"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Ton ein"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Zum Hören der Tasten bei der Eingabe eines Passworts ist ein Headset erforderlich."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Schließen Sie ein Headset an, um das Passwort gesprochen zu hören."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punkt."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Zur Startseite navigieren"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Nach oben navigieren"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Weitere Optionen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 8778744..ac48934 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Επιτρέπει στην εφαρμογή να διαβάζει τις πληροφορίες του προσωπικού προφίλ που έχουν αποθηκευτεί στη συσκευή σας, όπως το όνομα και τα στοιχεία επικοινωνίας σας. Αυτό σημαίνει ότι η εφαρμογή μπορεί να σας αναγνωρίσει και να στείλει πληροφορίες του προφίλ σας σε άλλους."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"εγγρ. σε δεδ. προφίλ"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Επιτρέπει στην εφαρμογή την αλλαγή ή την προσθήκη στο προσωπικό προφίλ πληροφοριών οι οποίες έχουν αποθηκευτεί στη συσκευή σας, όπως το όνομα και τα στοιχεία επικοινωνίας σας. Αυτό σημαίνει ότι άλλες εφαρμογές μπορούν να σας αναγνωρίσουν και να στείλουν πληροφορίες του προφίλ σας σε άλλους."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"διαβάστε τη ροή σας κοινωνικών δικτύων"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Επιτρέπει στην εφαρμογή να έχει πρόσβαση και να συγχρονίζει τις ενημερώσεις κοινωνικού περιεχομένου από τους φίλους σας. Κακόβουλες εφαρμογές μπορούν να το χρησιμοποιήσουν για να διαβάσουν απόρρητες επικοινωνίες μεταξύ εσάς και των φίλων σας σε κοινωνικά δίκτυα."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"γράψτε στη ροή σας κοινωνικών δικτύων"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Επιτρέπει στην εφαρμογή να εμφανίζει τις ενημερώσεις κοινωνικού περιεχομένου από τους φίλους σας. Κακόβουλες εφαρμογές μπορούν να το χρησιμοποιήσουν, να προσποιηθούν ότι πρόκειται για φίλους σας και να σας εξαπατήσουν ώστε να αποκαλύψετε τους κωδικούς σας ή άλλες εμπιστευτικές πληροφορίες."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"ανάγνωση συμβάντων ημερολογίου και εμπιστευτικών πληροφοριών"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Επιτρέπει σε μια εφαρμογή να διαβάζει όλα τα συμβάντα ημερολογίου που είναι αποθηκευμένα στο tablet σας, συμπεριλαμβανομένων των συμβάντων φίλων ή συναδέλφων. Μια κακόβουλη εφαρμογή με αυτήν την άδεια μπορεί να εξαγάγει προσωπικά στοιχεία από αυτά τα ημερολόγια χωρίς να το γνωρίζουν οι κάτοχοί τους."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Επιτρέπει σε μια εφαρμογή να διαβάζει όλα τα συμβάντα ημερολογίου που είναι αποθηκευμένα στο τηλέφωνό σας, συμπεριλαμβανομένων των συμβάντων φίλων ή συναδέλφων. Μια κακόβουλη εφαρμογή με αυτήν την άδεια μπορεί να εξαγάγει προσωπικά στοιχεία από αυτά τα ημερολόγια χωρίς να το γνωρίζουν οι κάτοχοί τους."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Τοποθετήστε μια κάρτα SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Η κάρτα SIM δεν υπάρχει ή δεν είναι δυνατή η ανάγνωσή της. Τοποθετήστε μια κάρτα SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Η κάρτα SIM απενεργοποιήθηκε οριστικά."\n" Επικοινωνήστε με τον παροχέα υπηρεσιών ασύρματου δικτύου για να λάβετε νέα κάρτα SIM."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Κουμπί προηγούμενου κομματιού"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Κουμπί επόμενου κομματιού"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Κουμπί παύσης"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Κουμπί αναπαραγωγής"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Κουμπί διακοπής"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Μόνο κλήσεις έκτακτης ανάγκης"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Το δίκτυο κλειδώθηκε"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Η κάρτα SIM είναι κλειδωμένη με κωδικό PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Ξεκλείδωμα"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ενεργοποίηση ήχου"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Απενεργοποίηση ήχου"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Ξεκίνησε η δημιουργία μοτίβου"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Το μοτίβο απαλείφθηκε"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Προστέθηκε κελί"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Το μοτίβο ολοκληρώθηκε"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ΑΒΓ"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"Αποκοπή"</string>
<string name="copy" msgid="2681946229533511987">"Αντιγραφή"</string>
<string name="paste" msgid="5629880836805036433">"Επικόλληση"</string>
- <string name="replace" msgid="5781686059063148930">"Αντικατάσταση???"</string>
+ <string name="replace" msgid="5781686059063148930">"Αντικατάσταση..."</string>
<string name="delete" msgid="6098684844021697789">"Διαγραφή"</string>
<string name="copyUrl" msgid="2538211579596067402">"Αντιγραφή διεύθυνσης URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Επιλογή κειμένου..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Αλλαγή τρόπου"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Επιλέξτε μια εφαρμογή"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Κοινή χρήση με"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Κοινή χρήση με <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Στοιχείο χειρισμού με δυνατότητα ολίσθησης. Πατήστε παρατεταμένα."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Κύλιση πάνω <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Κύλιση κάτω για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Φωτογραφική μηχανή"</string>
<string name="description_target_silent" msgid="893551287746522182">"Αθόρυβο"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Ενεργοποίηση ήχου"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Πλήκτρο. Για να ακούσετε τον ήχο του πατήματος των πλήκτρων απαιτούνται ακουστικά."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Συνδέστε ένα σετ ακουστικών για να ακούσετε τα πλήκτρα του κωδικού πρόσβασης να εκφωνούνται δυνατά."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Τελεία."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Πλοήγηση στην αρχική σελίδα"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Πλοήγηση προς τα επάνω"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Περισσότερες επιλογές"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index a6737d2..43deb8b 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Allows the application to read personal profile information stored on your device, such as your name and contact information. This means that the application can identify you and send your profile information to others."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"write to your profile data"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Allows the application to change or add to personal profile information stored on your device, such as your name and contact information. This means that other applications can identify you and send your profile information to others."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"read your social stream"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Allows the application to access and sync social updates from you and your friends. Malicious apps can use this to read private communications between you and your friends on social networks."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"write to your social stream"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Allows the application to display social updates from your friends. Malicious apps can use this to pretend to be a friend and trick you into revealing passwords or other confidential information."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"read calendar events plus confidential information"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Allows an application to read all calendar events stored on your tablet, including those of friends or colleagues. A malicious application with this permission can extract personal information from these calendars without the owners\' knowledge."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Allows an application to read all calendar events stored on your phone, including those of friends or colleagues. A malicious application with this permission can extract personal information from these calendars without the owners\' knowledge."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Please insert a SIM card."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"The SIM card is missing or not readable. Please insert a SIM card."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Your SIM card is permanently disabled."\n" Please contact your wireless service provider to obtain another SIM card."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Previous track button"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Next-track button"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pause button"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Play button"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Stop button"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Emergency calls only"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Network locked"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM card is PUK-locked."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Unlock"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sound on"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Sound off"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Pattern started"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Pattern cleared"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cell added"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Pattern completed"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"Cut"</string>
<string name="copy" msgid="2681946229533511987">"Copy"</string>
<string name="paste" msgid="5629880836805036433">"Paste"</string>
- <string name="replace" msgid="5781686059063148930">"Replace???"</string>
+ <string name="replace" msgid="5781686059063148930">"Replace..."</string>
<string name="delete" msgid="6098684844021697789">"Delete"</string>
<string name="copyUrl" msgid="2538211579596067402">"Copy URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Select text..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mode change"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Choose an application"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Share with"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Share with <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Sliding handle. Tap and hold."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Down for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Silent"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Sound on"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Key. Headset required to hear keys while typing a password."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Plug in a headset to hear password keys spoken aloud."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dot"</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Navigate home"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navigate up"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"More options"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 1cb6381..2df9779 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Permite que la aplicación lea información personal del perfil almacenada en tu dispositivo, como tu nombre e información de contacto. Esto significa que la aplicación puede identificarte y enviar tu información de perfil a otras personas."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"Escrib. en datos de tu perfil"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Permite que la aplicación cambie o agregue información personal del perfil almacenada en tu dispositivo, como tu nombre e información de contacto. Esto significa que otras aplicaciones pueden identificarte y enviar tu información de perfil a otras personas."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"Lectura de tu muro social"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Permite que la aplicación acceda a tus actualizaciones sociales y a las de tus amigos y las sincronice. Las aplicaciones maliciosas pueden usar este permiso para acceder a las comunicaciones privadas que mantienes con tus amigos en las redes sociales."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"Escritura en tu muro social"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Permite que la aplicación muestre las actualizaciones sociales de tus amigos. Las aplicaciones maliciosas pueden usar este permiso para hacerse pasar por un amigo y engañarte para que reveles contraseñas u otros datos confidenciales."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"Leer eventos de calendario e información confidencial"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Permite que una aplicación lea todos los eventos de calendario almacenados en la tableta, incluidos los de tus amigos o compañeros de trabajo. Una aplicación maliciosa con este permiso puede extraer información personal de estos calendarios sin que los propietarios lo sepan."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Permite que una aplicación lea todos los eventos del calendario almacenados en tu teléfono, incluidos los de tus amigos o compañeros de trabajo. Una aplicación maliciosa con este permiso puede extraer información personal de estos calendarios sin que los propietarios lo sepan."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Inserta una tarjeta SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Falta la tarjeta SIM o no es legible. Introduce una tarjeta SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Tu tarjeta SIM ha sido permanentemente desactivada."\n" Comunícate con tu proveedor de servicios inalámbricos para obtener una nueva tarjeta SIM."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Botón para pista anterior"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Botón para pista siguiente"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Botón Pausa"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Botón Reproducir."</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Botón Detener"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Sólo llamadas de emergencia"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Red bloqueada"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"La tarjeta SIM está bloqueada con PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sonido encendido"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Sonido apagado"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Se inició el patrón"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Se borró el patrón"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Se agregó un celular"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Se completó el patrón"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"Cortar"</string>
<string name="copy" msgid="2681946229533511987">"Copiar"</string>
<string name="paste" msgid="5629880836805036433">"Pegar"</string>
- <string name="replace" msgid="5781686059063148930">"¿Reemplazar?"</string>
+ <string name="replace" msgid="5781686059063148930">"Reemplazar..."</string>
<string name="delete" msgid="6098684844021697789">"Eliminar"</string>
<string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Seleccionar texto..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Cambio de modo"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Mayúscula"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Ingresar"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Elegir una aplicación"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Compartir con"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartir con <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Asidero deslizante (tocar y mantener la presión)"</string>
<string name="description_direction_up" msgid="1983114130441878529">"Hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
<string name="description_direction_down" msgid="4294993639091088240">"Hacia abajo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Cámara"</string>
<string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Sonido activado"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Tecla. Se requieren auriculares para escuchar el sonido de las teclas al ingresar una contraseña."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Conecta un auricular para escuchar las contraseñas en voz alta."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punto"</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Desplazarse hasta la página principal"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Desplazarse hacia arriba"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Más opciones"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 598d936..eced66b 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Permite que la aplicación acceda a información del perfil personal almacenada en el dispositivo (como tu nombre o la información de contacto), lo que significa que la aplicación puede identificarte y enviar la información de tu perfil a otros usuarios."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"escribir en datos de tu perfil"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Permite que la aplicación modifique la información del perfil personal almacenada en el dispositivo (como tu nombre o la información de contacto) o que añada contenido a esta información, lo que significa que otras aplicaciones pueden identificarte y enviar la información de tu perfil a otros usuarios."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"consulta tu actividad social"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Permite que la aplicación acceda a las actualizaciones sociales de tus amigos y las sincronice. Las aplicaciones malintencionadas pueden usar este permiso para leer conversaciones privadas con tus amigos en las redes sociales."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"escribir en tu actividad social"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Permite que la aplicación muestre actualizaciones sociales de tus amigos. Las aplicaciones malintencionadas pueden usar este permiso para suplantar la identidad de un amigo y hacer que reveles tus contraseñas u otra información confidencial."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"leer eventos de calendario e información confidencial"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Permite que una aplicación lea todos los eventos de calendario almacenados en el tablet, incluidos los de tus amigos o tus compañeros de trabajo. Las aplicaciones malintencionadas con este permiso pueden extraer información personal de estos calendarios sin el consentimiento de los propietarios."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Permite que una aplicación lea todos los eventos de calendario almacenados en el teléfono, incluidos los de tus amigos o tus compañeros de trabajo. Las aplicaciones malintencionadas con este permiso pueden extraer información personal de estos calendarios sin el consentimiento de los propietarios."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Inserta una tarjeta SIM"</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Falta la tarjeta SIM o no es legible. Introduce una tarjeta SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Tu tarjeta SIM se ha inhabilitado de forma permanente."\n" Ponte en contacto con tu proveedor de servicios inalámbricos para obtener otra tarjeta SIM."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Botón de canción anterior"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Botón de siguiente canción"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Botón de pausa"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Botón de reproducción"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Botón para detener la reproducción"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Solo llamadas de emergencia"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Bloqueada para la red"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"La tarjeta SIM está bloqueada con el código PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Activar sonido"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Desactivar sonido"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Patrón iniciado"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Patrón borrado"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Se ha añadido una celda."</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Patrón completado"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"Cortar"</string>
<string name="copy" msgid="2681946229533511987">"Copiar"</string>
<string name="paste" msgid="5629880836805036433">"Pegar"</string>
- <string name="replace" msgid="5781686059063148930">"Sustituir???"</string>
+ <string name="replace" msgid="5781686059063148930">"Sustituir..."</string>
<string name="delete" msgid="6098684844021697789">"Eliminar"</string>
<string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Seleccionar texto..."</string>
@@ -890,7 +903,7 @@
<string name="anr_application_process" msgid="7208175830253210526">"La aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> no responde. ¿Quieres cerrarla?"</string>
<string name="anr_process" msgid="306819947562555821">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> no responde."\n\n"¿Quieres cerrarlo?"</string>
<string name="force_close" msgid="8346072094521265605">"ACEPTAR"</string>
- <string name="report" msgid="4060218260984795706">"Informe"</string>
+ <string name="report" msgid="4060218260984795706">"Informar"</string>
<string name="wait" msgid="7147118217226317732">"Esperar"</string>
<string name="launch_warning_title" msgid="8323761616052121936">"Aplicación redireccionada"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando."</string>
@@ -989,7 +1002,7 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="3202838234780505886">"Si activas el almacenamiento USB, se detendrán algunas aplicaciones que estás utilizando y estas no estarán disponibles hasta que lo desactives."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Error de funcionamiento de USB"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Aceptar"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Conectado como un dispositivo de medios"</string>
+ <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Conectado como un dispositivo multimedia"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Conectado como una cámara"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Conectado como instalador"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Cambio de modo"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Mayús"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Intro"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Seleccionar una aplicación"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Compartir con"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartir con <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Tirador deslizante (mantener pulsado)"</string>
<string name="description_direction_up" msgid="1983114130441878529">"Hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
<string name="description_direction_down" msgid="4294993639091088240">"Hacia abajo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Cámara"</string>
<string name="description_target_silent" msgid="893551287746522182">"Silencio"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Sonido activado"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Se necesitan auriculares para escuchar las teclas mientras se escribe una contraseña."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Conecta un auricular para escuchar las contraseñas en voz alta."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punto"</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Ir al escritorio"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Desplazarse hacia arriba"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Más opciones"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index cbf0eed..869b540 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"به برنامه کاربردی اجازه میدهد اطلاعات مربوط به نمایه شخصی ذخیره شده بر روی دستگاه شما مانند نام و اطلاعات تماس شما را بخواند. این بدان معناست که برنامه میتواند شما را شناسایی کند و اطلاعات نمایه شما را به دیگران ارسال نماید."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"نوشتن در دادههای نمایه شما"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"به برنامه کاربردی اجازه میدهد به تغییر و یا اضافه کردن اطلاعات نمایه شخصی ذخیره شده بر روی دستگاه شما مانند نام و اطلاعات تماس شما، بپردازد. این بدان معناست که برنامههای دیگر میتوانند شما را شناسایی کنند و اطلاعات نمایه شما را به دیگران ارسال نمایند."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"خواندن جریان اجتماعی شما"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"به برنامه کاربردی امکان میدهد تا به بهروزرسانیهای شما و دوستانتان دسترسی داشته باشند و آنها را همگام کنند. برنامههای مخرب میتوانند از آن برای خواندن ارتباطات خصوصی بین شما و دوستانتان در شبکههای اجتماعی استفاده کنند."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"نوشتن در جریان اجتماعی شما"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"به برنامه کاربردی امکان میدهد تا به بهروزرسانیهای دوستان شما دسترسی داشته باشد. برنامههای مخرب میتوانند از آن استفاده کرده و وانمود کنند که دوست شما هستند، و شما را فریب دهند تا گذرواژه یا دیگر اطلاعات محرمانه خود را در اختیار آنها قرار دهید."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"خواندن رویدادهای تقویم به همراه اطلاعات محرمانه"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"به برنامه اجازه خواندن تمام رویدادهای تقویم موجود در رایانه لوحی شما را میدهد که این شامل تقویم دوستان و همکاران نیز میشود. یک برنامه مخرب با این اجازه میتواند بدون اطلاع مالک، اطلاعات شخصی را از این تقویمها استخراج کند."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"به یک برنامه کاربردی اجازه خواندن تمام رویدادهای تقویم موجود در گوشی شما را میدهد که این شامل تقویم دوستان و همکاران نیز میشود. یک برنامه مخرب با این اجازه میتواند بدون اطلاع مالک، اطلاعات شخصی را از این تقویمها استخراج کند."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"لطفاً سیم کارت را وارد کنید."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"سیم کارت موجود نیست یا قابل خواندن نیست. یک سیم کارت وارد کنید."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"سیم کارت شما به صورت دائمی غیرفعال شده است."\n" برای دریافت یک سیم کارت دیگر با ارائه دهنده خدمات بی سیم خود تماس بگیرید."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"دکمه تراک قبلی"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"دکمه تراک بعدی"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"دکمه مکث"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"دکمه پخش"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"دکمه توقف"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"فقط تماس های اضطراری"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"شبکه قفل شد"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"سیم کارت با PUK قفل شده است."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"بازگشایی قفل"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"صدا روشن"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"صدا خاموش"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"الگو شروع شد"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"الگو پاک شد"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"سلول اضافه شد"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"الگو تکمیل شد"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"برش"</string>
<string name="copy" msgid="2681946229533511987">"کپی"</string>
<string name="paste" msgid="5629880836805036433">"جای گذاری"</string>
- <string name="replace" msgid="5781686059063148930">"جایگزین شود؟؟؟"</string>
+ <string name="replace" msgid="5781686059063148930">"جایگزین شود..."</string>
<string name="delete" msgid="6098684844021697789">"حذف"</string>
<string name="copyUrl" msgid="2538211579596067402">"کپی URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"انتخاب متن..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"تغییر حالت"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"انتخاب برنامه کاربردی"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"اشتراکگذاری با"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"اشتراکگذاری با <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"کنترل کننده کشویی. ضربه زده و نگه دارید."</string>
<string name="description_direction_up" msgid="1983114130441878529">"بالا برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"پایین برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"دوربین"</string>
<string name="description_target_silent" msgid="893551287746522182">"ساکت"</string>
<string name="description_target_soundon" msgid="30052466675500172">"صدا روشن"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"کلید. برای شنیدن کلیدها هنگام تایپ یک گذرواژه به گوشی نیاز است."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"برای شنیدن کلیدهای گذرواژه که با صدای بلند خوانده میشوند، از هدست استفاده کنید."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"نقطه."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"رفتن به صفحه اصلی"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"حرکت به بالا"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"سایر گزینه ها"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 0a67111..d16d29b 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Sallii sovelluksen lukea yksityisiä profiilitietoja, kuten nimen ja yhteystiedot. Haittaohjelmat voivat käyttää tätä käyttäjien tunnistamiseen ja profiilitietojen levittämiseen muille."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"kirjoittaa profiilin tietoihin"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Sallii sovelluksen muuttaa tai lisätä laitteellesi tallennettuja yksityisiä profiilitietoja. Haittaohjelmat voivat käyttää tätä tunnistamiseesi ja profiilitietojesi lähettämiseen muille."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lue sosiaalista streamia"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Antaa sovelluksen käyttää ja synkronoida sinun ja kavereidesi päivityksiä sosiaalisista palveluista. Haitalliset sovellukset voivat käyttää tätä sosiaalisissa verkostoissa kavereidesi kanssa käytyjen yksityisten keskustelujen lukemiseen."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"kirjoita sosiaaliseen streamiin"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Antaa sovelluksen näyttää kavereidesi päivityksiä sosiaalisista palveluista. Haitalliset sovellukset voivat tämän asetuksen avulla tekeytyä kaveriksesi ja huijata sinua paljastamaan salasanoja tai muita luottamuksellisia tietoja."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"lue kalenteritapahtumia ja luottamuksellisia tietoja"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Antaa sovelluksen lukea kaikkia tablet-laitteelle tallennettuja kalenteritapahtumia (myös kavereiden ja työkavereiden lisäämiä). Haitalliset sovellukset voivat noutaa henkilötietoja kalentereista ilman omistajien lupaa."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Antaa sovelluksen lukea kaikkia puhelimeen tallennettuja kalenteritapahtumia (myös kavereiden ja työkavereiden lisäämiä). Haitalliset sovellukset voivat noutaa henkilötietoja kalentereista ilman omistajien lupaa."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Aseta SIM-kortti."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"SIM-korttia ei löydy tai ei voi lukea. Kytke SIM-kortti."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"SIM-kortti on poistettu pysyvästi käytöstä."\n" Ota yhteyttä operaattoriisi ja hanki uusi SIM-kortti."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Edellinen kappale -painike"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Seuraava kappale -painike"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Tauko-painike"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Toista-painike"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Keskeytä-painike"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Vain hätäpuhelut"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Verkko lukittu"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-kortti on PUK-lukittu."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Poista lukitus"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ääni käytössä"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Poista äänet käytöstä"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Kuvio aloitettu"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Kuvio tyhjennetty"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Solu lisätty"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Kuvio valmis"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Tilan muutos"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Valitse sovellus"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Jaa seuraavien kanssa:"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Jaa sovelluksessa <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Liukuva valitsin. Kosketa pitkään."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Ylös: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Alas: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Äänetön"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Ääni käytössä"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Näppäin. Tarvitset kuulokkeet kuullaksesi näppäimenpainallukset kirjoittaessasi salasanaa."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Liitä kuulokkeet kuullaksesi, mitä näppäimiä painat kirjoittaessasi salasanaa."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Piste."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Siirry etusivulle"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Siirry ylös"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Lisää asetuksia"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 03ac607..2839734 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Permet à l\'application de lire les informations de profil personnelles stockées sur votre appareil, telles que votre nom et vos coordonnées. Cela signifie que l\'application peut vous identifier et envoyer vos informations de profil à d\'autres."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"modifier vos données de profil"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Permet à l\'application de modifier ou d\'ajouter des informations personnelles stockées sur le profil de votre appareil, telles que votre nom et vos coordonnées. Cela signifie que d\'autres applications peuvent vous identifier et envoyer vos informations de profil à d\'autres."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lire flux des réseaux sociaux"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Permet à l\'application d\'accéder aux mises à jour de vos amis sur les réseaux sociaux et de les synchroniser. Les applications malveillantes peuvent utiliser cette fonctionnalité pour accéder à des communications privées entre vous et vos amis sur ces réseaux."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"Mettre à jour sur vos flux"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Permet à l\'application d\'afficher les mises à jour de vos amis sur les réseaux sociaux. Les applications malveillantes peuvent utiliser cette fonctionnalité pour se faire passer pour un ami et vous inciter à révéler des mots de passe ou autres informations confidentielles."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"consulter les événements d\'agenda ainsi que les informations confidentielles"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Permet à une application de lire tous les événements d\'agendas stockés sur votre tablette, y compris ceux de vos amis ou de vos collègues. Une application malveillante disposant de cette autorisation peut extraire des informations personnelles de ces agendas à l\'insu de leur propriétaire."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Permet à une application de consulter tous les événements d\'agendas stockés sur votre téléphone, y compris ceux de vos amis ou de vos collègues. Une application malveillante disposant de cette autorisation peut extraire des informations personnelles de ces agendas à l\'insu de leur propriétaire."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Insérez une carte SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Aucune carte SIM ou carte SIM illisible. Veuillez insérer une carte SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Votre carte SIM est définitivement désactivée."\n" Veuillez contacter votre opérateur pour obtenir une autre carte SIM."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Bouton du titre précédent"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Bouton du titre suivant"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Bouton de pause"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Bouton de lecture"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Bouton d\'arrêt"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Appels d\'urgence uniquement"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Réseau verrouillé"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"La carte SIM est verrouillée par clé PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Déverrouiller"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Son activé"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Son désactivé"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Schéma commencé."</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Schéma effacé."</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cellule ajoutée."</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Schéma terminé."</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -901,7 +914,7 @@
<string name="smv_application" msgid="295583804361236288">"L\'application <xliff:g id="APPLICATION">%1$s</xliff:g> (processus <xliff:g id="PROCESS">%2$s</xliff:g>) a enfreint ses propres règles du mode strict."</string>
<string name="smv_process" msgid="5120397012047462446">"Le processus <xliff:g id="PROCESS">%1$s</xliff:g> a enfreint ses propres règles du mode strict."</string>
<string name="android_upgrading_title" msgid="378740715658358071">"Mise à jour d\'Android..."</string>
- <string name="android_upgrading_apk" msgid="274409861603566003">"Optimisation de l\'application <xliff:g id="NUMBER_0">%1$d</xliff:g> sur <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <string name="android_upgrading_apk" msgid="274409861603566003">"Optimisation de l\'application (<xliff:g id="NUMBER_0">%1$d</xliff:g> sur <xliff:g id="NUMBER_1">%2$d</xliff:g>)..."</string>
<string name="android_upgrading_starting_apps" msgid="7959542881906488763">"Lancement des applications"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Finalisation de la mise à jour."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> en cours d\'exécution"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Changement de mode"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Maj"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Entrée"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Sélectionnez une application"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Partager avec"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Partager avec <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Poignée coulissante. Appuyez de manière prolongée."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Vers le haut pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
<string name="description_direction_down" msgid="4294993639091088240">"Vers le bas pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Appareil photo"</string>
<string name="description_target_silent" msgid="893551287746522182">"Mode silencieux"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Son activé"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Touche : casque nécessaire pour entendre le son des touches lorsque vous saisissez un mot de passe."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Branchez des écouteurs pour entendre l\'énoncé à haute voix des touches du mot de passe."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Point."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Retour à l\'accueil"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Parcourir vers le haut"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Plus d\'options"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
new file mode 100644
index 0000000..968ade8
--- /dev/null
+++ b/core/res/res/values-hi/strings.xml
@@ -0,0 +1,1214 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="byteShort" msgid="8340973892742019101">"B"</string>
+ <string name="kilobyteShort" msgid="5973789783504771878">"KB"</string>
+ <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+ <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+ <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
+ <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+ <string name="fileSizeSuffix" msgid="7670819340156489359">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+ <string name="untitled" msgid="6071602020171759109">"<शीर्षक-रहित>"</string>
+ <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+ <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+ <string name="emptyPhoneNumber" msgid="7694063042079676517">"(कोई फ़ोन नंबर नहीं)"</string>
+ <string name="unknownName" msgid="2277556546742746522">"(अज्ञात)"</string>
+ <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"ध्वनिमेल"</string>
+ <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+ <string name="mmiError" msgid="5154499457739052907">"कनेक्शन समस्या या अमान्य MMI कोड."</string>
+ <string name="mmiFdnError" msgid="5224398216385316471">"कार्रवाई केवल फ़िक्स्ड डायलिंग नंबर के लिए प्रतिबंधित है."</string>
+ <string name="serviceEnabled" msgid="8147278346414714315">"सेवा अक्षम थी."</string>
+ <string name="serviceEnabledFor" msgid="6856228140453471041">"सेवा इसके लिए सक्षम की गई थी:"</string>
+ <string name="serviceDisabled" msgid="1937553226592516411">"सेवा अक्षम कर दी गई है."</string>
+ <string name="serviceRegistered" msgid="6275019082598102493">"पंजीकरण सफल था."</string>
+ <string name="serviceErased" msgid="1288584695297200972">"मिटाना सफल था."</string>
+ <string name="passwordIncorrect" msgid="7612208839450128715">"गलत पासवर्ड"</string>
+ <string name="mmiComplete" msgid="8232527495411698359">"MMI पूर्ण."</string>
+ <string name="badPin" msgid="5085454289896032547">"आपके द्वारा लिखी गई पुरानी पिन सही नहीं है."</string>
+ <string name="badPuk" msgid="5702522162746042460">"आपके द्वारा लिखा गया PUK सही नहीं है."</string>
+ <string name="mismatchPin" msgid="3695902225843339274">"आपके द्वारा दर्ज की गई पिन मेल नहीं खाती हैं."</string>
+ <string name="invalidPin" msgid="3850018445187475377">"कोई ऐसा पिन लिखें, जिसमें 4 से 8 अंक हों."</string>
+ <string name="invalidPuk" msgid="8761456210898036513">"ऐसा PUK लिखें जो 8 अंकों या अधिक का हो."</string>
+ <string name="needPuk" msgid="919668385956251611">"आपका सिम कार्ड PUK लॉक किया गया है. इसे अनलॉक करने के लिए PUK कोड लिखें."</string>
+ <string name="needPuk2" msgid="4526033371987193070">"सिम कार्ड अनब्लॉक करने के लिए PUK2 लिखें."</string>
+ <string name="ClipMmi" msgid="6952821216480289285">"इनकमिंग कॉलर ID"</string>
+ <string name="ClirMmi" msgid="7784673673446833091">"आउटगोइंग कॉलर ID"</string>
+ <string name="CfMmi" msgid="5123218989141573515">"कॉल अग्रेषण"</string>
+ <string name="CwMmi" msgid="9129678056795016867">"कॉल प्रतीक्षा"</string>
+ <string name="BaMmi" msgid="455193067926770581">"कॉल बाधित करना"</string>
+ <string name="PwdMmi" msgid="7043715687905254199">"पासवर्ड बदलें"</string>
+ <string name="PinMmi" msgid="3113117780361190304">"पिन परिवर्तन"</string>
+ <string name="CnipMmi" msgid="3110534680557857162">"कॉलिंग नंबर उपस्थित"</string>
+ <string name="CnirMmi" msgid="3062102121430548731">"कॉलिंग नंबर प्रतिबंधित"</string>
+ <string name="ThreeWCMmi" msgid="9051047170321190368">"त्रिमार्गी कॉलिंग"</string>
+ <string name="RuacMmi" msgid="7827887459138308886">"अवांछित कष्टप्रद कॉल की अस्वीकृति"</string>
+ <string name="CndMmi" msgid="3116446237081575808">"कॉलिंग नंबर वितरण"</string>
+ <string name="DndMmi" msgid="1265478932418334331">"परेशान न करें"</string>
+ <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"कॉलर आईडी प्रतिबंधित पर डिफ़ॉल्ट है. अगली कॉल: प्रतिबंधित"</string>
+ <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"कॉलर ID प्रतिबंधित पर डिफ़ॉल्ट है. अगला कॉल: प्रतिबंधित नहीं"</string>
+ <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"कॉलर ID प्रतिबंधित नहीं पर डिफ़ॉल्ट है. अगला कॉल: प्रतिबंधित"</string>
+ <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"कॉलर ID प्रतिबंधित नहीं पर डिफ़ॉल्ट है. अगली कॉल: प्रतिबंधित नहीं"</string>
+ <string name="serviceNotProvisioned" msgid="8614830180508686666">"सेवा प्रावधान की हुई नहीं है."</string>
+ <string name="CLIRPermanent" msgid="5460892159398802465">"कॉलर ID सेटिंग परिवर्तित नहीं की जा सकती है."</string>
+ <string name="RestrictedChangedTitle" msgid="5592189398956187498">"प्रतिबंधित पहुंच बदली गई"</string>
+ <string name="RestrictedOnData" msgid="8653794784690065540">"डेटा सेवा अवरोधित है."</string>
+ <string name="RestrictedOnEmergency" msgid="6581163779072833665">"आपातकालीन सेवा अवरोधित है."</string>
+ <string name="RestrictedOnNormal" msgid="4953867011389750673">"ध्वनि सेवा अवरोधित है."</string>
+ <string name="RestrictedOnAllVoice" msgid="1459318899842232234">"सभी ध्वनि सेवाएं अवरोधित हैं."</string>
+ <string name="RestrictedOnSms" msgid="8314352327461638897">"SMS सेवा अवरोधित है."</string>
+ <string name="RestrictedOnVoiceData" msgid="8244438624660371717">"ध्वनि/डेटा सेवाएं अवरोधित हैं."</string>
+ <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"ध्वनि/SMS सेवाएं अवरोधित हैं."</string>
+ <string name="RestrictedOnAll" msgid="2714924667937117304">"सभी ध्वनि/डेटा/SMS सेवाएं अवरोधित हैं."</string>
+ <string name="serviceClassVoice" msgid="1258393812335258019">"ध्वनि"</string>
+ <string name="serviceClassData" msgid="872456782077937893">"डेटा"</string>
+ <string name="serviceClassFAX" msgid="5566624998840486475">"फ़ैक्स"</string>
+ <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
+ <string name="serviceClassDataAsync" msgid="4523454783498551468">"Async"</string>
+ <string name="serviceClassDataSync" msgid="7530000519646054776">"सिंक"</string>
+ <string name="serviceClassPacket" msgid="6991006557993423453">"पैकेट"</string>
+ <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+ <string name="roamingText0" msgid="7170335472198694945">"रोमिंग संकेतक चालू"</string>
+ <string name="roamingText1" msgid="5314861519752538922">"रोमिंग संकेतक बंद"</string>
+ <string name="roamingText2" msgid="8969929049081268115">"रोमिंग संकेतक चमक रहा है"</string>
+ <string name="roamingText3" msgid="5148255027043943317">"मोहल्ले से बाहर"</string>
+ <string name="roamingText4" msgid="8808456682550796530">"भवन से बाहर"</string>
+ <string name="roamingText5" msgid="7604063252850354350">"रोमिंग - पसंदीदा सिस्टम"</string>
+ <string name="roamingText6" msgid="2059440825782871513">"रोमिंग - उपलब्ध सिस्टम"</string>
+ <string name="roamingText7" msgid="7112078724097233605">"रोमिंग - गठबंधन सहयोगी"</string>
+ <string name="roamingText8" msgid="5989569778604089291">"रोमिंग - प्रीमियम सहयोगी"</string>
+ <string name="roamingText9" msgid="7969296811355152491">"रोमिंग - पूर्ण सेवा कार्यक्षमता"</string>
+ <string name="roamingText10" msgid="3992906999815316417">"रोमिंग - आंशिक सेवा कार्यक्षमता"</string>
+ <string name="roamingText11" msgid="4154476854426920970">"रोमिंग बैनर चालू"</string>
+ <string name="roamingText12" msgid="1189071119992726320">"रोमिंग बैनर बंद"</string>
+ <string name="roamingTextSearching" msgid="8360141885972279963">"सेवा खोज रहा है"</string>
+ <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अग्रेषित नहीं किया गया"</string>
+ <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
+ <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> <xliff:g id="TIME_DELAY">{2}</xliff:g> सेकंड के बाद"</string>
+ <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अग्रेषित नहीं किया गया"</string>
+ <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अग्रेषित नहीं किया गया"</string>
+ <string name="fcComplete" msgid="3118848230966886575">"सुविधा कोड पूर्ण."</string>
+ <string name="fcError" msgid="3327560126588500777">"कनेक्शन समस्या या अमान्य सुविधा कोड."</string>
+ <string name="httpErrorOk" msgid="1191919378083472204">"ठीक"</string>
+ <string name="httpError" msgid="6603022914760066338">"कोई नेटवर्क त्रुटि आई."</string>
+ <string name="httpErrorLookup" msgid="4517085806977851374">"URL ढूंढ़ा नहीं जा सका."</string>
+ <string name="httpErrorUnsupportedAuthScheme" msgid="2781440683514730227">"साइट प्रमाणीकरण योजना समर्थित नहीं है."</string>
+ <string name="httpErrorAuth" msgid="7293960746955020542">"प्रमाणीकरण विफल था."</string>
+ <string name="httpErrorProxyAuth" msgid="1788207010559081331">"प्रॉक्सी सर्वर द्वारा प्रमाणीकरण असफल था."</string>
+ <string name="httpErrorConnect" msgid="7623096283505770433">"सर्वर से कनेक्शन असफल था."</string>
+ <string name="httpErrorIO" msgid="4270874999047767599">"सर्वर संचार नहीं कर सकता. बाद में पुन: प्रयास करें."</string>
+ <string name="httpErrorTimeout" msgid="4743403703762883954">"सर्वर से कनेक्शन का समय समाप्त हुआ."</string>
+ <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"पृष्ठ में कई सर्वर रीडायरेक्ट हैं."</string>
+ <string name="httpErrorUnsupportedScheme" msgid="5257172771607996054">"यह प्रोटोकॉल समर्थित नहीं हैं."</string>
+ <string name="httpErrorFailedSslHandshake" msgid="3088290300440289771">"एक सुरक्षित कनेक्शन स्थापित नहीं किया जा सका."</string>
+ <string name="httpErrorBadUrl" msgid="6088183159988619736">"पृष्ठ खोला नहीं जा सका क्योंकि URL अमान्य है."</string>
+ <string name="httpErrorFile" msgid="8250549644091165175">"फ़ाइल तक पहुंचा नहीं जा सका."</string>
+ <string name="httpErrorFileNotFound" msgid="5588380756326017105">"अनुरोधित फ़ाइल नहीं मिली थी."</string>
+ <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"बहुत सारे अनुरोधों का संसाधन हो रहा है. बाद में पुन: प्रयास करें."</string>
+ <string name="notification_title" msgid="1259940370369187045">"<xliff:g id="ACCOUNT">%1$s</xliff:g> के लिए साइन-इन त्रुटि"</string>
+ <string name="contentServiceSync" msgid="8353523060269335667">"सिंक"</string>
+ <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"सिंक"</string>
+ <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"बहुत से <xliff:g id="CONTENT_TYPE">%s</xliff:g> हटाए जाते हैं."</string>
+ <string name="low_memory" product="tablet" msgid="2292820184396262278">"टेबलेट संग्रहण भर गया है! स्थान रिक्त करने के लिए कुछ फ़ाइलें हटाएं."</string>
+ <string name="low_memory" product="default" msgid="6632412458436461203">"फ़ोन संग्रहण भर गया है! स्थान रिक्त करने के लिए कुछ फ़ाइलें हटाएं."</string>
+ <string name="me" msgid="6545696007631404292">"मैं"</string>
+ <string name="power_dialog" product="tablet" msgid="8545351420865202853">"टेबलेट विकल्प"</string>
+ <string name="power_dialog" product="default" msgid="1319919075463988638">"फ़ोन विकल्प"</string>
+ <string name="silent_mode" msgid="7167703389802618663">"मौन मोड"</string>
+ <string name="turn_on_radio" msgid="3912793092339962371">"वायरलेस चालू करें"</string>
+ <string name="turn_off_radio" msgid="8198784949987062346">"वायरलेस बंद करें"</string>
+ <string name="screen_lock" msgid="799094655496098153">"स्क्रीन लॉक"</string>
+ <string name="power_off" msgid="4266614107412865048">"पावर बंद"</string>
+ <string name="shutdown_progress" msgid="2281079257329981203">"शट डाउन हो रहा है..."</string>
+ <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"आपकी टेबलेट शट डाउन हो जाएगी."</string>
+ <string name="shutdown_confirm" product="default" msgid="649792175242821353">"आपका फ़ोन शट डाउन हो जाएगा."</string>
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"क्या आप शट डाउन करना चाहेंगे?"</string>
+ <string name="recent_tasks_title" msgid="3691764623638127888">"हाल के"</string>
+ <string name="no_recent_tasks" msgid="279702952298056674">"हाल की कोई एप्लिकेशन नहीं."</string>
+ <string name="global_actions" product="tablet" msgid="408477140088053665">"टेबलेट विकल्प"</string>
+ <string name="global_actions" product="default" msgid="2406416831541615258">"फ़ोन विकल्प"</string>
+ <string name="global_action_lock" msgid="2844945191792119712">"स्क्रीन लॉक"</string>
+ <string name="global_action_power_off" msgid="4471879440839879722">"पावर बंद"</string>
+ <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"मौन मोड"</string>
+ <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ध्वनि बंद है"</string>
+ <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ध्वनि चालू है"</string>
+ <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"हवाई जहाज मोड"</string>
+ <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"हवाई जहाज मोड चालू है"</string>
+ <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"हवाई जहाज मोड बंद है"</string>
+ <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+ <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
+ <string name="android_system_label" msgid="6577375335728551336">"Android सिस्टम"</string>
+ <string name="permgrouplab_costMoney" msgid="5429808217861460401">"वे सेवाएं जिन पर आप खर्चा करते हैं"</string>
+ <string name="permgroupdesc_costMoney" msgid="8193824940620517189">"एप्लिकेशन को ऐसी चीज़ें करने की अनुमति देता है जिससे आपका धन खर्च हो सकता है."</string>
+ <string name="permgrouplab_messages" msgid="7521249148445456662">"आपके संदेश"</string>
+ <string name="permgroupdesc_messages" msgid="7045736972019211994">"अपने SMS, ई-मेल और अन्य संदेश पढ़ें और लिखें."</string>
+ <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"आपकी निजी जानकारी"</string>
+ <string name="permgroupdesc_personalInfo" product="tablet" msgid="6975389054186265786">"टेबलेट पर संग्रहीत आपके संपर्कों और कैलेंडर में सीधे पहुंचें."</string>
+ <string name="permgroupdesc_personalInfo" product="default" msgid="5488050357388806068">"फ़ोन पर संग्रहीत आपके संपर्कों और कैलेंडर में सीधे पहुंचें."</string>
+ <string name="permgrouplab_location" msgid="635149742436692049">"आपका स्थान"</string>
+ <string name="permgroupdesc_location" msgid="2430258821648348660">"अपने भौतिक स्थान की निगरानी करें"</string>
+ <string name="permgrouplab_network" msgid="5808983377727109831">"नेटवर्क संचार"</string>
+ <string name="permgroupdesc_network" msgid="5035763698958415998">"एप्लिकेशन को विभिन्न नेटवर्क सुविधाओं में पहुंच की अनुमति दें."</string>
+ <string name="permgrouplab_accounts" msgid="3359646291125325519">"आपके खाते"</string>
+ <string name="permgroupdesc_accounts" msgid="4948732641827091312">"उपलब्ध खातों में पहुंचें."</string>
+ <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"हार्डवेयर नियंत्रण"</string>
+ <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"हैंडसेट पर हार्डवेयर में सीधे पहुंचाता है."</string>
+ <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"फ़ोन कॉल"</string>
+ <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"फ़ोन कॉल पर नज़र रखें, रिकॉर्ड करें और संसाधित करें."</string>
+ <string name="permgrouplab_systemTools" msgid="4652191644082714048">"सिस्टम टूल"</string>
+ <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"सिस्टम का निम्न-स्तर पहुंच और नियंत्रण."</string>
+ <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"डेवलपमेंट टूल"</string>
+ <string name="permgroupdesc_developmentTools" msgid="9056431193893809814">"सुविधाएं केवल एप्लिकेशन डेवलपर के लिए आवश्यक है."</string>
+ <string name="permgrouplab_storage" msgid="1971118770546336966">"संग्रहण"</string>
+ <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB संग्रहण में पहुंचें."</string>
+ <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD कार्ड में पहुंचें."</string>
+ <string name="permlab_statusBar" msgid="7417192629601890791">"स्थिति बार अक्षम या संशोधित करें"</string>
+ <string name="permdesc_statusBar" msgid="1365473595331989732">"एप्लिकेशन को स्थिति बार अक्षम करने की या सिस्टम आइकन जोड़ने और निकालने की अनुमति देता है."</string>
+ <string name="permlab_statusBarService" msgid="7247281911387931485">"स्थिति बार"</string>
+ <string name="permdesc_statusBarService" msgid="4097605867643520920">"एप्लिकेशन को स्थिति बार होने की अनुमति देता है."</string>
+ <string name="permlab_expandStatusBar" msgid="1148198785937489264">"स्थिति बार विस्तृत/संक्षिप्त करें"</string>
+ <string name="permdesc_expandStatusBar" msgid="7088604400110768665">"स्थिति बार विस्तृत या संक्षिप्त करने की अनुमति एप्लिकेशन को देता है."</string>
+ <string name="permlab_processOutgoingCalls" msgid="1136262550878335980">"आउटगोइंग कॉल बीच में रोकें"</string>
+ <string name="permdesc_processOutgoingCalls" msgid="2228988201852654461">"एप्िलकेशन को आउटगोइंग कॉल संसाधित करने और डायल किए गए नंबर को बदलने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन आउटगोइंग कॉल पर नज़र रख सकती हैं, रीडायरेक्ट कर सकती या रोक सकती हैं."</string>
+ <string name="permlab_receiveSms" msgid="2697628268086208535">"SMS प्राप्त करें"</string>
+ <string name="permdesc_receiveSms" msgid="6298292335965966117">"एप्लिकेशन को SMS संदेशों को प्राप्त करने और संसाधित करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन आपके संदेशों पर नज़र रख सकती हैं या आपको बिना दिखाए उन्हें हटा सकती हैं."</string>
+ <string name="permlab_receiveMms" msgid="8894700916188083287">"MMS प्राप्त करें"</string>
+ <string name="permdesc_receiveMms" msgid="4563346832000174373">"एप्लिकेशन को SMS संदेशों को प्राप्त करने और संसाधित करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन आपके संदेशों पर नज़र रख सकते हैं या आपको बिना दिखाए उन्हें हटा सकते हैं."</string>
+ <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"आपातकालीन प्रसारण प्राप्त करें"</string>
+ <string name="permdesc_receiveEmergencyBroadcast" msgid="7118393393716546131">"एप्लिकेशन को आपातकालीन प्रसारण संदेशों को प्राप्त करने और संसाधित करने की अनुमति देता है. यह अनुमति केवल सिस्टम एप्लिकेशन के लिए उपलब्ध है."</string>
+ <string name="permlab_sendSms" msgid="5600830612147671529">"SMS संदेश भेजें"</string>
+ <string name="permdesc_sendSms" msgid="1946540351763502120">"एप्लिकेशन को SMS संदेश भेजने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन बिना आपकी पुष्टि के संदेश भेजकर आपका धन खर्च कर सकती हैं."</string>
+ <string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"बिना किसी पुष्टि के SMS संदेश भेजें"</string>
+ <string name="permdesc_sendSmsNoConfirmation" msgid="4477752891276276168">"एप्लिकेशन को SMS संदेश भेजने देता है. दुर्भावनापूर्ण एप्लिकेशन आपकी पुष्टि के बिना संदेश भेजकर आपका पैसा खर्च कर सकते हैं."</string>
+ <string name="permlab_readSms" msgid="4085333708122372256">"SMS या MMS पढ़ें"</string>
+ <string name="permdesc_readSms" product="tablet" msgid="5836710350295631545">"आपके टेबलेट या सिम कार्ड पर संग्रहीत SMS संदेशों को पढ़ने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन आपके क्रेडेंशियल संदेशों को पढ़ सकती हैं."</string>
+ <string name="permdesc_readSms" product="default" msgid="3002170087197294591">"आपके फ़ोन या सिम कार्ड पर संग्रहीत SMS संदेशों को पढ़ने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन आपके क्रेडेंशियल संदेशों को पढ़ सकते हैं."</string>
+ <string name="permlab_writeSms" msgid="6881122575154940744">"SMS या MMS संपादित करें"</string>
+ <string name="permdesc_writeSms" product="tablet" msgid="5332124772918835437">"आपके टेबलेट या सिम कार्ड पर संग्रहीत SMS संदेशों पर लिखने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन आपके संदेश हटा सकती हैं."</string>
+ <string name="permdesc_writeSms" product="default" msgid="6299398896177548095">"आपके फ़ोन या सिम कार्ड पर संग्रहीत SMS संदेशों पर लिखने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन आपके संदेशों को हटा सकती हैं."</string>
+ <string name="permlab_receiveWapPush" msgid="8258226427716551388">"WAP प्राप्त करें"</string>
+ <string name="permdesc_receiveWapPush" msgid="5979623826128082171">"एप्लिकेशन को WAP संदेशों को प्राप्त करने और संसाधित करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन आपके संदेशों पर नज़र रख सकती है या आपको बिना दिखाए उन्हें हटा सकती हैं."</string>
+ <string name="permlab_getTasks" msgid="5005277531132573353">"चल रही एप्लिकेशन पुन: प्राप्त करें"</string>
+ <string name="permdesc_getTasks" msgid="7048711358713443341">"एप्लिकेशन को वर्तमान में और हाल में चल रहे कार्यों के बारे में जानकारी पुनर्प्राप्त करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन को अन्य एप्लिकेशन के बारे में निजी जानकारी खोजने की अनुमति दे सकता है."</string>
+ <string name="permlab_reorderTasks" msgid="5669588525059921549">"चल रही एप्लिकेशन पुन: क्रमित करें"</string>
+ <string name="permdesc_reorderTasks" msgid="126252774270522835">"किसी एप्लिकेशन को कार्य अग्रभूमि और पृष्ठभूमि में लाने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन बिना आपके नियंत्रण के उन्हें सामने लाने पर बाध्य कर सकती हैं."</string>
+ <string name="permlab_removeTasks" msgid="4802740047161700683">"एप्लिकेशन चलाना रोकें"</string>
+ <string name="permdesc_removeTasks" msgid="2000332928514575461">"किसी एप्लिकेशन को कार्यों को निकालने और उनके एप्लिकेशन नष्ट करने की सुविधा देता है. दुर्भावनापूर्ण एप्लिकेशन अन्य एप्लिकेशन के व्यवहार को बाधित कर सकते हैं."</string>
+ <string name="permlab_setDebugApp" msgid="4339730312925176742">"एप्लिकेशन डीबग करना सक्षम करें"</string>
+ <string name="permdesc_setDebugApp" msgid="5584310661711990702">"किसी एप्लिकेशन को दूसरी एप्लिकेशन के लिए डीबग करना चालू करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग दूसरी एप्लिकेशन को समाप्त करने के लिए कर सकती हैं."</string>
+ <string name="permlab_changeConfiguration" msgid="8214475779521218295">"अपनी UI सेटिंग बदलें"</string>
+ <string name="permdesc_changeConfiguration" msgid="3465121501528064399">"किसी एप्लिकेशन को वर्तमान कॉन्फ़िगरेशन बदलने की अनुमति देता है जैसे स्थान या संपूर्ण फ़ॉन्ट आकार."</string>
+ <string name="permlab_enableCarMode" msgid="5684504058192921098">"कार मोड सक्षम करें"</string>
+ <string name="permdesc_enableCarMode" msgid="5673461159384850628">"किसी एप्लिकेशन को कार मोड सक्षम करने की अनुमति देता है."</string>
+ <string name="permlab_killBackgroundProcesses" msgid="8373714752793061963">"पृष्ठभूमि प्रक्रियाएं रोकें"</string>
+ <string name="permdesc_killBackgroundProcesses" msgid="2908829602869383753">"किसी एप्लिकेशन को दूसरी एप्लिकेशन की पृष्ठभूमि प्रक्रियाओं को बंद करने की अनुमति देता है, बल्कि स्मृति कम ना होने पर भी."</string>
+ <string name="permlab_forceStopPackages" msgid="1447830113260156236">"अन्य एप्लिकेशन को बंद करने के लिए बाध्य करें"</string>
+ <string name="permdesc_forceStopPackages" msgid="7263036616161367402">"किसी एप्लिकेशन को अन्य एप्लिकेशन बलपूर्वक बंद करने की अनुमति देता है."</string>
+ <string name="permlab_forceBack" msgid="1804196839880393631">"एप्लिकेशन को बंद करने के लिए बाध्य करें"</string>
+ <string name="permdesc_forceBack" msgid="6534109744159919013">"किसी एप्लिकेशन को अग्रभूमि में चलने वाली गतिविधि को बंद करने और वापस जाने को बाध्य करने की अनुमति देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+ <string name="permlab_dump" msgid="1681799862438954752">"सिस्टम की आंतरिक स्थिति पुनर्प्राप्त करें"</string>
+ <string name="permdesc_dump" msgid="2198776174276275220">"एप्िलकेशन को सिस्टम की आंतरिक स्थिति पुन: प्राप्त करने की अनुमति देता है. दुर्भावनापूर्ण एप्िलकेशन कई प्रकार की विस्तृत विविधतापूर्ण व्यक्तिगत और निजी जानकारी को पुन: प्राप्त कर सकते हैं जिसकी सामान्यतया उन्हें कोई आवश्यकता नहीं होनी चाहिए."</string>
+ <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"स्क्रीन सामग्री पुनर्प्राप्त करें"</string>
+ <string name="permdesc_retrieve_window_content" msgid="3390962289797156152">"एप्लिकेशन को सक्रिय विंडो की सामग्री पुनर्प्राप्त करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन संपूर्ण विंडो की सामग्री को पुनर्प्राप्त कर सकते हैं और पासवर्ड के अलावा इसके सभी पाठ का परीक्षण कर सकते हैं."</string>
+ <string name="permlab_shutdown" msgid="7185747824038909016">"आंशिक शटडाउन"</string>
+ <string name="permdesc_shutdown" msgid="7046500838746291775">"गतिविधि प्रबंधक को शटडाउन स्थिति में रखता है. पूर्ण शटडाउन निष्पादित नहीं करता है."</string>
+ <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"एप्लिकेशन स्विच करने से रोकता है"</string>
+ <string name="permdesc_stopAppSwitches" msgid="3857886086919033794">"उपयोगकर्ता को दूसरी एप्लिकेशन पर स्विच करने से रोकता है."</string>
+ <string name="permlab_runSetActivityWatcher" msgid="7811586187574696296">"सभी एप्लिकेशन को लॉन्च करने पर नज़र रखें और नियंत्रित करें"</string>
+ <string name="permdesc_runSetActivityWatcher" msgid="2149363027173451218">"किसी एप्लिकेशन को सिस्टम द्वारा गतिविधियों को लॉन्च करने के तरीकों पर नज़र रखने और उन्हें नियंत्रित करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन सिस्टम को पूरी तरह जोखिम में डाल सकती हैं. इस अनुमति की आवश्यकता केवल डेवलपमेंट के लिए है, सामान्य उपयोग के लिए कभी नहीं."</string>
+ <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"पैकेज निकाले गए प्रसारण भेजें"</string>
+ <string name="permdesc_broadcastPackageRemoved" msgid="3453286591439891260">"किसी एप्लिकेशन को सूचना प्रसारित करने की अनुमति देता है कि एक एप्लिकेशन पैकेज निकाल दिया गया है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग किसी दूसरी चल रही एप्लिकेशन को रोकने में कर सकती हैं."</string>
+ <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"SMS-प्राप्त प्रसार भेजें"</string>
+ <string name="permdesc_broadcastSmsReceived" msgid="9122419277306740155">"किसी एप्लिकेशन को सूचना प्रसारित करने की अनुमति देता है कि एक SMS संदेश प्राप्त हुआ है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग इनकमिंग SMS संदेश विकसित करने में कर सकती हैं."</string>
+ <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"WAP-PUSH-प्राप्त प्रसारण भेजें"</string>
+ <string name="permdesc_broadcastWapPush" msgid="3955303669461378091">"किसी एप्लिकेशन को एक सूचना प्रसारित करने की अनुमति देता है कि एक WAP PUSH संदेश प्राप्त हो गया है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग MMS संदेश रसीद विकसित करने या दुर्भावनापूर्ण भिन्न रूपों के साथ किसी वेब पृष्ठ की सामग्री मौन रूप से बदलने में कर सकती हैं."</string>
+ <string name="permlab_setProcessLimit" msgid="2451873664363662666">"चल रही प्रक्रियाओं की संख्या सीमित करें"</string>
+ <string name="permdesc_setProcessLimit" msgid="7824786028557379539">"किसी एप्लिकेशन को ऐसी प्रक्रियाओं की अधिकतम संख्या को नियंत्रित करने की अनुमति देता है जो चलाई जाएंगी. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं."</string>
+ <string name="permlab_setAlwaysFinish" msgid="5342837862439543783">"सभी पृष्ठभूमि एप्लिकेशन को बंद करें"</string>
+ <string name="permdesc_setAlwaysFinish" msgid="8773936403987091620">"किसी एप्लिकेशन को यह नियंत्रित करने की अनुमति देता है कि गतिविधियों के पृष्ठभूमि पर जाते ही क्या वे हमेशा समाप्त हो जाती है या नहीं. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं."</string>
+ <string name="permlab_batteryStats" msgid="7863923071360031652">"बैटरी आंकड़े संशोधित करें"</string>
+ <string name="permdesc_batteryStats" msgid="5847319823772230560">"संकलित बैटरी आंकड़ों के संशोधन की अनुमति देता है. सामान्य एप्लिकेशन द्वारा उपयोग किए जाने के लिए नहीं है."</string>
+ <string name="permlab_backup" msgid="470013022865453920">"सिस्टम बैकअप नियंत्रित और पुनर्स्थापित करें"</string>
+ <string name="permdesc_backup" msgid="4837493065154256525">"एप्लिकेशन को सिस्टम का बैकअप नियंत्रित करने और मैकेनिज़्म पुनर्स्थापित करने की अनुमति देता है. सामान्य एप्लिकेशन द्वारा उपयोग किए जाने के लिए नहीं है."</string>
+ <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"पूर्ण बैकअप या पुनर्स्थापना कार्यवाही की पुष्टि करें"</string>
+ <string name="permdesc_confirm_full_backup" msgid="9005017754175897954">"एप्लिकेशन को पूर्ण बैकअप पुष्टिकरण UI लॉन्च करने की अनुमति देता है. किसी भी एप्लिकेशन द्वारा उपयोग किए जाने के लिए नहीं."</string>
+ <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"अनधिकृत विंडो दिखाएं"</string>
+ <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"ऐसी विंडो के निर्माण की अनुमति देता है जिसका प्रयोजन आंतरिक सिस्टम उपयोगकर्ता इंटरफ़ेस द्वारा उपयोग के लिए हो. सामान्य एप्लिकेशन द्वारा उपयोग किए जाने के लिए नहीं है."</string>
+ <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"सिस्टम-स्तर अलर्ट प्रदर्शित करें"</string>
+ <string name="permdesc_systemAlertWindow" msgid="2884149573672821318">"किसी एप्लिकेशन को सिस्टम अलर्ट विंडो दिखाने की अनुमति देता है. दुर्भावनापूर्ण एप्िलकेशन संपूर्ण स्क्रीन का अधिग्रहण कर लेते हैं."</string>
+ <string name="permlab_setAnimationScale" msgid="2805103241153907174">"वैश्विक एनिमेशन गति संशोधित करें"</string>
+ <string name="permdesc_setAnimationScale" msgid="7181522138912391988">"किसी एप्लिकेशन को किसी भी समय वैश्विक एनिमेशन गति (तेज़ या धीमे एनिमेशन) बदलने की अनुमति देता है."</string>
+ <string name="permlab_manageAppTokens" msgid="17124341698093865">"एप्लिकेशन टोकन प्रबंधित करें"</string>
+ <string name="permdesc_manageAppTokens" msgid="977127907524195988">"एप्लिकेशन को उनके स्वयं के टोकन बनाने और प्रबंधित करने, उनके सामान्य Z-क्रम को दरकिनार करते हुए, की अनुमति देता है. सामान्य एप्लिकश्ोन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+ <string name="permlab_injectEvents" msgid="1378746584023586600">"कुंजियों और नियंत्रण बटन को दबाएं"</string>
+ <string name="permdesc_injectEvents" product="tablet" msgid="7200014808195664505">"किसी एप्लिकेशन को उनके स्वयं के इनपुट ईवेंट (कुंजी दबाव इत्यादि) को किसी दूसरी एप्लिकेशन को वितरित करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग टेबलेट अधिग्रहीत करने में कर सकती हैं."</string>
+ <string name="permdesc_injectEvents" product="default" msgid="3946098050410874715">"किसी एप्लिकेशन को उनके स्वयं के इनपुट ईवेंट (कुंजी दबाव इत्यादि) किसी दूसरी एप्लिकेशन को वितरित करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग फ़ोन अधिग्रहीत करने में कर सकती हैं."</string>
+ <string name="permlab_readInputState" msgid="469428900041249234">"आप जो भी लिखते हैं और जो कार्यवाहियां करते हैं उन्हें रिकॉर्ड करें"</string>
+ <string name="permdesc_readInputState" msgid="5132879321450325445">"एप्लिकेशन को आपके द्वारा दबाई जाने वाली कुंजियों को देखने की अनुमति देता है, तब भी जबकि आप किसी दूसरी एप्लिकेशन के साथ सहभागिता (जैसे पासवर्ड दर्ज करना) कर रहे हों. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होनी चाहिए."</string>
+ <string name="permlab_bindInputMethod" msgid="3360064620230515776">"किसी इनपुट विधि से आबद्ध करें"</string>
+ <string name="permdesc_bindInputMethod" msgid="3734838321027317228">"धारक को किसी इनपुट विधि के शीर्ष-स्तर इंटरफ़ेस को आबद्ध करने की अनुमति देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होनी चाहिए."</string>
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"किसी पाठ सेवा पर बने रहें"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"धारक को किसी पाठ सेवा के शीर्ष-स्तरीय इंटरफ़ेस पर बनाए रखता है(उदा. SpellCheckerService). सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं है."</string>
+ <string name="permlab_bindVpnService" msgid="4708596021161473255">"किसी VPN सेवा से आबद्ध करें"</string>
+ <string name="permdesc_bindVpnService" msgid="6011554199384584151">"धारक को किसी VPN सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध करने देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+ <string name="permlab_bindWallpaper" msgid="8716400279937856462">"वॉलपेपर से आबद्ध करें"</string>
+ <string name="permdesc_bindWallpaper" msgid="5287754520361915347">"धारक को किसी वॉलपेपर के शीर्ष-स्तर इंटरफ़ेस को आबद्ध करने की अनुमति देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"किसी विजेट सेवा से आबद्ध करें"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"धारक को किसी विजेट सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+ <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"किसी उपकरण व्यवस्थापक के साथ सहभागिता करें"</string>
+ <string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"धारक को किसी उपकरण व्यवस्थापक को उद्देश्य भेजने की अनुमति देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+ <string name="permlab_setOrientation" msgid="3365947717163866844">"स्क्रीन अभिविन्यास बदलें"</string>
+ <string name="permdesc_setOrientation" msgid="6335814461615851863">"किसी एप्लिकेशन को किसी भी समय स्क्रीन का घूर्णन बदलने की अनुमति देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+ <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"सूचक गति बदलें"</string>
+ <string name="permdesc_setPointerSpeed" msgid="137436038503379864">"किसी एप्लिकेशन को किसी भी समय माउस या ट्रैकपैड सूचक गति परिवर्तित करने की अनुमति देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+ <string name="permlab_signalPersistentProcesses" msgid="4255467255488653854">"एप्लिकेशन को Linux सिग्नल भेजें"</string>
+ <string name="permdesc_signalPersistentProcesses" msgid="3565530463215015289">"किसी एप्लिकेशन को अनुरोध करने की अनुमति देता है कि सभी आपूर्ति संकेत सभी लगातार प्रक्रियाओं को भेजे जाएं."</string>
+ <string name="permlab_persistentActivity" msgid="8659652042401085862">"एप्लिकेशन हमेशा चलाएं"</string>
+ <string name="permdesc_persistentActivity" msgid="5037199778265006008">"किसी एप्लिकेशन को लगातार स्वयं के भाग बनाने की अनुमति देता है, ताकि सिस्टम इसका उपयोग अन्य एप्लिकेशन के लिए नहीं कर सके."</string>
+ <string name="permlab_deletePackages" msgid="3343439331576348805">"एप्लिकेशन हटाएं"</string>
+ <string name="permdesc_deletePackages" msgid="3634943677518723314">"किसी एप्लिकेशन को Android पैकेज हटाने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग महत्वपूर्ण एप्लिकेशन हटाने में कर सकती हैं."</string>
+ <string name="permlab_clearAppUserData" msgid="2192134353540277878">"अन्य एप्लिकेशन का डेटा हटाएं"</string>
+ <string name="permdesc_clearAppUserData" msgid="7546345080434325456">"किसी एप्लिकेशन को उपयोगकर्ता डेटा साफ़ करने की अनुमति देता है."</string>
+ <string name="permlab_deleteCacheFiles" msgid="1518556602634276725">"अन्य एप्लिकेशन के कैश हटाएं"</string>
+ <string name="permdesc_deleteCacheFiles" msgid="2283074077168165971">"किसी एप्लिकेशन को कैश फ़ाइलें हटाने की अनुमति देता है."</string>
+ <string name="permlab_getPackageSize" msgid="4799785352306641460">"एप्लिकेशन संग्रहण स्थान मापें"</string>
+ <string name="permdesc_getPackageSize" msgid="5557253039670753437">"किसी एप्लिकेशन को उसका कोड, डेटा और कैश आकार पुनर्प्राप्त करने की अनुमति देता है"</string>
+ <string name="permlab_installPackages" msgid="335800214119051089">"एप्लिकेशन सीधे इंस्टॉल करें"</string>
+ <string name="permdesc_installPackages" msgid="526669220850066132">"किसी एप्लिकेशन को नए और अपडेट किए गए Android पैकेज इंस्टॉल करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग निरंकुश सशक्त अनुमतियों वाली नई एप्लिकेशन जोड़ने में कर सकती हैं."</string>
+ <string name="permlab_clearAppCache" msgid="4747698311163766540">"सभी एप्लिकेशन कैश डेटा हटाएं"</string>
+ <string name="permdesc_clearAppCache" product="tablet" msgid="3097119797652477973">"एप्लिकेशन कैश निर्देशिका में फ़ाइलों को हटाकर किसी एप्लिकेशन को टेबलेट संग्रहण रिक्त करने की अनुमति देता है. सिस्टम प्रक्रिया के लिए आम तौर पर पहुंच अत्यंत प्रतिबंधित है."</string>
+ <string name="permdesc_clearAppCache" product="default" msgid="7740465694193671402">"एप्लिकेशन कैश निर्देशिका में फ़ाइलों को हटाकर किसी एप्लिकेशन को फ़ोन संग्रहण रिक्त करने की अनुमति देता है. सिस्टम प्रक्रिया के लिए आम तौर पर पहुंच अत्यंत प्रतिबंधित है."</string>
+ <string name="permlab_movePackage" msgid="728454979946503926">"एप्लिकेशन संसाधनों को ले जाएं"</string>
+ <string name="permdesc_movePackage" msgid="6323049291923925277">"एप्लिकेशन संसाधनों को आंतरिक मीडिया से बाह्य मीडिया में और इसके ठीक विपरीत ले जाने की अनुमति किसी एप्लिकेशन को देता है."</string>
+ <string name="permlab_readLogs" msgid="6615778543198967614">"संवेदनशील लॉग डेटा पढ़ें"</string>
+ <string name="permdesc_readLogs" product="tablet" msgid="4077356893924755294">"किसी एप्लिकेशन को सिस्टम की विभिन्न लॉग फ़ाइलों से पढ़ने की अनुमति देता है. आप टेबलेट के साथ क्या कर रहे हैं इस बारे में यह इसे सामान्य जानकारी खोजने की अनुमति देता है, संभवत: व्यक्तिगत या निजी जानकारी शामिल करते हुए."</string>
+ <string name="permdesc_readLogs" product="default" msgid="8896449437464867766">"किसी एप्लिकेशन को सिस्टम की विभिन्न लॉग फ़ाइलों से पढ़ने की अनुमति देता है. आप फ़ोन के साथ क्या कर रहे हैं इस बारे में यह इसे सामान्य जानकारी खोजने की अनुमति देता है, संभवत: व्यक्तिगत या निजी जानकारी शामिल करते हुए."</string>
+ <string name="permlab_diagnostic" msgid="8076743953908000342">"निदान के स्वामित्व वाले संसाधनों को पढ़ें/लिखें"</string>
+ <string name="permdesc_diagnostic" msgid="3121238373951637049">"एप्लिकेशन को निदान समूह के स्वामित्व वाले किसी स्रोत को पढ़ने और लिखने की अनुमति देता है; उदाहरण के लिए, /dev में फ़ाइलें. यह सिस्टम की स्थिरता और सुरक्षा को संभावित रूप से प्रभावित कर सकता है. इसका उपयोग निर्माता या ऑपरेटर द्वारा केवल हार्डवेयर-विशेष निदान के लिए किया जाना चाहिए."</string>
+ <string name="permlab_changeComponentState" msgid="79425198834329406">"एप्लिकेशन घटकों के सक्षम या अक्षम करें"</string>
+ <string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"किसी दूसरी एप्लिकेशन का घटक सक्षम किया गया है या नहीं, यह बदलने की अनुमति किसी एप्लिकेशन को देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग महत्वपूर्ण टेबलेट क्षमताओं को अक्षम करने में कर सकती हैं. इस अनुमति के साथ ही देखभाल होना अत्यावश्यक है, क्योंकि एप्लिकेशन घटकों को व्यर्थ, असंगत या अस्थिर अवस्था में ले जाना संभव है."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"किसी दूसरी एप्लिकेशन का घटक सक्षम किया गया है या नहीं, यह बदलने की अनुमति किसी एप्लिकेशन को देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग महत्वपूर्ण फ़ोन क्षमताओं को अक्षम करने में कर सकती हैं. इस अनुमति के साथ ही देखभाल होना अत्यावश्यक है, क्योंकि एप्लिकेशन घटकों को व्यर्थ, असंगत या अस्थिर अवस्था में ले जाना संभव है."</string>
+ <string name="permlab_setPreferredApplications" msgid="3393305202145172005">"पसंदीदा एप्लिकेशन सेट करें"</string>
+ <string name="permdesc_setPreferredApplications" msgid="760008293501937546">"किसी एप्लिकेशन को आपकी पसंदीदा एप्लिकेशन संशोधित करने की अनुमति देता है. यह दुर्भावनापूर्ण एप्लिकेशन को आपसे निजी डेटा एकत्र करने के लिए आपकी मौजूदा एप्लिकेशन को चकमा देते हुए ऐसी एप्लिकेशन को मौन रूप से बदलने की अनुमति देता है जो चल रही हों."</string>
+ <string name="permlab_writeSettings" msgid="1365523497395143704">"वैश्विक सिस्टम सेटिंग संशोधित करें"</string>
+ <string name="permdesc_writeSettings" msgid="838789419871034696">"किसी एप्लिकेशन को सिस्टम के सेटिंग डेटा को संशोधित करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन आपके सिस्टम का कॉन्फ़िगरेश दूषित कर सकती हैं."</string>
+ <string name="permlab_writeSecureSettings" msgid="204676251876718288">"सुरक्षित सिस्टम सेटिंग संशोधित करें"</string>
+ <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"किसी एप्लिकेशन को सिस्टम का सुरक्षित सेटिंग डेटा संशोधित करने की अनुमति देता है. सामान्य एप्लिकेशन द्वारा उपयोग किए जाने के लिए नहीं है."</string>
+ <string name="permlab_writeGservices" msgid="2149426664226152185">"Google सेवाएं मैप संशोधित करें"</string>
+ <string name="permdesc_writeGservices" msgid="6602362746516676175">"किसी एप्लिकेशन को Google सेवा मैप संशोधित करने की अनुमति देता है. सामान्य एप्लिकेशन द्वारा उपयोग किए जाने के लिए नहीं है."</string>
+ <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"बूट पर स्वचालित रूप से प्रारंभ करें"</string>
+ <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7530977064379338199">"किसी एप्लिकेशन को सिस्टम द्वारा बूट करना समाप्त करने के तुरंत बाद स्वयं प्रारंभ होने की अनुमति देता है. इसके कारण टेबलेट को प्रारंभ होने में अधिक समय लग सकता है और हमेशा चलते रहने के द्वारा यह पूरे टेबलेट को धीमा करने की अनुमति एप्लिकेशन को दे सकता है."</string>
+ <string name="permdesc_receiveBootCompleted" product="default" msgid="698336728415008796">"किसी एप्लिकेशन को सिस्टम द्वारा बूट करना समाप्त करने के तुरंत बाद स्वयं प्रारंभ होने की अनुमति देता है. इसके कारण फ़ोन को प्रारंभ होने में अधिक समय लग सकता है और हमेशा चलते रहने के द्वारा यह पूरे फ़ोन को धीमा करने की अनुमति एप्लिकेशन को दे सकता है."</string>
+ <string name="permlab_broadcastSticky" msgid="7919126372606881614">"स्टिकी प्रसारण भेजें"</string>
+ <string name="permdesc_broadcastSticky" product="tablet" msgid="6322249605930062595">"किसी एप्लिकेशन को ऐसे रोचक प्रसारणों को भेजने की अनुमति देता है, जो प्रसारण समाप्त होने के बाद रहते हैं. दुर्भावनापूर्ण एप्लिकेशन बहुत सी स्मृति का उपयोग करके टेबलेट को धीमा या अस्थिर बना सकती हैं."</string>
+ <string name="permdesc_broadcastSticky" product="default" msgid="1920045289234052219">"किसी एप्लिकेशन को ऐसे रोचक प्रसारणों को भेजने की अनुमति देता है, जो प्रसारण समाप्त होने के बाद रहते हैं. दुर्भावनापूर्ण एप्लिकेशन बहुत सी स्मृति का उपयोग करके फ़ोन को धीमा या अस्थिर बना सकती हैं."</string>
+ <string name="permlab_readContacts" msgid="6219652189510218240">"संपर्क डेटा पढ़ें"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="7596158687301157686">"किसी एप्लिकेशन को आपके टेबलेट पर संग्रहीत सभी संपर्क (पता) डेटा पढ़ने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग दूसरे लोगों को आपका डेटा भेजने में कर सकती हैं."</string>
+ <string name="permdesc_readContacts" product="default" msgid="3371591512896545975">"किसी एप्लिकेशन को आपके फ़ोन पर संग्रहीत सभी संपर्क (पता) डेटा पढ़ने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग दूसरे लोगों को आपका डेटा भेजने में कर सकती हैं."</string>
+ <string name="permlab_writeContacts" msgid="644616215860933284">"संपर्क डेटा लिखें"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="7782689510038568495">"किसी एप्लिकेशन को आपके टेबलेट पर संग्रहीत संपर्क (पता) डेटा संशोधित करने की अनुमति देता है. दुर्भावनापूर्ण एप्िलकेशन इसका उपयोग आपके संपर्क डेटा को मिटाने या संशोधित करने में कर सकती हैं."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="3924383579108183601">"किसी एप्लिकेशन को आपके फ़ोन पर संग्रहीत संपर्क (पता) डेटा संशोधित करने की अनुमति देता है. दुर्भावनापूर्ण एप्िलकेशन इसका उपयोग आपके संपर्क डेटा को मिटाने या संशोधित करने में कर सकती हैं."</string>
+ <string name="permlab_readProfile" msgid="6824681438529842282">"अपना प्रोफ़ाइल डेटा पढ़ें"</string>
+ <string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"एप्लिकेशन को आपके उपकरण पर संग्रहीत निजी प्रोफाइल जानकारी पढ़ने देता है, जैसे आपका नाम और संपर्क जानकारी. इसका अर्थ है कि एप्लिकेशन आपको पहचान सकता है और आपकी प्रोफ़ाइल जानकारी दूसरों को भेज सकता है."</string>
+ <string name="permlab_writeProfile" msgid="4679878325177177400">"अपने प्रोफ़ाइल डेटा में लिखें"</string>
+ <string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"एप्लिकेशन को आपके उपकरण पर संग्रहीत निजी प्रोफ़ाइल जानकारी बदलने या जोड़ने देता है, जैसे आपका नाम और संपर्क जानकारी. इसका अर्थ है कि अन्य एप्लिकेशन आपको पहचान सकते हैं और आपकी प्रोफ़ाइल जानकारी दूसरों को भेज सकते हैं."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"अपनी सामाजिक स्ट्रीम पढ़ें"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"एप्लिकेशन को आपके और आपके मित्रों के सामाजिक अपडेट पर पहुंचने और समन्वयित करने देता है. दुर्भावनापूर्ण एप्लिकेशन सामाजिक नेटवर्क पर आपके और आपके मित्रों के बीच निजी संचार पढ़ने के लिए इसका उपयोग कर सकते हैं."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"सामाजिक स्ट्रीम में लिखें"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"एप्लिकेशन को आपके मित्रों के सामाजिक अपडेट प्रदर्शित करने देता है. दुर्भावनापूर्ण एप्लिकेशन मित्र होने का दिखावा करने और आपसे पासवर्ड या अन्य गोपनीय जानकारी प्रकट करने के लिए इसका उपयोग कर सकते हैं."</string>
+ <string name="permlab_readCalendar" msgid="5972727560257612398">"केलैंडर ईवेंट के साथ-साथ गोपनीय जानकारी पढ़ें"</string>
+ <string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"किसी एप्लिकेशन को आपके टैबलेट पर संग्रहीत सभी कैलेंडर ईवेंट पढ़ने देता है, उनके सहित जो मित्रों और सहकर्मियों के हैं. किसी दुर्भावनापूर्ण एप्लिकेशन के पास यह अनुमति हो तो वह इन कैलेंडर से स्वामी की जानकारी के बिना व्यक्तिगत जानकारी निकाल सकता है."</string>
+ <string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"किसी एप्लिकेशन को आपके फ़ोन पर संग्रहीत सभी कैलेंडर ईवेंट पढ़ने देता है, उनके सहित जो मित्रों और सहकर्मियों के हैं. किसी दुर्भावनापूर्ण एप्लिकेशन के पास यह अनुमति हो तो वह इन कैलेंडर से स्वामी की जानकारी के बिना व्यक्तिगत जानकारी निकाल सकता है."</string>
+ <string name="permlab_writeCalendar" msgid="8438874755193825647">"स्वामी की जानकारी के बिना कैलेंडर ईवेंट जोड़ें या संशोधित करें और अतिथियों को ईमेल भेजें"</string>
+ <string name="permdesc_writeCalendar" msgid="5368129321997977226">"किसी एप्लिकेशन को कैलेंडर स्वामी के रूप में ईवेंट आमंत्रण भेजने देता है और उन ईवेंट को जोड़ने, निकालने, बदलने देता है जिन्हें आप अपने उपकरण पर संशोधित कर सकते हैं, उनके सहित जो आपके मित्रों और सहकर्मियों के हैं. किसी दुर्भावनापूर्ण एप्लिकेशन के पास यह अनुमति हो तो वह ऐसे स्पैम ईमेल भेज सकता है जो कैलेंडर स्वामी की ओर से आते प्रतीत होते हैं, स्वामी की जानकारी के बिना ईवेंट संशोधित कर सकता है, या नकली ईवेंट जोड़ सकता है."</string>
+ <string name="permlab_accessMockLocation" msgid="8688334974036823330">"परीक्षण के लिए नकली स्थान स्रोत"</string>
+ <string name="permdesc_accessMockLocation" msgid="7648286063459727252">"परीक्षण के लिए नकली स्थान स्रोत बनाएं. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग वास्तविक स्थान स्रोतों जैसे GPS या नेटवर्क प्रदाताओं से वापस लौटे स्थान/या स्थिति ओवरराइड करने में कर सकती हैं."</string>
+ <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अतिरिक्त स्थान प्रदाता आदेशों में पहुंचे"</string>
+ <string name="permdesc_accessLocationExtraCommands" msgid="1948144701382451721">"अतिरिक्त स्थान प्रदाता आदेशों में पहुंचे. दुर्भावनापूर्ण एप्िलकेशन इसका उपयोग GPS या अन्य स्थान स्रोतों के संचालन में व्यवधान के लिए कर सकती हैं."</string>
+ <string name="permlab_installLocationProvider" msgid="6578101199825193873">"किसी स्थान प्रदाता को इंस्टॉल करने की अनुमति"</string>
+ <string name="permdesc_installLocationProvider" msgid="5449175116732002106">"परीक्षण के लिए नकली स्थान स्रोत बनाएं. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग वास्तविक स्थान स्रोतों जैसे GPS या नेटवर्क प्रदाताओं से वापस लौटे स्थान/या स्थिति ओवरराइड करने में या आपके स्थान की निगरानी करने और बाह्य स्रोत को रिपोर्ट करने में कर सकती हैं."</string>
+ <string name="permlab_accessFineLocation" msgid="8116127007541369477">"सही (GPS) स्थान"</string>
+ <string name="permdesc_accessFineLocation" product="tablet" msgid="243973693233359681">"सही स्थान स्रोतों में पहुंचें, जैसे टेबलेट पर वैश्विक स्थिति निर्धारण प्रणाली, जहां उपलब्ध हो. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग आपकी स्थिति का निर्धारण करने में कर सकती हैं और अतिरिक्त बैटरी पावर का उपभोग कर सकती हैं."</string>
+ <string name="permdesc_accessFineLocation" product="default" msgid="7411213317434337331">"सही स्थान स्रोतों में पहुंचें, जैसे फ़ोन पर वैश्विक स्थिति निर्धारण प्रणाली, जहां उपलब्ध हो. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग आपकी स्थिति का निर्धारण करने में कर सकती हैं और अतिरिक्त बैटरी पावर का उपभोग कर सकती हैं."</string>
+ <string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"ख़राब (नेटवर्क-आधारित) स्थान"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3704633168985466045">"सन्निकट टेबलेट स्थान निर्धारित करने के लिए ख़राब स्थान स्रोतों जैसे कि सेल्यूलर नेटवर्क डेटाबेस में पहुंचें, जहां उपलब्ध हो. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग यह निर्धारित करने में कर सकते हैं कि आप तकरीबन हैं कहां."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="8235655958070862293">"सन्निकट फ़ोन स्थान निर्धारित करने के लिए ख़राब स्थान स्रोतों जैसे कि सेल्यूलर नेटवर्क डेटाबेस में पहुंचें, जहां उपलब्ध हो. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग यह निर्धारित करने में कर सकती हैं कि आप तकरीबन हैं कहां."</string>
+ <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"SurfaceFlinger में पहुंचें"</string>
+ <string name="permdesc_accessSurfaceFlinger" msgid="6805241830020733025">"एप्लिकेशन को SurfaceFlinger निम्न-स्तर सुविधाओं का उपयोग करने की अनुमति देता है."</string>
+ <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"फ़्रेम बफ़र पढ़ें"</string>
+ <string name="permdesc_readFrameBuffer" msgid="7530020370469942528">"एप्लिकेशन को फ़्रेम बफ़र की सामग्री पढ़ने की अनुमति देता है."</string>
+ <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"अपनी ऑडियो सेटिंग बदलें"</string>
+ <string name="permdesc_modifyAudioSettings" msgid="5793461287365991922">"एप्लिकेशन को वैश्विक ऑडियो सेटिंग जैसे कि वॉल्यूम और रूटिंग, संशोधित करने की अनुमति देता है."</string>
+ <string name="permlab_recordAudio" msgid="3876049771427466323">"ऑडियो रिकॉर्ड करें"</string>
+ <string name="permdesc_recordAudio" msgid="6493228261176552356">"एप्लिकेशन को ऑडियो रिकॉर्ड पथ में पहुंच की अनुमति देता है."</string>
+ <string name="permlab_camera" msgid="3616391919559751192">"चित्र और वीडियो लें"</string>
+ <string name="permdesc_camera" msgid="6004878235852154239">"एप्लिकेशन को कैमरे से चित्र और वीडियो लेने की अनुमति देता है. यह एप्लिकेशन को किसी भी समय कैमरे द्वारा देखी जा रही छवियों को एकत्र करने की अनुमति देता है."</string>
+ <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"स्थायी रूप से टेबलेट अक्षम करें"</string>
+ <string name="permlab_brick" product="default" msgid="8337817093326370537">"फ़ोन को स्थायी रूप से अक्षम करें"</string>
+ <string name="permdesc_brick" product="tablet" msgid="7379164636920817963">"संपूर्ण टेबलेट को स्थायी रूप से अक्षम करने की अनुमति एप्लिकेशन को देता है. यह बहुत खतरनाक है."</string>
+ <string name="permdesc_brick" product="default" msgid="5569526552607599221">"संपूर्ण फ़ोन को स्थायी रूप से अक्षम करने की अनुमति एप्लिकेशन को देता है. यह बहुत खतरनाक है."</string>
+ <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"टेबलेट रीबूट के लिए बाध्य करें"</string>
+ <string name="permlab_reboot" product="default" msgid="2898560872462638242">"फ़ोन रीबूट के लिए बाध्य करें"</string>
+ <string name="permdesc_reboot" product="tablet" msgid="4555793623560701557">"एप्लिकेशन को टेबलेट रीबूट करने के लिए बाध्य करने की अनुमति देता है."</string>
+ <string name="permdesc_reboot" product="default" msgid="7914933292815491782">"फ़ोन को रीबूट करने के लिए बाध्य करने की अनुमति एप्लिकेशन को देता है."</string>
+ <string name="permlab_mount_unmount_filesystems" msgid="1761023272170956541">"फ़ाइलसिस्टम माउंट और अनमाउंट करें"</string>
+ <string name="permdesc_mount_unmount_filesystems" msgid="6253263792535859767">"एप्लिकेशन को निकाले जाने योग्य संग्रहण के लिए फ़ाइल सिस्टम माउंट और अनमाउंट करने की अनुमति देता है."</string>
+ <string name="permlab_mount_format_filesystems" msgid="5523285143576718981">"बाहरी संग्रहण प्रारूपित करें"</string>
+ <string name="permdesc_mount_format_filesystems" msgid="574060044906047386">"एप्लिकेशन को निकाले जाने योग्य संग्रहण को प्रारूपित करने की अनुमति देता है."</string>
+ <string name="permlab_asec_access" msgid="3411338632002193846">"आंतरिक संग्रहण पर जानकारी प्राप्त करें"</string>
+ <string name="permdesc_asec_access" msgid="8820326551687285439">"एप्लिकेशन को आंतरिक संग्रहण पर जानकारी प्राप्त करने की अनुमति देता है."</string>
+ <string name="permlab_asec_create" msgid="6414757234789336327">"आंतरिक संग्रहण बनाएं"</string>
+ <string name="permdesc_asec_create" msgid="2621346764995731250">"एप्लिकेशन को आंतरिक संग्रहण बनाने की अनुमति देता है."</string>
+ <string name="permlab_asec_destroy" msgid="526928328301618022">"आंतरिक संग्रहण नष्ट करें"</string>
+ <string name="permdesc_asec_destroy" msgid="2746706889208066256">"एप्लिकेशन को आंतरिक संग्रहण को नष्ट करने की अनुमति देता है."</string>
+ <string name="permlab_asec_mount_unmount" msgid="2456287623689029744">"आंतरिक संग्रहण माउंट / अनमाउंट करें"</string>
+ <string name="permdesc_asec_mount_unmount" msgid="5934375590189368200">"एप्लिकेशन को आंतरिक संग्रहण माउंट / अनमाउंट करने की अनुमति देता है."</string>
+ <string name="permlab_asec_rename" msgid="7496633954080472417">"आंतरिक संग्रहण का नाम बदलें"</string>
+ <string name="permdesc_asec_rename" msgid="2152829985238876790">"एप्लिकेशन को आंतरिक संग्रहण का नाम बदलने की अनुमति देता है."</string>
+ <string name="permlab_vibrate" msgid="7768356019980849603">"कंपनकर्त्ता को नियंत्रित करें"</string>
+ <string name="permdesc_vibrate" msgid="2886677177257789187">"एप्लिकेशन को कपंनकर्त्ता को नियंत्रित करने की अनुमति देता है."</string>
+ <string name="permlab_flashlight" msgid="2155920810121984215">"फ़्लैशलाइट नियंत्रित करें"</string>
+ <string name="permdesc_flashlight" msgid="6433045942283802309">"एप्लिकेशन को फ़्लैशलाइट नियंत्रित करने की अनुमति देता है."</string>
+ <string name="permlab_manageUsb" msgid="1113453430645402723">"USB उपकरणों की प्राथमिकताएं और अनुमतियां प्रबंधित करें"</string>
+ <string name="permdesc_manageUsb" msgid="6148489202092166164">"एप्लिकेशन को USB उपकरणों की प्राथमिकताओं और अनुमतियों को प्रबंधित करने की सुविधा देता है."</string>
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP प्रोटोकॉल लागू करें"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"MTP USB प्रोटोकॉल लागू करने के लिए कर्नेल MTP ड्राइवर में पहुंच की अनुमति देता है."</string>
+ <string name="permlab_hardware_test" msgid="4148290860400659146">"परीक्षण हार्डवेयर"</string>
+ <string name="permdesc_hardware_test" msgid="3668894686500081699">"किसी एप्लिकेशन को हार्डवेयर परीक्षण के लिए विविध पेरिफ़ेरल नियंत्रित करने की अनुमति देता है."</string>
+ <string name="permlab_callPhone" msgid="3925836347681847954">"फ़ोन नंबर पर सीधे कॉल करें"</string>
+ <string name="permdesc_callPhone" msgid="3369867353692722456">"एप्लिकेशन को बिना आपके हस्तक्षेप के फ़ोन नंबर पर कॉल करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन आपके फ़ोन बिल में अप्रत्याशित कॉल का कारण हो सकती हैं. ध्यान रखें कि यह एप्लिकेशन को आपातकालीन नंबर पर कॉल करने की अनुमति नहीं देता है."</string>
+ <string name="permlab_callPrivileged" msgid="4198349211108497879">"किसी भी फ़ोन नंबर पर सीधे कॉल करें"</string>
+ <string name="permdesc_callPrivileged" msgid="244405067160028452">"एप्लिकेशन को बिना आपके हस्तक्षेप के आपातकालीन नंबरों समेत किसी भी फ़ोन नंबर पर कॉल करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन आपातकालीन सेवाओं पर अनावश्यक और अवैध कॉल कर सकती हैं."</string>
+ <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"सीधे CDMA टेबलेट सेटअप प्रारंभ करें"</string>
+ <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"सीधे CDMA फ़ोन सेटअप प्रारंभ करें"</string>
+ <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"एप्लिकेशन को CDMA प्रावधानीकरण प्रारंभ करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन अनावश्यक रूप से CDMA प्रावधानीकरण प्रारंभ कर सकते हैं."</string>
+ <string name="permlab_locationUpdates" msgid="7785408253364335740">"स्थान अपडेट सूचनाएं नियंत्रित करें"</string>
+ <string name="permdesc_locationUpdates" msgid="2300018303720930256">"रेडियो से स्थान अपडेट सूचनाओं को सक्षम/अक्षम करने की अनुमति देता है. सामान्य एप्लिकेशन द्वारा उपयोग किए जाने के लिए नहीं है."</string>
+ <string name="permlab_checkinProperties" msgid="7855259461268734914">"चेकइन गुणों में पहुंचें"</string>
+ <string name="permdesc_checkinProperties" msgid="7150307006141883832">"चेकइन सेवा द्वारा अपलोड किए गए गुणों में पहुंच पढ़ने/लिखने की अनुमति देता है. सामान्य एप्लिकेशन द्वारा उपयोग किए जाने के लिए नहीं है."</string>
+ <string name="permlab_bindGadget" msgid="776905339015863471">"विजेट चुनें"</string>
+ <string name="permdesc_bindGadget" msgid="2098697834497452046">"किस एप्लिकेशन के साथ कौन से विजेट का उपयोग किया जा सकता है सिस्टम को यह बताने की अनुमति एप्लिकेशन को देता है. इस अनुमति के साथ, एप्लिकेशन दूसरी एप्लिकेशन को निजी डेटा में पहुंच प्रदान कर सकती है. सामान्य एप्लिकेशन द्वारा उपयोग किए जाने के लिए नहीं है."</string>
+ <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"फ़ोन स्थिति संशोधित करें"</string>
+ <string name="permdesc_modifyPhoneState" msgid="3302284561346956587">"एप्लिकेशन को उपकरण की फ़ोन सुविधाओं को नियंत्रित करने की अनुमति देता है. अनुमति प्राप्त एप्लिकेशन कभी भी आपको सूचित किए बिना नेटवर्क स्विच कर सकती है, फ़ोन रेडियो चालू और बंद एवं ऐसे ही अन्य कार्य कर सकती है."</string>
+ <string name="permlab_readPhoneState" msgid="2326172951448691631">"फ़ोन की स्थिति और पहचान पढें"</string>
+ <string name="permdesc_readPhoneState" msgid="188877305147626781">"एप्लिकेशन को उपकरण की फ़ोन सुविधाओं में पहुंच की अनुमति देता है. इस अनुमति के साथ वाला कोई एप्लिकेशन, कॉल सक्रिय हो या नहीं फिर भी इस फ़ोन का फ़ोन नंबर और क्रमांक, वह नंबर जिससे कॉल कनेक्ट की गई है और ऐसे ही अन्य नंबर निर्धारित कर सकती है."</string>
+ <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"टेबलेट को निष्क्रिय होने से रोकें"</string>
+ <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"फ़ोन को निष्क्रिय होने से रोकें"</string>
+ <string name="permdesc_wakeLock" product="tablet" msgid="4032181488045338551">"टेबलेट को निष्क्रिय होने से रोकने की अनुमति किसी एप्लिकेशन को देता है."</string>
+ <string name="permdesc_wakeLock" product="default" msgid="7584036471227467099">"फ़ोन को निष्क्रिय होने से रोकने की अनुमति किसी एप्लिकेशन को देता है."</string>
+ <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"टेबलेट चालू या बंद करें"</string>
+ <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"फ़ोन चालू या बंद करें"</string>
+ <string name="permdesc_devicePower" product="tablet" msgid="3853773100100451905">"एप्लिकेशन को टेबलेट चालू या बंद करने की अनुमति देता है."</string>
+ <string name="permdesc_devicePower" product="default" msgid="4577331933252444818">"एप्लिकेशन को फ़ोन चालू या बंद करने की अनुमति देता है."</string>
+ <string name="permlab_factoryTest" msgid="3715225492696416187">"फ़ैक्ट्री परीक्षण मोड में चलाएं"</string>
+ <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"टेबलेट हार्डवेयर में पूर्ण पहुंच की अनुमति देते हुए निम्न-स्तर निर्माता परीक्षण के रूप में चलाएं. केवल तभी उपलब्ध जब कोई टेबलेट निर्माता परीक्षण मोड में चल रहा हो."</string>
+ <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"फ़ोन हार्डवेयर में पूर्ण पहुंच की अनुमति देते हुए निम्न-स्तर निर्माता परीक्षण के रूप में चलाएं. केवल तभी उपलब्ध जब कोई फ़ोन निर्माता परीक्षण मोड में चल रहा हो."</string>
+ <string name="permlab_setWallpaper" msgid="6627192333373465143">"वॉलपेपर सेट करें"</string>
+ <string name="permdesc_setWallpaper" msgid="6417041752170585837">"एप्लिकेशन को सिस्टम वॉलपेपर सेट करने की अनुमति देता है."</string>
+ <string name="permlab_setWallpaperHints" msgid="3600721069353106851">"वॉलपेपर आकार सुझाव सेट करें"</string>
+ <string name="permdesc_setWallpaperHints" msgid="6019479164008079626">"एप्लिकेशन को सिस्टम वॉलपेपर आकार सुझाव सेट करने की अनुमति देता है."</string>
+ <string name="permlab_masterClear" msgid="2315750423139697397">"फ़ैक्ट्री डिफ़ॉल्ट पर सिस्टम रीसेट करें"</string>
+ <string name="permdesc_masterClear" msgid="5033465107545174514">"किसी एप्लिकेशन को सभी डेटा, कॉन्फ़िगरेशन और इंस्टॉल की हुई एप्लिकेशन मिटाते हुए सिस्टम को पूरी तरह से उसकी फ़ैक्ट्री सेटिंग पर रीसेट करने की अनुमति देता है."</string>
+ <string name="permlab_setTime" msgid="2021614829591775646">"समय सेट करें"</string>
+ <string name="permdesc_setTime" product="tablet" msgid="209693136361006073">"किसी एप्लिकेशन को टेबलेट की घड़ी का समय बदलने की अनुमति देता है."</string>
+ <string name="permdesc_setTime" product="default" msgid="667294309287080045">"किसी एप्लिकेशन को फ़ोन की घड़ी का समय बदलने की अनुमति देता है."</string>
+ <string name="permlab_setTimeZone" msgid="2945079801013077340">"समय क्षेत्र सेट करें"</string>
+ <string name="permdesc_setTimeZone" product="tablet" msgid="2522877107613885139">"किसी एप्लिकेशन को टेबलेट के समय क्षेत्र की बदलने की अनुमति देता है."</string>
+ <string name="permdesc_setTimeZone" product="default" msgid="1902540227418179364">"किसी एप्लिकेशन को फ़ोन का समय क्षेत्र बदलने की अनुमति देता है."</string>
+ <string name="permlab_accountManagerService" msgid="4829262349691386986">"खाता प्रबंधक सेवा के रूप में कार्य करें"</string>
+ <string name="permdesc_accountManagerService" msgid="6056903274106394752">"किसी एप्लिकेशन को खाता प्रमाणकर्त्ताओं को कॉल करने की अनुमति देता है"</string>
+ <string name="permlab_getAccounts" msgid="4549918644233460103">"ज्ञात खातों का पता लगाएं"</string>
+ <string name="permdesc_getAccounts" product="tablet" msgid="857622793935544694">"किसी एप्लिकेशन को टेबलेट द्वारा ज्ञात खातों की सूची प्राप्त करने की अनुमति देता है."</string>
+ <string name="permdesc_getAccounts" product="default" msgid="6839262446413155394">"किसी एप्िलकेशन को फ़ोन द्वारा ज्ञात खातों की सूची प्राप्त करने की अनुमति देता है."</string>
+ <string name="permlab_authenticateAccounts" msgid="3940505577982882450">"खाता प्रमाणकर्त्ता के रूप में कार्य करें"</string>
+ <string name="permdesc_authenticateAccounts" msgid="4006839406474208874">"एप्िलकेशन को खाता बनाने और उनके पासवर्ड प्राप्त करने और सेट करने समेत, खाता प्रबंधक की खाता प्रमाणीकरण क्षमताओं का उपयोग करने की अनुमति देता है."</string>
+ <string name="permlab_manageAccounts" msgid="4440380488312204365">"खाता सूची प्रबंधित करें"</string>
+ <string name="permdesc_manageAccounts" msgid="8804114016661104517">"किसी एप्लिकेशन को खातों को जोड़ना और निकालना एवं उनके पासवर्ड हटाना जैसी कार्रवाईयों को करने की अनुमति देता है."</string>
+ <string name="permlab_useCredentials" msgid="6401886092818819856">"किसी खाते के प्रमाणीकरण क्रेडेंशियल का उपयोग करें"</string>
+ <string name="permdesc_useCredentials" msgid="7416570544619546974">"किसी एप्लिकेशन को प्रमाणीकरण टोकन अनुरोध करने की अनुमति देता है."</string>
+ <string name="permlab_accessNetworkState" msgid="6865575199464405769">"नेटवर्क स्थिति देखें"</string>
+ <string name="permdesc_accessNetworkState" msgid="558721128707712766">"किसी एप्लिकेशन को सभी नेटवर्क की स्थिति देखने की अनुमति देता है."</string>
+ <string name="permlab_createNetworkSockets" msgid="9121633680349549585">"पूर्ण इंटरनेट पहुंच"</string>
+ <string name="permdesc_createNetworkSockets" msgid="4593339106921772192">"किसी एप्लिकेशन को नेटवर्क सॉकेट बनाने की अनुमति देता है."</string>
+ <string name="permlab_writeApnSettings" msgid="505660159675751896">"नेटवर्क सेटिंग और ट्रैफ़िक बदलें/रोकें"</string>
+ <string name="permdesc_writeApnSettings" msgid="2369786339323021771">"एप्लिकेशन को नेटवर्क सेटिंग बदलने और सभी नेटवर्क ट्रैफिक को रोकने और उनका निरीक्षण करने देता है, उदाहरण के लिए किसी APN की प्रॉक्सी और पोर्ट बदलना. दुर्भावनापूर्ण एप्लिकेशन आपकी जानकारी के बिना नेटवर्क पैकेट की निगरानी कर सकते हैं, रीडायरेक्ट, या संशोधित कर सकते हैं."</string>
+ <string name="permlab_changeNetworkState" msgid="958884291454327309">"नेटवर्क कनेक्टिविटी बदलें"</string>
+ <string name="permdesc_changeNetworkState" msgid="4199958910396387075">"किसी एप्लिकेशन को नेटवर्क कनेक्टिविटी की स्िथति बदलने की अनुमति देता है."</string>
+ <string name="permlab_changeTetherState" msgid="2702121155761140799">"टेदर की गई कनेक्टिविटी बदलें"</string>
+ <string name="permdesc_changeTetherState" msgid="8905815579146349568">"किसी एप्लिकेशन को टेदर किए गए नेटवर्क कनेक्टिविटी की स्िथति बदलने की अनुमति देता है."</string>
+ <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"पृष्ठभूमि डेटा उपयोग सेटिंग बदलें"</string>
+ <string name="permdesc_changeBackgroundDataSetting" msgid="1001482853266638864">"किसी एप्लिकेशन को पृष्ठभूमि डेटा उपयोग सेटिंग बदलने की अनुमति देता है."</string>
+ <string name="permlab_accessWifiState" msgid="8100926650211034400">"Wi-Fi स्थिति देखें"</string>
+ <string name="permdesc_accessWifiState" msgid="485796529139236346">"किसी एप्लिकेशन को Wi-Fi की स्थिति के बारे में जानकारी देखने की अनुमति देता है."</string>
+ <string name="permlab_changeWifiState" msgid="7280632711057112137">"Wi-Fi स्थिति बदलें"</string>
+ <string name="permdesc_changeWifiState" msgid="2950383153656873267">"किसी एप्लिकेशन को Wi-Fi पहुंच बिंदु से कनेक्ट और डिस्कनेक्ट करने और कॉन्फ़िगर किए हुए Wi-Fi नेटवर्क में परिवर्तन करने की अनुमति देता है."</string>
+ <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wi-Fi मल्टीकास्ट प्राप्ति को अनुमति दें"</string>
+ <string name="permdesc_changeWifiMulticastState" msgid="8199464507656067553">"किसी एप्लिकेशन को ऐसे पैकेट प्राप्त करने की अनुमति देता है जो सीधे आपके उपकरण के लिए संबोधित ना हो. आस-पास प्रस्तावित सेवाओं का पता चलने पर यह उपयोगी हो सकता है. यह ग़ैर-मल्टीकास्ट मोड से अधिक पावर का उपयोग करता है."</string>
+ <string name="permlab_bluetoothAdmin" msgid="1092209628459341292">"ब्लूटूथ व्यवस्थापन"</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="3511795757324345837">"किसी एप्लिकेशन को स्थानीय Bluetooth टेबलेट कॉन्फ़िगर करने की अनुमति देता है, और रिमोट उपकरणों के साथ खोजने और युग्मित करने की अनुमति देता है."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="7256289774667054555">"किसी एप्लिकेशन को स्थानीय Bluetooth फ़ोन कॉन्फ़िगर करने की अनुमति देता है, और रिमोट उपकरणों के साथ खोजने और युग्मित करने की अनुमति देता है."</string>
+ <string name="permlab_bluetooth" msgid="8361038707857018732">"Bluetooth कनेक्शन बनाएं"</string>
+ <string name="permdesc_bluetooth" product="tablet" msgid="4191941825910543803">"किसी एप्लिकेशन को स्थानीय Bluetooth टेबलेट का कॉन्फ़िगरेशन देखने की, और युग्मित उपकरणों के साथ कनेक्शन बनाने एवं स्वीकृत करने की अनुमति देता है."</string>
+ <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"किसी एप्लिकेशन को स्थानीय Bluetooth फ़ोन का कॉन्फ़िगरेशन देखने की, और युग्मित उपकरणों के साथ कनेक्शन बनाने एवं स्वीकृति देने की अनुमति देता है."</string>
+ <string name="permlab_nfc" msgid="4423351274757876953">"नियर फ़ील्ड कम्यूनिकेशन नियंत्रित करें"</string>
+ <string name="permdesc_nfc" msgid="9171401851954407226">"किसी एप्लिकेशन को नियर फ़ील्ड कम्यूनिकेशन (NFC) टैग, कार्ड और रीडर के साथ संचार करने की अनुमति देता है."</string>
+ <string name="permlab_disableKeyguard" msgid="4977406164311535092">"कीलॉक अक्षम करें"</string>
+ <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"किसी एप्लिकेशन को कीलॉक और संबद्ध पासवर्ड सुरक्षा को अक्षम करने की अनुमति देता है. एक विधिक उदाहरण यह है कि फ़ोन कीलॉक तब अक्षम करता है जब इनकमिंग फ़ोन कॉल प्राप्त हो रहा हो, फ़िर कॉल समाप्त हो जाने के बाद कीलॉक पुन: सक्षम करता है."</string>
+ <string name="permlab_readSyncSettings" msgid="6201810008230503052">"सिंक सेटिंग पढ़ें"</string>
+ <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"किसी एप्लिकेशन को सिंक सेटिंग पढ़ने की अनुमति देता है, जैसे संपर्कों के लिए सिंक सक्षम किया गया है या नहीं."</string>
+ <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"सिंक सेटिंग लिखें"</string>
+ <string name="permdesc_writeSyncSettings" msgid="2498201614431360044">"किसी एप्लिकेशन को सिंक सेटिंग संशोधित करने की अनुमति देता है, जैसे संपर्कों के लिए सिंक सक्षम किया गया है या नहीं."</string>
+ <string name="permlab_readSyncStats" msgid="7396577451360202448">"सिंक आंकड़े पढ़ें"</string>
+ <string name="permdesc_readSyncStats" msgid="7511448343374465000">"किसी एप्लिकेशन को सिंक आंकड़े पढ़ने की अनुमति देता है; जैसे, घटित हो चुके सिंक का इतिहास."</string>
+ <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ग्राहकी-प्राप्त फ़ीड पढ़ें"</string>
+ <string name="permdesc_subscribedFeedsRead" msgid="3622200625634207660">"किसी एप्लिकेशन को वर्तमान में सिंक किए गए फ़ीड के बारे में विवरण प्राप्त करने की अनुमति देता है."</string>
+ <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"ग्राहकी-प्राप्त फ़ीड लिखें"</string>
+ <string name="permdesc_subscribedFeedsWrite" msgid="8121607099326533878">"किसी एप्लिकेशन को आपके वर्तमान में सिंक किए गए फ़ीड संशोधित करने की अनुमति देता है. यह किसी दुर्भावनापूर्ण एप्लिकेशन को आपके सिंक किए गए फ़ीड को बदलने की अनुमति दे सकता है."</string>
+ <string name="permlab_readDictionary" msgid="432535716804748781">"उपयोगकर्ता परिभाषित शब्दकोष पढ़ें"</string>
+ <string name="permdesc_readDictionary" msgid="1082972603576360690">"किसी एप्लिकेशन को ऐसे निजी शब्दों, नामों या पदबंधों को पढ़ने की अनुमति देता है जो संभवत: उपयोगकर्ता द्वारा उपयोगकर्ता निर्देशिका में संग्रहीत किए गए हों."</string>
+ <string name="permlab_writeDictionary" msgid="6703109511836343341">"उपयोगकर्ता निर्धारित शब्दकोष में लिखें"</string>
+ <string name="permdesc_writeDictionary" msgid="2241256206524082880">"किसी एप्लिकेशन को उपयोगकर्ता शब्दकोष में नए शब्द लिखने की अनुमति देता है."</string>
+ <string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"USB संग्रहण सामग्रियों को संशोधित करें/हटाएं"</string>
+ <string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"SD कार्ड सामग्रियां संशोधित करें/हटाएं"</string>
+ <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"किसी एप्लिकेशन को USB संग्रहण पर लिखने की अनुमति देता है."</string>
+ <string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"किसी एप्लिकेशन को SD कार्ड पर लिखने की अनुमति देता है."</string>
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"आंतरिक मीडिया संग्रहण सामग्रियों को संशोधित करें/हटाएं"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"किसी एप्लिकेशन को आंतरिक मीडिया संग्रहण संशोधित करने की अनुमति देता है."</string>
+ <string name="permlab_cache_filesystem" msgid="5656487264819669824">"कैश फ़ाइल सिस्टम में पहंचे"</string>
+ <string name="permdesc_cache_filesystem" msgid="1624734528435659906">"किसी एप्लिकेशन को कैश फ़ाइल सिस्टम पढ़ने और लिखने की अनुमति देता है."</string>
+ <string name="permlab_use_sip" msgid="5986952362795870502">"इंटरनेट कॉल करें/प्राप्त करें"</string>
+ <string name="permdesc_use_sip" msgid="6320376185606661843">"किसी एप्लिकेशन को इंटरनेट कॉल करने/प्राप्त करने के लिए SIP सेवा का उपयोग करने की अनुमति देता है."</string>
+ <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"ऐतिहासिक नेटवर्क उपयोग पढें"</string>
+ <string name="permdesc_readNetworkUsageHistory" msgid="6040738474779135653">"किसी एप्लिकेशन को विशिष्ट नेटवर्कों और एप्लिकेशन के लिए ऐतिहासिक नेटवर्क उपयोग पढ़ने की अनुमति देता है."</string>
+ <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"नेटवर्क नीति प्रबंधित करें"</string>
+ <string name="permdesc_manageNetworkPolicy" msgid="3723795285132803958">"किसी एप्लिकेशन को नेटवर्क नीतियां प्रबंधित करने और एप्लिकेशन-विशिष्ट नियमों को परिभाषित करने की सुविधा देता है."</string>
+ <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"नेटवर्क उपयोग हिसाब संशोधित करें"</string>
+ <string name="permdesc_modifyNetworkAccounting" msgid="8702285686629184404">"एप्लिकेशन के लिए नेटवर्क उपयोग का हिसाब रखने का तरीका संशोधित करने देता है. सामान्य एप्लिकेशन द्वारा उपयोग के लिए नहीं है."</string>
+ <string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करें"</string>
+ <string name="policydesc_limitPassword" msgid="9083400080861728056">"स्क्रीन-अनलॉक पासवर्ड में अनुमति प्राप्त लंबाई और वर्णों को नियंत्रित करें"</string>
+ <string name="policylab_watchLogin" msgid="914130646942199503">"स्क्रीन-अनलॉक के प्रयासों पर निगरानी रखें"</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="933601759466308092">"स्क्रीन अनलॉक करने के दौरान गलत पासवर्ड लिखे जाने की संख्या पर नज़र रखता है, और यदि कई बार पासवर्ड गलत लिखा गया हो तो टेबलेट लॉक करता है या टेबलेट के सभी डेटा को मिटा देता है"</string>
+ <string name="policydesc_watchLogin" product="default" msgid="7227578260165172673">"स्क्रीन अनलॉक करने के दौरान गलत पासवर्ड लिखे जाने की संख्या पर नज़र रखता है, और यदि कई बार पासवर्ड गलत लिखा गया हो तो फ़ोन लॉक करता है या फ़ोन के सभी डेटा को मिटा देता है"</string>
+ <string name="policylab_resetPassword" msgid="2620077191242688955">"स्क्रीन-अनलॉक पासवर्ड बदलें"</string>
+ <string name="policydesc_resetPassword" msgid="5391240616981297361">"स्क्रीन-अनलॉक पासवर्ड बदलें"</string>
+ <string name="policylab_forceLock" msgid="2274085384704248431">"स्क्रीन लॉक करें"</string>
+ <string name="policydesc_forceLock" msgid="5696964126226028442">"नियंत्रित करें कि कैसे और कब स्क्रीन लॉक हो"</string>
+ <string name="policylab_wipeData" msgid="3910545446758639713">"सभी डेटा मिटाएं"</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="314455232799486222">"फ़ैक्ट्री डेटा रीसेट निष्पादित करके बिना चेतावनी के टेबलेट का डेटा मिटाएं"</string>
+ <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"फ़ैक्ट्री डेटा रीसेट करके, बिना चेतावनी के फ़ोन का डेटा मिटाएं"</string>
+ <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"उपकरण वैश्विक प्रॉक्सी सेट करें"</string>
+ <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"नीति सक्षम होने के दौरान उपकरण वैश्विक प्रॉक्सी सेट करें. केवल पहला उपकरण व्यवस्थापक, प्रभावी वैश्विक प्रॉक्सी सेट करता है."</string>
+ <string name="policylab_expirePassword" msgid="885279151847254056">"स्क्रीन लॉक करें पासवर्ड समाप्ति सेट करें"</string>
+ <string name="policydesc_expirePassword" msgid="4844430354224822074">"नियंत्रित करें कि कितने समय में स्क्रीन लॉक करें पासवर्ड बदला जाना चाहिए"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"संग्रहण एन्क्रिप्शन सेट करें"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"संग्रहीत एप्लिकेशन डेटा को एन्क्रिप्ट किए जाने की आवश्यकता होती है"</string>
+ <string name="policylab_disableCamera" msgid="6395301023152297826">"कैमरों को अक्षम करें"</string>
+ <string name="policydesc_disableCamera" msgid="5680054212889413366">"सभी उपकरण कैमरों का उपयोग रोकें"</string>
+ <string-array name="phoneTypes">
+ <item msgid="8901098336658710359">"घर"</item>
+ <item msgid="869923650527136615">"मोबाइल"</item>
+ <item msgid="7897544654242874543">"कार्यालय"</item>
+ <item msgid="1103601433382158155">"कार्यालय का फ़ैक्स"</item>
+ <item msgid="1735177144948329370">"घर का फ़ैक्स"</item>
+ <item msgid="603878674477207394">"पेजर"</item>
+ <item msgid="1650824275177931637">"अन्य"</item>
+ <item msgid="9192514806975898961">"कस्टम"</item>
+ </string-array>
+ <string-array name="emailAddressTypes">
+ <item msgid="8073994352956129127">"घर"</item>
+ <item msgid="7084237356602625604">"कार्यालय"</item>
+ <item msgid="1112044410659011023">"अन्य"</item>
+ <item msgid="2374913952870110618">"कस्टम"</item>
+ </string-array>
+ <string-array name="postalAddressTypes">
+ <item msgid="6880257626740047286">"घर"</item>
+ <item msgid="5629153956045109251">"कार्यालय"</item>
+ <item msgid="4966604264500343469">"अन्य"</item>
+ <item msgid="4932682847595299369">"कस्टम"</item>
+ </string-array>
+ <string-array name="imAddressTypes">
+ <item msgid="1738585194601476694">"घर"</item>
+ <item msgid="1359644565647383708">"कार्यालय"</item>
+ <item msgid="7868549401053615677">"अन्य"</item>
+ <item msgid="3145118944639869809">"कस्टम"</item>
+ </string-array>
+ <string-array name="organizationTypes">
+ <item msgid="7546335612189115615">"कार्यालय"</item>
+ <item msgid="4378074129049520373">"अन्य"</item>
+ <item msgid="3455047468583965104">"कस्टम"</item>
+ </string-array>
+ <string-array name="imProtocols">
+ <item msgid="8595261363518459565">"AIM"</item>
+ <item msgid="7390473628275490700">"Windows Live"</item>
+ <item msgid="7882877134931458217">"Yahoo"</item>
+ <item msgid="5035376313200585242">"Skype"</item>
+ <item msgid="7532363178459444943">"QQ"</item>
+ <item msgid="3713441034299660749">"Google टॉक"</item>
+ <item msgid="2506857312718630823">"ICQ"</item>
+ <item msgid="1648797903785279353">"Jabber"</item>
+ </string-array>
+ <string name="phoneTypeCustom" msgid="1644738059053355820">"कस्टम"</string>
+ <string name="phoneTypeHome" msgid="2570923463033985887">"घर"</string>
+ <string name="phoneTypeMobile" msgid="6501463557754751037">"मोबाइल"</string>
+ <string name="phoneTypeWork" msgid="8863939667059911633">"कार्यालय"</string>
+ <string name="phoneTypeFaxWork" msgid="3517792160008890912">"कार्यालय का फ़ैक्स"</string>
+ <string name="phoneTypeFaxHome" msgid="2067265972322971467">"घर का फ़ैक्स"</string>
+ <string name="phoneTypePager" msgid="7582359955394921732">"पेजर"</string>
+ <string name="phoneTypeOther" msgid="1544425847868765990">"अन्य"</string>
+ <string name="phoneTypeCallback" msgid="2712175203065678206">"पुन: कॉल करें"</string>
+ <string name="phoneTypeCar" msgid="8738360689616716982">"कार"</string>
+ <string name="phoneTypeCompanyMain" msgid="540434356461478916">"कंपनी का मुख्य"</string>
+ <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+ <string name="phoneTypeMain" msgid="6766137010628326916">"मुख्य"</string>
+ <string name="phoneTypeOtherFax" msgid="8587657145072446565">"अन्य फ़ैक्स"</string>
+ <string name="phoneTypeRadio" msgid="4093738079908667513">"रेडियो"</string>
+ <string name="phoneTypeTelex" msgid="3367879952476250512">"टेलेक्स"</string>
+ <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
+ <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"कार्यालय का मोबाइल"</string>
+ <string name="phoneTypeWorkPager" msgid="649938731231157056">"कार्यालय का पेजर"</string>
+ <string name="phoneTypeAssistant" msgid="5596772636128562884">"सहायक"</string>
+ <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
+ <string name="eventTypeCustom" msgid="7837586198458073404">"कस्टम"</string>
+ <string name="eventTypeBirthday" msgid="2813379844211390740">"जन्मदिन"</string>
+ <string name="eventTypeAnniversary" msgid="3876779744518284000">"वर्षगांठ"</string>
+ <string name="eventTypeOther" msgid="7388178939010143077">"अन्य"</string>
+ <string name="emailTypeCustom" msgid="8525960257804213846">"कस्टम"</string>
+ <string name="emailTypeHome" msgid="449227236140433919">"घर"</string>
+ <string name="emailTypeWork" msgid="3548058059601149973">"कार्यालय"</string>
+ <string name="emailTypeOther" msgid="2923008695272639549">"अन्य"</string>
+ <string name="emailTypeMobile" msgid="119919005321166205">"मोबाइल"</string>
+ <string name="postalTypeCustom" msgid="8903206903060479902">"कस्टम"</string>
+ <string name="postalTypeHome" msgid="8165756977184483097">"घर"</string>
+ <string name="postalTypeWork" msgid="5268172772387694495">"कार्यालय"</string>
+ <string name="postalTypeOther" msgid="2726111966623584341">"अन्य"</string>
+ <string name="imTypeCustom" msgid="2074028755527826046">"कस्टम"</string>
+ <string name="imTypeHome" msgid="6241181032954263892">"घर"</string>
+ <string name="imTypeWork" msgid="1371489290242433090">"कार्यालय"</string>
+ <string name="imTypeOther" msgid="5377007495735915478">"अन्य"</string>
+ <string name="imProtocolCustom" msgid="6919453836618749992">"कस्टम"</string>
+ <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
+ <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
+ <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
+ <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+ <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
+ <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google टॉक"</string>
+ <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
+ <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
+ <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
+ <string name="orgTypeWork" msgid="29268870505363872">"कार्यालय"</string>
+ <string name="orgTypeOther" msgid="3951781131570124082">"अन्य"</string>
+ <string name="orgTypeCustom" msgid="225523415372088322">"कस्टम"</string>
+ <string name="relationTypeCustom" msgid="3542403679827297300">"कस्टम"</string>
+ <string name="relationTypeAssistant" msgid="6274334825195379076">"सहायक"</string>
+ <string name="relationTypeBrother" msgid="8757913506784067713">"भाई"</string>
+ <string name="relationTypeChild" msgid="1890746277276881626">"बच्चा"</string>
+ <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"घरेलू सहयोगी"</string>
+ <string name="relationTypeFather" msgid="5228034687082050725">"पिता"</string>
+ <string name="relationTypeFriend" msgid="7313106762483391262">"मित्र"</string>
+ <string name="relationTypeManager" msgid="6365677861610137895">"प्रबंधक"</string>
+ <string name="relationTypeMother" msgid="4578571352962758304">"मां"</string>
+ <string name="relationTypeParent" msgid="4755635567562925226">"अभिभावक"</string>
+ <string name="relationTypePartner" msgid="7266490285120262781">"सहयोगी"</string>
+ <string name="relationTypeReferredBy" msgid="101573059844135524">"इसके द्वारा संदर्भित"</string>
+ <string name="relationTypeRelative" msgid="1799819930085610271">"संबंधी"</string>
+ <string name="relationTypeSister" msgid="1735983554479076481">"बहन"</string>
+ <string name="relationTypeSpouse" msgid="394136939428698117">"पति/पत्नी"</string>
+ <string name="sipAddressTypeCustom" msgid="2473580593111590945">"कस्टम"</string>
+ <string name="sipAddressTypeHome" msgid="6093598181069359295">"घर"</string>
+ <string name="sipAddressTypeWork" msgid="6920725730797099047">"कार्यालय"</string>
+ <string name="sipAddressTypeOther" msgid="4408436162950119849">"अन्य"</string>
+ <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"पिन कोड दर्ज करें"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="5965173481572346878">"PUK और नया पिन कोड लिखें"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK कोड"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="2987350144349051286">"नया पिन कोड"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"पासवर्ड दर्ज करने के लिए स्पर्श करें"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"अनलॉक करने के लिए पासवर्ड दर्ज करें"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"अनलॉक करने के लिए पिन दर्ज करें"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"गलत PIN कोड!"</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"अनलॉक करने के लिए, मेनू दबाएं और फिर 0 दबाएं."</string>
+ <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"आपातकालीन नंबर"</string>
+ <string name="lockscreen_carrier_default" msgid="8963839242565653192">"कोई सेवा नहीं."</string>
+ <string name="lockscreen_screen_locked" msgid="7288443074806832904">"स्क्रीन लॉक की गई है."</string>
+ <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"अनलॉक करने के लिए मेनू दबाएं या आपातलकालीन कॉल करें."</string>
+ <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"अनलॉक करने के लिए मेनू दबाएं."</string>
+ <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"अनलॉक करने के लिए प्रतिमान आरेखित करें"</string>
+ <string name="lockscreen_emergency_call" msgid="5347633784401285225">"आपातकालीन कॉल"</string>
+ <string name="lockscreen_return_to_call" msgid="5244259785500040021">"कॉल पर वापस लौटें"</string>
+ <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"सही!"</string>
+ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"क्षमा करें, पुन: प्रयास करें"</string>
+ <string name="lockscreen_password_wrong" msgid="6237443657358168819">"क्षमा करें, पुन: प्रयास करें"</string>
+ <string name="lockscreen_plugged_in" msgid="8057762828355572315">"चार्ज हो रही है, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <string name="lockscreen_charged" msgid="4938930459620989972">"चार्ज हो चुकी है."</string>
+ <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <string name="lockscreen_low_battery" msgid="1482873981919249740">"अपना चार्जर कनेक्ट करें."</string>
+ <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"कोई सिम कार्ड नहीं है."</string>
+ <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"टेबलेट में कोई सिम कार्ड नहीं है."</string>
+ <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"फ़ोन में कोई सिम कार्ड नहीं है."</string>
+ <string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"कृपया एक सिम कार्ड सम्मिलित करें."</string>
+ <string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"सिम कार्ड गुम है या पढ़ने योग्य नहीं है. कृपया सिम कार्ड डालें."</string>
+ <string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"आपका सिम कार्ड स्थायी रूप से अक्षम है."\n" कोई अन्य सिम कार्ड प्राप्त करने के लिए कृपया अपने वायरलेस सेवा प्रदाता से संपर्क करें."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"पिछला ट्रैक बटन"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"अगला ट्रैक बटन"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"रोकें बटन"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"चलाएं बटन"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"रोकें बटन"</string>
+ <string name="emergency_calls_only" msgid="6733978304386365407">"केवल आपातकालीन कॉल"</string>
+ <string name="lockscreen_network_locked_message" msgid="143389224986028501">"नेटवर्क लॉक किया गया"</string>
+ <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"सिम कार्ड PUK-लॉक किया हुआ है."</string>
+ <string name="lockscreen_sim_puk_locked_instructions" msgid="635967534992394321">"कृपया उपयोगकर्ता मार्गदर्शिका देखें या ग्राहक सहायता से संपर्क करें."</string>
+ <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"सिम कार्ड लॉक किया गया है."</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"सिम कार्ड अनलॉक कर रहा है…"</string>
+ <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="3514742106066877476">"आपने अपना अनलॉक वर्तमान में <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत आरेखित किया है. "\n\n"कृपया <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+ <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="4906034376425175381">"आपने अपना पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत दर्ज किया है. "\n\n"कृपया <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6827749231465145590">"आपने अपनी पिन <xliff:g id="NUMBER_0">%d</xliff:g> बार दर्ज की है. "\n\n"कृपया <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="8687762517114904651">"आपने अपना अनलॉक प्रतिमान गलत तरीके से <xliff:g id="NUMBER_0">%d</xliff:g> बार आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने Google साइन-इन का उपयोग करते हुए अपने टेबलेट को अनलॉक करने को कहा जाएगा."\n\n" कृपया <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="3351013842320127827">"आपने अपना अनलॉक प्रतिमान <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने Google साइन-इन का उपयोग करते हुए फ़ोन को अनलॉक करने को कहा जाएगा."\n\n" कृपया <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"आप गलत तरीके से टेबलेट को अनलॉक करने का प्रयास <xliff:g id="NUMBER_0">%d</xliff:g> बार कर चुके हैं. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयास के बाद, टेबलेट फ़ैक्टरी डिफ़ॉल्ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"आप गलत तरीके से फ़ोन को अनलॉक करने का प्रयास <xliff:g id="NUMBER_0">%d</xliff:g> बार कर चुके हैं. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयास के बाद, फ़ोन फ़ैक्टरी डिफ़ॉल्ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"आप टेबलेट को गलत तरीके से <xliff:g id="NUMBER">%d</xliff:g> बार अनलॉक करने का प्रयास कर चुके हैं. टेबलेट अब फ़ैक्टरी डिफ़ॉल्ट पर रीसेट हो जाएगा."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"आप फ़ोन को गलत तरीके से <xliff:g id="NUMBER">%d</xliff:g> बार अनलॉक करने का प्रयास कर चुके हैं. फ़ोन अब फ़ैक्टरी डिफ़ॉल्ट पर रीसेट हो जाएगा."</string>
+ <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+ <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"प्रतिमान भूल गए?"</string>
+ <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"खाता अनलॉक"</string>
+ <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"बहुत सारे प्रतिमान प्रयास!"</string>
+ <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"अनलॉक करने के लिए, अपने Google खाते के साथ साइन इन करें"</string>
+ <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"उपयोगकर्ता नाम (ईमेल)"</string>
+ <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"पासवर्ड"</string>
+ <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"साइन इन करें"</string>
+ <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"अमान्य उपयोगकर्ता नाम या पासवर्ड."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"अपना उपयोगकर्ता नाम या पासवर्ड भूल गए हैं?"\n<b>"google.com/accounts/recovery"</b>" पर जाएं"</string>
+ <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"जांच की जा रही है..."</string>
+ <string name="lockscreen_unlock_label" msgid="737440483220667054">"अनलॉक करें"</string>
+ <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"ध्वनि चालू करें"</string>
+ <string name="lockscreen_sound_off_label" msgid="996822825154319026">"ध्वनि बंद"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"प्रतिमान प्रारंभ किया गया"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"प्रतिमान साफ़ किया गया"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"कक्ष जोड़ा गया"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"प्रतिमान पूरा किया गया"</string>
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+ <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+ <string name="factorytest_failed" msgid="5410270329114212041">"फ़ैक्ट्री परीक्षण विफल"</string>
+ <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST क्रिया केवल /system/app में इंस्टॉल किए गए पैकेज के लिए समर्थित है."</string>
+ <string name="factorytest_no_action" msgid="872991874799998561">"ऐसा कोई पैकेज नहीं मिला था जो FACTORY_TEST कार्रवाई प्रदान करता हो."</string>
+ <string name="factorytest_reboot" msgid="6320168203050791643">"रीबूट करें"</string>
+ <string name="js_dialog_title" msgid="8143918455087008109">"\'<xliff:g id="TITLE">%s</xliff:g>\' पर पृष्ठ कहता है:"</string>
+ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
+ <string name="js_dialog_before_unload" msgid="1901675448179653089">"इस पृष्ठ से दूर नेविगेट करें?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"जारी रखने के लिए ठीक का चयन करें, या वर्तमान पृष्ठ पर रहने के लिए रद्द करें का चयन करें."</string>
+ <string name="save_password_label" msgid="6860261758665825069">"पुष्टि करें"</string>
+ <string name="double_tap_toast" msgid="1068216937244567247">"युक्ति: ज़म इन और आउट के लिए दो बार टैप करें."</string>
+ <string name="autofill_this_form" msgid="1272247532604569872">"स्वतः भरण"</string>
+ <string name="setup_autofill" msgid="8154593408885654044">"स्वत: भरण सेटअप करें"</string>
+ <string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+ <string name="autofill_province" msgid="2231806553863422300">"प्रांत"</string>
+ <string name="autofill_postal_code" msgid="4696430407689377108">"डाक कोड"</string>
+ <string name="autofill_state" msgid="6988894195520044613">"राज्य"</string>
+ <string name="autofill_zip_code" msgid="8697544592627322946">"ज़िप कोड"</string>
+ <string name="autofill_county" msgid="237073771020362891">"काउंटी"</string>
+ <string name="autofill_island" msgid="4020100875984667025">"द्वीप"</string>
+ <string name="autofill_district" msgid="8400735073392267672">"जिला"</string>
+ <string name="autofill_department" msgid="5343279462564453309">"विभाग"</string>
+ <string name="autofill_prefecture" msgid="2028499485065800419">"प्रशासकीय क्षेत्र"</string>
+ <string name="autofill_parish" msgid="8202206105468820057">"मोहल्ला"</string>
+ <string name="autofill_area" msgid="3547409050889952423">"क्षेत्र"</string>
+ <string name="autofill_emirate" msgid="2893880978835698818">"अमीरात"</string>
+ <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"ब्राउज़र का इतिहास और बुकमार्क पढ़ें"</string>
+ <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"एप्लिकेशन को ब्राउज़र द्वारा विज़िट किए गए सभी URL और ब्राउज़र के सभी बुकमार्क को पढ़ने की अनुमति देता है."</string>
+ <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"ब्राउज़र का इतिहास और बुकमार्क लिखें"</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="7193514090469945307">"किसी एप्लिकेशन को आपके टेबलेट पर संग्रहीत ब्राउज़र का इतिहास या बुकमार्क संशोधित करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन आपके ब्राउज़र के डेटा को मिटाने या संशोधित करने में इसका उपयोग कर सकती हैं."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"किसी एप्लिकेशन को आपके फ़ोन पर संग्रहीत ब्राउज़र का इतिहास या बुकमार्क संशोधित करने की सुविधा देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग आपके ब्राउज़र के डेटा को मिटाने या संशोधित करने में कर सकती हैं."</string>
+ <string name="permlab_setAlarm" msgid="5924401328803615165">"अलार्म क्लॉक में अलार्म सेट करें"</string>
+ <string name="permdesc_setAlarm" msgid="5966966598149875082">"किसी एप्लिकेशन को इंस्टॉल की गई अलार्म क्लॉक एप्लिकेशन में अलार्म सेट करने की अनुमति देता है. हो सकता है कुछ अलार्म क्लॉक एप्लिकेशन इस सुविधा को लागू नहीं कर सकें."</string>
+ <string name="permlab_addVoicemail" msgid="5525660026090959044">"ध्वनिमेल जोड़ें"</string>
+ <string name="permdesc_addVoicemail" msgid="4828507394878206682">"एप्लिकेशन को आपके ध्वनिमेल इनबॉक्स में संदेश जोड़ने देता है."</string>
+ <string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"ब्राउज़र भौगोलिक-स्थान अनुमतियों को संशोधित करें"</string>
+ <string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"किसी एप्लिकेशन को ब्राउज़र के भौगोलिक स्थान की अनुमतियों को संशोधित करने की अनुमति देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग स्वेच्छाचारी वेब साइट को स्थान जानकारी भेजने की अनुमति देने में कर सकती हैं."</string>
+ <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"पैकेज सत्यापित करें"</string>
+ <string name="permdesc_packageVerificationAgent" msgid="6033195477325381106">"एप्लिकेशन को इंस्टॉल करने योग्य पैकेज सत्यापित करने देता है."</string>
+ <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"पैकेज प्रमाणक से आबद्ध करें"</string>
+ <string name="permdesc_bindPackageVerifier" msgid="2409521927385789318">"धारक को पैकेज प्रमाणक के अनुरोध करने की अनुमति देता है. सामान्य एप्लिकेशन के लिए कभी आवश्यक नहीं होना चाहिए."</string>
+ <string name="save_password_message" msgid="767344687139195790">"क्या आप चाहते हैं कि ब्राउज़र पासवर्ड को याद रखे?"</string>
+ <string name="save_password_notnow" msgid="6389675316706699758">"अभी नहीं"</string>
+ <string name="save_password_remember" msgid="6491879678996749466">"याद रखें"</string>
+ <string name="save_password_never" msgid="8274330296785855105">"कभी नहीं"</string>
+ <string name="open_permission_deny" msgid="5661861460947222274">"आपके पास इस पृष्ठ को खोलने की अनुमति नहीं है."</string>
+ <string name="text_copied" msgid="4985729524670131385">"पाठ की क्लिपबोर्ड पर प्रतिलिपि बनाई गई."</string>
+ <string name="more_item_label" msgid="4650918923083320495">"अधिक"</string>
+ <string name="prepend_shortcut_label" msgid="2572214461676015642">"मेनू+"</string>
+ <string name="menu_space_shortcut_label" msgid="2410328639272162537">"space"</string>
+ <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
+ <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"हटाएं"</string>
+ <string name="search_go" msgid="8298016669822141719">"खोजें"</string>
+ <string name="searchview_description_search" msgid="6749826639098512120">"खोजें"</string>
+ <string name="searchview_description_query" msgid="5911778593125355124">"खोज क्वेरी"</string>
+ <string name="searchview_description_clear" msgid="1330281990951833033">"क्वेरी साफ़ करें"</string>
+ <string name="searchview_description_submit" msgid="2688450133297983542">"क्वेरी सबमिट करें"</string>
+ <string name="searchview_description_voice" msgid="2453203695674994440">"ध्वनि खोज"</string>
+ <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 माह पहले"</string>
+ <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 माह से पहले"</string>
+ <plurals name="num_seconds_ago">
+ <item quantity="one" msgid="4869870056547896011">"1 सेकंड पहले"</item>
+ <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> सेकंड पहले"</item>
+ </plurals>
+ <plurals name="num_minutes_ago">
+ <item quantity="one" msgid="3306787433088810191">"1 मिनट पहले"</item>
+ <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> मिनट पहले"</item>
+ </plurals>
+ <plurals name="num_hours_ago">
+ <item quantity="one" msgid="9150797944610821849">"1 घंटे पहले"</item>
+ <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> घंटे पहले"</item>
+ </plurals>
+ <plurals name="last_num_days">
+ <item quantity="other" msgid="3069992808164318268">"अंतिम <xliff:g id="COUNT">%d</xliff:g> दिन"</item>
+ </plurals>
+ <string name="last_month" msgid="3959346739979055432">"पिछला माह"</string>
+ <string name="older" msgid="5211975022815554840">"इससे पुराना"</string>
+ <plurals name="num_days_ago">
+ <item quantity="one" msgid="861358534398115820">"बीता कल"</item>
+ <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> दिन पहले"</item>
+ </plurals>
+ <plurals name="in_num_seconds">
+ <item quantity="one" msgid="2729745560954905102">"1 सेकंड में"</item>
+ <item quantity="other" msgid="1241926116443974687">"<xliff:g id="COUNT">%d</xliff:g> सेकंड में"</item>
+ </plurals>
+ <plurals name="in_num_minutes">
+ <item quantity="one" msgid="8793095251325200395">"1 मिनट में"</item>
+ <item quantity="other" msgid="3330713936399448749">"<xliff:g id="COUNT">%d</xliff:g> मिनट में"</item>
+ </plurals>
+ <plurals name="in_num_hours">
+ <item quantity="one" msgid="7164353342477769999">"1 घंटे में"</item>
+ <item quantity="other" msgid="547290677353727389">"<xliff:g id="COUNT">%d</xliff:g> घंटे में"</item>
+ </plurals>
+ <plurals name="in_num_days">
+ <item quantity="one" msgid="5413088743009839518">"आने वाला कल"</item>
+ <item quantity="other" msgid="5109449375100953247">"<xliff:g id="COUNT">%d</xliff:g> दिन में"</item>
+ </plurals>
+ <plurals name="abbrev_num_seconds_ago">
+ <item quantity="one" msgid="1849036840200069118">"1 सेकंड पहले"</item>
+ <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> सेकंड पहले"</item>
+ </plurals>
+ <plurals name="abbrev_num_minutes_ago">
+ <item quantity="one" msgid="6361490147113871545">"1 मिनट पहले"</item>
+ <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> मिनट पहले"</item>
+ </plurals>
+ <plurals name="abbrev_num_hours_ago">
+ <item quantity="one" msgid="4796212039724722116">"1 घंटे पहले"</item>
+ <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> घंटे पहले"</item>
+ </plurals>
+ <plurals name="abbrev_num_days_ago">
+ <item quantity="one" msgid="8463161711492680309">"बीता कल"</item>
+ <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> दिन पहले"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_seconds">
+ <item quantity="one" msgid="5842225370795066299">"1 सेकंड में"</item>
+ <item quantity="other" msgid="5495880108825805108">"<xliff:g id="COUNT">%d</xliff:g> सेकंड में"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_minutes">
+ <item quantity="one" msgid="562786149928284878">"1 मिनट में"</item>
+ <item quantity="other" msgid="4216113292706568726">"<xliff:g id="COUNT">%d</xliff:g> मिनट में"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_hours">
+ <item quantity="one" msgid="3274708118124045246">"1 घंटे में"</item>
+ <item quantity="other" msgid="3705373766798013406">"<xliff:g id="COUNT">%d</xliff:g> घंटे में"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_days">
+ <item quantity="one" msgid="2178576254385739855">"आने वाला कल"</item>
+ <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g> दिन में"</item>
+ </plurals>
+ <string name="preposition_for_date" msgid="9093949757757445117">"<xliff:g id="DATE">%s</xliff:g> को"</string>
+ <string name="preposition_for_time" msgid="5506831244263083793">"<xliff:g id="TIME">%s</xliff:g> पर"</string>
+ <string name="preposition_for_year" msgid="5040395640711867177">"<xliff:g id="YEAR">%s</xliff:g> में"</string>
+ <string name="day" msgid="8144195776058119424">"दिन"</string>
+ <string name="days" msgid="4774547661021344602">"दिन"</string>
+ <string name="hour" msgid="2126771916426189481">"घंटा"</string>
+ <string name="hours" msgid="894424005266852993">"घंटे"</string>
+ <string name="minute" msgid="9148878657703769868">"मिनट"</string>
+ <string name="minutes" msgid="5646001005827034509">"मिनट"</string>
+ <string name="second" msgid="3184235808021478">"सेकंड"</string>
+ <string name="seconds" msgid="3161515347216589235">"सेकंड"</string>
+ <string name="week" msgid="5617961537173061583">"सप्ताह"</string>
+ <string name="weeks" msgid="6509623834583944518">"सप्ताह"</string>
+ <string name="year" msgid="4001118221013892076">"वर्ष"</string>
+ <string name="years" msgid="6881577717993213522">"वर्ष"</string>
+ <string name="VideoView_error_title" msgid="3359437293118172396">"वीडियो चला नहीं सकते"</string>
+ <string name="VideoView_error_text_invalid_progressive_playback" msgid="897920883624437033">"क्षमा करें, यह वीडियो इस उपकरण की स्ट्रीमिंग के लिए मान्य नहीं है."</string>
+ <string name="VideoView_error_text_unknown" msgid="710301040038083944">"क्षमा करें, इस वीडियो को चलाया नहीं जा सकता."</string>
+ <string name="VideoView_error_button" msgid="2822238215100679592">"ठीक"</string>
+ <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="noon" msgid="7245353528818587908">"अपराह्न"</string>
+ <string name="Noon" msgid="3342127745230013127">"अपराह्न"</string>
+ <string name="midnight" msgid="7166259508850457595">"मध्यरात्रि"</string>
+ <string name="Midnight" msgid="5630806906897892201">"मध्यरात्रि"</string>
+ <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
+ <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
+ <string name="selectAll" msgid="6876518925844129331">"सभी का चयन करें"</string>
+ <string name="cut" msgid="3092569408438626261">"काटें"</string>
+ <string name="copy" msgid="2681946229533511987">"प्रतिलिपि बनाएं"</string>
+ <string name="paste" msgid="5629880836805036433">"चिपकाएं"</string>
+ <string name="replace" msgid="5781686059063148930">"बदलें•"</string>
+ <string name="delete" msgid="6098684844021697789">"हटाएं"</string>
+ <string name="copyUrl" msgid="2538211579596067402">"URL की प्रतिलिपि बनाएं"</string>
+ <string name="selectTextMode" msgid="6738556348861347240">"पाठ का चयन करें..."</string>
+ <string name="textSelectionCABTitle" msgid="5236850394370820357">"पाठ चयन"</string>
+ <string name="addToDictionary" msgid="9090375111134433012">"डिक्शनरी में जोड़ें"</string>
+ <string name="deleteText" msgid="7070985395199629156">"हटाएं"</string>
+ <string name="inputMethod" msgid="1653630062304567879">"इनपुट विधि"</string>
+ <string name="editTextMenuTitle" msgid="4909135564941815494">"पाठ क्रियाएं"</string>
+ <string name="low_internal_storage_view_title" msgid="1399732408701697546">"स्थान की कमी"</string>
+ <string name="low_internal_storage_view_text" product="tablet" msgid="4231085657068852042">"टेबलेट संग्रहण स्थान कम हो रहा है."</string>
+ <string name="low_internal_storage_view_text" product="default" msgid="635106544616378836">"फ़ोन संग्रहण स्थान कम हो रहा है."</string>
+ <string name="ok" msgid="5970060430562524910">"ठीक"</string>
+ <string name="cancel" msgid="6442560571259935130">"रद्द करें"</string>
+ <string name="yes" msgid="5362982303337969312">"ठीक"</string>
+ <string name="no" msgid="5141531044935541497">"रद्द करें"</string>
+ <string name="dialog_alert_title" msgid="2049658708609043103">"ध्यानाकर्षण"</string>
+ <string name="loading" msgid="1760724998928255250">"लोड हो रहा है..."</string>
+ <string name="capital_on" msgid="1544682755514494298">"चालू"</string>
+ <string name="capital_off" msgid="6815870386972805832">"बंद"</string>
+ <string name="whichApplication" msgid="4533185947064773386">"इसका उपयोग करके क्रिया पूर्ण करें"</string>
+ <string name="alwaysUse" msgid="4583018368000610438">"इस क्रिया के लिए डिफ़ॉल्ट रूप से उपयोग करें."</string>
+ <string name="clearDefaultHintMsg" msgid="4815455344600932173">"होम सेटिंग > एप्लिकेशन > एप्लिकेशन प्रबंधित करें में डिफ़ॉल्ट साफ़ करें."</string>
+ <string name="chooseActivity" msgid="1009246475582238425">"किसी क्रिया का चयन करें"</string>
+ <string name="chooseUsbActivity" msgid="7892597146032121735">"USB उपकरण के लिए किसी एप्लिकेशन का चयन करें"</string>
+ <string name="noApplications" msgid="1691104391758345586">"कोई एप्लिकेशन इस क्रिया को निष्पादित नहीं कर सकती."</string>
+ <string name="aerr_title" msgid="1905800560317137752"></string>
+ <string name="aerr_application" msgid="932628488013092776">"दुर्भाग्यवश, <xliff:g id="APPLICATION">%1$s</xliff:g> रुक गया है."</string>
+ <string name="aerr_process" msgid="4507058997035697579">"दुर्भाग्यवश, <xliff:g id="PROCESS">%1$s</xliff:g> प्रक्रिया रुक गई है."</string>
+ <string name="anr_title" msgid="4351948481459135709"></string>
+ <string name="anr_activity_application" msgid="8339738283149696827">"<xliff:g id="APPLICATION">%2$s</xliff:g> प्रतिसाद नहीं दे रहा है."\n\n"क्या आप इसे बंद करना चाहेंगे?"</string>
+ <string name="anr_activity_process" msgid="7018289416670457797">"<xliff:g id="ACTIVITY">%1$s</xliff:g> गतिविधि प्रतिसाद नहीं दे रही है."\n\n"क्या आप इसे बंद करना चाहेंगे?"</string>
+ <string name="anr_application_process" msgid="7208175830253210526">"<xliff:g id="APPLICATION">%1$s</xliff:g> प्रतिसाद नहीं दे रहा है. क्या आप इसे बंद करना चाहेंगे?"</string>
+ <string name="anr_process" msgid="306819947562555821">"<xliff:g id="PROCESS">%1$s</xliff:g> प्रक्रिया प्रतिसाद नहीं दे रही है."\n\n"क्या आप इसे बंद करना चाहेंगे?"</string>
+ <string name="force_close" msgid="8346072094521265605">"ठीक"</string>
+ <string name="report" msgid="4060218260984795706">"रिपोर्ट करें"</string>
+ <string name="wait" msgid="7147118217226317732">"प्रतीक्षा करें"</string>
+ <string name="launch_warning_title" msgid="8323761616052121936">"एप्लिकेशन रीडायरेक्ट की गई"</string>
+ <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> अभी चल रहा है."</string>
+ <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> को वास्तविक रूप से लॉन्च किया गया था."</string>
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"स्केल"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"हमेशा दिखाएं"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"इसे सेटिंग > एप्लिकेशन > एप्लिकेशन प्रबंधित करें के साथ पुन: सक्षम करें."</string>
+ <string name="smv_application" msgid="295583804361236288">"एप्लिकेशन <xliff:g id="APPLICATION">%1$s</xliff:g> (<xliff:g id="PROCESS">%2$s</xliff:g> प्रक्रिया) ने उसकी स्व-प्रवर्तित StrictMode नीति का उल्लंघन किया है."</string>
+ <string name="smv_process" msgid="5120397012047462446">"प्रक्रिया <xliff:g id="PROCESS">%1$s</xliff:g> ने उसकी स्व-प्रवर्तित StrictMode नीति का उल्लंघन किया है."</string>
+ <string name="android_upgrading_title" msgid="378740715658358071">"Android अपग्रेड हो रहा है..."</string>
+ <string name="android_upgrading_apk" msgid="274409861603566003">"<xliff:g id="NUMBER_1">%2$d</xliff:g> में से <xliff:g id="NUMBER_0">%1$d</xliff:g> एप्लिकेशन अनुकूलित हो रहा है."</string>
+ <string name="android_upgrading_starting_apps" msgid="7959542881906488763">"एप्लिकेशन प्रारंभ हो रहे हैं."</string>
+ <string name="android_upgrading_complete" msgid="1405954754112999229">"बूट समाप्त हो रहा है."</string>
+ <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> चल रही है"</string>
+ <string name="heavy_weight_notification_detail" msgid="2423977499339403402">"एप्लिकेशन पर स्विच करने के लिए चयन करें"</string>
+ <string name="heavy_weight_switcher_title" msgid="1135403633766694316">"एप्लिकेशन स्विच करें?"</string>
+ <string name="heavy_weight_switcher_text" msgid="4592075610079319667">"आप किसी नई एप्लिकेशन को चला सकें इसके पूर्व, पहले से चल रही दूसरी एप्लिकेशन को बंद किया जाना आवश्यक है."</string>
+ <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> पर वापस लौटें"</string>
+ <string name="old_app_description" msgid="942967900237208466">"नई एप्लिकेशन प्रारंभ ना करें."</string>
+ <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> प्रारंभ करें"</string>
+ <string name="new_app_description" msgid="6830398339826789493">"पुरानी एप्लिकेशन को बिना सहेजे बंद करें."</string>
+ <string name="sendText" msgid="5132506121645618310">"पाठ के लिए क्रिया का चयन करें"</string>
+ <string name="volume_ringtone" msgid="6885421406845734650">"रिंगर वॉल्यूम"</string>
+ <string name="volume_music" msgid="5421651157138628171">"मीडिया वॉल्यूम"</string>
+ <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Bluetooth द्वारा चलाया जा रहा है"</string>
+ <string name="volume_music_hint_silent_ringtone_selected" msgid="6158339745293431194">"मौन रिंगटोन का चयन किया गया"</string>
+ <string name="volume_call" msgid="3941680041282788711">"कॉल के दौरान वॉल्यूम"</string>
+ <string name="volume_bluetooth_call" msgid="2002891926351151534">"Bluetooth कॉल के दौरान वॉल्यूम"</string>
+ <string name="volume_alarm" msgid="1985191616042689100">"अलार्म वॉल्यूम"</string>
+ <string name="volume_notification" msgid="2422265656744276715">"सूचना वॉल्यूम"</string>
+ <string name="volume_unknown" msgid="1400219669770445902">"वॉल्यूम"</string>
+ <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetooth वॉल्यूम"</string>
+ <string name="volume_icon_description_ringer" msgid="3326003847006162496">"रिंगटोन वॉल्यूम"</string>
+ <string name="volume_icon_description_incall" msgid="8890073218154543397">"कॉल वॉल्यूम"</string>
+ <string name="volume_icon_description_media" msgid="4217311719665194215">"मीडिया वॉल्यूम"</string>
+ <string name="volume_icon_description_notification" msgid="7044986546477282274">"सूचना वॉल्यूम"</string>
+ <string name="ringtone_default" msgid="3789758980357696936">"डिफ़ॉल्ट रिंगटोन"</string>
+ <string name="ringtone_default_with_actual" msgid="8129563480895990372">"डिफ़ॉल्ट रिंगटोन (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+ <string name="ringtone_silent" msgid="4440324407807468713">"मौन"</string>
+ <string name="ringtone_picker_title" msgid="3515143939175119094">"रिंगटोन"</string>
+ <string name="ringtone_unknown" msgid="5477919988701784788">"अज्ञात रिंगटोन"</string>
+ <plurals name="wifi_available">
+ <item quantity="one" msgid="6654123987418168693">"Wi-Fi नेटवर्क उपलब्ध"</item>
+ <item quantity="other" msgid="4192424489168397386">"Wi-Fi नेटवर्क उपलब्ध"</item>
+ </plurals>
+ <plurals name="wifi_available_detailed">
+ <item quantity="one" msgid="1634101450343277345">"उपलब्ध Wi-Fi नेटवर्क खोलें"</item>
+ <item quantity="other" msgid="7915895323644292768">"खुले Wi-Fi नेटवर्क उपलब्ध है"</item>
+ </plurals>
+ <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi से कनेक्ट नहीं हो सका"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4917472096696322767">" के पास एक कमज़ोर इंटरनेट कनेक्शन है."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi प्रत्यक्ष"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Wi-Fi प्रत्यक्ष कार्यवाही प्रारंभ करें. इससे Wi-Fi क्लाइंट/हॉटस्पॉट कार्यवाही बंद हो जाएगी."</string>
+ <string name="wifi_p2p_failed_message" msgid="1820097493844848281">"Wi-Fi प्रत्यक्ष प्रारंभ नहीं हो सका"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"<xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g> से Wi-Fi प्रत्यक्ष कनेक्शन सेटअप अनुरोध. स्वीकार करने के लिए ठीक क्लिक करें."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"<xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g> से Wi-Fi प्रत्यक्ष कनेक्शन सेटअप अनुरोध. आगे बढ़ने के लिए पिन दर्ज करें."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"कनेक्शन सेटअप को आगे बढ़ाने के लिए WPS पिन <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> को साथी उपकरण <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> पर दर्ज करना आवश्यक है"</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi प्रत्यक्ष चालू है"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"सेटिंग के लिए स्पर्श करें"</string>
+ <string name="select_character" msgid="3365550120617701745">"वर्ण सम्मिलित करें"</string>
+ <string name="sms_control_default_app_name" msgid="7630529934366549163">"अज्ञात एप्लिकेशन"</string>
+ <string name="sms_control_title" msgid="7296612781128917719">"SMS संदेश भेज रहा है"</string>
+ <string name="sms_control_message" msgid="1289331457999236205">"बड़ी संख्या में SMS संदेश भेजे जा रहे हैं. जारी रखने के लिए \"ठीक\" का चयन करें, या भेजना बंद करने के लिए \"रद्द करें\" का चयन करें."</string>
+ <string name="sms_control_yes" msgid="2532062172402615953">"ठीक"</string>
+ <string name="sms_control_no" msgid="1715320703137199869">"रद्द करें"</string>
+ <string name="sim_removed_title" msgid="6227712319223226185">"सिमकार्ड निकाला गया"</string>
+ <string name="sim_removed_message" msgid="2333164559970958645">"मान्य सिम कार्ड डालकर पुन: प्रारंभ करने तक मोबाइल नेटवर्क अनुपलब्ध रहेगा."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"पूर्ण"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"सिम कार्ड जोड़ा गया"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"मोबाइल नेटवर्क पर पहुंचने के लिए आपको अपने उपकरण को पुन: प्रारंभ करना होगा."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"पुन: प्रारंभ करें"</string>
+ <string name="time_picker_dialog_title" msgid="8349362623068819295">"समय सेट करें"</string>
+ <string name="date_picker_dialog_title" msgid="5879450659453782278">"दिनांक सेट करें"</string>
+ <string name="date_time_set" msgid="5777075614321087758">"सेट करें"</string>
+ <string name="default_permission_group" msgid="2690160991405646128">"डिफ़ॉल्ट"</string>
+ <string name="no_permissions" msgid="7283357728219338112">"किसी अनुमति की आवश्यकता नहीं है"</string>
+ <string name="perms_hide" msgid="7283915391320676226"><b>"छुपाएं"</b></string>
+ <string name="perms_show_all" msgid="2671791163933091180"><b>"सभी दिखाएं"</b></string>
+ <string name="usb_storage_activity_title" msgid="2399289999608900443">"USB विशाल संग्रहण"</string>
+ <string name="usb_storage_title" msgid="5901459041398751495">"USB कनेक्ट किया गया"</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"आप USB द्वारा अपने कंप्यूटर से कनेक्ट हैं. यदि आप अपने कंप्यूटर और Android के USB संग्रहण के बीच फ़ाइलों की प्रतिलिपि बनाना चाहते हैं तो नीचे बटन को स्पर्श करें."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"आप USB द्वारा अपने कंप्यूटर से कनेक्ट हैं. यदि आपने कंप्यूटर और आपके Android के SD कार्ड के बीच फ़ाइलों की प्रतिलिपि बनाना चाहते हैं तो नीचे बटन को स्पर्श करें."</string>
+ <string name="usb_storage_button_mount" msgid="1052259930369508235">"USB संग्रहण चालू करें"</string>
+ <string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"USB विशाल संग्रहण के लिए आपके USB संग्रहण के उपयोग में समस्या है."</string>
+ <string name="usb_storage_error_message" product="default" msgid="120810397713773275">"USB विशाल संग्रहण के लिए आपके SD कार्ड का उपयोग करने में समस्या है."</string>
+ <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB कनेक्ट किया गया"</string>
+ <string name="usb_storage_notification_message" msgid="7380082404288219341">"आपके कंप्यूटर में/से फ़ाइल की प्रतिलिपि बनाने के लिए चयन करें."</string>
+ <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB संग्रहण बंद करें"</string>
+ <string name="usb_storage_stop_notification_message" msgid="2591813490269841539">"USB संग्रहण बंद करने के लिए चयन करें."</string>
+ <string name="usb_storage_stop_title" msgid="660129851708775853">"USB संग्रहण उपयोग में है"</string>
+ <string name="usb_storage_stop_message" product="nosdcard" msgid="1368842269463745067">"USB संग्रहण बंद करने के पहले, सुनिश्चित करें कि आपने अपने कंप्यूटर से अपने Android का USB संग्रहण अनमाउंट (“बाहर”) कर दिया है."</string>
+ <string name="usb_storage_stop_message" product="default" msgid="3613713396426604104">"USB संग्रहण बंद करने के पहले, सुनिश्चित करें कि आपने अपने कंप्यूटर से Android का SD कार्ड अनमाउंट (“बाहर”) कर दिया है."</string>
+ <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB संग्रहण बंद करें"</string>
+ <string name="usb_storage_stop_error_message" msgid="143881914840412108">"USB संग्रहण को बंद करने में समस्या थी. यह सुनिश्चित करने के लिए चेक करें कि आपने USB होस्ट को अनमाउंट किया है या नहीं, फिर पुन: प्रयास करें."</string>
+ <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB संग्रहण चालू करें"</string>
+ <string name="dlg_confirm_kill_storage_users_text" msgid="3202838234780505886">"यदि आप USB संग्रहण चालू करते हैं, तो आपके द्वारा उपयोग की जारी कुछ एप्लिकेशन बंद हो जाएंगी और जब तक आप USB संग्रहण बंद नहीं करते तब तक संभवत: अनुपलब्ध रहेंगी."</string>
+ <string name="dlg_error_title" msgid="7323658469626514207">"USB कार्यवाही विफल"</string>
+ <string name="dlg_ok" msgid="7376953167039865701">"ठीक"</string>
+ <string name="usb_mtp_notification_title" msgid="3699913097391550394">"किसी मीडिया उपकरण के रूप में कनेक्ट किया गया"</string>
+ <string name="usb_ptp_notification_title" msgid="1960817192216064833">"कैमरे के रूप में कनेक्ट करें"</string>
+ <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"किसी इंस्टॉलर के रूप में कनेक्ट किया गया"</string>
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB सहायक सामग्री से कनेक्ट किया गया"</string>
+ <string name="usb_notification_message" msgid="4447869605109736382">"अन्य USB विकल्पों के लिए स्पर्श करें"</string>
+ <string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"USB संग्रहण प्रारूपित करें"</string>
+ <string name="extmedia_format_title" product="default" msgid="8663247929551095854">"SD कार्ड प्रारूपित करें"</string>
+ <string name="extmedia_format_message" product="nosdcard" msgid="8296908079722897772">"USB संग्रहण में स्टोर की गई सभी फ़ाइल मिटाते हुए उसे फ़ार्मेट करें? क्रिया को पूर्ववत नहीं किया जा सकता है!"</string>
+ <string name="extmedia_format_message" product="default" msgid="3621369962433523619">"क्या आप वाकई SD कार्ड को प्रारूपित करना चाहते हैं? आपके कार्ड का सारा डेटा खो जाएगा."</string>
+ <string name="extmedia_format_button_format" msgid="4131064560127478695">"प्रारूपित करें"</string>
+ <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग करना कनेक्ट किया गया"</string>
+ <string name="adb_active_notification_message" msgid="8470296818270110396">"USB डीबग करना अक्षम करने के लिए चयन करें."</string>
+ <string name="select_input_method" msgid="6865512749462072765">"इनपुट विधि का चयन करें"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"इनपुट पद्धतियां कॉन्फ़िगर करें"</string>
+ <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+ <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+ <string name="candidates_style" msgid="4333913089637062257"><u>"उम्मीदवार"</u></string>
+ <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB संग्रहण तैयार किया जा रहा है"</string>
+ <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD कार्ड तैयार कर रहा है"</string>
+ <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"त्रुटियों की जांच कर रहा है."</string>
+ <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"रिक्त USB संग्रहण"</string>
+ <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"रिक्त SD कार्ड"</string>
+ <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="8623130522556087311">"USB संग्रहण रिक्त है या फ़ाइल सिस्टम असमर्थित है."</string>
+ <string name="ext_media_nofs_notification_message" product="default" msgid="3817704088027829380">"SD कार्ड रिक्त है या फ़ाइल सिस्टम असमर्थित है."</string>
+ <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"क्षतिग्रस्त USB संग्रहण"</string>
+ <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"क्षतिग्रस्त SD कार्ड"</string>
+ <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="529021299294450667">"USB संग्रहण क्षतिग्रस्त है. आपको उसे पुन: प्रारूपित करना पड़ सकता है."</string>
+ <string name="ext_media_unmountable_notification_message" product="default" msgid="6902531775948238989">"SD कार्ड क्षतिग्रस्त है. आपको इसे पुन: प्रारूपित करना पड़ सकता है."</string>
+ <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB संग्रहण अप्रत्याशित रूप से निकाला गया"</string>
+ <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD कार्ड को अनपेक्षित रूप से निकाल दिया गया"</string>
+ <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"डेटा हानि से बचने के लिए निकालने से पहले USB संग्रहण अनमाउंट करें."</string>
+ <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"डेटा हानि से बचने के लिए निकालने से पहले SD कार्ड अनमाउंट करें."</string>
+ <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB संग्रहण निकालने के लिए सुरक्षित है"</string>
+ <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD कार्ड निकालने के लिए सुरक्षित है"</string>
+ <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"आप USB संग्रहण को सुरक्षित रूप से निकाल सकते हैं."</string>
+ <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"आप SD कार्ड को सुरक्षित रूप से निकाल सकते हैं."</string>
+ <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"USB संग्रहण निकाला गया"</string>
+ <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"SD कार्ड निकाल दिया गया है"</string>
+ <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB संग्रहण निकाला गया. नया मीडिया सम्मिलित करें."</string>
+ <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD कार्ड निकाला गया. एक नया सम्मिलित करें."</string>
+ <string name="activity_list_empty" msgid="4168820609403385789">"कोई मिलती जुलती गतिविधि नहीं मिली"</string>
+ <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"घटक उपयोग आंकड़े अपडेट करें"</string>
+ <string name="permdesc_pkgUsageStats" msgid="891553695716752835">"संकलित घटक उपयोग आंकड़ो के संशोधन की अनुमति देता है. सामान्य एप्लिकेशन द्वारा उपयोग किए जाने के लिए नहीं है."</string>
+ <string name="permlab_copyProtectedData" msgid="1660908117394854464">"सामग्री की प्रतिलिपि बनाने के लिए डिफ़ॉल्ट कंटेनर सेवा के बुलावे की अनुमति देता है. सामान्य एप्लिकेशन द्वारा उपयोग किए जाने के लिए नहीं है."</string>
+ <string name="permdesc_copyProtectedData" msgid="537780957633976401">"सामग्री की प्रतिलिपि बनाने के लिए डिफ़ॉल्ट कंटेनर सेवा के बुलावे की अनुमति देता है. सामान्य एप्लिकेशन द्वारा उपयोग किए जाने के लिए नहीं है."</string>
+ <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"ज़ूम नियंत्रण के लिए दो बार टैप करें"</string>
+ <string name="gadget_host_error_inflating" msgid="2613287218853846830">"त्रुटि वर्धक विजेट"</string>
+ <string name="ime_action_go" msgid="8320845651737369027">"जाएं"</string>
+ <string name="ime_action_search" msgid="658110271822807811">"खोजें"</string>
+ <string name="ime_action_send" msgid="2316166556349314424">"भेजें"</string>
+ <string name="ime_action_next" msgid="3138843904009813834">"अगला"</string>
+ <string name="ime_action_done" msgid="8971516117910934605">"पूर्ण"</string>
+ <string name="ime_action_previous" msgid="1443550039250105948">"पिछला"</string>
+ <string name="ime_action_default" msgid="2840921885558045721">"निष्पादित करें"</string>
+ <string name="dial_number_using" msgid="5789176425167573586">"<xliff:g id="NUMBER">%s</xliff:g> के उपयोग द्वारा "\n" नंबर डायल करें"</string>
+ <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g> का उपयोग करके"\n" संपर्क बनाएं"</string>
+ <string name="grant_credentials_permission_message_header" msgid="6824538733852821001">"निम्न एक या अधिक एप्लिकेशन अभी और भविष्य में आपके खाते में पहुंच के लिए अनुमति का अनुरोध करती हैं."</string>
+ <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"क्या आप इस अनुरोध को अनुमति देना चाहते हैं?"</string>
+ <string name="grant_permissions_header_text" msgid="2722567482180797717">"पहुंच अनुरोध"</string>
+ <string name="allow" msgid="7225948811296386551">"अनुमति दें"</string>
+ <string name="deny" msgid="2081879885755434506">"अस्वीकारें"</string>
+ <string name="permission_request_notification_title" msgid="5390555465778213840">"अनुमति अनुरोधित"</string>
+ <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"<xliff:g id="ACCOUNT">%s</xliff:g> खाते के लिए "\n"अनुमति का अनुरोध किया गया"</string>
+ <string name="input_method_binding_label" msgid="1283557179944992649">"इनपुट विधि"</string>
+ <string name="sync_binding_label" msgid="3687969138375092423">"सिंक"</string>
+ <string name="accessibility_binding_label" msgid="4148120742096474641">"पहुंच-योग्यता"</string>
+ <string name="wallpaper_binding_label" msgid="1240087844304687662">"वॉलपेपर"</string>
+ <string name="chooser_wallpaper" msgid="7873476199295190279">"वॉलपेपर बदलें"</string>
+ <string name="vpn_title" msgid="8219003246858087489">"VPN सक्रिय है."</string>
+ <string name="vpn_title_long" msgid="6400714798049252294">"VPN को <xliff:g id="APP">%s</xliff:g> द्वारा सक्रिय किया गया है"</string>
+ <string name="vpn_text" msgid="1610714069627824309">"नेटवर्क प्रबंधित करने के लिए टैप करें."</string>
+ <string name="vpn_text_long" msgid="4907843483284977618">"<xliff:g id="SESSION">%s</xliff:g> से कनेक्ट किया गया. नेटवर्क प्रबंधित करने के लिए टैप करें."</string>
+ <string name="upload_file" msgid="2897957172366730416">"फ़ाइल चुनें"</string>
+ <string name="no_file_chosen" msgid="6363648562170759465">"कोई फ़ाइल चुनी नहीं गई"</string>
+ <string name="reset" msgid="2448168080964209908">"रीसेट करें"</string>
+ <string name="submit" msgid="1602335572089911941">"सबमिट करें"</string>
+ <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"कार मोड सक्षम किया गया"</string>
+ <string name="car_mode_disable_notification_message" msgid="668663626721675614">"कार मोड से बाहर निकलने के लिए चयन करें."</string>
+ <string name="tethered_notification_title" msgid="3146694234398202601">"टेदरिंग या हॉटस्पॉट सक्रिय"</string>
+ <string name="tethered_notification_message" msgid="3067108323903048927">"कॉन्फ़िगर करने के लिए स्पर्श करें"</string>
+ <string name="back_button_label" msgid="2300470004503343439">"वापस जाएं"</string>
+ <string name="next_button_label" msgid="1080555104677992408">"अगला"</string>
+ <string name="skip_button_label" msgid="1275362299471631819">"छोड़ें"</string>
+ <string name="throttle_warning_notification_title" msgid="4890894267454867276">"उच्च मोबाइल डेटा उपयोग"</string>
+ <string name="throttle_warning_notification_message" msgid="2609734763845705708">"मोबाइल डेटा उपयोग के बारे में अधिक जानने के लिए स्पर्श करें"</string>
+ <string name="throttled_notification_title" msgid="6269541897729781332">"मोबाइल डेटा अधिकतम सीमा से अधिक है"</string>
+ <string name="throttled_notification_message" msgid="4712369856601275146">"मोबाइल डेटा उपयोग के बारे में अधिक जानने के लिए स्पर्श करें"</string>
+ <string name="no_matches" msgid="8129421908915840737">"कोई मिलान नहीं"</string>
+ <string name="find_on_page" msgid="1946799233822820384">"पृष्ठ पर ढूंढें"</string>
+ <plurals name="matches_found">
+ <item quantity="one" msgid="8167147081136579439">"1 मिलान"</item>
+ <item quantity="other" msgid="4641872797067609177">"<xliff:g id="TOTAL">%d</xliff:g> में से <xliff:g id="INDEX">%d</xliff:g>"</item>
+ </plurals>
+ <string name="action_mode_done" msgid="7217581640461922289">"पूर्ण"</string>
+ <string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"USB संग्रहण अनमाउंट कर रहा है..."</string>
+ <string name="progress_unmounting" product="default" msgid="5556813978958789471">"SD कार्ड अनमाउंट कर रहा है..."</string>
+ <string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"USB संग्रहण मिटा रहा है..."</string>
+ <string name="progress_erasing" product="default" msgid="2115214724367534095">"SD कार्ड मिटा रहा है..."</string>
+ <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB संग्रहण नहीं मिटाया जा सका."</string>
+ <string name="format_error" product="default" msgid="7315248696644510935">"SD कार्ड नहीं मिटाया जा सका."</string>
+ <string name="media_bad_removal" msgid="7960864061016603281">"SD कार्ड को अनमाउंट होने से पहले निकाल दिया गया था."</string>
+ <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB संग्रहण वर्तमान में जांचा जा रहा है."</string>
+ <string name="media_checking" product="default" msgid="7334762503904827481">"SD कार्ड वर्तमान में जांचा जा रहा है."</string>
+ <string name="media_removed" msgid="7001526905057952097">"SD कार्ड निकाल दिया गया है."</string>
+ <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"USB संग्रहण का उपयोग वर्तमान में एक कंप्यूटर द्वारा किया जा रहा है."</string>
+ <string name="media_shared" product="default" msgid="5706130568133540435">"SD कार्ड का उपयोग वर्तमान में एक कंप्यूटर द्वारा किया जा रहा है."</string>
+ <string name="media_unknown_state" msgid="729192782197290385">"बाह्य मीडिया अज्ञात स्थिति में है."</string>
+ <string name="share" msgid="1778686618230011964">"शेयर करें"</string>
+ <string name="find" msgid="4808270900322985960">"ढूंढें"</string>
+ <string name="websearch" msgid="4337157977400211589">"वेब खोज"</string>
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> की ओर से स्थान अनुरोध"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"स्थान अनुरोध"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) द्वारा अनुरोधित"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"हां"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"नहीं"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"हटाने की सीमा पार हो गई"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> खाते के लिए <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> हटाए गए आइटम हैं. आप क्या करना चाहेंगे?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"आइटम हटाएं."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"हटाए गए को पूर्ववत करें."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"अभी कुछ न करें."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"किसी खाते का चयन करें"</string>
+ <string name="add_account_label" msgid="2935267344849993553">"कोई खाता जोड़ें"</string>
+ <string name="choose_account_text" msgid="6891230675141555481">"आप किस खाते का उपयोग करना चाहेंगे?"</string>
+ <string name="add_account_button_label" msgid="3611982894853435874">"खाता जोड़ें"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"वृद्धि"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"कमी"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="1343063395404990189">"<xliff:g id="VALUE">%s</xliff:g> टैप करके रखें."</string>
+ <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"बढ़ते क्रम के लिए ऊपर और घटते क्रम के लिए नीचे की ओर स्लाइड करें."</string>
+ <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"बढ़ते क्रम में मिनट"</string>
+ <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"घटते क्रम में मिनट"</string>
+ <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"बढ़ते क्रम में घंटा"</string>
+ <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"घटते क्रम में घंटा"</string>
+ <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"सायं सेट करें"</string>
+ <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"प्रात: सेट करें"</string>
+ <string name="date_picker_increment_month_button" msgid="6324978841467899081">"बढ़ते क्रम में माह"</string>
+ <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"घटते क्रम में माह"</string>
+ <string name="date_picker_increment_day_button" msgid="4397040141921413183">"बढ़ते क्रम में दिन"</string>
+ <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"घटते क्रम में दिन"</string>
+ <string name="date_picker_increment_year_button" msgid="3058553394722295105">"बढ़ते क्रम में वर्ष"</string>
+ <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"घटते क्रम में वर्ष"</string>
+ <string name="checkbox_checked" msgid="7222044992652711167">"चेक किया गया"</string>
+ <string name="checkbox_not_checked" msgid="5174639551134444056">"चेक नहीं किया गया"</string>
+ <string name="radiobutton_selected" msgid="8603599808486581511">"चयनित"</string>
+ <string name="radiobutton_not_selected" msgid="2908760184307722393">"चयनित नहीं"</string>
+ <string name="switch_on" msgid="551417728476977311">"चालू"</string>
+ <string name="switch_off" msgid="7249798614327155088">"बंद"</string>
+ <string name="togglebutton_pressed" msgid="4180411746647422233">"दबाया गया"</string>
+ <string name="togglebutton_not_pressed" msgid="4495147725636134425">"दबाया नहीं गया."</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"रद्द करें"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"हटाएं"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"पूर्ण"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mode change"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"कोई एप्लिकेशन चुनें"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"इसके साथ साझा करें:"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> के साथ साझा करें"</string>
+ <string name="content_description_sliding_handle" msgid="7311938669217173870">"स्लाइडिंग हैंडल. टैप करके रखें."</string>
+ <string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए ऊपर."</string>
+ <string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए नीचे."</string>
+ <string name="description_direction_left" msgid="6814008463839915747">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए बाएं."</string>
+ <string name="description_direction_right" msgid="4296057241963012862">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए दाएं."</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"अनलॉक करें"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"कैमरा"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"मौन"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"ध्वनि चालू करें"</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"ज़ोर से बोली गईं पासवर्ड कुंजियां सुनने के लिए हेडसेट प्लग इन करें."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"बिंदु."</string>
+ <string name="action_bar_home_description" msgid="5293600496601490216">"होम पर नेविगेट करें"</string>
+ <string name="action_bar_up_description" msgid="2237496562952152589">"ऊपर नेविगेट करें"</string>
+ <string name="action_menu_overflow_description" msgid="2295659037509008453">"अधिक विकल्प"</string>
+ <string name="storage_internal" msgid="7556050805474115618">"आंतरिक संग्रहण"</string>
+ <string name="storage_sd_card" msgid="8921771478629812343">"SD कार्ड"</string>
+ <string name="storage_usb" msgid="3017954059538517278">"USB संग्रहण"</string>
+ <string name="extract_edit_menu_button" msgid="302060189057163906">"संपादित करें..."</string>
+ <string name="data_usage_warning_title" msgid="1955638862122232342">"डेटा उपयोग की चेतावनी"</string>
+ <string name="data_usage_warning_body" msgid="7217480745540055170">"उपयोग व सेटिंग देखने हेतु स्पर्श करें"</string>
+ <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G डेटा अक्षम किया गया"</string>
+ <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G डेटा अक्षम किया गया"</string>
+ <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"मोबाइल डेटा अक्षम किया गया"</string>
+ <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi-Fi डेटा अक्षम हो गया"</string>
+ <string name="data_usage_limit_body" msgid="4313857592916426843">"सक्षम करने के लिए स्पर्श करें"</string>
+ <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G डेटा सीमा पार हो गई है"</string>
+ <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G डेटा सीमा पार हो गई है"</string>
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"मोबाइल डेटा सीमा पार हो गई है"</string>
+ <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi डेटा सीमा पार हो गई है"</string>
+ <string name="data_usage_limit_snoozed_body" msgid="2932736326652880660">"<xliff:g id="SIZE">%s</xliff:g> निर्दिष्ट सीमा से अधिक"</string>
+ <string name="data_usage_restricted_title" msgid="5965157361036321914">"पृष्ठभूमि डेटा प्रतिबंधित है"</string>
+ <string name="data_usage_restricted_body" msgid="5087354814839059798">"प्रतिबंध निकालने के लिए स्पर्श करें"</string>
+ <string name="ssl_certificate" msgid="6510040486049237639">"सुरक्षा प्रमाणपत्र"</string>
+ <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"यह प्रमाणपत्र मान्य है."</string>
+ <string name="issued_to" msgid="454239480274921032">"इन्हें जारी किया गया:"</string>
+ <string name="common_name" msgid="2233209299434172646">"सामान्य नाम:"</string>
+ <string name="org_name" msgid="6973561190762085236">"संगठन:"</string>
+ <string name="org_unit" msgid="7265981890422070383">"संगठनात्मक इकाई:"</string>
+ <string name="issued_by" msgid="2647584988057481566">"जारीकर्ता:"</string>
+ <string name="validity_period" msgid="8818886137545983110">"मान्यता:"</string>
+ <string name="issued_on" msgid="5895017404361397232">"जारी करने का दिनांक:"</string>
+ <string name="expires_on" msgid="3676242949915959821">"समय समाप्ति दिनांक:"</string>
+ <string name="serial_number" msgid="758814067660862493">"क्रमांक:"</string>
+ <string name="fingerprints" msgid="4516019619850763049">"फ़िंगरप्रिंट:"</string>
+ <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 फ़िंगरप्रिंट:"</string>
+ <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 फ़िंगरप्रिंट:"</string>
+ <string name="activity_chooser_view_see_all" msgid="180268188117163072">"सभी देखें..."</string>
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"गतिविधि का चयन करें"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"इससे साझा करें..."</string>
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"उपकरण लॉक कर दिया गया."</string>
+ <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 37a8fd1..62e753f 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Aplikaciji omogućuje čitanje osobnih informacija profila koje su pohranjene na vašem uređaju, poput vašeg imena i kontaktnih podataka. To znači da vas aplikacija može identificirati i slati informacije vašeg profila drugima."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"pisanje u podatke profila"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Aplikaciji omogućuje promjenu ili dodavanje informacija u osobne informacije profila koje su spremljene na vašem uređaju, poput vašeg imena i kontaktnih podataka. To znači da vas druge aplikacije mogu identificirati i slati informacije vašeg profila drugima."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"čitanje društvenog streama"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Aplikaciji omogućuje pristup i sinkronizaciju društvenih ažuriranja vaših prijatelja. Zlonamjerne aplikacije to mogu upotrijebiti za pristup privatnim porukama između vas i vaših prijatelja na društvenim mrežama."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"pisanje društvenog streama"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Aplikaciji omogućuje prikazivanje društvenih ažuriranja vaših prijatelja. Zlonamjerne aplikacije to mogu upotrijebiti kako bi se predstavile kao prijatelj i zavarale vas da otkrijete zaporke ili druge povjerljive informacije."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"čitajte kalendarske događaje i povjerljive informacije"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Aplikaciji omogućuje čitanje svih kalendarskih događaja pohranjenih na tabletnom računalu, uključujući događaje prijatelja ili suradnika. Zlonamjerna aplikacija s tim dopuštenjem može izdvajati osobne podatke iz tih kalendara bez znanja vlasnika."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Aplikaciji omogućuje čitanje svih kalendarskih događaja na vašem telefonu, uključujući događaje prijatelja ili suradnika. Zlonamjerne aplikacije s tim dopuštenjem mogu izdvajati osobne podatke iz tih kalendara bez znanja vlasnika."</string>
@@ -661,6 +665,16 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Umetnite SIM karticu."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Nedostaje SIM kartica ili nije čitljiva. Umetnite SIM karticu."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Vaša SIM kartica trajno je onemogućena."\n"Obratite se svom pružatelju bežičnih usluga za dobivanje druge SIM kartice."</string>
+ <!-- no translation found for lockscreen_transport_prev_description (201594905152746886) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_next_description (6089297650481292363) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_pause_description (7659088786780128001) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_play_description (5888422938351019426) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_stop_description (4562318378766987601) -->
+ <skip />
<string name="emergency_calls_only" msgid="6733978304386365407">"Samo hitni pozivi"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Mreža je zaključana"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM kartica je zaključana PUK-om."</string>
@@ -690,6 +704,14 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Otključaj"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Zvuk je uključen"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Zvuk isključen"</string>
+ <!-- no translation found for lockscreen_access_pattern_start (3941045502933142847) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_cleared (5583479721001639579) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_cell_added (6756031208359292487) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_detected (4988730895554057058) -->
+ <skip />
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1144,6 +1166,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Promjena načina"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Odaberite aplikaciju"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Dijeljenje sa"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Dijeli s aplikacijom <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Klizna ručka. Dotaknite i držite."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Gore za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Dolje za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1178,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Fotoaparat"</string>
<string name="description_target_silent" msgid="893551287746522182">"Bešumno"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Zvuk je uključen"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Tipka. Da bi se pri upisivanju zaporke čule tipke, potrebne su slušalice."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Priključite slušalice da biste čuli tipke zaporke izgovorene naglas."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Točka."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Kreni na početnu"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Kreni gore"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Više opcija"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 913ea39..b2b61e6 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Engedélyezi, hogy az alkalmazás a készüléken tárolt személyes profiladatokat olvassa, például az Ön nevét és elérhetőségét. Ez azt jelenti, az alkalmazás képes az Ön azonosítására, és elküldheti a profiladatokat másoknak."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"írás a profiladatokba"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Engedélyezi, hogy az alkalmazás megváltoztassa vagy hozzáadja a készüléken tárolt személyes profiladatokat, például az Ön nevét és elérhetőségét. Ez azt jelenti, hogy más alkalmazások is azonosíthatják Önt, és elküldhetik a profiladatokat másoknak."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"közösségi adatfolyam olvasása"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Lehetővé teszi az alkalmazásnak, hogy hozzáférjen közösségi frissítéseihez, és szinkronizálja azokat. Rosszindulatú alkalmazások használhatják ezt, hogy hozzáférjenek barátaival történő magánbeszélgetéseihez a közösségi hálózatokon."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"írás a közösség adatfolyamra"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Lehetővé teszi az alkalmazásnak, hogy megjelenítse barátai közösségi frissítéseit. Rosszindulatú alkalmazások használhatják ezt ismerősnek tettetve magukat, hogy jelszavakat és más bizalmas információt csaljanak ki Öntől."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"naptári események és bizalmas információk beolvasása"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Lehetővé teszi egy alkalmazás számára a táblagépén található összes naptári esemény beolvasását, beleértve az ismerőseihez vagy munkatársaihoz tartozó eseményeket is. Ha egy rosszindulatú alkalmazás megkapja ezt az engedélyt, akkor vissza tudja fejteni a személyes adatokat ezekből a naptárakból, a tulajdonos tudomása nélkül."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Lehetővé teszi egy alkalmazás részére, hogy beolvassa a telefonján tárolt összes naptáreseményt, beleértve az ismerősök és kollégák eseményeit is. Ha egy rosszindulatú alkalmazás megkapja ezt az engedélyt, akkor vissza tudja fejteni a személyes adatokat ezekből a naptárakból, a tulajdonos tudomása nélkül."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Kérjük, helyezzen be egy SIM-kártyát."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"A SIM-kártya hiányzik vagy nem olvasható. Helyezzen be egy SIM-kártyát."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"SIM-kártyája véglegesen letiltva."\n" Kérjük, forduljon a vezeték nélküli szolgáltatójához másik SIM-kártya beszerzése érdekében."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Előző szám gomb"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Következő szám gomb"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Szünet gomb"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Lejátszás gomb"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Leállítás gomb"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Csak segélyhívások"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"A hálózat lezárva"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"A SIM-kártya le van zárva a PUK-kóddal."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Feloldás"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Hang bekapcsolása"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Hang kikapcsolva"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Minta elindítva"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Minta törölve"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cella hozzáadva"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Minta befejezve"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"Kivágás"</string>
<string name="copy" msgid="2681946229533511987">"Másolás"</string>
<string name="paste" msgid="5629880836805036433">"Beillesztés"</string>
- <string name="replace" msgid="5781686059063148930">"Csere???"</string>
+ <string name="replace" msgid="5781686059063148930">"Csere..."</string>
<string name="delete" msgid="6098684844021697789">"Törlés"</string>
<string name="copyUrl" msgid="2538211579596067402">"URL másolása"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Szöveg kijelölése..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mód váltása"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Válasszon egy alkalmazást"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Megosztás a következővel:"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Ossza meg a következő alkalmazással: <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Csúsztatható fogantyú. Érintse meg és tartsa."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Fel: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
<string name="description_direction_down" msgid="4294993639091088240">"Le: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Némítás"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Hang bekapcsolása"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Billentyű. Fülhallgató szükséges, ha hallani szeretné a billentyűket a jelszó megadása közben."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Csatlakoztasson egy fejhallgatót, ha hallani szeretné a jelszó gombjait felolvasva."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Pont."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Ugrás a főoldalra"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Felfele mozgás"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"További lehetőségek"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index b48cba4..1f74260 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -220,7 +220,7 @@
<string name="permdesc_enableCarMode" msgid="5673461159384850628">"Mengizinkan aplikasi mengaktifkan mode mobil."</string>
<string name="permlab_killBackgroundProcesses" msgid="8373714752793061963">"hentikan proses latar belakang"</string>
<string name="permdesc_killBackgroundProcesses" msgid="2908829602869383753">"Mengizinkan aplikasi menghentikan proses latar belakang dari aplikasi lainnya, meskipun memori rendah."</string>
- <string name="permlab_forceStopPackages" msgid="1447830113260156236">"paksa berhenti aplikasi yang lain"</string>
+ <string name="permlab_forceStopPackages" msgid="1447830113260156236">"paksa aplikasi lain berhenti"</string>
<string name="permdesc_forceStopPackages" msgid="7263036616161367402">"Mengizinkan aplikasi menghentikan aplikasi lain secara paksa."</string>
<string name="permlab_forceBack" msgid="1804196839880393631">"tutup paksa aplikasi"</string>
<string name="permdesc_forceBack" msgid="6534109744159919013">"Mengizinkan aplikasi menutup dan mengembalikan aktivitas apa pun yang berada di latar depan secara paksa. Tidak pernah diperlukan untuk aplikasi normal."</string>
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Memungkinkan aplikasi membaca informasi profil pribadi yang tersimpan pada perangkat Anda, seperti nama dan informasi kontak. Artinya aplikasi dapat mengidentifikasi Anda dan mengirimkan informasi profil Anda kepada orang lain."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"menulis ke data profil Anda"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Memungkinkan aplikasi mengubah atau menambah informasi profil pribadi yang tersimpan pada perangkat Anda, seperti nama dan informasi kontak. Artinya aplikasi lain dapat mengidentifikasi Anda dan mengirimkan informasi profil Anda kepada orang lain."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"membaca aliran sosial Anda"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Mengizinkan aplikasi untuk mengakses dan menyinkronkan pembaruan sosial dari Anda dan teman. Aplikasi berbahaya dapat menggunakan ini untuk membaca komunikasi pribadi antara Anda dan teman di jaringan sosial."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"menulis ke aliran sosial Anda"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Mengizinkan aplikasi untuk menampilkan pembaruan sosial dari teman Anda. Aplikasi berbahaya dapat menggunakan ini untuk berpura-pura menjadi seorang teman dan menipu Anda untuk mengungkapkan sandi atau informasi rahasia lainnya."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"baca acara kalender serta informasi rahasia"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Memungkinkan aplikasi membaca semua acara kalender yang disimpan pada tablet Anda, termasuk acara teman atau rekan kerja. Aplikasi berbahaya dengan izin ini dapat mengambil informasi pribadi dari kalender ini tanpa sepengetahuan pemilik."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Memungkinkan aplikasi membaca semua acara kalender yang disimpan di ponsel Anda, termasuk acara teman atau rekan kerja. Aplikasi berbahaya dengan izin ini dapat mengambil informasi pribadi dari kalender ini tanpa sepengetahuan pemilik."</string>
@@ -661,6 +665,16 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Masukkan kartu SIM"</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Kartu SIM tidak ada atau tidak dapat dibaca. Masukkan kartu SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Kartu SIM Anda dinonaktifkan secara permanen."\n" Hubungi penyedia layanan nirkabel Anda untuk mendapatkan kartu SIM lainnya."</string>
+ <!-- no translation found for lockscreen_transport_prev_description (201594905152746886) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_next_description (6089297650481292363) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_pause_description (7659088786780128001) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_play_description (5888422938351019426) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_stop_description (4562318378766987601) -->
+ <skip />
<string name="emergency_calls_only" msgid="6733978304386365407">"Panggilan darurat saja"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Jaringan terkunci"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Kartu SIM terkunci PUK."</string>
@@ -690,6 +704,14 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Buka kunci"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Suara hidup"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Suara mati"</string>
+ <!-- no translation found for lockscreen_access_pattern_start (3941045502933142847) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_cleared (5583479721001639579) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_cell_added (6756031208359292487) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_detected (4988730895554057058) -->
+ <skip />
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +877,7 @@
<string name="cut" msgid="3092569408438626261">"Potong"</string>
<string name="copy" msgid="2681946229533511987">"Salin"</string>
<string name="paste" msgid="5629880836805036433">"Tempel"</string>
- <string name="replace" msgid="5781686059063148930">"Ganti???"</string>
+ <string name="replace" msgid="5781686059063148930">"Ganti..."</string>
<string name="delete" msgid="6098684844021697789">"Hapus"</string>
<string name="copyUrl" msgid="2538211579596067402">"Salin URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Pilih teks..."</string>
@@ -989,9 +1011,9 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="3202838234780505886">"Jika Anda menghidupkan penyimpanan USB, sebagian aplikasi yang Anda gunakan akan berhenti dan mungkin tidak tersedia sampai Anda mematikan penyimpanan USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Operasi USB gagal"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Terhubung sebagai perangkat media"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Terhubung sebagai kamera"</string>
- <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Terhubung sebagai pemasang"</string>
+ <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Tersambung sebagai perangkat media"</string>
+ <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Tersambung sebagai kamera"</string>
+ <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Tersambung sebagai pemasang"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tersambung ke aksesori USB"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Sentuh untuk opsi USB lainnya"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Format penyimpanan USB"</string>
@@ -1144,6 +1166,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Pengubahan mode"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Pilih aplikasi"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Berbagi dengan"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Berbagi dengan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Gagang geser. Ketuk dan tahan."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Ke bawah untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1178,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Senyap"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Suara hidup"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Tombol. Perlu headset untuk mendengarkan suara tombol saat mengetik sandi."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Pasang headset untuk mendengar tombol sandi yang diucapkan dengan keras."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Titik."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Navigasi ke beranda"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navigasi naik"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Opsi lainnya"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 91ad6c1..9646d6a 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Consente all\'applicazione di leggere le informazioni del profilo personale memorizzato sul dispositivo, come il tuo nome e le tue informazioni di contatto. Ciò significa che l\'applicazione è in grado di identificarti e di inviare le tue informazioni di profilo ad altri."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"scrittura dati del profilo"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Consente all\'applicazione di modificare o aggiungere informazioni al profilo personale memorizzato sul dispositivo, come il tuo nome e le tue informazioni di contatto. Ciò significa che altre applicazioni sono in grado di identificarti e di inviare le tue informazioni di profilo ad altri."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lettura del tuo stream sociale"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Consente all\'applicazione di accedere agli aggiornamenti tuoi e dei tuoi amici dai social network e di sincronizzarli. Le applicazioni dannose possono farne uso per accedere alle comunicazioni private tra te e i tuoi amici sui social network."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"scrittura nel tuo stream sociale"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Consente all\'applicazione di visualizzare aggiornamenti dai tuoi amici che utilizzano social network. Le applicazioni dannose possono farne uso per impersonare un amico e indurti a rivelare password o altre informazioni riservate."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"lettura di eventi di calendario e di informazioni riservate"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Consente a un\'applicazione di leggere tutti gli eventi di calendario memorizzati sul tablet, compresi quelli di amici o colleghi. Un\'applicazione dannosa con questa autorizzazione può estrarre informazioni personali dai calendari a insaputa dei proprietari."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Consente a un\'applicazione di leggere tutti gli eventi di calendario memorizzati sul telefono, compresi quelli di amici o colleghi. Un\'applicazione dannosa con questa autorizzazione può estrarre informazioni personali dai calendari a insaputa dei proprietari."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Inserisci una SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Scheda SIM mancante o non leggibile. Inserisci una scheda SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"La scheda SIM è stata disattivata definitivamente."\n" Contatta il fornitore del tuo servizio wireless per ricevere un\'altra scheda SIM."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Pulsante traccia precedente"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Pulsante traccia successiva"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pulsante Pausa"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Pulsante Riproduci"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Pulsante di arresto"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Solo chiamate di emergenza"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Rete bloccata"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"La SIM è bloccata tramite PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Sblocca"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Audio attivato"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Audio disattivato"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Sequenza iniziata"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Sequenza cancellata"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cella aggiunta"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Sequenza completata"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -882,8 +895,8 @@
<string name="chooseUsbActivity" msgid="7892597146032121735">"Seleziona un\'applicazione per il dispositivo USB"</string>
<string name="noApplications" msgid="1691104391758345586">"Nessuna applicazione è in grado di svolgere questa azione."</string>
<string name="aerr_title" msgid="1905800560317137752"></string>
- <string name="aerr_application" msgid="932628488013092776">"Purtroppo l\'applicazione <xliff:g id="APPLICATION">%1$s</xliff:g> si è bloccata in modo anomalo."</string>
- <string name="aerr_process" msgid="4507058997035697579">"Purtroppo il processo <xliff:g id="PROCESS">%1$s</xliff:g> si è interrotto."</string>
+ <string name="aerr_application" msgid="932628488013092776">"L\'applicazione <xliff:g id="APPLICATION">%1$s</xliff:g> si è bloccata in modo anomalo."</string>
+ <string name="aerr_process" msgid="4507058997035697579">"Il processo <xliff:g id="PROCESS">%1$s</xliff:g> si è interrotto."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="8339738283149696827">"<xliff:g id="APPLICATION">%2$s</xliff:g> non risponde."\n\n"Vuoi chiuderla?"</string>
<string name="anr_activity_process" msgid="7018289416670457797">"L\'attività <xliff:g id="ACTIVITY">%1$s</xliff:g> non risponde."\n\n"Vuoi chiuderla?"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Cambio modalità"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Maiuscolo"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Invio"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Scegli un\'applicazione"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Condividi con"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Condividi con <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Maniglia scorrevole. Tocca e tieni premuto."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Su per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Giù per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Fotocamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Silenzioso"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Audio attivato"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Tasto. Set auricolari richiesto per udire i tasti durante la digitazione di una password."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Collega gli auricolari per ascoltare la pronuncia dei tasti premuti per la password."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punto."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Vai alla home page"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Vai in alto"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Altre opzioni"</string>
@@ -1175,7 +1192,7 @@
<string name="data_usage_limit_snoozed_body" msgid="2932736326652880660">"<xliff:g id="SIZE">%s</xliff:g> oltre il limite indicato"</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Dati in background limitati"</string>
<string name="data_usage_restricted_body" msgid="5087354814839059798">"Tocca per rimuovere restrizione"</string>
- <string name="ssl_certificate" msgid="6510040486049237639">"Certificato di protezione"</string>
+ <string name="ssl_certificate" msgid="6510040486049237639">"Certificato di sicurezza"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Questo certificato è valido."</string>
<string name="issued_to" msgid="454239480274921032">"Rilasciato a:"</string>
<string name="common_name" msgid="2233209299434172646">"Nome comune:"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 9216007..232232c 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -29,8 +29,7 @@
<string name="fileSizeSuffix" msgid="7670819340156489359">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="6071602020171759109">"<ללא כותרת>"</string>
<string name="ellipsis" msgid="7899829516048813237">"???"</string>
- <!-- no translation found for ellipsis_two_dots (1228078994866030736) -->
- <skip />
+ <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(אין מספר טלפון)"</string>
<string name="unknownName" msgid="2277556546742746522">"(לא ידוע)"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"דואר קולי"</string>
@@ -331,11 +330,15 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"מאפשר ליישום לקרוא נתוני פרופיל אישי המאוחסנים במכשיר שלך, כגון שמך ופרטי הקשר שלך. משמעות הדבר היא שהיישום יכול לזהות אותך ולשלוח את נתוני הפרופיל שלך לאחרים."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"כתוב בנתוני הפרופיל שלך"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"מאפשר ליישום לשנות או להוסיף לנתוני הפרופיל האישי המאוחסנים במכשיר, כגון שמך ופרטי הקשר שלך. משמעות הדבר היא שיישומים אחרים יכולים לזהות אותך ולשלוח את נתוני הפרופיל שלך לאחרים."</string>
- <string name="permlab_readCalendar" msgid="5972727560257612398">"קריאת אירועי לוח שנה וגם מידע סודי"</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"קריאת הזרם החברתי שלך"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"מאפשר ליישום לגשת לעדכונים חברתיים מהחברים שלך ולסנכרן אותם. יישומים זדוניים יוכלו להשתמש בכך כדי לגשת למסרים שהועברו באופן פרטי בינך לבין חבריך ברשתות חברתיות."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"כתיבה בזרם החברתי שלך"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"מאפשר ליישום להציג עדכונים חברתיים מהחברים שלך. יישומים זדוניים יוכלו להשתמש בכך כדי להתחזות לאחד מחבריך ולדלות ממך בדרכי מרמה סיסמאות או מידע סודי אחר."</string>
+ <string name="permlab_readCalendar" msgid="5972727560257612398">"קריאת אירועי יומן וגם מידע סודי"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"מאפשר ליישום לקרוא את כל אירועי לוח השנה שמאוחסנים בטבלט שלך, כולל אירועים של חברים או עמיתים לעבודה. יישום זדוני בעל הרשאה זו יוכל לחלץ מידע אישי מלוחות שנה אלה ללא ידיעת הבעלים."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"מאפשר ליישום לקרוא את כל אירועי לוח השנה המאוחסנים בטלפון שלך, כולל אירועים של חברים או עמיתים לעבודה. יישום זדוני בעל הרשאה זו יוכל לחלץ מידע אישי מלוחות השנה האלה ללא ידיעת הבעלים."</string>
- <string name="permlab_writeCalendar" msgid="8438874755193825647">"הוספה ושינוי של אירועי לוח שנה ושליחת דוא\"ל לאורחים ללא ידיעת הבעלים"</string>
- <string name="permdesc_writeCalendar" msgid="5368129321997977226">"מאפשר ליישום לשלוח הזמנות לאירוע בתור הבעלים של לוח השנה ולהוסיף, להסיר ולשנות אירועים שניתן לשנות במכשיר, כולל אלה של חברים או עמיתים לעבודה. יישום זדוני בעל הרשאה זו יוכל לשלוח הודעות דואר זבל שייראו כאילו נשלחו מהבעלים של לוח השנה, לשנות אירועים ללא ידיעת הבעלים או להוסיף אירועים מזויפים."</string>
+ <string name="permlab_writeCalendar" msgid="8438874755193825647">"הוספה ושינוי של אירועי יומן ושליחת דוא\"ל לאורחים ללא ידיעת הבעלים"</string>
+ <string name="permdesc_writeCalendar" msgid="5368129321997977226">"מאפשר ליישום לשלוח הזמנות לאירוע בתור הבעלים של לוח השנה ולהוסיף, להסיר ולשנות אירועים שניתן לשנות במכשיר, כולל אלה של חברים או עמיתים לעבודה. יישום זדוני בעל הרשאה זו יוכל לשלוח הודעות ספאם שייראו כאילו נשלחו מהבעלים של לוח השנה, לשנות אירועים ללא ידיעת הבעלים או להוסיף אירועים מזויפים."</string>
<string name="permlab_accessMockLocation" msgid="8688334974036823330">"צור מקורות מיקום מדומים לצורך בדיקה"</string>
<string name="permdesc_accessMockLocation" msgid="7648286063459727252">"צור מקורות מיקום מדומים לצורך בדיקה. יישומים זדוניים עלולים להשתמש באפשרות זו כדי לעקוף את המיקום ו/או הסטטוס המוחזרים על ידי מקורות המיקום האמיתיים כגון GPS או ספקי רשת."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"גישה לפקודות ספק מיקום נוספות"</string>
@@ -662,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"הכנס כרטיס SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"כרטיס ה-SIM חסר או לא קריא. הכנס כרטיס SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"כרטיס ה-SIM שלך מושבת לצמיתות."\n" צור קשר עם ספק השירות האלחוטי שלך כדי לקבל כרטיס SIM אחר."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"לחצן הרצועה הקודמת"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"לחצן הרצועה הבאה"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"לחצן ההשהיה"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"לחצן ההפעלה"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"לחצן העצירה"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"שיחות חירום בלבד"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"רשת נעולה"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"כרטיס SIM נעול באמצעות PUK."</string>
@@ -691,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"בטל נעילה"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"קול פועל"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"ללא קול"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"יצירת התבנית החלה"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"התבנית נמחקה"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"התא נוסף"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"התבנית הושלמה"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"אבג"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -856,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"חתוך"</string>
<string name="copy" msgid="2681946229533511987">"העתק"</string>
<string name="paste" msgid="5629880836805036433">"הדבק"</string>
- <string name="replace" msgid="5781686059063148930">"להחליף???"</string>
+ <string name="replace" msgid="5781686059063148930">"להחליף..."</string>
<string name="delete" msgid="6098684844021697789">"מחק"</string>
<string name="copyUrl" msgid="2538211579596067402">"העתק כתובת אתר"</string>
<string name="selectTextMode" msgid="6738556348861347240">"בחר טקסט..."</string>
@@ -1145,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"שינוי מצב"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"בחר יישום"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"שתף עם"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"שתף עם <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"ידית להחלקה. הקש והחזק."</string>
<string name="description_direction_up" msgid="1983114130441878529">"\'למעלה\' עבור <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"\'למטה\' עבור <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1154,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"מצלמה"</string>
<string name="description_target_silent" msgid="893551287746522182">"שקט"</string>
<string name="description_target_soundon" msgid="30052466675500172">"הקול פועל"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"מקש. נדרשות אוזניות כדי לשמוע את המקשים בעת הקלדת סיסמה."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"חבר אוזניות כדי לשמוע הקראה של מפתחות סיסמה."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"נקודה."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"נווט לדף הבית"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"נווט למעלה"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"אפשרויות נוספות"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index e78b26e..9e6e8b8 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"端末に保存されている名前や連絡先情報といった個人のプロフィール情報をアプリケーションが読み取ることを許可します。このアプリケーションは身元を特定したり、プロフィール情報を第三者に転送したりする可能性があります。"</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"プロフィールデータに書き込む"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"端末に保存されている名前や連絡先情報といった個人のプロフィール情報をアプリケーションが変更または追加することを許可します。このアプリケーションは身元を特定したり、プロフィール情報を第三者に転送したりする可能性があります。"</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ソーシャルストリームを読む"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"あなたや友だちのソーシャルアップデートにアクセスして同期することをアプリに許可します。これにより、悪意のあるアプリがソーシャルネットワーク上で交わされるあなたと友だちの個人的なやり取りを読めるようになります。"</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ソーシャルストリームに書く"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"友だちのソーシャルアップデートの表示をアプリに許可します。これにより、悪意のあるアプリが友だちになりすまし、パスワードなどのあなたの機密情報を入手できるようになります。"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"カレンダーの予定と機密情報を読み取る"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"タブレットに保存したすべてのカレンダーの予定(友だちや同僚の予定も含む)を読み取ることをアプリケーションに許可します。悪意のあるアプリケーションにこの許可を与えると、所有者の知らないうちにカレンダーから個人情報が引き出される恐れがあります。"</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"端末に保存したすべてのカレンダーの予定(友だちや同僚の予定も含む)を読み取ることをアプリケーションに許可します。悪意のあるアプリケーションにこの許可を与えると、所有者の知らないうちにカレンダーから個人情報が引き出される恐れがあります。"</string>
@@ -661,6 +665,16 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"SIMカードを挿入してください。"</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"SIMカードが見つからないか読み取れません。SIMカードを挿入してください。"</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"お使いのSIMカードは永久に無効となっています。"\n"ワイヤレスサービスプロバイダに問い合わせて新しいSIMカードを入手してください。"</string>
+ <!-- no translation found for lockscreen_transport_prev_description (201594905152746886) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_next_description (6089297650481292363) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_pause_description (7659088786780128001) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_play_description (5888422938351019426) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_stop_description (4562318378766987601) -->
+ <skip />
<string name="emergency_calls_only" msgid="6733978304386365407">"緊急通報のみ"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"ネットワークがロックされました"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIMカードはPUKでロックされています。"</string>
@@ -690,6 +704,14 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"ロック解除"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"サウンドON"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"サウンドOFF"</string>
+ <!-- no translation found for lockscreen_access_pattern_start (3941045502933142847) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_cleared (5583479721001639579) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_cell_added (6756031208359292487) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_detected (4988730895554057058) -->
+ <skip />
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1144,6 +1166,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"モードを変更"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"アプリの選択"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"共有"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>と共有"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"スライダーハンドルです。タップして押し続けます。"</string>
<string name="description_direction_up" msgid="1983114130441878529">"上は<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>です。"</string>
<string name="description_direction_down" msgid="4294993639091088240">"下は<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>です。"</string>
@@ -1153,7 +1178,8 @@
<string name="description_target_camera" msgid="969071997552486814">"カメラ"</string>
<string name="description_target_silent" msgid="893551287746522182">"マナーモード"</string>
<string name="description_target_soundon" msgid="30052466675500172">"サウンドON"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"キー。パスワードの入力中にキーの音を聞くにはヘッドセットが必要です。"</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"パスワードのキーが音声出力されるのでヘッドセットを接続してください。"</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"ドット。"</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"ホームへ移動"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"上へ移動"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"その他のオプション"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 8ea2e3f..95fbeeb 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"애플리케이션이 기기에 저장된 개인 프로필 정보(예: 사용자 이름, 연락처 정보 등)를 읽을 수 있도록 합니다. 이것은 애플리케이션이 사용자를 확인하고 다른 사용자들에게 해당 프로필 정보를 전송할 수 있다는 것을 의미합니다."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"프로필 데이터에 쓰기"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"애플리케이션이 기기에 저장된 개인 프로필 정보(예: 사용자 이름, 연락처 정보 등)를 변경하거나 추가할 수 있도록 합니다. 이것은 다른 애플리케이션이 사용자를 확인하고 다른 사용자들에게 해당 프로필 정보를 전송할 수 있다는 것을 의미합니다."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"소셜 스트림 읽기"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"애플리케이션이 나와 친구의 최신 소셜 소식에 액세스하고 동기화할 수 있도록 허용합니다. 이 경우 악성 앱이 소셜 네트워크에서 나와 친구가 주고받은 사적인 내용을 읽을 수 있습니다."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"소셜 스트림에 쓰기"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"애플리케이션이 친구의 최신 소셜 소식을 표시할 수 있도록 허용합니다. 이 경우 악성 앱이 친구로 가장하고 나를 속여 비밀번호나 기타 기밀 정보를 알아낼 수 있습니다."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"캘린더 일정 및 기밀정보 읽기"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"애플리케이션이 친구나 동료의 일정을 포함하여 태블릿에 저장된 모든 캘린더 일정을 읽을 수 있도록 합니다. 이 권한이 있는 악성 애플리케이션은 소유자 몰래 이러한 캘린더에서 개인정보를 추출할 수 있습니다."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"애플리케이션이 친구나 동료의 일정을 포함하여 휴대전화에 저장된 모든 캘린더 일정을 읽을 수 있도록 합니다. 이 권한이 있는 악성 애플리케이션은 소유자 몰래 이러한 캘린더에서 개인정보를 추출할 수 있습니다."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"SIM 카드를 삽입하세요."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"SIM 카드가 없거나 읽을 수 없습니다. SIM 카드를 삽입하세요."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"SIM 카드 사용이 영구적으로 중지됩니다."\n"다른 SIM 카드를 사용하려면 무선 서비스 제공업체에 문의하시기 바랍니다."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"이전 트랙 버튼"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"다음 트랙 버튼"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"일시중지 버튼"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"재생 버튼"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"중지 버튼"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"긴급 통화만"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"네트워크 잠김"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM 카드가 PUK 잠김 상태입니다."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"잠금해제"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"사운드 켜기"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"사운드 끄기"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"패턴 시작됨"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"패턴 삭제됨"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"셀 추가됨"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"패턴 완료됨"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"모드 변경"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift 키"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter 키"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"애플리케이션 선택"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"공유 대상:"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>와(과) 공유"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"슬라이딩 핸들을 길게 탭하세요."</string>
<string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 위로 슬라이드"</string>
<string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 아래로 슬라이드"</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"카메라"</string>
<string name="description_target_silent" msgid="893551287746522182">"무음"</string>
<string name="description_target_soundon" msgid="30052466675500172">"사운드 켜기"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"키. 비밀번호를 입력할 때 키 소리를 들으려면 헤드셋이 필요합니다."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"비밀번호 키를 음성으로 들으려면 헤드셋을 연결하세요."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"점"</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"홈 탐색"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"위로 탐색"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"옵션 더보기"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 8e92325..b62284a 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Programai leidžiama skaityti įrenginyje saugomą asmeninio profilio informaciją, pvz., vardą ir kontaktinę informaciją. Vadinasi, programa galės jus identifikuoti ir siųsti profilio informaciją kitiems."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"rašyti kaip profilio duomenis"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Programai leidžiama keisti įrenginyje saugomą asmeninio profilio informaciją, pvz., vardą ir kontaktinę informaciją, arba jos pridėti. Vadinasi, kitos programos galės jus identifikuoti ir siųsti profilio informaciją kitiems."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"skaityti socialinį srautą"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Programai leidžiama pasiekti ir sinchronizuoti socialinius draugų naujinius. Tuo pasinaudojusios kenkėjiškos programos gali skaityti jūsų bendravimą su draugais viešuosiuose tinkluose."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"rašyti į socialinį srautą"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Programai leidžiama rodyti socialinius draugų naujinius. Tuo pasinaudojusios kenkėjiškos programos gali apsimesti draugu ir apgaule gauti jūsų slaptažodžius ar kitą konfidencialią informaciją."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"nuskaito kalendoriaus įvykius ir konfidencialią informaciją"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Programai leidžiama nuskaityti visus jūsų planšetiniame kompiuteryje saugomus kalendoriaus įvykius – įskaitant ir jūsų draugų bei bendradarbių. Šį leidimą gavusi kenkėjiška programa gali paimti asmeninius duomenis iš šių kalendorių be savininko žinios."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Programai leidžiama nuskaityti visus jūsų telefone saugomus kalendoriaus įvykius – įskaitant ir jūsų draugų bei bendradarbių. Šį leidimą gavusi kenkėjiška programa gali paimti asmeninius duomenis iš šių kalendorių be savininko žinios."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Įdėkite SIM kortelę."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Trūksta SIM kortelės arba ji neskaitoma. Įdėkite SIM kortelę."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"SIM kortelė visam laikui neleidžiama."\n" Jei norite gauti kitą SIM kortelę, susisiekite su belaidžio ryšio paslaugos teikėju."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Ankstesnio takelio mygtukas"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Kito takelio mygtukas"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pristabdymo mygtukas"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Paleidimo mygtukas"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Sustabdymo mygtukas"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Tik pagalbos skambučiai"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Tinklas užrakintas"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM kortelė užrakinta PUK kodu."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Atblokuoti"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Garsas įjungtas"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Išjungti garsą"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Šablonas pradėtas"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Šablonas išvalytas"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Pridėtas langelis"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Šablonas užbaigtas"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"Iškirpti"</string>
<string name="copy" msgid="2681946229533511987">"Kopijuoti"</string>
<string name="paste" msgid="5629880836805036433">"Įklijuoti"</string>
- <string name="replace" msgid="5781686059063148930">"Pakeisti???"</string>
+ <string name="replace" msgid="5781686059063148930">"Pakeisti•"</string>
<string name="delete" msgid="6098684844021697789">"Ištrinti"</string>
<string name="copyUrl" msgid="2538211579596067402">"Kopijuoti URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Pasirinkti tekstą..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Režimo keitimas"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Įvesti"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Pasirinkite programą"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Bendrinti su"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Bendrinti su „<xliff:g id="APPLICATION_NAME">%s</xliff:g>“"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Slydimo valdymas. Palieskite ir laikykite."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Aukštyn į <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Žemyn į <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Vaizdo kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Begarsis"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Garsas įjungtas"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Klavišai. Jei norite įvesdami slaptažodį girdėti klavišų garsus, reikia ausinių."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Įjunkite ausines, kad išgirstumėte sakomus slaptažodžio klavišus."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Taškas."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Naršyti pagrindinį puslapį"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Naršyti į viršų"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Daugiau parinkčių"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index cea1cc8..9812b43 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Ļauj lietojumprogrammai lasīt ierīcē glabāto personiskā profila informāciju, piemēram, jūsu vārdu un kontaktinformāciju. Tas nozīmē, ka lietojumprogramma var jūs identificēt un sūtīt jūsu profila informāciju citām personām."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"rakstīšana jūsu profila datos"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Ļauj lietojumprogrammai mainīt vai pievienot ierīcē glabāto personiskā profila informāciju, piemēram, jūsu vārdu un kontaktinformāciju. Tas nozīmē, ka citas lietojumprogrammas var jūs identificēt un sūtīt jūsu profila informāciju citām personām."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lasīt jūsu soc. tīklu straumi"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Ļauj lietojumprogrammai piekļūt jūsu un jūsu draugu atjauninājumiem sociālajos tīklos un sinhronizēt tos. Ļaunprātīgas lietotnes var izmantot šo atļauju, lai piekļūtu jūsu un jūsu draugu savstarpējām privātām sarunām sociālajos tīklos."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"rakstīt sociālo tīklu straumē"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Ļauj lietojumprogrammai rādīt jūsu draugu atjauninājumus sociālajos tīklos. Ļaunprātīgas lietotnes var izmantot šo atļauju, lai uzdotos par jūsu draugu un mudinātu jūs atklāt paroles vai citu konfidenciālu informāciju."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"lasīt kalendāra pasākumus un konfidenciālu informāciju"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Ļauj lietojumprogrammai lasīt visus planšetdatorā saglabātos kalendāra pasākumus, tostarp jūsu draugu un darbabiedru pasākumus. Ļaunprātīga lietojumprogramma, izmantojot šo atļauju, bez īpašnieka ziņas no šiem kalendāriem var iegūt personisku informāciju."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Ļauj lietojumprogrammai lasīt visus tālrunī saglabātos kalendāra pasākumus, tostarp jūsu draugu un darbabiedru pasākumus. Ļaunprātīga lietojumprogramma, izmantojot šo atļauju, bez īpašnieka ziņas no šiem kalendāriem var iegūt personisku informāciju."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Lūdzu, ievietojiet SIM karti."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Nav SIM kartes, vai arī tā nav lasāma. Lūdzu, ievietojiet SIM karti."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Jūsu SIM karte ir neatgriezeniski atspējota."\n"Lūdzu, sazinieties ar savu bezvadu pakalpojumu sniedzēju, lai iegūtu citu SIM karti."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Iepriekšējā ieraksta poga"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Nākamā ieraksta poga"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pārtraukšanas poga"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Atskaņošanas poga"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Apturēšanas poga"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Tikai ārkārtas zvani"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Tīkls ir bloķēts."</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM karte ir bloķēta ar PUK kodu."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Atbloķēt"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Skaņa ir ieslēgta"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Skaņa ir izslēgta."</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Kombinācija uzsākta"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Kombinācija notīrīta"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Šūna pievienota"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Kombinācija pabeigta"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Režīma maiņa"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Pārslēgšanas taustiņš"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Ievadīšanas taustiņš"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Lietojumprogrammas izvēle"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Kopīgot ar:"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Kopīgot ar lietojumprogrammu <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Bīdāms rokturis. Pieskarieties tam un turiet to nospiestu."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Bīdiet uz augšu, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Bīdiet uz leju, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Klusums"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Skaņa ieslēgta"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Taustiņš. Lai, rakstot paroli, dzirdētu taustiņu signālus, nepieciešamas austiņas."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Pievienojiet austiņas, lai dzirdētu paroles rakstzīmes."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punkts."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Pārvietoties uz sākuma ekrānu"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Pārvietoties augšup"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Vairāk opciju"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index c51c491..b17803fa 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Membenarkan aplikasi untuk membaca maklumat profil peribadi yang disimpan pada peranti anda, seperti nama dan maklumat kenalan anda. Ini bermakna aplikasi itu boleh mengenal pasti anda dan menghantar maklumat profil anda kepada orang lain."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"tulis ke data profil anda"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Membenarkan aplikasi untuk menukar atau menambah maklumat profil peribadi yang disimpan pada peranti anda, seperti nama dan maklumat kenalan anda. Ini bermakna aplikasi lain boleh mengenal pasti anda dan menghantar maklumat profil anda kepada orang lain."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"baca aliran sosial anda"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Membenarkan aplikasi mengakses dan menyegerakkan kemas kini sosial daripada rakan-rakan anda. Aplikasi berniat jahat boleh menggunakan ini untuk membaca komunikasi peribadi di antara anda dan rakan-rakan anda pada rangkaian sosial."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"tulis ke aliran sosial anda"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Membenarkan aplikasi memaparkan kemas kini sosial daripada rakan-rakan anda. Aplikasi berniat jahat boleh menggunakan ini untuk berpura-pura menjadi rakan dan memperdayakan anda untuk mendedahkan kata laluan atau maklumat sulit lain."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"baca acara kalendar serta maklumat sulit"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Membenarkan aplikasi membaca semua acara kalendar yang disimpan pada tablet anda, termasuk acara rakan atau rakan sekerja. Aplikasi berniat jahat dengan kebenaran ini boleh menyari maklumat peribadi dari kalendar ini tanpa pengetahuan pemiliknya."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Membenarkan aplikasi untuk membaca semua acara kalendar yang disimpan pada telefon anda, termasuk acara rakan atau rakan sekerja. Aplikasi berniat jahat dengan kebenaran ini boleh menyari maklumat peribadi dari kalendar ini tanpa pengetahuan pemiliknya."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Sila masukkan kad SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Kad SIM tiada atau tidak boleh dibaca. Sila masukkan kad SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Kad SIM anda dilumpuhkan secara kekal."\n" Sila hubungi pembekal perkhidmatan wayarles anda untuk mendapatkan kad SIM lain."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Butang lagu sebelumnya"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Butang lagu seterusnya"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Butang Jeda"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Butang main"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Butang berhenti"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Panggilan kecemasan sahaja"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Rangkaian dikunci"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Kad SIM dikunci dengan PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Buka kunci"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Bunyi dihidupkan"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Bunyi dimatikan"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Corak dimulakan"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Corak dipadamkan"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Sel ditambahkan"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Corak siap"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,12 +868,12 @@
<string name="cut" msgid="3092569408438626261">"Potong"</string>
<string name="copy" msgid="2681946229533511987">"Salin"</string>
<string name="paste" msgid="5629880836805036433">"Tampal"</string>
- <string name="replace" msgid="5781686059063148930">"Ganti???"</string>
+ <string name="replace" msgid="5781686059063148930">"Ganti..."</string>
<string name="delete" msgid="6098684844021697789">"Padam"</string>
<string name="copyUrl" msgid="2538211579596067402">"Salin URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Pilih teks..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Pemilihan teks"</string>
- <string name="addToDictionary" msgid="9090375111134433012">"tambah ke kamus"</string>
+ <string name="addToDictionary" msgid="9090375111134433012">"tambahkan pada kamus"</string>
<string name="deleteText" msgid="7070985395199629156">"padam"</string>
<string name="inputMethod" msgid="1653630062304567879">"Kaedah input"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Tindakan teks"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Perubahan mod"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Masuk"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Pilih satu aplikasi"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Kongsi dengan"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Kongsi dengan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Pemegang gelongsor. Ketik dan tahan."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Bawah untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Senyap"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Bunyi dihidupkan"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Kekunci. Set kepala diperlukan untuk mendengar kekunci semasa menaip kata laluan."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Pasangkan set kepala untuk mendengar kekunci kata laluan disebut dengan kuat."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Titik."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Navigasi laman utama"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navigasi ke atas"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Lagi pilihan"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 36381f6..8ab8262 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Gir applikasjonen tillatelse til å lese personlig profilinformasjon lagret på enheten, for eksempel navn og kontaktinformasjon. Dette betyr at applikasjonen kan identifisere deg og sende din profilinformasjon til andre."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"skriv til profildataene dine"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Gir applikasjonen tillatelse til å endre eller legge til personlig profilinformasjon lagret på enheten, for eksempel navn og kontaktinformasjon. Dette betyr at andre applikasjoner kan identifisere deg og sende din profilinformasjon til andre."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lese din sosiale strøm"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Gir tillatelse til at appen får tilgang til og kan synkronisere oppdateringer fra deg og vennene dine. Apper med skadelig programvare kan utnytte denne tillatelsen til å lese privat kommunikasjon som du har med vennene dine i sosiale nettverk."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skrive i din sosiale strøm"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Gir tillatelse til at appen kan vise sosiale oppdateringer fra vennene dine. Apper med skadelig programvare kan utnytte denne tillatelsen gjennom å opptre som en venn og således lure deg til å oppgi passord eller annen konfidensiell informasjon."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"les kalenderhendelser og konfidensiell informasjon"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Lar en applikasjon lese alle kalenderhendelser lagret på nettbrettet, herunder de som tilhører venner eller kollegaer. En skadelig applikasjon med denne tillatelsen kan trekke ut personlige opplysninger fra disse kalenderne uten eiernes viten."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Lar applikasjoner lese alle kalenderhendelser lagret på telefonen, herunder de som tilhører venner eller kollegaer. Skadelige applikasjon med denne tillatelsen kan trekke ut personlige opplysninger fra disse kalenderne uten eiernes viten."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Sett inn et SIM-kort."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"SIM-kort mangler eller er uleselig. Sett inn et SIM-kort."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"SIM-kortet er permanent deaktivert."\n" Ta kontakt med mobiltjenesteleverandøren din for å få et annet SIM-kort."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Forrige sang-knappen"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Neste sang-knappen"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pause-knappen"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Avspilling-knappen"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Stopp-knappen"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Kun nødanrop"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Nettverk ikke tillatt"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-kortet er PUK-låst."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Lås opp"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Lyd på"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Lyd av"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Mønsteret er påbegynt"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Mønsteret er slettet"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Celle er lagt til"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Mønsteret er fullført"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modusendring"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Velg en app"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Del med"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Del med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Glidebryter. Trykk og hold inne."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Opp for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Ned for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Stille"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Lyd på"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Tast. Hodetelefoner kreves for å høre tastene mens du skriver inn et passord."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Koble til hodetelefoner for å høre hvilke taster som brukes for å skrive inn passordet."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punktum."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Gå til startsiden"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Gå opp"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Flere alternativer"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index d023c04..cf5485d 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Hiermee kan de app persoonlijke profielgegevens lezen die op uw apparaat staan, zoals uw naam en contactgegevens. Dit houdt in dat de app u kan identificeren en uw profielgegevens kan doorsturen naar anderen."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"schrijven naar profielgegevens"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Hiermee kan de app persoonlijke profielgegevens die op uw apparaat staan, zoals uw naam en contactgegevens, wijzigen of toevoegen. Dit houdt in dat andere apps u kunnen identificeren en uw profielgegevens kunnen doorsturen naar anderen."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"uw sociale stream lezen"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Hiermee kan de app toegang krijgen tot sociale updates van u en uw vrienden en deze synchroniseren. Schadelijke apps kunnen hiermee toegang krijgen tot privécommunicatie tussen u en uw vrienden in sociale netwerken."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"schrijven naar sociale streams"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Hiermee kan de app sociale updates van uw vrienden weergeven. Schadelijke apps kunnen deze mogelijkheid gebruiken om zich voor te doen als vriend en u wachtwoorden of andere vertrouwelijke gegevens te laten vrijgeven."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"agenda-afspraken en vertrouwelijke informatie lezen"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Hiermee kan een app alle agenda-afspraken lezen die op uw tablet zijn opgeslagen, inclusief de afspraken van vrienden of collega\'s. Een schadelijke app die over deze rechten beschikt, kan persoonlijke gegevens extraheren uit deze agenda\'s zonder medeweten van de eigenaren van de agenda\'s."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Hiermee kan een app alle agenda-afspraken lezen die op uw telefoon zijn opgeslagen, inclusief de afspraken van vrienden of collega\'s. Een schadelijke app die over deze rechten beschikt, kan persoonlijke gegevens extraheren uit deze agenda\'s zonder medeweten van de eigenaren van de agenda\'s."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Plaats een SIM-kaart."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"De simkaart ontbreekt of kan niet worden gelezen. Plaats een simkaart."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Uw simkaart is permanent uitgeschakeld."\n" Neem contact op met uw draadloze serviceprovider voor een nieuwe simkaart."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Knop voor vorig nummer"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Knop voor volgend nummer"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Knop voor onderbreken"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Knop voor afspelen"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Knop voor stoppen"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Alleen noodoproepen"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Netwerk vergrendeld"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-kaart is vergrendeld met PUK-code."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Ontgrendelen"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Geluid aan"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Geluid uit"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Patroon gestart"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Patroon gewist"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cel toegevoegd"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Patroon voltooid"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"Alt"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modus wijzigen"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Een applicatie kiezen"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Delen met"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Delen met <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Schuifgreep. Tikken en blijven aanraken."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Omhoog voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Omlaag voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Stil"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Geluid aan"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Toetsaanslag. Headset vereist om toetsaanslagen te kunnen horen bij het typen van een wachtwoord."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Sluit een headset aan om wachtwoordtoetsen hardop te laten voorlezen."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Stip."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Navigeren naar startpositie"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Omhoog navigeren"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Meer opties"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 4b0423a..5fd6336 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Umożliwia aplikacji odczytywanie osobistych informacji z profilu, przechowywanych w urządzeniu – np. imienia, nazwiska czy danych kontaktowych. Oznacza to, że aplikacja może Cię zidentyfikować i wysyłać do innych osób informacje o Twoim profilu."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"zapis danych w Twoim profilu"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Umożliwia aplikacji zmienianie lub dodawanie danych do osobistych informacji w profilu, przechowywanych w urządzeniu – np. imienia, nazwiska czy danych kontaktowych. Oznacza to, że inne aplikacje mogą Cię zidentyfikować i wysyłać do innych osób informacje o Twoim profilu."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"odczyt sieci społecznościowych"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Zezwala aplikacji na dostęp do aktualności społecznościowych od Ciebie i znajomych oraz na ich synchronizowanie. Złośliwe aplikacje mogą dzięki temu odczytywać prywatne informacje wymienianie przez Ciebie ze znajomymi w sieciach społecznościowych."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"zapis sieci społecznościowych"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Zezwala aplikacji na wyświetlanie aktualności społecznościowych od znajomych. Złośliwe aplikacje mogą dzięki temu udawać znajomych i wyłudzać hasła lub inne poufne informacje."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"odczyt wydarzeń w kalendarzu wraz z informacjami poufnymi"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Zezwala aplikacji na odczyt wszystkich wydarzeń w kalendarzu zapisanych w tablecie, w tym dotyczących znajomych lub współpracowników. Złośliwa aplikacja z tym uprawnieniem może bez wiedzy właściciela pobierać z kalendarza informacje osobiste."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Zezwala aplikacji na odczyt wszystkich wydarzeń w kalendarzu zapisanych w telefonie, w tym dotyczących znajomych lub współpracowników. Złośliwa aplikacja z tym uprawnieniem może bez wiedzy właściciela pobierać z kalendarza informacje osobiste."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Włóż kartę SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Brak karty SIM lub nie można jej odczytać. Włóż kartę SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Karta SIM jest trwale wyłączona."\n" Skontaktuj się z dostawcą usług bezprzewodowych, aby uzyskać inną kartę SIM."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Przycisk poprzedniego utworu"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Przycisk następnego utworu"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Przycisk wstrzymania"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Przycisk odtwarzania"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Przycisk zatrzymania"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Tylko połączenia alarmowe"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Sieć zablokowana"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Karta SIM jest zablokowana kodem PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Odblokuj"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Włącz dźwięk"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Wyłącz dźwięk"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Wzór rozpoczęty"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Wzór wyczyszczony"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Dodano komórkę."</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Wzór ukończony"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Zmiana trybu"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Wybierz aplikację"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Udostępnij przez"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Udostępnij przez <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Uchwyt przesuwny. Dotknij i przytrzymaj."</string>
<string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>: w górę"</string>
<string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>: w dół"</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Aparat"</string>
<string name="description_target_silent" msgid="893551287746522182">"Wyciszenie"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Włącz dźwięk"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Klawisz. Wymagany jest zestaw słuchawkowy, aby słyszeć klawisze podczas wpisywania hasła."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Podłącz zestaw słuchawkowy, aby usłyszeć znaki hasła wypowiadane na głos."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Kropka"</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Przejdź do strony głównej"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Przejdź wyżej"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Więcej opcji"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 1ae0d72..9875c9d 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Permite que a aplicação leia informações do perfil pessoal armazenadas no aparelho, como o seu nome e as informações de contacto. Isto significa que a aplicação pode identificá-lo e enviar informações do seu perfil a outras pessoas."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"escrever nos dados do seu perfil"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Permite que a aplicação altere ou adicione dados às informações do perfil pessoal armazenadas no aparelho, como o seu nome e as informações de contacto. Isto significa que outras aplicações o podem identificar e enviar informações do seu perfil a outras pessoas."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ler o seu fluxo social"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Permite que a aplicação para aceda e sincronize atualizações sociais de si e dos seus amigos. Aplicações maliciosas podem usar isso para ler as comunicações privadas entre si e os seus amigos em redes sociais."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"escrever para o seu fluxo social"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Permite que a aplicação mostre atualizações sociais dos seus amigos. Aplicações maliciosas podem usar isso para fingirem ser um amigo e levá-lo a revelar senhas ou outras informações confidenciais."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"ler eventos do calendário, para além de informações confidenciais"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Permite que uma aplicação leia todos os eventos do calendário armazenados no tablet, incluindo os de amigos ou colegas de trabalho. Uma aplicação maliciosa com esta permissão pode extrair informações pessoais destes calendários sem o conhecimento dos proprietários."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Permite que uma aplicação leia todos os eventos do calendário armazenados no telemóvel, incluindo os de amigos ou colegas de trabalho. Uma aplicação maliciosa com esta permissão pode extrair informações pessoais destes calendários sem o conhecimento dos proprietários."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Introduza um cartão SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"O cartão SIM está em falta ou não é legível. Introduza um cartão SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"O seu cartão SIM está desativado definitivamente."\n" Contacte o seu fornecedor de serviços de rede sem fios para obter outro cartão."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Botão Faixa anterior"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Botão Faixa seguinte"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Botão Pausa"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Botão Reproduzir."</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Botão Interromper"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Apenas chamadas de emergência"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Rede bloqueada"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"O cartão SIM está bloqueado por PUK"</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Som activado"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Som desactivado"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Sequência iniciada"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Sequência apagada"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Célula adicionada"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Sequência concluída"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Alteração do modo"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Escolha uma aplicação"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Partilhar com:"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartilhar com <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Faixa deslizante. Mantenha premida."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Para cima para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Para baixo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Câmara"</string>
<string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Som ativado"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Tecla. São necessários auscultadores com microfone integrado para ouvir as teclas ao escrever uma palavra-passe."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Ligue os auscultadores com microfone integrado para ouvir as teclas da palavra-passe."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Ponto."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Navegar para página inicial"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navegar para cima"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Mais opções"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 3e2e497..7ddf142 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Permite que o aplicativo leia informações pessoais de seu perfil armazenadas em seu dispositivo, como seu nome e suas informações de contato. Isso significa que o aplicativo pode identificá-lo e enviar as informações de seu perfil para outras pessoas."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"escrever nos dados do perfil"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Permite que o aplicativo altere ou adicione informações de perfil pessoais armazenadas em seu dispositivo, como seu nome e suas informações de contato. Isso significa que outros aplicativos podem identificá-lo e enviar informações de seu perfil para outras pessoas."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ler suas transmissões sociais"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Permite que o aplicativo acesse e sincronize suas atualizações sociais e as de seus amigos. Aplicativos maliciosos podem usar esse recurso para ler comunicações privadas entre você e seus amigos em redes sociais."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"escrever p/ suas transm. soc."</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Permite que o aplicativo mostre atualizações sociais de seus amigos. Aplicativos maliciosos podem usar esse recurso para fingir ser um amigo e fazer você revelar senhas ou outras informações confidenciais."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"ler compromissos e informações confidenciais"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Permite que um aplicativo leia todos os compromissos armazenados na agenda de seu tablet, incluindo os de amigos ou de colegas de trabalho. Um aplicativo malicioso com essa permissão pode extrair informações pessoais dessa agenda sem que seus donos saibam."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Permite que um aplicativo leia todos os compromissos armazenados na agenda de seu telefone, incluindo os de amigos ou de colegas de trabalho. Um aplicativo malicioso com essa permissão pode extrair informações pessoais dessa agenda sem que seus donos saibam."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Insira um cartão SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"O cartão SIM não foi inserido ou não está legível. Insira um cartão SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Seu cartão SIM está permanentemente desativado."\n" Entre em contato com seu provedor de serviços de rede sem fio para obter outro cartão SIM."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Botão \"Faixa anterior\""</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Botão \"Próxima faixa\""</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Botão \"Pausar\""</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Botão \"Reproduzir\""</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Botão \"Parar\""</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Apenas chamadas de emergência"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Rede bloqueada"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"O cartão SIM está bloqueado pelo PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Som ativado"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Som desativado"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Padrão iniciado"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Padrão apagado"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Célula adicionada"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Padrão concluído"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"Recortar"</string>
<string name="copy" msgid="2681946229533511987">"Copiar"</string>
<string name="paste" msgid="5629880836805036433">"Colar"</string>
- <string name="replace" msgid="5781686059063148930">"Substituir???"</string>
+ <string name="replace" msgid="5781686059063148930">"Substituir..."</string>
<string name="delete" msgid="6098684844021697789">"Excluir"</string>
<string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Selecionar texto..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Alteração do modo"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Escolha um aplicativo"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Compartilhar com"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartilhar com <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Alça deslizante. Toque e segure."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Deslize para cima para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Deslize para baixo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Câmera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Som ativado"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Tecla. É necessário um fone de ouvido para ouvir as teclas durante a digitação de uma senha."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Conecte um fone de ouvido para ouvir as teclas da senha em voz alta."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Ponto final."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Navegar na página inicial"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navegar para cima"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Mais opções"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 31ea5b0..643b79e 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -358,6 +358,14 @@
<skip />
<!-- no translation found for permdesc_writeProfile (6431297330378229453) -->
<skip />
+ <!-- no translation found for permlab_readSocialStream (1268920956152419170) -->
+ <skip />
+ <!-- no translation found for permdesc_readSocialStream (6619997662735851111) -->
+ <skip />
+ <!-- no translation found for permlab_writeSocialStream (3504179222493235645) -->
+ <skip />
+ <!-- no translation found for permdesc_writeSocialStream (2689083745826002521) -->
+ <skip />
<!-- outdated translation 6898987798303840534 --> <string name="permlab_readCalendar" msgid="5972727560257612398">"leger eveniments da chalender"</string>
<!-- outdated translation 5533029139652095734 --> <string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Permetta ad ina applicaziun da leger tut ils eveniments da chalender memorisads sin Voss telefonin. Applicaziuns donnegiusas pon uschia trametter Voss eveniments da chalender ad autras persunas."</string>
<!-- outdated translation 5533029139652095734 --> <string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Permetta ad ina applicaziun da leger tut ils eveniments da chalender memorisads sin Voss telefonin. Applicaziuns donnegiusas pon uschia trametter Voss eveniments da chalender ad autras persunas."</string>
@@ -738,6 +746,16 @@
<skip />
<!-- no translation found for lockscreen_permanent_disabled_sim_instructions (1631853574702335453) -->
<skip />
+ <!-- no translation found for lockscreen_transport_prev_description (201594905152746886) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_next_description (6089297650481292363) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_pause_description (7659088786780128001) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_play_description (5888422938351019426) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_stop_description (4562318378766987601) -->
+ <skip />
<string name="emergency_calls_only" msgid="6733978304386365407">"Mo cloms d\'urgenza"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Rait bloccada"</string>
<!-- no translation found for lockscreen_sim_puk_locked_message (7441797339976230) -->
@@ -774,6 +792,14 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Debloccar"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Tun activà"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Tun deactivà"</string>
+ <!-- no translation found for lockscreen_access_pattern_start (3941045502933142847) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_cleared (5583479721001639579) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_cell_added (6756031208359292487) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_detected (4988730895554057058) -->
+ <skip />
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1378,6 +1404,12 @@
<skip />
<!-- no translation found for keyboardview_keycode_enter (2985864015076059467) -->
<skip />
+ <!-- no translation found for activitychooserview_choose_application (4540794444768613567) -->
+ <skip />
+ <!-- no translation found for shareactionprovider_share_with (806688056141131819) -->
+ <skip />
+ <!-- no translation found for shareactionprovider_share_with_application (5627411384638389738) -->
+ <skip />
<!-- no translation found for content_description_sliding_handle (7311938669217173870) -->
<skip />
<!-- no translation found for description_direction_up (1983114130441878529) -->
@@ -1396,7 +1428,9 @@
<skip />
<!-- no translation found for description_target_soundon (30052466675500172) -->
<skip />
- <!-- no translation found for keyboard_headset_required_to_hear_password (4407722573911224960) -->
+ <!-- no translation found for keyboard_headset_required_to_hear_password (5913502399391940888) -->
+ <skip />
+ <!-- no translation found for keyboard_password_character_no_headset (2859873770886153678) -->
<skip />
<!-- no translation found for action_bar_home_description (5293600496601490216) -->
<skip />
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 00ec512..0fcbd3f 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Permite aplicaţiei să citească informaţiile din profilul personal stocate pe dispozitivul dvs., cum ar fi numele şi informaţiile dvs. de contact. Aceasta înseamnă că aplicaţia vă poate identifica şi poate trimite informaţiile din profilul dvs. altor persoane."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"scriere date în profilul dvs."</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Permite aplicaţiei să schimbe sau să adauge conţinut în informaţiile din profilul personal stocate pe dispozitivul dvs., cum ar fi numele şi informaţiile dvs. de contact. Aceasta înseamnă că alte aplicaţii vă pot identifica şi pot trimite informaţiile din profilul dvs. altor persoane."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"citeşte fluxul social"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Permite aplicaţiei să acceseze şi să sincronizeze actualizările sociale de la dvs. şi de la prietenii dvs. Aplicaţiile rău-intenţionate se pot folosi de această funcţie pentru a citi comunicările private dintre dvs. şi prietenii dvs. de pe reţelele sociale."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"scrie în fluxul social"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Permite aplicaţiei să afişeze actualizări sociale de la prietenii dvs. Aplicaţiile rău-intenţionate se pot folosi de această funcţie pentru a simula un prieten, cu scopul de a vă păcăli să oferiţi parole sau alte informaţii confidenţiale."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"citirea evenimentelor din calendar şi a informaţiilor confidenţiale"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Permite unei aplicaţii să citească toate evenimentele din calendar stocate pe tableta dvs., inclusiv evenimentele prietenilor sau colegilor. O aplicaţie rău intenţionată care are această permisiune poate extrage informaţii cu caracter personal din aceste calendare fără ştirea proprietarului."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Permite unei aplicaţii să citească toate evenimentele din calendar stocate pe telefonul dvs., inclusiv evenimentele prietenilor sau colegilor. O aplicaţie rău intenţionată care are această permisiune poate extrage informaţii cu caracter personal din aceste calendare fără ştirea proprietarului."</string>
@@ -661,6 +665,16 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Introduceţi un card SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Cartela SIM lipseşte sau nu poate fi citită. Introduceţi o cartelă SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Cartela dvs. SIM este dezactivată definitiv."\n" Contactaţi furnizorul de servicii wireless pentru a obţine o altă cartelă SIM."</string>
+ <!-- no translation found for lockscreen_transport_prev_description (201594905152746886) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_next_description (6089297650481292363) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_pause_description (7659088786780128001) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_play_description (5888422938351019426) -->
+ <skip />
+ <!-- no translation found for lockscreen_transport_stop_description (4562318378766987601) -->
+ <skip />
<string name="emergency_calls_only" msgid="6733978304386365407">"Numai apeluri de urgenţă"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Reţea blocată"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Cardul SIM este blocat cu codul PUK."</string>
@@ -690,6 +704,14 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Deblocaţi"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sunet activat"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Sunet dezactivat"</string>
+ <!-- no translation found for lockscreen_access_pattern_start (3941045502933142847) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_cleared (5583479721001639579) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_cell_added (6756031208359292487) -->
+ <skip />
+ <!-- no translation found for lockscreen_access_pattern_detected (4988730895554057058) -->
+ <skip />
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +877,7 @@
<string name="cut" msgid="3092569408438626261">"Decupaţi"</string>
<string name="copy" msgid="2681946229533511987">"Copiaţi"</string>
<string name="paste" msgid="5629880836805036433">"Inseraţi"</string>
- <string name="replace" msgid="5781686059063148930">"Înlocuiţi???"</string>
+ <string name="replace" msgid="5781686059063148930">"Înlocuiţi..."</string>
<string name="delete" msgid="6098684844021697789">"Ştergeţi"</string>
<string name="copyUrl" msgid="2538211579596067402">"Copiaţi adresa URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Selectaţi text..."</string>
@@ -1144,6 +1166,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Schimbarea modului"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Alegeţi o aplicaţie"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Permiteţi accesul pentru"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Permiteţi accesul pentru <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Mâner glisant. Apăsaţi şi ţineţi apăsat."</string>
<string name="description_direction_up" msgid="1983114130441878529">"În sus pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"În jos pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1178,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Cameră foto"</string>
<string name="description_target_silent" msgid="893551287746522182">"Silenţios"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Sunet activat"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Tastă. Setul căşti-microfon este necesar pentru ascultarea tastelor când introduceţi o parolă."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Conectaţi un set de căşti pentru a auzi tastele apăsate la introducerea parolei rostite cu voce tare."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punct."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Navigaţi la ecranul de pornire"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navigaţi în sus"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Mai multe opţiuni"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 2c96759..0541edf 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -326,10 +326,14 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"перезаписывать данные контакта"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="7782689510038568495">"Позволяет приложению изменять данные (адрес) контакта, сохраненные в памяти планшетного ПК. Вредоносные приложения могут использовать эту возможность для удаления или изменения данных контакта."</string>
<string name="permdesc_writeContacts" product="default" msgid="3924383579108183601">"Позволяет приложению изменять данные (адрес) контакта, сохраненные в памяти телефона. Вредоносные приложения могут использовать эту возможность для удаления или изменения данных контакта."</string>
- <string name="permlab_readProfile" msgid="6824681438529842282">"получать данные профиля"</string>
+ <string name="permlab_readProfile" msgid="6824681438529842282">"просматривать данные профиля"</string>
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Позволяет приложению получать доступ к хранящейся на вашем устройстве личной информации профиля, например к имени и контактным данным. Это означает, что приложение может идентифицировать вас и отправить эти данные другим пользователям."</string>
- <string name="permlab_writeProfile" msgid="4679878325177177400">"запись в данные профиля"</string>
+ <string name="permlab_writeProfile" msgid="4679878325177177400">"изменение данных профиля"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Позволяет приложению изменять или добавлять в личный профиль хранящуюся на вашем устройстве информацию, например имя или контактные данные. Это означает, что приложение может идентифицировать вас и отправить эти данные другим пользователям."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"читать записи в вашей социальной ленте"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Позволяет приложению читать и синхронизировать новости от вас и ваших друзей. Вредоносные программы могут таким образом получить доступ к вашим личным записям в социальных сетях."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"добавлять записи в вашу социальную ленту"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Позволяет приложению отображать новости от друзей в социальных сетях. Вредоносные программы могут таким образом получить доступ к вашим паролям и другим конфиденциальным данным."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"просматривать в календаре мероприятия и конфиденциальную информацию"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Приложениe получит доступ ко всем данным календаря, сохраненным в вашем устройстве (в том числе к мероприятиям ваших друзей и коллег). Вредоносное ПО с таким уровнем доступа сможет извлекать личную информацию без ведома владельцев календарей."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Приложениe получит доступ ко всем данным календаря, сохраненным в вашем телефоне (в том числе к мероприятиям ваших друзей и коллег). Вредоносное ПО с таким уровнем доступа сможет извлекать личную информацию без ведома владельцев календарей."</string>
@@ -655,12 +659,17 @@
<string name="lockscreen_charged" msgid="4938930459620989972">"Батарея заряжена"</string>
<string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_low_battery" msgid="1482873981919249740">"Подключите зарядное устройство."</string>
- <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Нет SIM-карты."</string>
+ <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Нет SIM-карты"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"SIM-карта не установлена."</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"SIM-карта не установлена."</string>
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Вставьте SIM-карту."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"SIM-карта отсутствует или не читается. Вставьте SIM-карту."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Ваша SIM-карта окончательно заблокирована."\n"Чтобы получить новую SIM-карту, обратитесь к оператору мобильной связи."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Кнопка перехода к предыдущему треку"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Кнопка перехода к следующему треку"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Кнопка паузы"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Кнопка воспроизведения"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Кнопка остановки"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Только экстренные вызовы"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Сеть заблокирована"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-карта заблокирована с помощью кода PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Разблокировать"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Вкл. звук"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Откл. звук"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Ввод графического ключа начался"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Графический ключ сброшен"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Ячейка добавлена"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Графический ключ введен"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"АБВ"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -923,10 +936,10 @@
<string name="volume_notification" msgid="2422265656744276715">"Громкость уведомления"</string>
<string name="volume_unknown" msgid="1400219669770445902">"Громкость"</string>
<string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Громкость Bluetooth-устройства"</string>
- <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Громкость мелодии звонка"</string>
+ <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Громкость рингтона"</string>
<string name="volume_icon_description_incall" msgid="8890073218154543397">"Громкости мелодии вызова"</string>
<string name="volume_icon_description_media" msgid="4217311719665194215">"Громкость мультимедиа"</string>
- <string name="volume_icon_description_notification" msgid="7044986546477282274">"Громкость мелодии оповещений"</string>
+ <string name="volume_icon_description_notification" msgid="7044986546477282274">"Громкость уведомлений"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Мелодия по умолчанию"</string>
<string name="ringtone_default_with_actual" msgid="8129563480895990372">"По умолчанию (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="4440324407807468713">"Без звука"</string>
@@ -1066,7 +1079,7 @@
<string name="reset" msgid="2448168080964209908">"Сбросить"</string>
<string name="submit" msgid="1602335572089911941">"Отправить"</string>
<string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Включен режим \"Штурман\""</string>
- <string name="car_mode_disable_notification_message" msgid="668663626721675614">"Чтобы закрыть приложение, нажмите здесь."</string>
+ <string name="car_mode_disable_notification_message" msgid="668663626721675614">"Чтобы выйти, нажмите здесь."</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"USB-модем или точка доступа Wi-Fi активны"</string>
<string name="tethered_notification_message" msgid="3067108323903048927">"Нажмите для настройки"</string>
<string name="back_button_label" msgid="2300470004503343439">"Назад"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Клавиша смены режима"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Клавиша смены регистра"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Клавиша ввода"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Выберите приложение"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Открыть доступ:"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Открыть доступ приложению \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\""</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Сенсорное управление. Нажмите и удерживайте."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Проведите вверх, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Проведите вниз, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
<string name="description_target_silent" msgid="893551287746522182">"Без звука"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Включить звук"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Необходима гарнитура, чтобы услышать нажатие клавиш при вводе пароля."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Подключите гарнитуру, чтобы услышать пароль."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Точка"</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Перейти на главную"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Перейти вверх"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Ещё"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 05a0072..abcb3f6 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Umožňuje aplikácii čítať osobné informácie profilu uložené v zariadení, ako sú vaše meno a kontaktné údaje. Aplikácia vás takto môže identifikovať a poslať informácie profilu ostatným používateľom."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"zapisovať do údajov profilu"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Umožňuje aplikácii zmeniť alebo pridať osobné informácie profilu uložené v zariadení, ako sú vaše meno a kontaktné údaje. Iné aplikácie vás takto môžu identifikovať a poslať vaše informácie profilu ostatným používateľom."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"čítať váš sociálny stream"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Umožňuje aplikácii pristupovať k sociálnym aktualizáciám vašich priateľov a synchronizovať ich. Škodlivé aplikácie to môžu využiť na pristupovanie k súkromnej komunikácii medzi vami a vašimi priateľmi na sociálnych sieťach."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"písať do vášho sociálneho streamu"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Umožňuje aplikácii zobrazovať sociálne aktualizácie vašich priateľov. Škodlivé aplikácie to môžu využiť a predstierať, že sú vaším priateľom. Týmto spôsobom môžu od vás získať heslá a iné dôverné informácie."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"čítať udalosti v kalendári a dôverné informácie"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Umožňuje aplikácii načítať všetky udalosti v kalendári, ktoré sú uložené v tablete (vrátane udalostí priateľov alebo kolegov). Škodlivá aplikácia môže pomocou tohto oprávnenia získavať osobné údaje z týchto kalendárov bez vedomia vlastníka."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Umožňuje aplikácii načítať všetky udalosti v kalendári, ktoré sú uložené v telefóne (vrátane udalostí priateľov alebo kolegov). Škodlivá aplikácia môže pomocou tohto oprávnenia získavať osobné údaje z týchto kalendárov bez vedomia vlastníka."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Vložte kartu SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Karta SIM chýba alebo sa z nej nedá čítať. Vložte kartu SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Vaša karta SIM je natrvalo zakázaná."\n"Ak chcete získať inú kartu SIM, kontaktujte poskytovateľa bezdrôtových služieb."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Tlačidlo Predchádzajúca stopa"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Tlačidlo Ďalšia stopa"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Tlačidlo Pozastaviť"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Tlačidlo Prehrať"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Tlačidlo Zastaviť"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Len tiesňové volania"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Sieť je zablokovaná"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Karta SIM je uzamknutá pomocou kódu PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Odomknúť"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Zapnúť zvuk"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Vypnúť zvuk"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Bezpečnostný vzor bol začatý"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Bezpečnostný vzor bol vymazaný"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Bunka bola pridaná"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Bezpečnostný vzor bol dokončený"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"Vystrihnúť"</string>
<string name="copy" msgid="2681946229533511987">"Kopírovať"</string>
<string name="paste" msgid="5629880836805036433">"Prilepiť"</string>
- <string name="replace" msgid="5781686059063148930">"Nahradiť???"</string>
+ <string name="replace" msgid="5781686059063148930">"Nahradiť•"</string>
<string name="delete" msgid="6098684844021697789">"Odstrániť"</string>
<string name="copyUrl" msgid="2538211579596067402">"Skopírovať adresu URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Vybrať text..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Zmena režimu"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Zvoľte aplikáciu"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Zdieľať s"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Zdieľať s aplikáciou <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Posuvné tlačidlo. Klepnite a podržte."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Nahor na <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Nadol na <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Fotoaparát"</string>
<string name="description_target_silent" msgid="893551287746522182">"Tichý"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Zapnúť zvuk"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Kláves. Pri zadávaní hesla je potrebné použiť náhlavnú súpravu."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Ak si chcete vypočuť nahlas vyslovené klávesy hesla, pripojte náhlavnú súpravu."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Bodka."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Prejsť na plochu"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Prejsť na"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Viac možností"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 7bdc3b5..12fac56 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Programu omogoča branje podatkov v osebnem profilu, shranjenih v napravi, na primer imen in podatkov za stik. To pomeni, da lahko program ugotovi, kdo ste, in pošlje podatke v profilu drugim."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"pisanje v podatke v profilu"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Programu omogoča spreminjanje in dodajanje podatkov med podatke v osebnem profilu, shranjene v napravi, na primer imena in podatke za stik. To pomeni, da lahko program ugotovi, kdo ste, in pošlje podatke v profilu drugim."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"preberite svoj družabni tok"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Dovoli programom dostop do družabnih posodobitev vas in vaših prijateljev. Zlonamerni programi lahko to uporabijo za branje zasebne komunikacije med vami in prijatelji v družabnih omrežjih."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"pišite v svoj družabni tok"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Dovoli programom prikaz družabnih posodobitev vaših prijateljev. Zlonamerni programi lahko to uporabijo, da se predstavijo kot prijatelji in vas zavedejo, da razkrijete gesla ali druge zaupne podatke."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"branje dogodkov v koledarju in zaupnih podatkov"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Programu dovoli, da bere dogodke v koledarju, shranjene v tabličnem računalniku, vključno z dogodki prijateljev in sodelavcev. Zlonamerni program lahko iz njih dobi osebne podatke brez vednosti lastnika."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Programu dovoli branje vseh dogodkov koledarja, shranjenih v telefonu, vključno z dogodki prijateljev in sodelavcev. Zlonamerni program lahko iz njih pridobi osebne podatke brez vednosti lastnika."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Vstavite kartico SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Ni kartice SIM ali je ni mogoče prebrati. Vstavite kartico SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Kartica SIM je trajno onemogočena."\n" Če želite dobiti drugo kartico SIM, se obrnite na ponudnika brezžičnih storitev."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Gumb za prejšnjo skladbo"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Gumb za naslednjo skladbo"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Gumb »Premor«"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Gumb »Predvajaj«."</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Gumb »Ustavi«"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Le klici v sili"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Omrežje je zaklenjeno"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Kartica SIM je zaklenjena s kodo PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Odkleni"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Vklopi zvok"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Izklopi zvok"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Vzorec se je začel"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Vzorec je izbrisan"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Celica je dodana"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Vzorec je končan"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"Izreži"</string>
<string name="copy" msgid="2681946229533511987">"Kopiraj"</string>
<string name="paste" msgid="5629880836805036433">"Prilepi"</string>
- <string name="replace" msgid="5781686059063148930">"Zamenjaj???"</string>
+ <string name="replace" msgid="5781686059063148930">"Zamenjaj •"</string>
<string name="delete" msgid="6098684844021697789">"Izbriši"</string>
<string name="copyUrl" msgid="2538211579596067402">"Kopiraj URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Izbiranje besedila ..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Sprememba načina"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Tipka Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Tipka Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Izberite program"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Delite z"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Delite s programom <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Drsna ročica. Tapnite in pridržite."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Gor za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Dol za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Fotoaparat"</string>
<string name="description_target_silent" msgid="893551287746522182">"Tiho"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Vklopljen zvok"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Če želite med vnašanjem gesla slišati tipke, potrebujete slušalke."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Priključite slušalke, če želite slišati zvok tipkanja gesla."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Pika."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Krmarjenje domov"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Krmarjenje navzgor"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Več možnosti"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index ef40d65..f08b80e 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Дозвољава апликацији да чита личне информације о профилу сачуване на уређају, као што су име и информације за контакт. То значи да апликација може да вас идентификује и шаље информације о профилу другима."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"уписивање у податке профила"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Дозвољава апликацији да мења личне информације о профилу сачуване на уређају, као што су име и информације за контакт, или им доприноси. То значи да друге апликације могу да вас идентификују и шаљу информације о профилу другима."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"читање друштвеног стрима"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Дозвољава апликацији да приступа вашим друштвеним ажурирањима и друштвеним ажурирањима пријатеља и да их синхронизује. Злонамерне апликације могу помоћу тога да читају приватне преписке између вас и пријатеља на друштвеним мрежама."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"писање у друштвени стрим"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Дозвољава апликацији да приказује друштвена ажурирања пријатеља. Злонамерне апликације могу помоћу тога да се претварају да су пријатељи и да вас преваре како бисте им открили лозинке или друге поверљиве информације."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"читање календарских догађаја и поверљивих информација"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Дозвољава апликацији да чита све календарске догађаје сачуване на таблету, укључујући догађаје пријатеља или колега. Злонамерна апликација са овом дозволом може да издвоји личне информације из тих календара без знања власника."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Дозвољава апликацији да чита све календарске догађаје сачуване на телефону, укључујући догађаје пријатеља или колега. Злонамерна апликација са овом дозволом може да издвоји личне информације из тих календара без знања власника."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Уметните SIM картицу."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Недостаје SIM картица или не може да се прочита. Уметните SIM картицу."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"SIM картица је трајно онемогућена."\n" Обратите се добављачу услуге бежичне мреже да бисте добили другу SIM картицу."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Дугме за претходну песму"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Дугме за следећу песму"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Дугме за паузу"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Дугме Пусти"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Дугме за заустављање"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Само хитни позиви"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Мрежа је закључана"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM картица је закључана PUK кодом."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Откључај"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Укључи звук"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Искључи звук"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Образац је започет"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Образац је обрисан"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Ћелија је додата"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Образац је довршен"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Промена режима"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Изаберите апликацију"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Дели са"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Дели са апликацијом <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Клизна ручица. Додирните и задржите."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Надоле за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
<string name="description_target_silent" msgid="893551287746522182">"Нечујно"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Укључи звук"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Тастер. Потребне су слушалице да бисте чули тастере док куцате лозинку."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Укључите слушалице да бисте чули наглас изговорене тастере за лозинку."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Тачка."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Кретање до Почетне"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Кретање нагоре"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Још опција"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 73b9be3..4230f28 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Tillåter att appen läser personlig profilinformation som lagrats på enheten, t.ex. ditt namn och kontaktuppgifter. Det innebär att appen kan identifiera dig och skicka din profilinformation till andra."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"skriver till data för din profil"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Tillåter att appen ändrar eller lägger till personlig profilinformation som lagras på din enhet, t.ex. ditt namn och kontaktuppgifter. Det innebär att andra appar kan identifiera dig och skicka profilinformation till andra."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"läs mitt sociala flöde"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Gör det möjligt för appen få åtkomst till och synkronisera sociala uppdateringar från dig och dina vänner. Skadliga appar kan använda detta för att läsa privata konversationer mellan dig och dina vänner på sociala nätverk."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skriv till mitt sociala flöde"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Gör det möjligt för appen att visa sociala uppdateringar från dina vänner. Skadliga program kan använda detta för att låtsas vara en vän och lura dig att avslöja lösenord eller annan konfidentiell information."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"läsa kalenderuppgifter plus konfidentiell information"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Tillåter att en app läser alla kalenderuppgifter som sparats på din pekdator, inklusive dina vänners eller kollegors uppgifter. Skadliga appar kan använda detta för att hämta personliga uppgifter från kalendrarna utan ägarens vetskap."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Tillåter att en app läser kalenderuppgifter som har lagrats på din telefon, även dina vänners eller kollegors uppgifter. Skadliga appar kan använda detta för att hämta personliga uppgifter från kalendrar utan ägarens vetskap."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Sätt i ett SIM-kort."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"SIM-kort saknas eller kan inte läsas. Sätt i ett SIM-kort."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"SIM-kortet har inaktiverats permanent."\n" Beställ ett nytt SIM-kort från din operatör."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Knapp för föregående spår"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Knapp för nästa spår"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pausknappen"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Uppspelningsknappen"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Stoppknappen"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Endast nödsamtal"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Nätverk låst"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-kortet är PUK-låst."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Lås upp"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ljud på"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Ljud av"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Skriver grafiskt lösenord"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Grafiskt lösenord har tagits bort"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"En cell har lagts till"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Grafiskt lösenord har slutförts"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"Klipp ut"</string>
<string name="copy" msgid="2681946229533511987">"Kopiera"</string>
<string name="paste" msgid="5629880836805036433">"Klistra in"</string>
- <string name="replace" msgid="5781686059063148930">"Ersätt???"</string>
+ <string name="replace" msgid="5781686059063148930">"Ersätt..."</string>
<string name="delete" msgid="6098684844021697789">"Ta bort"</string>
<string name="copyUrl" msgid="2538211579596067402">"Kopiera webbadress"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Markera text..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Funktionsändring"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Skift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Retur"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Välj en app"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Dela med"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Dela med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Skärmlåsfunktion. Tryck och dra."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Upp för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Ned för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Tyst"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Ljud på"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Du behöver ett headset för att höra tangenterna när du skriver in ett lösenord."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Anslut hörlurar om du vill höra lösenorden läsas upp."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punkt."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Visa startsidan"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navigera uppåt"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Fler alternativ"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 1566034..b5465ac 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Inaruhusu programu kusoma maelezo mafupi ya binafsi yaliyohifadhiwa kwenye kifaa chako, kama vile jina lako na maelezo yako ya anwani. Hii ina maanisha programu inaweza kukutambua na kutuma habari maelezo yako mafupi kwa wengine."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"andika kwenye data ya maelezo yako mafupi"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Inaruhusu programu kubadilisha au kuongeza maelezo binafsi ya maelezo yako mafupi yaliyohifadhiwa kwenye kifaa chako, kama vile jina lako na maelezo ya anwani. Hii ina maanisha programu nyingine ziweze kukutambua na kutuma maelezo ya maelezo yako mafupi kwa wengine."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"soma mkondo wako wa kijamii"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Inaruhusu programu kufikia na kulandanisha usasisho kutoka kwako na marafiki wako. Prog hasidi zinaweza kutumia hizi kusoma mawasiliano ya kibinafsi kati yako na marafiki wako kwenye mitandao ya kijamii."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"andika kwa mkondo wako wa kijamii"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Inaruhusu programu kuonyesha usasisho ya kijamii kutoka kwa marafiki wako. Prog hasidi zinaweza kutumia hizi zikijifanya kuwa rafiki na kukuhadaa kuonyesha nenosiri au taarifa zingine za siri."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"soma matukio ya kalenda pamoja na maelezo ya siri"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Huruhusu programu kusoma matukio yote ya kalenda yaliyohifadhiwa kwenye kompyuta yako ndogo, pamoja na za marafiki au wafanyakazi wenza. Programu hasidi yenye kibali hiki kinaweza kuchukua maelezo ya kibinagsi kutoka kwa kalenda hizi bila ufahamu wa mmiliki."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Huruhusu programu kusoma matukio yote ya kalenda yaliyohifadhiwa kwenye simu yako, pamoja na za marafiki au marafiki wenza. Programu hasidi yenye kibali hiki inaweza kuchukua maelezo ya kibinafsi kutoka kwa kalenda hizi bila ufahamu wa mmiliki."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Tafadhali ingiza kadi ya SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Kadi ya SIM inakosekana au haisomekani. Tafadhali ingiza kadi ya SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Kadi yako ya SIM imelemazwa kabisa. "\n" tafadhali wasiliana na mtoa huduma wako wa psiwaya ili kupata kadi nyingine ya SIM."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Kitufe cha awali cha wimbo"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Kitufe cha wimbo unaofuata"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Kitufe cha pauzi"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Kitufe cha kucheza"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Kitufe cha kusitisha"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Simu za dharura pekee"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Mtandao umefungwa"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Kadi ya SIM imefungwa na PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Fungua"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sauti imewezeshwa"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Sauti imezimwa"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Kiolezo imeanzishwa"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Kiolezo imefutwa"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Kiini imeongezwa"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Kiolezo imekamilika"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"Kata"</string>
<string name="copy" msgid="2681946229533511987">"Nakala"</string>
<string name="paste" msgid="5629880836805036433">"Bandika"</string>
- <string name="replace" msgid="5781686059063148930">"Badilisha???"</string>
+ <string name="replace" msgid="5781686059063148930">"Badilisha..."</string>
<string name="delete" msgid="6098684844021697789">"Futa"</string>
<string name="copyUrl" msgid="2538211579596067402">"Nakili URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Chagua maandishi"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modi ya mabadiliko"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Songa"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Ingiza"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Chagua programu"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Gawa na"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Gawa na <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Kishikilio cha Kuslaidi. Wahi na shikilia."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Juu ajili ya<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Chini kwa ajili ya<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Kimya"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Sauti imewashwa"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Muhimu. Kifaa cha kuskiza kilihitaji kusikiliza vichupo wakati wa kucharaza nenosiri."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Chomeka plagi ya kifaa cha kichwa cha kusikiza ili kusikiliza msimbo wa nenosiri inayozungumwa kwa sauti ya juu."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Nukta."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Abiri nyumbani"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Ongoza"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Chaguo zaidi"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index bb9db21..fd4955d 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"อนุญาตให้แอปพลิเคชันอ่านข้อมูลโปรไฟล์ส่วนบุคคลที่จัดเก็บในอุปกรณ์ของคุณ เช่น ชื่อและข้อมูลรายชื่อติดต่อของคุณ ซึ่งหมายความว่าแอปพลิเคชันจะสามารถระบุตัวคุณและส่งข้อมูลโปรไฟล์ของคุณไปให้ผู้อื่นได้"</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"เขียนลงในข้อมูลโปรไฟล์ของคุณ"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"อนุญาตให้แอปพลิเคชันเปลี่ยนแปลงหรือเพิ่มลงในข้อมูลโปรไฟล์ส่วนบุคคลที่จัดเก็บในอุปกรณ์ของคุณ เช่น ชื่อและข้อมูลรายชื่อติดต่อของคุณ ซึ่งหมายความว่าแอปพลิเคชันอื่นจะสามารถระบุตัวคุณและส่งข้อมูลโปรไฟล์ของคุณไปให้ผู้อื่นได้"</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"อ่านสตรีมเครือข่ายสังคม"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"อนุญาตให้แอปพลิเคชันเข้าถึงและซิงค์การอัปเดตในเครือข่ายสังคมจากคุณและเพื่อน แอปพลิเคชันที่เป็นอันตรายสามารถใช้การทำงานนี้เพื่ออ่านการติดต่อส่วนตัวระหว่างคุณกับเพื่อนในเครือข่ายสังคมได้"</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"เขียนในสตรีมเครือข่ายสังคม"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"อนุญาตให้แอปพลิเคชันแสดงการอัปเดตในเครือข่ายสังคมจากเพื่อนของคุณ แอปพลิเคชันที่เป็นอันตรายสามารถใช้การทำงานนี้เพื่อปลอมเป็นเพื่อนคุณและหลอกให้บอกรหัสผ่านหรือข้อมูลลับอื่นๆ"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"อ่านกิจกรรมบนปฏิทินรวมถึงข้อมูลที่เป็นความลับ"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"อนุญาตให้แอปพลิเคชันอ่านกิจกรรมทั้งหมดบนปฏิทินที่จัดเก็บไว้ในแท็บเล็ตของคุณ รวมถึงกิจกรรมของเพื่อนและเพื่อนร่วมงานของคุณด้วย แอปพลิเคชันที่เป็นอันตรายซึ่งได้รับอนุญาตจะสามารถดึงข้อมูลส่วนบุคคลจากกิจกรรมบนปฏิทินเหล่านี้ได้โดยที่เจ้าของไม่ทราบ"</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"อนุญาตให้แอปพลิเคชันอ่านกิจกรรมทั้งหมดบนปฏิทินที่จัดเก็บไว้ในโทรศัพท์ของคุณ รวมถึงกิจกรรมของเพื่อนและเพื่อนร่วมงานของคุณด้วย แอปพลิเคชันที่เป็นอันตรายซึ่งได้รับอนุญาตจะสามารถดึงข้อมูลส่วนบุคคลจากกิจกรรมบนปฏิทินเหล่านี้ได้โดยที่เจ้าของไม่ทราบ"</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"โปรดใส่ซิมการ์ด"</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"ไม่มีซิมการ์ดหรือไม่สามารถอ่านได้ โปรดใส่ซิมการ์ด"</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"ซิมการ์ดของคุณถูกปิดใช้งานอย่างถาวร"\n"โปรดติดต่อผู้ให้บริการไร้สายของคุณเพื่อรับซิมการ์ดอีกอันหนึ่ง"</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"ปุ่มแทร็กก่อนหน้า"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"ปุ่มแทร็กถัดไป"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"ปุ่มหยุดชั่วคราว"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"ปุ่มเล่น"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"ปุ่มหยุด"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"โทรฉุกเฉินเท่านั้น"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"ล็อกเครือข่ายไว้"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"ซิมการ์ดถูกล็อกด้วย PUK"</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"ปลดล็อก"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"เปิดเสียง"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"ปิดเสียง"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"เริ่มวาดรูปแบบแล้ว"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"ล้างรูปแบบแล้ว"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"เพิ่มเซลแล้ว"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"วาดรูปแบบเสร็จสิ้น"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"ตัด"</string>
<string name="copy" msgid="2681946229533511987">"คัดลอก"</string>
<string name="paste" msgid="5629880836805036433">"วาง"</string>
- <string name="replace" msgid="5781686059063148930">"แทนที่???"</string>
+ <string name="replace" msgid="5781686059063148930">"แทนที่..."</string>
<string name="delete" msgid="6098684844021697789">"ลบ"</string>
<string name="copyUrl" msgid="2538211579596067402">"คัดลอก URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"เลือกข้อความ..."</string>
@@ -873,7 +886,7 @@
<string name="no" msgid="5141531044935541497">"ยกเลิก"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"โปรดทราบ"</string>
<string name="loading" msgid="1760724998928255250">"กำลังโหลด..."</string>
- <string name="capital_on" msgid="1544682755514494298">"ในวันที่"</string>
+ <string name="capital_on" msgid="1544682755514494298">"เปิด"</string>
<string name="capital_off" msgid="6815870386972805832">"ปิด"</string>
<string name="whichApplication" msgid="4533185947064773386">"ทำงานให้เสร็จโดยใช้"</string>
<string name="alwaysUse" msgid="4583018368000610438">"ใช้ค่าเริ่มต้นสำหรับการทำงานนี้"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"เปลี่ยนโหมด"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"ป้อน"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"เลือกแอปพลิเคชัน"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"แบ่งปันกับ"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"แบ่งปันด้วย <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"ที่จับสำหรับเลื่อน แตะค้างไว้"</string>
<string name="description_direction_up" msgid="1983114130441878529">"เลื่อนขึ้นเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
<string name="description_direction_down" msgid="4294993639091088240">"เลื่อนลงเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"กล้องถ่ายรูป"</string>
<string name="description_target_silent" msgid="893551287746522182">"ปิดเสียง"</string>
<string name="description_target_soundon" msgid="30052466675500172">"เปิดเสียง"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"แป้นพิมพ์ จำเป็นต้องใช้ชุดหูฟังในการฟังเสียงแป้นพิมพ์ขณะพิมพ์รหัสผ่าน"</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"เสียบชุดหูฟังเพื่อฟังเสียงเมื่อพิมพ์รหัสผ่าน"</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"เครื่องหมายจุด"</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"นำทางไปหน้าแรก"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"นำทางขึ้น"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"ตัวเลือกเพิ่มเติม"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 8eca89b..746cb96 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Pinapayagan ang application na bumasa ng personal na impormasyon ng profile na nakaimbak sa iyong device, tulad ng iyong pangalan at impormasyon ng contact. Nangangahulugan ito na makikilala ka ng application at maipapadala ang iyong impormasyon ng profile sa iba."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"i-write sa iyong data ng profile"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Pinapayagan ang application na baguhin o magdagdag sa personal na impormasyon ng profile na nakaimbak sa iyong device, tulad ng iyong pangalan at impormasyon ng contact. Nangangahulugan ito na makikilala ka ng iba pang mga application at maipapadala ang iyong impormasyon ng profile sa iba."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"basahin ang iyong social stream"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Binibigyang-daan ang application upang mag-access at mag-sync ng mga social update mula sa iyo at iyong mga kaibigan. Maaari itong gamitin ng mga nakakahamak na apps upang basahin ang mga pribadong pag-uusap sa pagitan mo at ng iyong mga kaibigan sa mga social network."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"magsulat sa iyong social stream"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Binibigyang-daan ang application upang magpakita ng mga social update mula sa iyong mga kaibigan. Maaari itong gamitin ng mga nakakahamak na apps upang magpanggap na kaibigan at linlangin ka sa pagsisiwalat ng mga password o ibang kumpedensyal na impormasyon."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"magbasa ng mga kaganapan sa kalendaryo kasama ang kumpedensyal na impormasyon"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Pinapayagan ang isang application na basahin ang lahat ng kaganapan sa kalendaryong naka-imbak sa iyong tablet, kasama ang mga nasa kaibigan o katrabaho. Ang isang nakapanghahamak na application na may ganitong pahintulot ay maaaring kumuha ng personal na impormasyon mula sa mga kalendaryong ito nang hindi nalalaman ng mga may-ari."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Pinapayagan ang isang application na basahin ang lahat ng kaganapan sa kalendaryong naka-imbak sa iyong telepono, kasama ang mga nasa kaibigan o katrabaho. Ang isang nakapanghahamak na application na may ganitong pahintulot ay maaaring kumuha ng personal na impormasyon mula sa mga kalendaryong ito nang hindi nalalaman ng mga may-ari."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Mangyaring magpasok ng SIM card."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Nawawala o hindi nababasa ang SIM card. Mangyaring magpasok ng isang SIM card."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Ang iyong SIM card ay permanenteng hindi pinagana."\n" Mangyaring makipag-ugnay sa iyong wireless service provider upang makakuha ng isa pang SIM card."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Button na nakaraang track"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Button na Susunod na track"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Button na I-pause"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Button na I-play"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Button na Itigil"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Mga pang-emergency na tawag lang"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Naka-lock ang network"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Naka-PUK-lock ang SIM card."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"I-unlock"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"I-on ang tunog"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"I-off ang tunog"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Sinimulan ang pattern"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Na-clear ang pattern"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Idinagdag ang cell"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Nakumpleto ang pattern"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"I-cut"</string>
<string name="copy" msgid="2681946229533511987">"Kopyahin"</string>
<string name="paste" msgid="5629880836805036433">"I-paste"</string>
- <string name="replace" msgid="5781686059063148930">"Palitan???"</string>
+ <string name="replace" msgid="5781686059063148930">"Palitan..."</string>
<string name="delete" msgid="6098684844021697789">"Tanggalin"</string>
<string name="copyUrl" msgid="2538211579596067402">"Kopyahin ang URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Pumili ng teksto..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Pagbabago ng Mode"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Pumili ng isang application"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Ibahagi sa"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Ibahagi sa <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Hawakan sa pag-slide. Tapikin at i-hold."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Nakataas para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Nakababa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Tahimik"</string>
<string name="description_target_soundon" msgid="30052466675500172">"I-on ang tunog"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Key. Kinakailangan ng headset upang marinig ang mga key habang nata-type ng password."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Mag-plug in ng isang headset upang marinig ang mga password key na binabanggit nang malakas."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dot."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Magnabiga sa home"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Magnabiga pataas"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Higit pang mga pagpipilian"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 381c65b..2b76c22 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Uygulamaya, adınız ve iletişim bilgileriniz gibi, cihazınızda saklı kişisel profil bilgilerinizi okuma izni verir. Bu, uygulamanın sizi tanımlayabilmesi ve profil bilgilerinizi başkalarına gönderebilmesi anlamına gelir."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"profil verilerime yaz"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Uygulamaya, adınız ve iletişim bilgileriniz gibi, cihazınızda saklı kişisel profil bilgilerinizi değiştirme veya ekleme izni verir. Bu, diğer uygulamaların sizi tanımlayabileceği ve profil bilgilerinizi başkalarına gönderebileceği anlamına gelir."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"sosyal akışımı oku"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Uygulamaya, sizden ve arkadaşlarınızdan gelen sosyal güncellemelere erişme ve bunları senkronize etme izni verir. Kötü amaçlı uygulamalar bu izni, sosyal ağlar üzerinde sizinle arkadaşlarınız arasındaki kişisel iletişimi okumak için kullanabilir."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"sosyal akışıma yaz"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Uygulamaya, arkadaşlarınızdan gelen sosyal güncellemeleri görüntüleme izni verir. Kötü amaçlı uygulamalar bu izni, kendisini sizin bir arkadaşınız gibi tanıtıp sizi kandırarak şifrelerinizi veya diğer gizli bilgilerinizi almak için kullanabilir."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"takvim etkinliklerini ve gizli bilgileri oku"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Uygulamaya, tabletinizde saklı takvim etkinliklerini (özel veya iş arkadaşlarınızınkiler dahil) okuma izni verir. Kötü amaçlı bir uygulama bu izni kullanarak, sahibin bilgisi olmadan bu takvimlerden kişisel bilgileri alabilir."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Uygulamaya, telefonunuzda saklı takvim etkinliklerini (özel veya iş arkadaşlarınızınkiler dahil) okuma izni verir. Kötü amaçlı bir uygulama bu izni kullanarak, sahibin bilgisi olmadan bu takvimlerden kişisel bilgileri alabilir."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Lütfen SIM kart takın."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"SIM kart eksik veya okunamıyor. Bir SIM kart takın."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"SIM kartınız kalıcı olarak devre dışı bırakıldı."\n" Başka bir SIM kart almak için kablosuz servis sağlayıcınıza başvurun."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Önceki parça düğmesi"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Sonraki parça düğmesi"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Duraklat düğmesi"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Oynat düğmesi"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Durdur düğmesi"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Yalnızca acil çağrılar için"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Ağ kilitli"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM kart PUK kilidi devrede."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Kilit Aç"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sesi aç"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Sesi kapat"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Desen başlatıldı"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Desen temizlendi"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Hücre eklendi"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Desen tamamlandı"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mod değiştirme"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"ÜstKrkt"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Giriş"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Uygulama seçin"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Şununla paylaş:"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ile paylaş"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Kayar tutma yeri. Hafifçe vurun ve basılı tutun."</string>
<string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için yukarı."</string>
<string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için aşağı."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Sessiz"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Ses açık"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Tuş. Şifre yazarken tuşları duyabilmek için kulaklık gerekir."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Şifre tuşlarının sesli okunmasını dinlemek için mikrofonlu kulaklık takın."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Nokta."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Ana sayfaya git"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Yukarı git"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Diğer seçenekler"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 8ae915c..c71cc8c 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Дозволяє програмі читати особисту інформацію профілю, збережену на вашому пристрої, як-от ваше ім’я та контактну інформацію. Це означає, що така програма може ідентифікувати вашу особу та надсилати інформацію вашого профілю іншим."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"записувати в дані профілю"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Дозволяє програмі змінювати чи додавати особисту інформацію профілю, збережену на вашому пристрої, як-от ваше ім’я та контактну інформацію. Це означає, що інші програми можуть ідентифікувати вашу особу та надсилати інформацію вашого профілю іншим."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"читати ваш соціальний потік"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Дозволяє програмі отримувати доступ до оновлень із соціальних мереж від вас і ваших друзів та синхронізувати їх. Шкідливі програми можуть використовувати це для доступу до приватного спілкування між вами та вашими друзями в соціальних мережах."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"писати у ваш соціальний потік"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Дозволяє програмі відображати оновлення із соціальних мереж від ваших друзів. Шкідливі програми можуть використовувати це, щоб видавати себе за вашого друга й оманливим шляхом отримувати ваші паролі чи іншу конфіденційну інформацію."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"читати події календаря, а також конфіденційну інформацію"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Дозволяє програмі читати всі події календаря, збережені в планшетному ПК, включно з подіями друзів або співробітників. Шкідлива програма з таким дозволом може отримувати особисту інформацію з цих календарів без відома власників."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Дозволяє програмі читати всі події календаря, збережені в телефоні, включно з подіями друзів або співробітників. Шкідлива програма з таким дозволом може отримувати особисту інформацію з цих календарів без відома власників."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Вставте SIM-карту."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"SIM-карта відсутня або недоступна для зчитування. Вставте SIM-карту."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Вашу SIM-карту вимкнено назавжди."\n" Зверніться до свого постачальника послуг бездротового зв’язку, щоб отримати іншу SIM-карту."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Кнопка \"Попередня доріжка\""</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Кнопка \"Наступна доріжка\""</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Кнопка \"Призупинити\""</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Кнопка \"Відтворити\""</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Кнопка \"Зупинити\""</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Лише аварійні виклики"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Мережу заблок."</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-карту заблоковано PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Розблок."</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Увімк. звук"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Вимкн. звук"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Малювання ключа розпочалося"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Ключ очищено"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Телефон додано"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Малювання ключа закінчено"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Зміна режиму"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Виберіть програму"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Надіслати через"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Надіслати через <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Ручка-повзунок. Торкніться й утримуйте її."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Угору, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Униз, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
<string name="description_target_silent" msgid="893551287746522182">"Без звуку"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Увімкнути звук"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Клавіша. Гарнітура має чути звук клавіш під час введення пароля."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Підключіть гарнітуру, щоб прослухати відтворені вголос символи пароля."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Крапка."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Перейти на головну"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Перейти вгору"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Інші варіанти"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index d0c633e..c65ecf4 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Cho phép ứng dụng đọc thông tin tiểu sử cá nhân được lưu trên thiết bị của bạn, ví dụ như tên và thông tin liên hệ của bạn. Điều này nghĩa là ứng dụng có thể nhận dạng bạn và gửi thông tin tiểu sử của bạn cho những người khác."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"ghi dữ liệu t.sử của bạn"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Cho phép ứng dụng thay đổi hoặc thêm vào thông tin tiểu sử cá nhân được lưu trữ trên thiết bị của bạn, ví dụ như tên và thông tin liên hệ của bạn. Điều này nghĩa là các ứng dụng khác có thể nhận dạng bạn và gửi thông tin tiểu sử của bạn cho những người khác."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"đọc luồng xã hội của bạn"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Cho phép ứng dụng truy cập và đồng bộ hóa các bản cập nhật xã hội từ bạn bè của bạn. Các ứng dụng độc hại có thể sử dụng điều này để đọc thông tin liên lạc riêng tư giữa bạn và bạn bè của bạn trên mạng xã hội."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ghi luồng xã hội của bạn"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Cho phép ứng dụng hiển thị các bản cập nhật xã hội từ bạn bè của bạn. Các ứng dụng độc hại có thể sử dụng điều này để giả vờ là một người bạn và lừa đảo bạn tiết lộ mật khẩu hoặc thông tin bảo mật khác."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"đọc các sự kiện lịch và thông tin bí mật"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Cho phép ứng dụng đọc tất cả các sự kiện lịch được lưu trữ trên máy tính bảng của bạn, bao gồm các sự kiện của bạn bè hoặc đồng nghiệp. Ứng dụng độc hại có quyền này có thể trích xuất thông tin cá nhân từ những lịch này mà chủ sở hữu không hề biết."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Cho phép ứng dụng đọc tất cả các sự kiện lịch được lưu trữ trên điện thoại của bạn, bao gồm các sự kiện của bạn bè hoặc đồng nghiệp. Ứng dụng độc hại có quyền này có thể trích xuất thông tin cá nhân từ những lịch này mà chủ sở hữu không hề biết."</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Vui lòng lắp thẻ SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Thẻ SIM bị thiếu hoặc không thể đọc được. Vui lòng lắp thẻ SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Thẻ SIM của bạn đã bị vô hiệu hóa vĩnh viễn."\n" Hãy liên hệ với nhà cung cấp dịch vụ không dây của bạn để lấy thẻ SIM khác."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Nút bài hát trước"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Nút bài hát tiếp theo"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Nút tạm dừng"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Nút phát"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Nút dừng"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Chỉ cuộc gọi khẩn cấp"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Mạng đã khoá"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Thẻ SIM đã bị khoá PUK."</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Mở khoá"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Bật âm thanh"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Tắt âm thanh"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Đã bắt đầu vẽ hình"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Đã xóa hình"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Đã thêm ô"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Đã vẽ xong hình"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"Cắt"</string>
<string name="copy" msgid="2681946229533511987">"Sao chép"</string>
<string name="paste" msgid="5629880836805036433">"Dán"</string>
- <string name="replace" msgid="5781686059063148930">"Thay thế???"</string>
+ <string name="replace" msgid="5781686059063148930">"Thay thế..."</string>
<string name="delete" msgid="6098684844021697789">"Xóa"</string>
<string name="copyUrl" msgid="2538211579596067402">"Sao chép URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Chọn văn bản..."</string>
@@ -1002,7 +1015,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Gỡ lỗi USB đã được kết nối"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Chọn để vô hiệu hoá gỡ lỗi USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Chọn phương thức nhập"</string>
- <string name="configure_input_methods" msgid="6324843080254191535">"Định cấu hình phương pháp nhập liệu"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Định cấu hình phương thức nhập liệu"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"ứng viên"</u></string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Thay đổi chế độ"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Chọn ứng dụng"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Chia sẻ với"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Chia sẻ với <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Tay trượt. Bấm và giữ."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Lên để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Xuống để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Máy ảnh"</string>
<string name="description_target_silent" msgid="893551287746522182">"Im lặng"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Bật âm thanh"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Phím. Yêu cầu phải có tai nghe để nghe phím khi nhập mật khẩu."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Hãy cắm tai nghe để nghe mật khẩu."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dấu chấm."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Điều hướng về trang chủ"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Điều hướng lên trên"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Tùy chọn khác"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 48e474a..d559569 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"允许应用程序读取您设备上存储的个人资料信息(如您的姓名和联系人信息)。这意味着应用程序可以识别您的身份并将您的个人资料发送给他人。"</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"写入到您的个人资料数据"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"允许应用程序更改您设备上存储的个人资料信息(如您的姓名和联系人信息),或者向其中添加信息。这意味着其他应用程序可以识别您的身份并将您的个人资料发送给他人。"</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"读取您的社交视频流"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"允许应用程序访问并同步您和好友的社交最新动态。恶意应用程序可借此读取您与社交网络上的好友之间的私人交流信息。"</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"写入您的社交视频流"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"允许应用程序显示好友的社交最新动态。恶意应用程序可借此冒充为您的一位好友,诱骗您泄露密码或其他机密信息。"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"读取日历活动和机密信息"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"允许应用程序读取您平板电脑上存储的所有日历活动(包括朋友或同事的活动)。拥有此权限的恶意应用程序可在所有者不知情的情况下,从这些日历中提取个人信息。"</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"允许应用程序读取您手机上存储的所有日历活动(包括朋友或同事的活动)。拥有此权限的恶意应用程序可在所有者不知情的情况下,从这些日历中提取个人信息。"</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"请插入 SIM 卡"</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"SIM 卡丢失或无法读取。请插入 SIM 卡。"</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"您的 SIM 卡已永久停用。"\n"请与您的无线服务提供商联系,以便重新获取一张 SIM 卡。"</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"“上一曲目”按钮"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"“下一曲目”按钮"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"“暂停”按钮"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"“播放”按钮"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"“停止”按钮"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"只能使用紧急呼叫"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"网络已锁定"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM 卡已用 PUK 码锁定"</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"解锁"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"打开声音"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"关闭声音"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"开始绘制图案"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"图案已清除"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"单元格已添加"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"图案绘制完成"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"剪切"</string>
<string name="copy" msgid="2681946229533511987">"复制"</string>
<string name="paste" msgid="5629880836805036433">"粘贴"</string>
- <string name="replace" msgid="5781686059063148930">"替换???"</string>
+ <string name="replace" msgid="5781686059063148930">"替换..."</string>
<string name="delete" msgid="6098684844021697789">"删除"</string>
<string name="copyUrl" msgid="2538211579596067402">"复制网址"</string>
<string name="selectTextMode" msgid="6738556348861347240">"选择文字..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"模式更改"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"选择一个应用程序"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"共享对象"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"与“<xliff:g id="APPLICATION_NAME">%s</xliff:g>”共享"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"滑动手柄。点按并按住。"</string>
<string name="description_direction_up" msgid="1983114130441878529">"向上滑动<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
<string name="description_direction_down" msgid="4294993639091088240">"向下滑动<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"相机"</string>
<string name="description_target_silent" msgid="893551287746522182">"静音"</string>
<string name="description_target_soundon" msgid="30052466675500172">"打开声音"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"按键声。需要插入耳机才能在键入密码时听到按键声。"</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"需要插入耳机才能听到密码的按键声。"</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"点。"</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"导航首页"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"向上导航"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"更多选项"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 4d2890e48..4b791f1 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"允許應用程式讀取儲存在裝置上的個人資料資訊,例如您的姓名和聯絡資訊。這表示該應用程式可以識別您的身分,並將您的個人資料資訊傳送給他人。"</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"寫入您的個人資料"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"允許應用程式新增或變更儲存在裝置上的個人資料資訊,例如您的姓名和聯絡資訊。這表示其他應用程式可以識別您的身分,並將您的個人資料資訊傳送給他人。"</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"讀取您的社交串流"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"允許應用程式存取並同步處理好友的最新動態。惡意應用程式可能會藉此竊取您和好友在社交網路上的私人訊息。"</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"寫入您的社交串流"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"允許應用程式顯示好友的最新動態。惡意應用程式可能會藉此假冒您的好友,騙取您的密碼或其他機密資訊。"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"讀取日曆活動與機密資訊"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"允許應用程式讀取所有儲存在您平板電腦上的日曆活動,包含好友或同事的日曆活動。惡意應用程式可能藉此在未經擁有者同意的情況下,從這些日曆擷取個人資訊。"</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"允許應用程式讀取所有儲存在您手機上的日曆活動,包含好友或同事的日曆活動。惡意應用程式可能藉此在未經擁有者同意的情況下,從這些日曆擷取個人資訊。"</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"請插入 SIM 卡。"</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"找不到 SIM 卡或無法讀取 SIM 卡,請插入 SIM 卡。"</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"您的 SIM 卡已永久停用。"\n"請與您的無線服務供應商聯絡,以取得其他 SIM 卡。"</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"[上一首曲目] 按鈕"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"[下一首曲目] 按鈕"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"[暫停] 按鈕"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"[播放] 按鈕"</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"[停止] 按鈕"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"僅可撥打緊急電話"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"網路已鎖定"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM 的 PUK 已鎖定。"</string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"解除封鎖"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"開啟音效"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"關閉音效"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"已開始繪畫解鎖圖形"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"已清除解鎖圖形"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"已加入 1 格"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"已畫出解鎖圖形"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -855,7 +868,7 @@
<string name="cut" msgid="3092569408438626261">"剪下"</string>
<string name="copy" msgid="2681946229533511987">"複製"</string>
<string name="paste" msgid="5629880836805036433">"貼上"</string>
- <string name="replace" msgid="5781686059063148930">"取代???"</string>
+ <string name="replace" msgid="5781686059063148930">"取代…"</string>
<string name="delete" msgid="6098684844021697789">"刪除"</string>
<string name="copyUrl" msgid="2538211579596067402">"複製網址"</string>
<string name="selectTextMode" msgid="6738556348861347240">"選取文字..."</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"模式變更"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift 鍵"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter 鍵"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"選擇應用程式"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"分享對象:"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"與「<xliff:g id="APPLICATION_NAME">%s</xliff:g>」分享"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"滑動控制。持續輕按。"</string>
<string name="description_direction_up" msgid="1983114130441878529">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
<string name="description_direction_down" msgid="4294993639091088240">"向下滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"相機"</string>
<string name="description_target_silent" msgid="893551287746522182">"靜音"</string>
<string name="description_target_soundon" msgid="30052466675500172">"開啟音效"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"提醒您,輸入密碼時需要使用耳機才能聽到按鍵名稱。"</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"接上耳機即可聽見系統朗讀密碼鍵。"</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"點。"</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"瀏覽首頁"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"向上瀏覽"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"更多選項"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 87c96f3..a61416f 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -32,11 +32,11 @@
<string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Ayikho inombolo yocingo)"</string>
<string name="unknownName" msgid="2277556546742746522">"(Akwaziwa)"</string>
- <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Umyalezo wezwi"</string>
+ <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Ivoyisimeyili"</string>
<string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
<string name="mmiError" msgid="5154499457739052907">"Inkinga yoxhumano noma ikhadi ye-MMI engalungile."</string>
<string name="mmiFdnError" msgid="5224398216385316471">"Umsebenzi uvinjelwe ekudayeleni izinombolo ezingaguquki kuphela."</string>
- <string name="serviceEnabled" msgid="8147278346414714315">"Insizakalo ivaliwe."</string>
+ <string name="serviceEnabled" msgid="8147278346414714315">"Isevisi ivaliwe."</string>
<string name="serviceEnabledFor" msgid="6856228140453471041">"Isevisi ivulelwe:"</string>
<string name="serviceDisabled" msgid="1937553226592516411">"Isevisi ivaliwe."</string>
<string name="serviceRegistered" msgid="6275019082598102493">"Ukubhalisa kuphumelele."</string>
@@ -52,9 +52,9 @@
<string name="needPuk2" msgid="4526033371987193070">"Thayipha i-PUK2 ukuze uvule ikhadi le-SIM."</string>
<string name="ClipMmi" msgid="6952821216480289285">"I-ID Yocingo Olungenayo"</string>
<string name="ClirMmi" msgid="7784673673446833091">"I-ID Yomshayeli Ephumayo"</string>
- <string name="CfMmi" msgid="5123218989141573515">"Ukudlulisa ucingo"</string>
- <string name="CwMmi" msgid="9129678056795016867">"Ucingo lulindile"</string>
- <string name="BaMmi" msgid="455193067926770581">"Ukuvima ucingo"</string>
+ <string name="CfMmi" msgid="5123218989141573515">"Ukudlulisa ikholi"</string>
+ <string name="CwMmi" msgid="9129678056795016867">"Ikholi ilindile"</string>
+ <string name="BaMmi" msgid="455193067926770581">"Ukuvimba ikholi"</string>
<string name="PwdMmi" msgid="7043715687905254199">"Shintsha iphasiwedi"</string>
<string name="PinMmi" msgid="3113117780361190304">"shintsha i-PIN"</string>
<string name="CnipMmi" msgid="3110534680557857162">"Ukushayela inombolo kukhona"</string>
@@ -171,7 +171,7 @@
<string name="permgroupdesc_accounts" msgid="4948732641827091312">"Finyelela kuma-akhawunti atholakalayo"</string>
<string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Izilawuli zezingxenyekazi zekhompyutha"</string>
<string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Ukufinyelela okuqondile ihadiwe nehendsethi."</string>
- <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Izincingo zefoni"</string>
+ <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Amakholi efoni"</string>
<string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Qapha, bhala, futhi wenze amakholi wefoni."</string>
<string name="permgrouplab_systemTools" msgid="4652191644082714048">"Amathuluzi esistimu"</string>
<string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Ukufinyelela kwezinga eliphansi nokulawula uhlelo."</string>
@@ -180,7 +180,7 @@
<string name="permgrouplab_storage" msgid="1971118770546336966">"Isitoreji"</string>
<string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Finyelela kwisitoreji se-USB."</string>
<string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Finyelela ikhadi le-SD."</string>
- <string name="permlab_statusBar" msgid="7417192629601890791">"vimbela noma guqula ibha yomumo"</string>
+ <string name="permlab_statusBar" msgid="7417192629601890791">"khubaza noma guqula ibha yomumo"</string>
<string name="permdesc_statusBar" msgid="1365473595331989732">"Ivumela uhlelo lokusebenza ukuvimbela umudwa ochaza ngesimo noma ukufaka noma ukukhipha izithonjana zohlelo."</string>
<string name="permlab_statusBarService" msgid="7247281911387931485">"umudwa ochaza ngesimo"</string>
<string name="permdesc_statusBarService" msgid="4097605867643520920">"Ivumela uhlelo lokusebenza ukuba umudwa ochaza ngesimo."</string>
@@ -252,13 +252,13 @@
<string name="permdesc_confirm_full_backup" msgid="9005017754175897954">"Ivumela uhlelo lokusebenza ukuqalisa ukuqinisekisw okuphelele kwesipele kwe-UI. Akumelwe kusetshenziswe noma yiluphi uhlelo lokusebenza."</string>
<string name="permlab_internalSystemWindow" msgid="2148563628140193231">"bonisa amawindi angavunyelwe"</string>
<string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Ivumela ukwenziwa kwemawindi ehloselwe ukusebenziswa uxhumano lomsebenzisi wohlelo lwangaphakathi. Ayisebenziswa izinhlelo zokusebenza ezivamile"</string>
- <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"bonisa izexwayiso zezinga lesistimu"</string>
+ <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"bonisa izaziso zezinga lesistimu"</string>
<string name="permdesc_systemAlertWindow" msgid="2884149573672821318">"Ivumela uhlelo lokusebenza ukubonisa amawindi okuxwayisa ohlelo. Izinhlelo zokusebenza ezinonya zingase zithathe isikrini sonke."</string>
<string name="permlab_setAnimationScale" msgid="2805103241153907174">"guqula isivinini sokugqwayiza jikelele"</string>
<string name="permdesc_setAnimationScale" msgid="7181522138912391988">"Ivumela uhlelo lokusebenza ukushintsha isivinini sokugqwayiza jikelele (ukugqwayiza okusheshayo noma okulengayo) nganoma isiphi isikhathi."</string>
<string name="permlab_manageAppTokens" msgid="17124341698093865">"phatha amathokeni ohlelo lokusebenza"</string>
<string name="permdesc_manageAppTokens" msgid="977127907524195988">"Ivumela izinhlelo zokusebenza ukwenza nokuphatha amathokhini awo, ngokudlula ukuhleleka kuka-Z. Akusoze kwadingeka ezinhlelweni ezivamile."</string>
- <string name="permlab_injectEvents" msgid="1378746584023586600">"cindizela okhiye nezinkinobho zokulawula"</string>
+ <string name="permlab_injectEvents" msgid="1378746584023586600">"chofoza okhiye nezinkinobho zokulawula"</string>
<string name="permdesc_injectEvents" product="tablet" msgid="7200014808195664505">"Ivumela uhlelo lokusebenza ukuthumela izenzakalo zawo zokufakwayo (ukucindezela ukhiye, nokunye) kwezinye izihlelo zokusebenza. Izinhlelo ezinonya zingasebenzisa lokhu ukuthatha ithebhulethi."</string>
<string name="permdesc_injectEvents" product="default" msgid="3946098050410874715">"Ivumela uhlelo lokusebenza ukuthumela izenzakalo zawo zokufakwayo (ukucindezela ukhiye, nokunye) kwezinye izihlelo zokusebeza. Izinhlelo ezinonya zingasebenzisa lokhu ukuthatha ifoni."</string>
<string name="permlab_readInputState" msgid="469428900041249234">"qopha lokho okuthayiphayo nezinyathelo ozithathayo"</string>
@@ -330,6 +330,10 @@
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Ivumela isisetshenziswa ukuthi sifunde imininingwane yakho egcinwe kwi-device yakho, efana igama lakho kanye nemininingwane yokuxhumana. Lokhu kuchaza ukuthi isisetshenziswa singakwazi ukubona ukuthi nguwe bese sithumela imininingwane yakho kwabanye."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"bhala imininingwane yemininingo yakho"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Ivumela isisetshenziswa ukuthi sifunde imininingwane yakho egcinwe kwi-device yakho, efana igama lakho kanye nemininingwane yokuxhumana. Lokhu kuchaza ukuthi isisetshenziswa singakwazi ukubona ukuthi nguwe bese sithumela imininingwane yakho kwabanye."</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"funda ngezindlela zakho zokuxhumana nabanye abantu"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Ivumela insiza ukuthi ifinyelele iphinde ivumelanisa izaziso zokuxhumana nabanye abantu. Izinsiza ezinobungozi zingasebnzisa lokhu ukufunda ukuxhumana okuyimfihlo phakathi kwakho nabangani bakho."</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"bhala indlela yakho yokuxhumana nabantu"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Ivumela insiza ukuthi ikhombise izaziso zokuxhumana komphakathi ebanganini bakho. Izinsiza ezinobungozi zingasebenzisa lokhu ukwenza sengathi umngani zikukhohlise ukuze uveze iphasiwedi yakho noma eminye imininingwane yakho eyimfihlo."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"funda izenzakalo zekhalenda kanye nokwaziswa okuyimfihlo"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Ivumela uhlelo lokusebenza ukufunda zonke izenzakalo zekhalenda ezilondolozwe kwithebhulethi yakho, kuhlanganise ezabangani noma osebenza nabo. Uhlelo lokusebenza olu-malicious olunalemvume lungase luthathe ukwaziswa komuntu siqu kulamakhalenda ngaphandle kolwazi lomnikazi."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Ivumela uhlelo lokusebenza ukufunda zonke izenzakalo zekhalenda ezilondolozwe efonini yakho, kuhlanganise ezabangani noma osebenza nabo. Uhlelo lokusebenza olu-malicious olunalemvume lungase luthathe ukwaziswa komuntu siqu kulamakhalenda ngaphandle kolwazi lomnikazi."</string>
@@ -417,7 +421,7 @@
<string name="permlab_factoryTest" msgid="3715225492696416187">"sebenzisa kwimodi yokuhlola yemboni"</string>
<string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Sebenzise njengokuhlola komkhiqizi wezinga eliphansi, uvumela ukufinyelela okugcwele ihadiwe yethebhulethi. Itholakala kuphela lapho ithebhulethi isebenza kwimodi yokuhlola yomkhiqizi."</string>
<string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Sebenzise njengokuhlola komkhiqizi wezinga eliphansi, uvumela ukufinyelela okugcwele ihadiwe yefoni. Itholakala kuphela lapho ifoni isebenza kwimodi yokuhlola yomkhiqizi."</string>
- <string name="permlab_setWallpaper" msgid="6627192333373465143">"setha iphepha donga"</string>
+ <string name="permlab_setWallpaper" msgid="6627192333373465143">"setha iphephadonga"</string>
<string name="permdesc_setWallpaper" msgid="6417041752170585837">"Ivumela uhlelo lokusebenza ukuhlela iphephadonga lesistimu."</string>
<string name="permlab_setWallpaperHints" msgid="3600721069353106851">"setha izixwayiso zosayizi wephephadonga"</string>
<string name="permdesc_setWallpaperHints" msgid="6019479164008079626">"Ivumela uhlelo lokusebenza ukuhlela izihlawumbisela zosayizi wephephadonga lohlelo."</string>
@@ -461,12 +465,12 @@
<string name="permlab_bluetoothAdmin" msgid="1092209628459341292">"ukubhalisela i-bluetooth"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="3511795757324345837">"Ivumela uhlelo lokusebenza ukumisa ithebhulethi ye-Bluetooth yasendawni, nokuthola nokubhanqanisa namadivaysi okulawula okukude."</string>
<string name="permdesc_bluetoothAdmin" product="default" msgid="7256289774667054555">"Ivumela uhlelo lokusebenza ukumisa ifoni ye-Bluetooth yasendawni, nokuthola nokubhanqanisa namadivaysi okulawula okukude."</string>
- <string name="permlab_bluetooth" msgid="8361038707857018732">"Yenza uxhumano lwe-Bluetooth"</string>
+ <string name="permlab_bluetooth" msgid="8361038707857018732">"Dala uxhumano lwe-Bluetooth"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="4191941825910543803">"Ivumela uhlelo lokusebenza ukubuka ukumisa ifoni yethebhulethi ye-Bluetooth yasendaweni, nokwenza futhi nokwamukela uxhumano ngamadivaysi abhangqene."</string>
<string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Ivumela uhlelo lokusebenza ukubuka ukumisa ifoni ye-Bluetooth yasendaweni, nokwenza futhi nokwamukela uxhumano ngamadivaysi abhangqene."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"lawula Uxhumano Lwenkambu Eseduze"</string>
<string name="permdesc_nfc" msgid="9171401851954407226">"Ivumela uhlelo lokusebenza ukuxhumana nezilengisi, amakhadi, nabafundi Bokuxhumana Nenkambu Eseduze (NFC)."</string>
- <string name="permlab_disableKeyguard" msgid="4977406164311535092">"vimbela ukuvala ukhiye"</string>
+ <string name="permlab_disableKeyguard" msgid="4977406164311535092">"khubaza ukuvala ukhiye"</string>
<string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Ivumela uhlelo lokusebenza ukuvimbela ukuvala ukhiye nanoma yikuphi ukuphepha kwephasiwedi okuhlobene. Isibonelo esisemthethweni salokhu ukuba ifoni ivimbele ukuvala ukhiye laphi ithola ikholi engenayo, bese ivumela futhi ukuvala ukhiye lapho ucingo seluqedile."</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"funda izilungiselelo zokuvumelanisa"</string>
<string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Ivumela uhlelo lokusebenza ukufunda izilungiselelo zokuvumelanisa, njengokuthi ingabe ukuvumelanisa kuvulelwe yini Othintana nabo."</string>
@@ -639,14 +643,14 @@
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Faka iphasiwedi ukuvula"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Faka i-PIN ukuvula"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Ikhodi ye-PIN engalungile!"</string>
- <string name="keyguard_label_text" msgid="861796461028298424">"Ukuvula, cindezela Menyu bese 0."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Ukuvula, chofoza Menyu bese 0."</string>
<string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Inombolo ephuthumayo"</string>
<string name="lockscreen_carrier_default" msgid="8963839242565653192">"Ayikho isevisi"</string>
<string name="lockscreen_screen_locked" msgid="7288443074806832904">"Isikrini sivaliwe."</string>
- <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Cindezela Menyu ukuvula noma ukwenza ucingo oluphuthumayo."</string>
- <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Cindezela Menyu ukuvula."</string>
+ <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Chofoza Menyu ukuvula noma ukwenza ikholi ephuthumayo."</string>
+ <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Chofoza Menyu ukuvula."</string>
<string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Dweba iphathini ukuvula"</string>
- <string name="lockscreen_emergency_call" msgid="5347633784401285225">"Ucingo oluphuthumayo"</string>
+ <string name="lockscreen_emergency_call" msgid="5347633784401285225">"Ikholi ephuthumayo"</string>
<string name="lockscreen_return_to_call" msgid="5244259785500040021">"Buyela ekholini"</string>
<string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Lungile!"</string>
<string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Uxolo, zama futhi"</string>
@@ -661,6 +665,11 @@
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Sicela ufake ikhadi le-SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="7138450788301444298">"Ikhadi le-SIM alitholakali noma alifundeki. Sicela ufake ikhadi le-SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="1631853574702335453">"Ikhadi lakho lwe-SIM lukhubazekhisiwe ngokuphelele. "\n" Sicela uthintane nomhlinzeki wosizo ongenantambo ukuthola elinye ikhadi le-SIM."</string>
+ <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Inkinombo yengoma yangaphambilini"</string>
+ <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Inkinobho yengoma elandelayo"</string>
+ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Inkinobho yokukuma kancane"</string>
+ <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Inkinobho yokudlala."</string>
+ <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Misa inkinombo"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Amakholi aphuthumayo kuphela"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Inethiwekhi ivaliwe"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Ikhadi le-SIM livalwe nge-PUK."</string>
@@ -676,13 +685,13 @@
<string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Uzame ngokusebenzisa indlela engafanele ukuvula izikhathi <xliff:g id="NUMBER_0">%d</xliff:g> zocingo. Ngemuva <xliff:g id="NUMBER_1">%d</xliff:g> kokuzama kaningana ngaphandle kwempumelelo, ucingo luzobiyiselwa kwizimiso zasembonini futhi yonke imininingo yomsebenzisi izolahleka."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Uzame ukuvula ngendlela engafanele izikhathi <xliff:g id="NUMBER">%d</xliff:g> ze-tablet. I-tablet manje seyizosethwa kabusha ibe yizimiso zasembonini."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Uzame ukuvula ngendlela engafanele izikhathi <xliff:g id="NUMBER">%d</xliff:g> zocingo. Ucingo manje seyizosethwa kabusha ibe yizimiso zasembonini."</string>
- <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Zama futhi emizuzwini engu <xliff:g id="NUMBER">%d</xliff:g>."</string>
+ <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Zama futhi emaminithini angu <xliff:g id="NUMBER">%d</xliff:g>."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Ukhohlwe iphethini?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Ukuvulwa kwe-akhawunti"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Kunemizamo eminingi kakhulu yephathini!"</string>
<string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Ukuvula, ngena ngemvumekwi-akhawunti ye-Google"</string>
<string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Igama lomsebenzisi (i-imeyli)"</string>
- <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"I-password"</string>
+ <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Iphasiwedi"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Ngena ngemvume"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Igama lomsebezisi elingalungile noma iphasiwedi."</string>
<string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Ukhohlwe igama lomsebenzisi noma i-password?"\n"Vakashela"<b>"google.com/accounts/recovery"</b></string>
@@ -690,6 +699,10 @@
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Vula"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Umsindo uvuliwe"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Umsindo uvaliwe"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Kuqalwe iphethini"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Iphethini isusiwe"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Kwengezwe"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Iphethini isiphelile"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -754,7 +767,7 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"xazulula umbuzo"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Thumela umbuzo"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Ukucinga ngezwi"</string>
- <string name="oneMonthDurationPast" msgid="7396384508953779925">"inyanga eyi-1 edlule"</string>
+ <string name="oneMonthDurationPast" msgid="7396384508953779925">"inyanga engu-1 edlule"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Ngaphambi kwenyanga engu-1 edlule"</string>
<plurals name="num_seconds_ago">
<item quantity="one" msgid="4869870056547896011">"isekhondi elingu-1 eledlule"</item>
@@ -834,7 +847,7 @@
<string name="hours" msgid="894424005266852993">"amahora"</string>
<string name="minute" msgid="9148878657703769868">"Okuncane"</string>
<string name="minutes" msgid="5646001005827034509">"imizuzu"</string>
- <string name="second" msgid="3184235808021478">"umzuzwana"</string>
+ <string name="second" msgid="3184235808021478">"isekhondi"</string>
<string name="seconds" msgid="3161515347216589235">"amasekhondi"</string>
<string name="week" msgid="5617961537173061583">"iviki"</string>
<string name="weeks" msgid="6509623834583944518">"amaviki"</string>
@@ -1144,6 +1157,9 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Ukushintsha kwendlela esetshenziswayo"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Beka kwenye indawo"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Faka"</string>
+ <string name="activitychooserview_choose_application" msgid="4540794444768613567">"Khetha insiza"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Yabelana no"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Yabelana no <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="7311938669217173870">"Isibambo esishelelayo. Thepha bese uyabamba."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Phezulu kwe <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Ngaphansi kwe <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1153,7 +1169,8 @@
<string name="description_target_camera" msgid="969071997552486814">"Ikhamera"</string>
<string name="description_target_silent" msgid="893551287746522182">"Thulile"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Umsindo uvuliwe"</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="4407722573911224960">"Izinkinobho. I-Headset edingeka ukuze kuzwakale izinkinobho ngesikhathi uthayipha i-password."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Faka ama-headset ukuze uzwe izinkinobho zephasiwedi eziphimiswayo."</string>
+ <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Icashazi."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Zulazulela ekhaya"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Zulazulela phezulu"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Izinketho ezingaphezulu"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 6c7a981..d7691f7 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2639,6 +2639,9 @@
<!-- The offset of the baseline within this view. See {see android.view.View#getBaseline}
for details -->
<attr name="baseline" format="dimension" />
+ <!-- @hide The alpha value (0-255) set on the ImageView's drawable. Equivalent
+ to calling ImageView.setAlpha(int), not the same as View.setAlpha(float). -->
+ <attr name="drawableAlpha" format="integer" />
</declare-styleable>
<declare-styleable name="ToggleButton">
<!-- The text for the button when it is checked. -->
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index a9c603f..c37871b 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -85,8 +85,8 @@
<color name="darker_gray">#aaa</color>
<!-- For security permissions -->
- <color name="perms_dangerous_grp_color">#dd6826</color>
- <color name="perms_dangerous_perm_color">#dd6826</color>
+ <color name="perms_dangerous_grp_color">#33b5e5</color>
+ <color name="perms_dangerous_perm_color">#33b5e5</color>
<color name="shadow">#cc222222</color>
<!-- For search-related UIs -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b1dc252..fb4783b 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -953,7 +953,7 @@
social updates from your friends. Malicious apps can use this to pretend to be a friend
and trick you into revealing passwords or other confidential information.</string>
-
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_readCalendar">read calendar events plus confidential information</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1831,6 +1831,17 @@
<string name="lockscreen_permanent_disabled_sim_instructions">Your SIM card is permanently disabled.\n
Please contact your wireless service provider to obtain another SIM card.</string>
+ <!-- Shown on transport control of lockscreen. Pressing button goes to previous track. -->
+ <string name="lockscreen_transport_prev_description">Previous track button</string>
+ <!-- Shown on transport control of lockscreen. Pressing button goes to next track. -->
+ <string name="lockscreen_transport_next_description">Next track button</string>
+ <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+ <string name="lockscreen_transport_pause_description">Pause button</string>
+ <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+ <string name="lockscreen_transport_play_description">Play button</string>
+ <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+ <string name="lockscreen_transport_stop_description">Stop button</string>
+
<!-- Shown in the lock screen when there is emergency calls only mode. -->
<string name="emergency_calls_only" msgid="2485604591272668370">Emergency calls only</string>
@@ -1958,6 +1969,15 @@
<!-- Displayed on lock screen's right tab - turn sound off -->
<string name="lockscreen_sound_off_label">Sound off</string>
+ <!-- Accessibility description sent when user starts drawing a lock pattern. [CHAR LIMIT=NONE] -->
+ <string name="lockscreen_access_pattern_start">Pattern started</string>
+ <!-- Accessibility description sent when the pattern times out and is cleared. [CHAR LIMIT=NONE] -->
+ <string name="lockscreen_access_pattern_cleared">Pattern cleared</string>
+ <!-- Accessibility description sent when user adds a cell to the pattern. [CHAR LIMIT=NONE] -->
+ <string name="lockscreen_access_pattern_cell_added">Cell added</string>
+ <!-- Accessibility description sent when user completes drawing a pattern. [CHAR LIMIT=NONE] -->
+ <string name="lockscreen_access_pattern_detected">Pattern completed</string>
+
<!-- Password keyboard strings. Used by LockScreen and Settings --><skip />
<!-- Label for "switch to symbols" key. Must be short to fit on key! -->
<string name="password_keyboard_label_symbol_key">\?123</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 20af731..e60e8b2 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -230,10 +230,11 @@
<style name="TextAppearance.StatusBar.Icon">
</style>
<style name="TextAppearance.StatusBar.EventContent">
- <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:textColor">?android:attr/textColorSecondary</item>
<item name="android:textSize">13sp</item>
</style>
<style name="TextAppearance.StatusBar.EventContent.Title">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textSize">16sp</item>
<item name="android:textStyle">bold</item>
</style>
diff --git a/core/tests/coretests/src/android/database/CursorWindowTest.java b/core/tests/coretests/src/android/database/CursorWindowTest.java
index 07e75cb..8c8081c 100644
--- a/core/tests/coretests/src/android/database/CursorWindowTest.java
+++ b/core/tests/coretests/src/android/database/CursorWindowTest.java
@@ -16,17 +16,11 @@
package android.database;
-import android.database.AbstractCursor;
import android.test.suitebuilder.annotation.SmallTest;
-import com.android.common.ArrayListCursor;
import android.database.CursorWindow;
import android.test.PerformanceTestCase;
-import com.google.android.collect.Lists;
-
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Random;
import junit.framework.TestCase;
@@ -41,48 +35,6 @@
}
@SmallTest
- public void testWriteCursorToWindow() throws Exception {
- // create cursor
- String[] colNames = new String[]{"name", "number", "profit"};
- int colsize = colNames.length;
- ArrayList<ArrayList> list = createTestList(10, colsize);
- AbstractCursor cursor = new ArrayListCursor(colNames, (ArrayList<ArrayList>) list);
-
- // fill window
- CursorWindow window = new CursorWindow(false);
- cursor.fillWindow(0, window);
-
- // read from cursor window
- for (int i = 0; i < list.size(); i++) {
- ArrayList<Integer> col = list.get(i);
- for (int j = 0; j < colsize; j++) {
- String s = window.getString(i, j);
- int r2 = col.get(j);
- int r1 = Integer.parseInt(s);
- assertEquals(r2, r1);
- }
- }
-
- // test cursor window handle startpos != 0
- window.clear();
- cursor.fillWindow(1, window);
- // read from cursor from window
- for (int i = 1; i < list.size(); i++) {
- ArrayList<Integer> col = list.get(i);
- for (int j = 0; j < colsize; j++) {
- String s = window.getString(i, j);
- int r2 = col.get(j);
- int r1 = Integer.parseInt(s);
- assertEquals(r2, r1);
- }
- }
-
- // Clear the window and make sure it's empty
- window.clear();
- assertEquals(0, window.getNumRows());
- }
-
- @SmallTest
public void testValuesLocalWindow() {
doTestValues(new CursorWindow(true));
}
@@ -124,50 +76,4 @@
assertTrue(window.putBlob(blob, 0, 6));
assertTrue(Arrays.equals(blob, window.getBlob(0, 6)));
}
-
- @SmallTest
- public void testNull() {
- CursorWindow window = getOneByOneWindow();
-
- // Put in a null value and read it back as various types
- assertTrue(window.putNull(0, 0));
- assertNull(window.getString(0, 0));
- assertEquals(0, window.getLong(0, 0));
- assertEquals(0.0, window.getDouble(0, 0));
- assertNull(window.getBlob(0, 0));
- }
-
- @SmallTest
- public void testEmptyString() {
- CursorWindow window = getOneByOneWindow();
-
- // put size 0 string and read it back as various types
- assertTrue(window.putString("", 0, 0));
- assertEquals("", window.getString(0, 0));
- assertEquals(0, window.getLong(0, 0));
- assertEquals(0.0, window.getDouble(0, 0));
- }
-
- private CursorWindow getOneByOneWindow() {
- CursorWindow window = new CursorWindow(false);
- assertTrue(window.setNumColumns(1));
- assertTrue(window.allocRow());
- return window;
- }
-
- private static ArrayList<ArrayList> createTestList(int rows, int cols) {
- ArrayList<ArrayList> list = Lists.newArrayList();
- Random generator = new Random();
-
- for (int i = 0; i < rows; i++) {
- ArrayList<Integer> col = Lists.newArrayList();
- list.add(col);
- for (int j = 0; j < cols; j++) {
- // generate random number
- Integer r = generator.nextInt();
- col.add(r);
- }
- }
- return list;
- }
}
diff --git a/core/tests/coretests/src/android/webkit/AccessibilityInjectorTest.java b/core/tests/coretests/src/android/webkit/AccessibilityInjectorTest.java
index 2ed7c52..417a85f 100644
--- a/core/tests/coretests/src/android/webkit/AccessibilityInjectorTest.java
+++ b/core/tests/coretests/src/android/webkit/AccessibilityInjectorTest.java
@@ -1677,7 +1677,7 @@
}
});
}
- mWebView.loadData(html, "text/html", "utf-8");
+ mWebView.loadData(html, "text/html", null);
}
});
synchronized (sTestLock) {
diff --git a/core/tests/coretests/src/android/widget/SimpleCursorAdapterTest.java b/core/tests/coretests/src/android/widget/SimpleCursorAdapterTest.java
index 7726f02..62466f1 100644
--- a/core/tests/coretests/src/android/widget/SimpleCursorAdapterTest.java
+++ b/core/tests/coretests/src/android/widget/SimpleCursorAdapterTest.java
@@ -16,11 +16,11 @@
package android.widget;
-import com.android.common.ArrayListCursor;
import com.google.android.collect.Lists;
import android.content.Context;
import android.database.Cursor;
+import android.database.MatrixCursor;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
@@ -52,14 +52,14 @@
super.setUp();
// all the pieces needed for the various tests
- mFrom = new String[]{"Column1", "Column2"};
+ mFrom = new String[]{"Column1", "Column2", "_id"};
mTo = new int[]{com.android.internal.R.id.text1, com.android.internal.R.id.text2};
mLayout = com.android.internal.R.layout.simple_list_item_2;
mContext = getContext();
// raw data for building a basic test cursor
mData2x2 = createTestList(2, 2);
- mCursor2x2 = new ArrayListCursor(mFrom, mData2x2);
+ mCursor2x2 = createCursor(mFrom, mData2x2);
}
/**
@@ -77,6 +77,7 @@
Integer r = generator.nextInt();
col.add(r);
}
+ col.add(i);
}
return list;
}
@@ -115,7 +116,7 @@
// now put in a different cursor (5 rows)
ArrayList<ArrayList> data2 = createTestList(5, 2);
- Cursor c2 = new ArrayListCursor(mFrom, data2);
+ Cursor c2 = createCursor(mFrom, data2);
ca.changeCursor(c2);
// Now see if we can pull 5 rows from the adapter
@@ -155,8 +156,8 @@
assertEquals(columns[1], 1);
// Now make a new cursor with similar data but rearrange the columns
- String[] swappedFrom = new String[]{"Column2", "Column1"};
- Cursor c2 = new ArrayListCursor(swappedFrom, mData2x2);
+ String[] swappedFrom = new String[]{"Column2", "Column1", "_id"};
+ Cursor c2 = createCursor(swappedFrom, mData2x2);
ca.changeCursor(c2);
assertEquals(2, ca.getCount());
@@ -235,7 +236,15 @@
assertEquals(1, viewIds.length);
assertEquals(com.android.internal.R.id.text2, viewIds[0]);
}
-
+
+ private static MatrixCursor createCursor(String[] columns, ArrayList<ArrayList> list) {
+ MatrixCursor cursor = new MatrixCursor(columns, list.size());
+ for (ArrayList row : list) {
+ cursor.addRow(row);
+ }
+ return cursor;
+ }
+
/**
* This is simply a way to sneak a look at the protected mFrom() array. A more API-
* friendly way to do this would be to mock out a View and a ViewBinder and exercise
diff --git a/core/tests/coretests/src/android/widget/focus/ListWithMailMessages.java b/core/tests/coretests/src/android/widget/focus/ListWithMailMessages.java
index 5de4ad5..5c891f9 100644
--- a/core/tests/coretests/src/android/widget/focus/ListWithMailMessages.java
+++ b/core/tests/coretests/src/android/widget/focus/ListWithMailMessages.java
@@ -120,7 +120,6 @@
}
final String mimeType = "text/html";
- final String encoding = "utf-8";
@Override
@@ -137,7 +136,7 @@
subject.setText(message.getSubject());
WebView body = (WebView) messageUi.findViewById(R.id.body);
- body.loadData(message.getBody(), mimeType, encoding);
+ body.loadData(message.getBody(), mimeType, null);
// body.setText(message.getBody());
body.setFocusable(message.isFocusable());
diff --git a/data/keyboards/keyboards.mk b/data/keyboards/keyboards.mk
index 564f41c..c964961 100644
--- a/data/keyboards/keyboards.mk
+++ b/data/keyboards/keyboards.mk
@@ -24,6 +24,3 @@
PRODUCT_COPY_FILES += $(foreach file,$(keyconfigs),\
frameworks/base/data/keyboards/$(file):system/usr/idc/$(file))
-
-PRODUCT_PACKAGES := $(keylayouts) $(keycharmaps) $(keyconfigs)
-
diff --git a/data/sounds/AudioPackage7.mk b/data/sounds/AudioPackage7.mk
index 629ceb3..8d92b05 100755
--- a/data/sounds/AudioPackage7.mk
+++ b/data/sounds/AudioPackage7.mk
@@ -27,35 +27,33 @@
$(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
$(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
$(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \
- $(LOCAL_PATH)/notifications/ogg/Altair.ogg:system/media/audio/notifications/Altair.ogg \
$(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
- $(LOCAL_PATH)/notifications/ogg/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:system/media/audio/notifications/Bellatrix.ogg \
$(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \
$(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \
- $(LOCAL_PATH)/notifications/ogg/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \
$(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
$(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \
$(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \
$(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \
$(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
$(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \
- $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \
$(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \
$(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \
$(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Acheron.ogg:system/media/audio/ringtones/Acheron.ogg \
$(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \
$(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \
$(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \
$(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:system/media/audio/ringtones/CanisMajor.ogg \
$(LOCAL_PATH)/ringtones/ogg/Carina.ogg:system/media/audio/ringtones/Carina.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Cassiopeia.ogg:system/media/audio/ringtones/Cassiopeia.ogg \
$(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \
$(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:system/media/audio/ringtones/Cygnus.ogg \
$(LOCAL_PATH)/ringtones/ogg/Draco.ogg:system/media/audio/ringtones/Draco.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg \
$(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \
$(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Nasqueron.ogg:system/media/audio/ringtones/Nasqueron.ogg \
$(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \
$(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \
$(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:system/media/audio/ringtones/Perseus.ogg \
@@ -64,6 +62,6 @@
$(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \
$(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \
$(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Testudo.ogg:system/media/audio/ringtones/Testudo.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:system/media/audio/ringtones/Themos.ogg \
$(LOCAL_PATH)/ringtones/ogg/UrsaMinor.ogg:system/media/audio/ringtones/UrsaMinor.ogg \
- $(LOCAL_PATH)/ringtones/ogg/Vespa.ogg:system/media/audio/ringtones/Vespa.ogg
+ $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg
diff --git a/data/sounds/effects/ogg/Lock.ogg b/data/sounds/effects/ogg/Lock.ogg
index ed845be..e7928e4 100644
--- a/data/sounds/effects/ogg/Lock.ogg
+++ b/data/sounds/effects/ogg/Lock.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/Unlock.ogg b/data/sounds/effects/ogg/Unlock.ogg
index 0a47b5c..cca9594 100644
--- a/data/sounds/effects/ogg/Unlock.ogg
+++ b/data/sounds/effects/ogg/Unlock.ogg
Binary files differ
diff --git a/data/sounds/effects/wav/Lock.wav b/data/sounds/effects/wav/Lock.wav
index 1655a89..b8076369 100644
--- a/data/sounds/effects/wav/Lock.wav
+++ b/data/sounds/effects/wav/Lock.wav
Binary files differ
diff --git a/data/sounds/effects/wav/Unlock.wav b/data/sounds/effects/wav/Unlock.wav
index 2229d03..e1d475e 100644
--- a/data/sounds/effects/wav/Unlock.wav
+++ b/data/sounds/effects/wav/Unlock.wav
Binary files differ
diff --git a/data/sounds/notifications/ogg/Acrux.ogg b/data/sounds/notifications/ogg/Acrux.ogg
new file mode 100644
index 0000000..74ad149
--- /dev/null
+++ b/data/sounds/notifications/ogg/Acrux.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Bellatrix.ogg b/data/sounds/notifications/ogg/Bellatrix.ogg
new file mode 100644
index 0000000..37a1bdc
--- /dev/null
+++ b/data/sounds/notifications/ogg/Bellatrix.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Pollux.ogg b/data/sounds/notifications/ogg/Pollux.ogg
new file mode 100644
index 0000000..2f907fd
--- /dev/null
+++ b/data/sounds/notifications/ogg/Pollux.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Tejat.ogg b/data/sounds/notifications/ogg/Tejat.ogg
new file mode 100644
index 0000000..04ba06c
--- /dev/null
+++ b/data/sounds/notifications/ogg/Tejat.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Girtab.ogg b/data/sounds/ringtones/ogg/Girtab.ogg
new file mode 100644
index 0000000..f6b3a35
--- /dev/null
+++ b/data/sounds/ringtones/ogg/Girtab.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Themos.ogg b/data/sounds/ringtones/ogg/Themos.ogg
new file mode 100644
index 0000000..bc850b8
--- /dev/null
+++ b/data/sounds/ringtones/ogg/Themos.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Zeta.ogg b/data/sounds/ringtones/ogg/Zeta.ogg
new file mode 100644
index 0000000..ef64d2f
--- /dev/null
+++ b/data/sounds/ringtones/ogg/Zeta.ogg
Binary files differ
diff --git a/data/sounds/ringtones/wav/Themos.wav b/data/sounds/ringtones/wav/Themos.wav
new file mode 100644
index 0000000..d4d5c6e
--- /dev/null
+++ b/data/sounds/ringtones/wav/Themos.wav
Binary files differ
diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd
index 7a0e17f..95542bc 100644
--- a/docs/html/guide/appendix/api-levels.jd
+++ b/docs/html/guide/appendix/api-levels.jd
@@ -84,6 +84,12 @@
<table>
<tr><th>Platform Version</th><th>API Level</th><th>VERSION_CODE</th><th>Notes</th></tr>
+ <tr><td><a href="{@docRoot}sdk/android-4.0.html">Android 4.0</a></td>
+ <td><a href="{@docRoot}sdk/api_diff/14/changes.html" title="Diff Report">14</a></td>
+ <td>{@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH}</td>
+ <td><a href="{@docRoot}sdk/android-4.0-highlights.html">Platform
+Highlights</a></td></tr>
+
<tr><td><a href="{@docRoot}sdk/android-3.2.html">Android 3.2</a></td>
<td><a href="{@docRoot}sdk/api_diff/13/changes.html" title="Diff Report">13</a></td>
<td>{@link android.os.Build.VERSION_CODES#HONEYCOMB_MR2}</td>
diff --git a/docs/html/guide/appendix/media-formats.jd b/docs/html/guide/appendix/media-formats.jd
index ccc63a2..137f138 100644
--- a/docs/html/guide/appendix/media-formats.jd
+++ b/docs/html/guide/appendix/media-formats.jd
@@ -14,7 +14,7 @@
<h2>See also</h2>
<ol>
-<li><a href="{@docRoot}guide/topics/media/index.html">Audio and Video</a></li>
+<li><a href="{@docRoot}guide/topics/media/index.html">Multimedia and Camera</a></li>
</ol>
<h2>Key classes</h2>
diff --git a/docs/html/guide/developing/devices/emulator.jd b/docs/html/guide/developing/devices/emulator.jd
index fe00531..8211275 100644
--- a/docs/html/guide/developing/devices/emulator.jd
+++ b/docs/html/guide/developing/devices/emulator.jd
@@ -32,6 +32,12 @@
</ol>
</li>
</ol>
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}guide/developing/tools/emulator.html">Android Emulator</a></li>
+ <li><a href="{@docRoot}guide/developing/devices/managing-avds.html">Managing AVDs with AVD Manager</a></li>
+ </ol>
</div>
</div>
@@ -63,8 +69,6 @@
-
-
<h2 id="overview">Overview</h2>
<p>The Android emulator is a QEMU-based application that provides a virtual ARM
@@ -166,7 +170,8 @@
<p>To stop an emulator instance, just close the emulator's window.</p>
-
+<p>For a reference of the emulator's startup commands and keyboard mapping, see
+the <a href="{@docRoot}guide/developing/tools/emulator.html">Android Emulator</a> document.</p>
diff --git a/docs/html/guide/developing/projects/projects-cmdline.jd b/docs/html/guide/developing/projects/projects-cmdline.jd
index 08e0d9a..81c2c58 100644
--- a/docs/html/guide/developing/projects/projects-cmdline.jd
+++ b/docs/html/guide/developing/projects/projects-cmdline.jd
@@ -114,7 +114,7 @@
<p class="caution"><strong>Caution:</strong> You should refrain from moving the location of the
SDK directory, because this will break the SDK location property located in <code>local.properties</code>.
If you need to update the SDK location, use the <code>android update project</code> command.
- See <a href="UpdatingAProject">Updating a Project</a> for more information.</p>
+ See <a href="#UpdatingAProject">Updating a Project</a> for more information.</p>
<h2 id="UpdatingAProject">Updating a Project</h2>
diff --git a/docs/html/guide/developing/tools/emulator.jd b/docs/html/guide/developing/tools/emulator.jd
index ff667f2..5151ec1 100644
--- a/docs/html/guide/developing/tools/emulator.jd
+++ b/docs/html/guide/developing/tools/emulator.jd
@@ -3,6 +3,25 @@
parent.link=index.html
@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#startup-options">Emulator Startup Options</a></li>
+ <li><a href="#KeyMapping">Emulator Keyboard Mapping</a></li>
+ </ol>
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}guide/developing/devices/emulator.html">Using the Android Emulator</a></li>
+ <li><a href="{@docRoot}guide/developing/devices/index.html">Managing Virtual Devices</a></li>
+ </ol>
+
+</div>
+</div>
+
+
<p>The Android SDK includes a mobile device emulator — a virtual mobile device
that runs on your computer. The emulator lets you develop and test
Android applications without using a physical device.</p>
@@ -451,7 +470,10 @@
<td>See comments for <code>-skin</code>, above.</td></tr>
</table>
-<h2>Emulator Keyboard Mapping</h2>
+
+
+<h2 id="KeyMapping">Emulator Keyboard Mapping</h2>
+
<p>The table below summarizes the mappings between the emulator keys and and
the keys of your keyboard. </p>
<p class="table-caption"><strong>Table 2.</strong> Emulator keyboard mapping</p>
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 18d9a48..b7710c3 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -233,44 +233,70 @@
</ul>
<ul>
- <li class="toggle-list">
+ <li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/graphics/index.html">
<span class="en">Graphics</span>
- </a></div>
+ </a><span class="new-child">new!</span></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/graphics/2d-graphics.html">
- <span class="en">2D Graphics</span>
- </a></li>
+ <span class="en">Canvas and Drawables</span></a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/graphics/hardware-accel.html">
+ <span class="en">Hardware Acceleration</span></a>
+ <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>guide/topics/graphics/opengl.html">
- <span class="en">3D with OpenGL</span>
- </a></li>
- <li><a href="<?cs var:toroot ?>guide/topics/graphics/animation.html">
- <span class="en">Property Animation</span>
- </a></li>
- <li><a href="<?cs var:toroot ?>guide/topics/graphics/view-animation.html">
- <span class="en">View Animation</span>
- </a></li>
+ <span class="en">OpenGL</span>
+ </a><span class="new">updated</span></li>
</ul>
</li>
<li class="toggle-list">
- <div><a href="<?cs var:toroot ?>guide/topics/renderscript/index.html">
- <span class="en">RenderScript</span>
- </a></div>
- <ul>
- <li><a href="<?cs var:toroot ?>guide/topics/renderscript/graphics.html">
- <span class="en">3D Graphics</span>
- </a>
- </li>
- <li><a href="<?cs var:toroot ?>guide/topics/renderscript/compute.html">
- <span class="en">Compute</span>
- </a>
- </li>
- </ul>
- </li>
+ <div><a href="<?cs var:toroot ?>guide/topics/graphics/animation.html">
+ <span class="en">Animation</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>guide/topics/graphics/prop-animation.html">
+ <span class="en">Property Animation</span></a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/graphics/view-animation.html">
+ <span class="en">View Animation</span></a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/graphics/drawable-animation.html">
+ <span class="en">Drawable Animation</span></a></li>
+ </ul>
+ </li>
+ <li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>guide/topics/renderscript/index.html">
+ <span class="en">RenderScript</span></a>
+ </div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>guide/topics/renderscript/graphics.html">
+ <span class="en">Graphics</span>
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>guide/topics/renderscript/compute.html">
+ <span class="en">Compute</span>
+ </a>
+ </li>
+ </ul>
+ </li>
- <li><a href="<?cs var:toroot ?>guide/topics/media/index.html">
- <span class="en">Media</span>
- </a></li>
+ <li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>guide/topics/media/index.html">
+ <span class="en">Multimedia and Camera</span>
+ </a><span class="new">updated</span></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>guide/topics/media/mediaplayer.html">
+ <span class="en">Media Playback</span></a>
+ </li>
+ <li><a href="<?cs var:toroot ?>guide/topics/media/jetplayer.html">
+ <span class="en">JetPlayer</span></a>
+ </li>
+ <li><a href="<?cs var:toroot ?>guide/topics/media/camera.html">
+ <span class="en">Camera</span></a>
+ <span class="new">new!</span>
+ </li>
+ <li><a href="<?cs var:toroot ?>guide/topics/media/audio-capture.html">
+ <span class="en">Audio Capture</span></a>
+ </li>
+ </ul>
+ </li>
<li>
<a href="<?cs var:toroot ?>guide/topics/clipboard/copy-paste.html">
<span class="en">Copy and Paste</span>
@@ -306,9 +332,15 @@
<li><a href="<?cs var:toroot?>guide/topics/wireless/bluetooth.html">
<span class="en">Bluetooth</span></a>
</li>
- <li><a href="<?cs var:toroot?>guide/topics/nfc/index.html">
- <span class="en">Near Field Communication</span>
- </a></li>
+ <li class="toggle-list">
+ <div><a href="<?cs var:toroot?>guide/topics/nfc/index.html">
+ <span class="en">Near Field Communication</span></a> <span class="new">updated</span>
+ </div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>guide/topics/nfc/nfc.html">NFC Basics</a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/nfc/advanced-nfc.html">Advanced NFC</a></li>
+ </ul>
+ </li>
<li class="toggle-list">
<div><a href="<?cs var:toroot?>guide/topics/usb/index.html">
<span class="en">USB</span></a>
@@ -689,7 +721,7 @@
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/index.html">
<span class="en">UI Guidelines</span>
- </a></div>
+ </a> <span class="new-child">updated</span></div>
<ul>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design.html">
diff --git a/docs/html/guide/practices/optimizing-for-3.0.jd b/docs/html/guide/practices/optimizing-for-3.0.jd
index e968372..a24dba8f 100644
--- a/docs/html/guide/practices/optimizing-for-3.0.jd
+++ b/docs/html/guide/practices/optimizing-for-3.0.jd
@@ -411,8 +411,8 @@
>Action Bar</a>: Samples that demonstrate various Action Bar features, such as tabs, logos, and
action items.</li>
<li><a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/content/ClipboardSample.
-html">Clipboard</a>: An example of how to use the clipboard for copy and paste operations.</li>
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/content/ClipboardSample.html"
+>Clipboard</a>: An example of how to use the clipboard for copy and paste operations.</li>
<li><a
href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/DragAndDropDemo.html">
Drag and Drop</a>: An example of how to perform drag and drop with new View events.</li>
@@ -427,11 +427,11 @@
Property Animation</a>: Several samples using the new animation APIs to animate object
properties.</li>
<li><a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.
-html">Search View Widget</a>: Example using the new search widget in the Action Bar (as an
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.html">
+Search View Widget</a>: Example using the new search widget in the Action Bar (as an
"action view").</li>
<li><a
-href="{@docRoot}resources/samples/Renderscript/index.html">Renderscript</a>: Contains several
+href="{@docRoot}resources/samples/RenderScript/index.html">Renderscript</a>: Contains several
different applications that demonstrate using renderscript APIs for computations and 3D
graphics.</li>
</ul>
diff --git a/docs/html/guide/practices/screen-compat-mode.jd b/docs/html/guide/practices/screen-compat-mode.jd
index a792386..7f10914 100644
--- a/docs/html/guide/practices/screen-compat-mode.jd
+++ b/docs/html/guide/practices/screen-compat-mode.jd
@@ -48,7 +48,7 @@
to resize for larger screens such as tablets. Since Android 1.6, Android has supported a
variety of screen sizes and does most of the work to resize application layouts so that they
properly fit each screen. However, if your application does not successfully follow the guide to
-<a href="{@docRoot}guide/topics/practices/screens_support.html">Supporting Multiple Screens</a>,
+<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>,
then it might encounter some rendering issues on larger screens. For applications with this
problem, screen compatibility mode can make the application a little more usable on larger
screens.</p>
@@ -71,7 +71,7 @@
android:minSdkVersion}</a> or <a
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
android:targetSdkVersion}</a> to {@code "4"} or higher, or set <a
-href="guide/topics/manifest/supports-screens-element.html#resizeable">{@code
+href="{@docRoot}guide/topics/manifest/supports-screens-element.html#resizeable">{@code
android:resizeable}</a> to {@code "true"}.</p>
</dd>
@@ -83,7 +83,7 @@
<p>This was introduced with Android 3.2 to further
assist applications on the latest tablet devices when the applications have not yet
implemented techniques for <a
-href="{@docRoot}guide/topics/practices/screens_support.html">Supporting Multiple
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
Screens</a>.</p>
<p>In general, large screen devices running Android 3.2 or higher allow users to enable
screen compatibility mode when the application does not <strong>explicitly declare that it supports
@@ -211,7 +211,7 @@
which you should want your application to run—it causes pixelation and blurring in your UI,
due to zooming. The proper way to make your application work well on large screens is to follow the
guide to <a
-href="{@docRoot}guide/topics/practices/screens_support.html">Supporting Multiple Screens</a> and
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a> and
provide alternative layouts for different screen sizes.</p>
<p>By default, when you've set either <a
diff --git a/docs/html/guide/practices/screens_support.jd b/docs/html/guide/practices/screens_support.jd
index 6dec4b3..0c3c7d3 100644
--- a/docs/html/guide/practices/screens_support.jd
+++ b/docs/html/guide/practices/screens_support.jd
@@ -1111,7 +1111,7 @@
<img src="{@docRoot}images/screens_support/scale-test.png" alt="" />
<p class="img-caption"><strong>Figure 5.</strong> Comparison of pre-scaled and auto-scaled
bitmaps, from <a
-href="resources/samples/ApiDemos/src/com/example/android/apis/graphics/DensityActivity.html">
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/DensityActivity.html">
ApiDemos</a>.
</p>
</div>
@@ -1150,7 +1150,7 @@
scaled bitmaps have slightly different appearances depending on whether they are pre-scaled or
auto-scaled at draw time. You can find the source code for this sample application, which
demonstrates using pre-scaled and auto-scaled bitmaps, in <a
-href="resources/samples/ApiDemos/src/com/example/android/apis/graphics/DensityActivity.html">
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/DensityActivity.html">
ApiDemos</a>.</p>
<p class="note"><strong>Note:</strong> In Android 3.0 and above, there should be no perceivable
diff --git a/docs/html/guide/topics/admin/device-admin.jd b/docs/html/guide/topics/admin/device-admin.jd
index 7dddd9a..7bbf5e6 100644
--- a/docs/html/guide/topics/admin/device-admin.jd
+++ b/docs/html/guide/topics/admin/device-admin.jd
@@ -619,8 +619,8 @@
mDPM.setPasswordExpirationTimeout(mDeviceAdminSample, pwExpiration);
</pre>
-<p>From the <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/
-DeviceAdminSample.html"> Device Administration API sample</a>, here is the code
+<p>From the <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.html"
+>Device Administration API sample</a>, here is the code
that updates the password expiration status:</p>
<pre>
diff --git a/docs/html/guide/topics/fundamentals/fragments.jd b/docs/html/guide/topics/fundamentals/fragments.jd
index 8f61945..d34a798 100644
--- a/docs/html/guide/topics/fundamentals/fragments.jd
+++ b/docs/html/guide/topics/fundamentals/fragments.jd
@@ -117,7 +117,7 @@
two
fragments in <em>Activity A</em>, when running on an extra large screen (a tablet, for example).
However, on a normal-sized screen (a phone, for example),
-there's not be enough room for both fragments, so <em>Activity A</em> includes only the fragment for
+there would not be enough room for both fragments, so <em>Activity A</em> includes only the fragment for
the list of articles, and when the user selects an article, it starts <em>Activity B</em>, which
includes the fragment to read the article. Thus, the application supports both design patterns
suggested in figure 1.</p>
diff --git a/docs/html/guide/topics/fundamentals/loaders.jd b/docs/html/guide/topics/fundamentals/loaders.jd
index d31f090..3aad204 100644
--- a/docs/html/guide/topics/fundamentals/loaders.jd
+++ b/docs/html/guide/topics/fundamentals/loaders.jd
@@ -32,7 +32,8 @@
<h2>Related samples</h2>
<ol>
<li> <a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentListCursorLoader.html">FragmentListCursorLoader</a></li>
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.html">
+LoaderCursor</a></li>
<li> <a
href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html">
LoaderThrottle</a></li>
@@ -485,7 +486,9 @@
<p>There are a few different samples in <strong>ApiDemos</strong> that
illustrate how to use loaders:</p>
<ul>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentListCursorLoader.html">FragmentListCursorLoader</a> — A complete version of the
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.html">
+LoaderCursor</a> — A complete version of the
snippet shown above.</li>
<li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a> — An example of how to use throttling to
reduce the number of queries a content provider does then its data changes.</li>
diff --git a/docs/html/guide/topics/graphics/2d-graphics.jd b/docs/html/guide/topics/graphics/2d-graphics.jd
index 618cdf8..5abffb3 100644
--- a/docs/html/guide/topics/graphics/2d-graphics.jd
+++ b/docs/html/guide/topics/graphics/2d-graphics.jd
@@ -1,296 +1,484 @@
-page.title=2D Graphics
+page.title=Canvas and Drawables
parent.title=Graphics
parent.link=index.html
@jd:body
-
<div id="qv-wrapper">
<div id="qv">
- <h2>In this document</h2>
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#draw-with-canvas">Draw with a Canvas</a>
<ol>
- <li><a href="#drawables">Drawables</a>
+ <li><a href="#on-view">On a View</a></li>
+ <li><a href="#on-surfaceview">On a SurfaceView</a></li>
+ </ol>
+ </li>
+ <li><a href="#drawables">Drawables</a>
<ol>
<li><a href="#drawables-from-images">Creating from resource images</a></li>
<li><a href="#drawables-from-xml">Creating from resource XML</a></li>
</ol>
- </li>
- <li><a href="#shape-drawable">Shape Drawable</a></li>
- <!-- <li><a href="#state-list">StateListDrawable</a></li> -->
- <li><a href="#nine-patch">Nine-patch</a></li>
- </ol>
+ </li>
+ <li><a href="#shape-drawable">Shape Drawable</a></li>
+ <li><a href="#nine-patch">Nine-patch</a></li>
+ </ol>
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL with the Framework
+APIs</a></li>
+ <li><a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a></li>
+ </ol>
</div>
</div>
-<p>Android offers a custom 2D graphics library for drawing and animating shapes and images.
-The {@link android.graphics.drawable} and {@link android.view.animation}
-packages are where you'll find the common classes used for drawing and animating in two-dimensions.
+<p>The Android framework APIs provides a set 2D drawing APIs that allow you to render your own
+custom graphics onto a canvas or to modify existing Views to customize their look and feel.
+When drawing 2D graphics, you'll typically do so in one of two ways:</p>
+
+<ol type="a">
+ <li>Draw your graphics or animations into a View object from your layout. In this manner,
+ the drawing of your graphics is handled by the system's
+ normal View hierarchy drawing process — you simply define the graphics to go inside the View.</li>
+ <li>Draw your graphics directly to a Canvas. This way, you personally call the appropriate class's
+ {@link android.view.View#onDraw onDraw()} method (passing it your Canvas), or one of the Canvas
+<code>draw...()</code> methods (like
+ <code>{@link android.graphics.Canvas#drawPicture(Picture,Rect) drawPicture()}</code>). In doing so, you are also in
+ control of any animation.</li>
+</ol>
+
+<p>Option "a," drawing to a View, is your best choice when you want to draw simple graphics that do not
+need to change dynamically and are not part of a performance-intensive game. For example, you should
+draw your graphics into a View when you want to display a static graphic or predefined animation, within
+an otherwise static application. Read <a href="#drawables">Drawables</a> for more information.</li>
</p>
-<p>This document offers an introduction to drawing graphics in your Android application.
-We'll discuss the basics of using Drawable objects to draw
-graphics, how to use a couple subclasses of the Drawable class, and how to
-create animations that either tween (move, stretch, rotate) a single graphic
-or animate a series of graphics (like a roll of film).</p>
+<p>Option "b," drawing to a Canvas, is better when your application needs to regularly re-draw itself.
+Applications such as video games should be drawing to the Canvas on its own. However, there's more than
+one way to do this:</p>
+<ul>
+ <li>In the same thread as your UI Activity, wherein you create a custom View component in
+ your layout, call <code>{@link android.view.View#invalidate()}</code> and then handle the
+ <code>{@link android.view.View#onDraw(Canvas) onDraw()}</code> callback.</li>
+ <li>Or, in a separate thread, wherein you manage a {@link android.view.SurfaceView} and
+ perform draws to the Canvas as fast as your thread is capable
+ (you do not need to request <code>invalidate()</code>).</li>
+</ul>
+
+<h2 id="draw-with-canvas">Draw with a Canvas</h2>
+
+<p>When you're writing an application in which you would like to perform specialized drawing
+and/or control the animation of graphics,
+you should do so by drawing through a {@link android.graphics.Canvas}. A Canvas works for you as
+a pretense, or interface, to the actual surface upon which your graphics will be drawn — it
+holds all of your "draw" calls. Via the Canvas, your drawing is actually performed upon an
+underlying {@link android.graphics.Bitmap}, which is placed into the window.</p>
+
+<p>In the event that you're drawing within the <code>{@link android.view.View#onDraw(Canvas) onDraw()}</code>
+callback method, the Canvas is provided for you and you need only place your drawing calls upon it.
+You can also acquire a Canvas from <code>{@link android.view.SurfaceHolder#lockCanvas() SurfaceHolder.lockCanvas()}</code>,
+when dealing with a SurfaceView object. (Both of these scenarios are discussed in the following sections.)
+However, if you need to create a new Canvas, then you must define the {@link android.graphics.Bitmap}
+upon which drawing will actually be performed. The Bitmap is always required for a Canvas. You can set up
+a new Canvas like this:</p>
+<pre>
+Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
+Canvas c = new Canvas(b);
+</pre>
+
+<p>Now your Canvas will draw onto the defined Bitmap. After drawing upon it with the Canvas, you can then carry your
+Bitmap to another Canvas with one of the <code>{@link android.graphics.Canvas#drawBitmap(Bitmap,Matrix,Paint)
+Canvas.drawBitmap(Bitmap,...)}</code> methods. It's recommended that you ultimately draw your final
+graphics through a Canvas offered to you
+by <code>{@link android.view.View#onDraw(Canvas) View.onDraw()}</code> or
+<code>{@link android.view.SurfaceHolder#lockCanvas() SurfaceHolder.lockCanvas()}</code> (see the following sections).</p>
+
+<p>The {@link android.graphics.Canvas} class has its own set of drawing methods that you can use,
+like <code>drawBitmap(...)</code>, <code>drawRect(...)</code>, <code>drawText(...)</code>, and many more.
+Other classes that you might use also have <code>draw()</code> methods. For example, you'll probably
+have some {@link android.graphics.drawable.Drawable} objects that you want to put on the Canvas. Drawable
+has its own <code>{@link android.graphics.drawable.Drawable#draw(Canvas) draw()}</code> method
+that takes your Canvas as an argument.</p>
+
+
+<h3 id="on-view">On a View</h3>
+
+<p>If your application does not require a significant amount of processing or
+frame-rate speed (perhaps for a chess game, a snake game,
+or another slowly-animated application), then you should consider creating a custom View component
+and drawing with a Canvas in <code>{@link android.view.View#onDraw(Canvas) View.onDraw()}</code>.
+The most convenient aspect of doing so is that the Android framework will
+provide you with a pre-defined Canvas to which you will place your drawing calls.</p>
+
+<p>To start, extend the {@link android.view.View} class (or descendant thereof) and define
+the <code>{@link android.view.View#onDraw(Canvas) onDraw()}</code> callback method. This method will be called by the Android
+framework to request that your View draw itself. This is where you will perform all your calls
+to draw through the {@link android.graphics.Canvas}, which is passed to you through the <code>onDraw()</code> callback.</p>
+
+<p>The Android framework will only call <code>onDraw()</code> as necessary. Each time that
+your application is prepared to be drawn, you must request your View be invalidated by calling
+<code>{@link android.view.View#invalidate()}</code>. This indicates that you'd like your View to be drawn and
+Android will then call your <code>onDraw()</code> method (though is not guaranteed that the callback will
+be instantaneous). </p>
+
+<p>Inside your View component's <code>onDraw()</code>, use the Canvas given to you for all your drawing,
+using various <code>Canvas.draw...()</code> methods, or other class <code>draw()</code> methods that
+take your Canvas as an argument. Once your <code>onDraw()</code> is complete, the Android framework will
+use your Canvas to draw a Bitmap handled by the system.</p>
+
+<p class="note"><strong>Note: </strong> In order to request an invalidate from a thread other than your main
+Activity's thread, you must call <code>{@link android.view.View#postInvalidate()}</code>.</p>
+
+<p>Also read <a href="{@docRoot}guide/topics/ui/custom-components.html">Building Custom Components</a>
+for a guide to extending a View class, and <a href="2d-graphics.html">2D Graphics: Drawables</a> for
+information on using Drawable objects like images from your resources and other primitive shapes.</p>
+
+<p>For a sample application, see the Snake game, in the SDK samples folder:
+<code><your-sdk-directory>/samples/Snake/</code>.</p>
+
+<h3 id="on-surfaceview">On a SurfaceView</h3>
+
+<p>The {@link android.view.SurfaceView} is a special subclass of View that offers a dedicated
+drawing surface within the View hierarchy. The aim is to offer this drawing surface to
+an application's secondary thread, so that the application isn't required
+to wait until the system's View hierarchy is ready to draw. Instead, a secondary thread
+that has reference to a SurfaceView can draw to its own Canvas at its own pace.</p>
+
+<p>To begin, you need to create a new class that extends {@link android.view.SurfaceView}. The class should also
+implement {@link android.view.SurfaceHolder.Callback}. This subclass is an interface that will notify you
+with information about the underlying {@link android.view.Surface}, such as when it is created, changed, or destroyed.
+These events are important so that you know when you can start drawing, whether you need
+to make adjustments based on new surface properties, and when to stop drawing and potentially
+kill some tasks. Inside your SurfaceView class is also a good place to define your secondary Thread class, which will
+perform all the drawing procedures to your Canvas.</p>
+
+<p>Instead of handling the Surface object directly, you should handle it via
+a {@link android.view.SurfaceHolder}. So, when your SurfaceView is initialized, get the SurfaceHolder by calling
+<code>{@link android.view.SurfaceView#getHolder()}</code>. You should then notify the SurfaceHolder that you'd
+like to receive SurfaceHolder callbacks (from {@link android.view.SurfaceHolder.Callback}) by calling
+{@link android.view.SurfaceHolder#addCallback(SurfaceHolder.Callback) addCallback()}
+(pass it <var>this</var>). Then override each of the
+{@link android.view.SurfaceHolder.Callback} methods inside your SurfaceView class.</p>
+
+<p>In order to draw to the Surface Canvas from within your second thread, you must pass the thread your SurfaceHandler
+and retrieve the Canvas with <code>{@link android.view.SurfaceHolder#lockCanvas() lockCanvas()}</code>.
+You can now take the Canvas given to you by the SurfaceHolder and do your necessary drawing upon it.
+Once you're done drawing with the Canvas, call
+<code>{@link android.view.SurfaceHolder#unlockCanvasAndPost(Canvas) unlockCanvasAndPost()}</code>, passing it
+your Canvas object. The Surface will now draw the Canvas as you left it. Perform this sequence of locking and
+unlocking the canvas each time you want to redraw.</p>
+
+<p class="note"><strong>Note:</strong> On each pass you retrieve the Canvas from the SurfaceHolder,
+the previous state of the Canvas will be retained. In order to properly animate your graphics, you must re-paint the
+entire surface. For example, you can clear the previous state of the Canvas by filling in a color
+with <code>{@link android.graphics.Canvas#drawColor(int) drawColor()}</code> or setting a background image
+with <code>{@link android.graphics.Canvas#drawBitmap(Bitmap,Rect,RectF,Paint) drawBitmap()}</code>. Otherwise,
+you will see traces of the drawings you previously performed.</p>
+
+
+<p>For a sample application, see the Lunar Lander game, in the SDK samples folder:
+<code><your-sdk-directory>/samples/LunarLander/</code>. Or,
+browse the source in the <a href="{@docRoot}guide/samples/index.html">Sample Code</a> section.</p>
<h2 id="drawables">Drawables</h2>
+<p>Android offers a custom 2D graphics library for drawing shapes and images.
+ The {@link android.graphics.drawable} package is where you'll find the common classes used for
+ drawing in two-dimensions.</p>
-<p>A {@link android.graphics.drawable.Drawable} is a general abstraction for "something that can be drawn."
-You'll discover that the Drawable class extends to define a variety of specific kinds of drawable graphics,
-including {@link android.graphics.drawable.BitmapDrawable}, {@link android.graphics.drawable.ShapeDrawable},
-{@link android.graphics.drawable.PictureDrawable}, {@link android.graphics.drawable.LayerDrawable}, and several more.
-Of course, you can also extend these to define your own custom Drawable objects that behave in unique ways.</p>
+<p>This document discusses the basics of using Drawable objects to draw graphics and how to use a
+couple subclasses of the Drawable class. For information on using Drawables to do frame-by-frame
+animation, see <a href="{@docRoot}guide/topics/animation/drawable-animation.html">Drawable
+Animation</a>.</p>
-<p>There are three ways to define and instantiate a Drawable: using an image saved in your project resources;
-using an XML file that defines the Drawable properties; or using the normal class constructors. Below, we'll discuss
-each the first two techniques (using constructors is nothing new for an experienced developer).</p>
+<p>A {@link android.graphics.drawable.Drawable} is a general abstraction for "something that can be
+ drawn." You'll discover that the Drawable class extends to define a variety of specific kinds of
+drawable graphics, including {@link android.graphics.drawable.BitmapDrawable}, {@link
+ android.graphics.drawable.ShapeDrawable}, {@link android.graphics.drawable.PictureDrawable},
+{@link android.graphics.drawable.LayerDrawable}, and several more. Of course, you can also extend
+these to define your own custom Drawable objects that behave in unique ways.</p>
+
+<p>There are three ways to define and instantiate a Drawable: using an image saved in your project
+ resources; using an XML file that defines the Drawable properties; or using the normal class
+constructors. Below, we'll discuss each the first two techniques (using constructors is nothing new
+for an experienced developer).</p>
<h3 id="drawables-from-images">Creating from resource images</h3>
-<p>A simple way to add graphics to your application is by referencing an image file from your project resources.
-Supported file types are PNG (preferred), JPG (acceptable) and GIF (discouraged). This technique would
-obviously be preferred for application icons, logos, or other graphics such as those used in a game.</p>
+<p>A simple way to add graphics to your application is by referencing an image file from your
+ project resources. Supported file types are PNG (preferred), JPG (acceptable) and GIF
+(discouraged). This technique would obviously be preferred for application icons, logos, or other
+graphics such as those used in a game.</p>
-<p>To use an image resource, just add your file to the <code>res/drawable/</code> directory of your project.
-From there, you can reference it from your code or your XML layout.
-Either way, it is referred using a resource ID, which is the file name without the file type
-extension (E.g., <code>my_image.png</code> is referenced as <var>my_image</var>).</p>
+<p>To use an image resource, just add your file to the <code>res/drawable/</code> directory of your
+ project. From there, you can reference it from your code or your XML layout.
+ Either way, it is referred using a resource ID, which is the file name without the file type
+ extension (E.g., <code>my_image.png</code> is referenced as <var>my_image</var>).</p>
-<p class="note"><strong>Note:</strong> Image resources placed in <code>res/drawable/</code> may be
-automatically optimized with lossless image compression by the
-<code>aapt</code> tool during the build process. For example, a true-color PNG that does
-not require more than 256 colors may be converted to an 8-bit PNG with a color palette. This
-will result in an image of equal quality but which requires less memory. So be aware that the
-image binaries placed in this directory can change during the build. If you plan on reading
-an image as a bit stream in order to convert it to a bitmap, put your images in the <code>res/raw/</code>
-folder instead, where they will not be optimized.</p>
+<p class="note"><strong>Note:</strong> Image resources placed in <code>res/drawable/</code> may be
+ automatically optimized with lossless image compression by the
+ <code>aapt</code> tool during the build process. For example, a true-color PNG that does
+ not require more than 256 colors may be converted to an 8-bit PNG with a color palette. This
+ will result in an image of equal quality but which requires less memory. So be aware that the
+ image binaries placed in this directory can change during the build. If you plan on reading
+ an image as a bit stream in order to convert it to a bitmap, put your images in the
+ <code>res/raw/</code> folder instead, where they will not be optimized.</p>
<h4>Example code</h4>
-<p>The following code snippet demonstrates how to build an {@link android.widget.ImageView} that uses an image
-from drawable resources and add it to the layout.</p>
+<p>The following code snippet demonstrates how to build an {@link android.widget.ImageView} that
+ uses an image from drawable resources and add it to the layout.</p>
<pre>
-LinearLayout mLinearLayout;
+ LinearLayout mLinearLayout;
-protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
- // Create a LinearLayout in which to add the ImageView
- mLinearLayout = new LinearLayout(this);
+ // Create a LinearLayout in which to add the ImageView
+ mLinearLayout = new LinearLayout(this);
- // Instantiate an ImageView and define its properties
- ImageView i = new ImageView(this);
- i.setImageResource(R.drawable.my_image);
- i.setAdjustViewBounds(true); // set the ImageView bounds to match the Drawable's dimensions
- i.setLayoutParams(new Gallery.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
+ // Instantiate an ImageView and define its properties
+ ImageView i = new ImageView(this);
+ i.setImageResource(R.drawable.my_image);
+ i.setAdjustViewBounds(true); // set the ImageView bounds to match the Drawable's dimensions
+ i.setLayoutParams(new Gallery.LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT));
- // Add the ImageView to the layout and set the layout as the content view
- mLinearLayout.addView(i);
- setContentView(mLinearLayout);
-}
+ // Add the ImageView to the layout and set the layout as the content view
+ mLinearLayout.addView(i);
+ setContentView(mLinearLayout);
+ }
</pre>
-<p>In other cases, you may want to handle your image resource as a
-{@link android.graphics.drawable.Drawable} object.
-To do so, create a Drawable from the resource like so:
-<pre>
-Resources res = mContext.getResources();
-Drawable myImage = res.getDrawable(R.drawable.my_image);
-</pre>
+<p>In other cases, you may want to handle your image resource as a
+ {@link android.graphics.drawable.Drawable} object.
+ To do so, create a Drawable from the resource like so:
+ <pre>
+ Resources res = mContext.getResources();
+ Drawable myImage = res.getDrawable(R.drawable.my_image);
+ </pre>
-<p class="warning"><strong>Note:</strong> Each unique resource in your project can maintain only one
-state, no matter how many different objects you may instantiate for it. For example, if you instantiate two
-Drawable objects from the same image resource, then change a property (such as the alpha) for one of the
-Drawables, then it will also affect the other. So when dealing with multiple instances of an image resource,
-instead of directly transforming the Drawable, you should perform a <a href="#tween-animation">tween animation</a>.</p>
+ <p class="warning"><strong>Note:</strong> Each unique resource in your project can maintain only
+one state, no matter how many different objects you may instantiate for it. For example, if you
+ instantiate two Drawable objects from the same image resource, then change a property (such
+as the alpha) for one of the Drawables, then it will also affect the other. So when dealing with
+multiple instances of an image resource, instead of directly transforming the Drawable, you
+should perform a <a href="{@docRoot}guide/topics/graphics/view-animation.html#tween-animation">tween
+animation</a>.</p>
-<h4>Example XML</h4>
-<p>The XML snippet below shows how to add a resource Drawable to an
-{@link android.widget.ImageView} in the XML layout (with some red tint just for fun).
-<pre>
-<ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:tint="#55ff0000"
- android:src="@drawable/my_image"/>
-</pre>
-<p>For more information on using project resources, read about
- <a href="{@docRoot}guide/topics/resources/index.html">Resources and Assets</a>.</p>
+ <h4>Example XML</h4>
+ <p>The XML snippet below shows how to add a resource Drawable to an
+ {@link android.widget.ImageView} in the XML layout (with some red tint just for fun).
+ <pre>
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:tint="#55ff0000"
+ android:src="@drawable/my_image"/>
+ </pre>
+ <p>For more information on using project resources, read about
+ <a href="{@docRoot}guide/topics/resources/index.html">Resources and Assets</a>.</p>
-<h3 id="drawables-from-xml">Creating from resource XML</h3>
+ <h3 id="drawables-from-xml">Creating from resource XML</h3>
-<p>By now, you should be familiar with Android's principles of developing a
-<a href="{@docRoot}guide/topics/ui/index.html">User Interface</a>. Hence, you understand the power
-and flexibility inherent in defining objects in XML. This philosophy caries over from Views to Drawables.
-If there is a Drawable object that you'd like to create, which is not initially dependent on variables defined by
-your application code or user interaction, then defining the Drawable in XML is a good option.
-Even if you expect your Drawable to change its properties during the user's experience with your application,
-you should consider defining the object in XML, as you can always modify properties once it is instantiated.</p>
+ <p>By now, you should be familiar with Android's principles of developing a
+ <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a>. Hence, you understand the
+power and flexibility inherent in defining objects in XML. This philosophy caries over from Views
+to Drawables. If there is a Drawable object that you'd like to create, which is not initially
+dependent on variables defined by your application code or user interaction, then defining the
+Drawable in XML is a good option. Even if you expect your Drawable to change its properties
+during the user's experience with your application, you should consider defining the object in
+XML, as you can always modify properties once it is instantiated.</p>
-<p>Once you've defined your Drawable in XML, save the file in the <code>res/drawable/</code> directory of
-your project. Then, retrieve and instantiate the object by calling
-{@link android.content.res.Resources#getDrawable(int) Resources.getDrawable()}, passing it the resource ID
-of your XML file. (See the <a href="#drawable-xml-example">example below</a>.)</p>
+ <p>Once you've defined your Drawable in XML, save the file in the <code>res/drawable/</code>
+ directory of your project. Then, retrieve and instantiate the object by calling
+ {@link android.content.res.Resources#getDrawable(int) Resources.getDrawable()}, passing it the
+ resource ID of your XML file. (See the <a href="#drawable-xml-example">example
+below</a>.)</p>
-<p>Any Drawable subclass that supports the <code>inflate()</code> method can be defined in
-XML and instantiated by your application.
-Each Drawable that supports XML inflation utilizes specific XML attributes that help define the object
-properties (see the class reference to see what these are). See the class documentation for each
-Drawable subclass for information on how to define it in XML.
+ <p>Any Drawable subclass that supports the <code>inflate()</code> method can be defined in
+ XML and instantiated by your application. Each Drawable that supports XML inflation utilizes
+specific XML attributes that help define the object
+ properties (see the class reference to see what these are). See the class documentation for each
+ Drawable subclass for information on how to define it in XML.
-<h4 id="drawable-xml-example">Example</h4>
-<p>Here's some XML that defines a TransitionDrawable:</p>
-<pre>
-<transition xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/image_expand">
- <item android:drawable="@drawable/image_collapse">
-</transition>
-</pre>
+ <h4 id="drawable-xml-example">Example</h4>
+ <p>Here's some XML that defines a TransitionDrawable:</p>
+ <pre>
+ <transition xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/image_expand">
+ <item android:drawable="@drawable/image_collapse">
+ </transition>
+ </pre>
-<p>With this XML saved in the file <code>res/drawable/expand_collapse.xml</code>,
-the following code will instantiate the TransitionDrawable and set it as the content of an ImageView:</p>
-<pre>
-Resources res = mContext.getResources();
-TransitionDrawable transition = (TransitionDrawable) res.getDrawable(R.drawable.expand_collapse);
-ImageView image = (ImageView) findViewById(R.id.toggle_image);
-image.setImageDrawable(transition);
-</pre>
-<p>Then this transition can be run forward (for 1 second) with:</p>
-<pre>transition.startTransition(1000);</pre>
+ <p>With this XML saved in the file <code>res/drawable/expand_collapse.xml</code>,
+ the following code will instantiate the TransitionDrawable and set it as the content of an
+ ImageView:</p>
+ <pre>
+ Resources res = mContext.getResources();
+ TransitionDrawable transition = (TransitionDrawable)
+res.getDrawable(R.drawable.expand_collapse);
+ ImageView image = (ImageView) findViewById(R.id.toggle_image);
+ image.setImageDrawable(transition);
+ </pre>
+ <p>Then this transition can be run forward (for 1 second) with:</p>
+ <pre>transition.startTransition(1000);</pre>
-<p>Refer to the Drawable classes listed above for more information on the XML attributes supported by each.</p>
+ <p>Refer to the Drawable classes listed above for more information on the XML attributes
+supported by each.</p>
-<h2 id="shape-drawable">Shape Drawable</h2>
+ <h2 id="shape-drawable">Shape Drawable</h2>
-<p>When you want to dynamically draw some two-dimensional graphics, a {@link android.graphics.drawable.ShapeDrawable}
-object will probably suit your needs. With a ShapeDrawable, you can programmatically draw
-primitive shapes and style them in any way imaginable.</p>
+ <p>When you want to dynamically draw some two-dimensional graphics, a {@link
+ android.graphics.drawable.ShapeDrawable}
+ object will probably suit your needs. With a ShapeDrawable, you can programmatically draw
+ primitive shapes and style them in any way imaginable.</p>
-<p>A ShapeDrawable is an extension of {@link android.graphics.drawable.Drawable}, so you can use one where ever
-a Drawable is expected — perhaps for the background of a View, set with
-{@link android.view.View#setBackgroundDrawable(android.graphics.drawable.Drawable) setBackgroundDrawable()}.
-Of course, you can also draw your shape as its own custom {@link android.view.View},
-to be added to your layout however you please.
-Because the ShapeDrawable has its own <code>draw()</code> method, you can create a subclass of View that
-draws the ShapeDrawable during the <code>View.onDraw()</code> method.
-Here's a basic extension of the View class that does just this, to draw a ShapeDrawable as a View:</p>
-<pre>
-public class CustomDrawableView extends View {
- private ShapeDrawable mDrawable;
+ <p>A ShapeDrawable is an extension of {@link android.graphics.drawable.Drawable}, so you can use
+one where ever
+ a Drawable is expected — perhaps for the background of a View, set with
+ {@link android.view.View#setBackgroundDrawable(android.graphics.drawable.Drawable)
+ setBackgroundDrawable()}.
+ Of course, you can also draw your shape as its own custom {@link android.view.View},
+ to be added to your layout however you please.
+ Because the ShapeDrawable has its own <code>draw()</code> method, you can create a subclass of
+View that
+ draws the ShapeDrawable during the <code>View.onDraw()</code> method.
+ Here's a basic extension of the View class that does just this, to draw a ShapeDrawable as a
+ View:</p>
+ <pre>
+ public class CustomDrawableView extends View {
+ private ShapeDrawable mDrawable;
- public CustomDrawableView(Context context) {
- super(context);
+ public CustomDrawableView(Context context) {
+ super(context);
- int x = 10;
- int y = 10;
- int width = 300;
- int height = 50;
+ int x = 10;
+ int y = 10;
+ int width = 300;
+ int height = 50;
- mDrawable = new ShapeDrawable(new OvalShape());
- mDrawable.getPaint().setColor(0xff74AC23);
- mDrawable.setBounds(x, y, x + width, y + height);
- }
+ mDrawable = new ShapeDrawable(new OvalShape());
+ mDrawable.getPaint().setColor(0xff74AC23);
+ mDrawable.setBounds(x, y, x + width, y + height);
+ }
- protected void onDraw(Canvas canvas) {
- mDrawable.draw(canvas);
- }
-}
-</pre>
+ protected void onDraw(Canvas canvas) {
+ mDrawable.draw(canvas);
+ }
+ }
+ </pre>
-<p>In the constructor, a ShapeDrawable is defines as an {@link android.graphics.drawable.shapes.OvalShape}.
-It's then given a color and the bounds of the shape are set. If you do not set the bounds, then the
-shape will not be drawn, whereas if you don't set the color, it will default to black.</p>
-<p>With the custom View defined, it can be drawn any way you like. With the sample above, we can
-draw the shape programmatically in an Activity:</p>
-<pre>
-CustomDrawableView mCustomDrawableView;
+ <p>In the constructor, a ShapeDrawable is defines as an {@link
+ android.graphics.drawable.shapes.OvalShape}.
+ It's then given a color and the bounds of the shape are set. If you do not set the bounds,
+then the
+ shape will not be drawn, whereas if you don't set the color, it will default to black.</p>
+ <p>With the custom View defined, it can be drawn any way you like. With the sample above, we can
+ draw the shape programmatically in an Activity:</p>
+ <pre>
+ CustomDrawableView mCustomDrawableView;
-protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mCustomDrawableView = new CustomDrawableView(this);
-
- setContentView(mCustomDrawableView);
-}
-</pre>
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mCustomDrawableView = new CustomDrawableView(this);
-<p>If you'd like to draw this custom drawable from the XML layout instead of from the Activity,
-then the CustomDrawable class must override the {@link android.view.View#View(android.content.Context, android.util.AttributeSet) View(Context, AttributeSet)} constructor, which is called when
-instantiating a View via inflation from XML. Then add a CustomDrawable element to the XML,
-like so:</p>
-<pre>
-<com.example.shapedrawable.CustomDrawableView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
-</pre>
+ setContentView(mCustomDrawableView);
+ }
+ </pre>
-<p>The ShapeDrawable class (like many other Drawable types in the {@link android.graphics.drawable} package)
-allows you to define various properties of the drawable with public methods.
-Some properties you might want to adjust include
-alpha transparency, color filter, dither, opacity and color.</p>
+ <p>If you'd like to draw this custom drawable from the XML layout instead of from the Activity,
+ then the CustomDrawable class must override the {@link
+ android.view.View#View(android.content.Context, android.util.AttributeSet) View(Context,
+ AttributeSet)} constructor, which is called when
+ instantiating a View via inflation from XML. Then add a CustomDrawable element to the XML,
+ like so:</p>
+ <pre>
+ <com.example.shapedrawable.CustomDrawableView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ />
+ </pre>
-<p>You can also define primitive drawable shapes using XML. For more information, see the
-section about Shape Drawables in the <a
+ <p>The ShapeDrawable class (like many other Drawable types in the {@link
+android.graphics.drawable} package)
+ allows you to define various properties of the drawable with public methods.
+ Some properties you might want to adjust include
+ alpha transparency, color filter, dither, opacity and color.</p>
+
+ <p>You can also define primitive drawable shapes using XML. For more information, see the
+ section about Shape Drawables in the <a
+
href="{@docRoot}guide/topics/resources/drawable-resource.html#Shape">Drawable Resources</a>
-document.</p>
+ document.</p>
-<!-- TODO
-<h2 id="state-list">StateListDrawable</h2>
+ <!-- TODO
+ <h2 id="state-list">StateListDrawable</h2>
-<p>A StateListDrawable is an extension of the DrawableContainer class, making it little different.
-The primary distinction is that the
-StateListDrawable manages a collection of images for the Drawable, instead of just one.
-This means that it can switch the image when you want, without switching objects. However, the
-intention of the StateListDrawable is to automatically change the image used based on the state
-of the object it's attached to.
--->
+ <p>A StateListDrawable is an extension of the DrawableContainer class, making it little
+different.
+ The primary distinction is that the
+ StateListDrawable manages a collection of images for the Drawable, instead of just one.
+ This means that it can switch the image when you want, without switching objects. However,
+the
+ intention of the StateListDrawable is to automatically change the image used based on the
+state
+ of the object it's attached to.
+ -->
-<h2 id="nine-patch">Nine-patch</h2>
+ <h2 id="nine-patch">Nine-patch</h2>
-<p>A {@link android.graphics.drawable.NinePatchDrawable} graphic is a stretchable bitmap image, which Android
-will automatically resize to accommodate the contents of the View in which you have placed it as the background.
-An example use of a NinePatch is the backgrounds used by standard Android buttons —
-buttons must stretch to accommodate strings of various lengths. A NinePatch drawable is a standard PNG
-image that includes an extra 1-pixel-wide border. It must be saved with the extension <code>.9.png</code>,
-and saved into the <code>res/drawable/</code> directory of your project.
-</p>
-<p>
- The border is used to define the stretchable and static areas of
- the image. You indicate a stretchable section by drawing one (or more) 1-pixel-wide
- black line(s) in the left and top part of the border (the other border pixels should
- be fully transparent or white). You can have as many stretchable sections as you want:
- their relative size stays the same, so the largest sections always remain the largest.
-</p>
-<p>
- You can also define an optional drawable section of the image (effectively,
- the padding lines) by drawing a line on the right and bottom lines.
- If a View object sets the NinePatch as its background and then specifies the
- View's text, it will stretch itself so that all the text fits inside only
- the area designated by the right and bottom lines (if included). If the
- padding lines are not included, Android uses the left and top lines to
- define this drawable area.
-</p>
-<p>To clarify the difference between the different lines, the left and top lines define
-which pixels of the image are allowed to be replicated in order to stretch the image.
-The bottom and right lines define the relative area within the image that the contents
-of the View are allowed to lie within.</p>
-<p>
- Here is a sample NinePatch file used to define a button:
-</p>
- <img src="{@docRoot}images/ninepatch_raw.png" alt="" />
+ <p>A {@link android.graphics.drawable.NinePatchDrawable} graphic is a stretchable bitmap
+image, which Android
+ will automatically resize to accommodate the contents of the View in which you have
+placed it as the background.
+ An example use of a NinePatch is the backgrounds used by standard Android buttons —
+ buttons must stretch to accommodate strings of various lengths. A NinePatch drawable is a
+standard PNG
+ image that includes an extra 1-pixel-wide border. It must be saved with the extension
+ <code>.9.png</code>,
+ and saved into the <code>res/drawable/</code> directory of your project.
+ </p>
+ <p>
+ The border is used to define the stretchable and static areas of
+ the image. You indicate a stretchable section by drawing one (or more) 1-pixel-wide
+ black line(s) in the left and top part of the border (the other border pixels should
+ be fully transparent or white). You can have as many stretchable sections as you want:
+ their relative size stays the same, so the largest sections always remain the largest.
+ </p>
+ <p>
+ You can also define an optional drawable section of the image (effectively,
+ the padding lines) by drawing a line on the right and bottom lines.
+ If a View object sets the NinePatch as its background and then specifies the
+ View's text, it will stretch itself so that all the text fits inside only
+ the area designated by the right and bottom lines (if included). If the
+ padding lines are not included, Android uses the left and top lines to
+ define this drawable area.
+ </p>
+ <p>To clarify the difference between the different lines, the left and top lines define
+ which pixels of the image are allowed to be replicated in order to stretch the image.
+ The bottom and right lines define the relative area within the image that the contents
+ of the View are allowed to lie within.</p>
+ <p>
+ Here is a sample NinePatch file used to define a button:
+ </p>
+ <img src="{@docRoot}images/ninepatch_raw.png" alt="" />
-<p>This NinePatch defines one stretchable area with the left and top lines
-and the drawable area with the bottom and right lines. In the top image, the dotted grey
-lines identify the regions of the image that will be replicated in order to stretch the image. The pink
-rectangle in the bottom image identifies the region in which the contents of the View are allowed.
-If the contents don't fit in this region, then the image will be stretched so that they do.
+ <p>This NinePatch defines one stretchable area with the left and top lines
+ and the drawable area with the bottom and right lines. In the top image, the dotted grey
+ lines identify the regions of the image that will be replicated in order to stretch the
+image. The pink
+ rectangle in the bottom image identifies the region in which the contents of the View are
+allowed.
+ If the contents don't fit in this region, then the image will be stretched so that they
+do.
</p>
-<p>The <a href="{@docRoot}guide/developing/tools/draw9patch.html">Draw 9-patch</a> tool offers
- an extremely handy way to create your NinePatch images, using a WYSIWYG graphics editor. It
+<p>The <a href="{@docRoot}guide/developing/tools/draw9patch.html">Draw 9-patch</a> tool offers
+ an extremely handy way to create your NinePatch images, using a WYSIWYG graphics editor. It
even raises warnings if the region you've defined for the stretchable area is at risk of
producing drawing artifacts as a result of the pixel replication.
</p>
@@ -298,7 +486,8 @@
<h3>Example XML</h3>
<p>Here's some sample layout XML that demonstrates how to add a NinePatch image to a
-couple of buttons. (The NinePatch image is saved as <code>res/drawable/my_button_background.9.png</code>
+couple of buttons. (The NinePatch image is saved as
+<code>res/drawable/my_button_background.9.png</code>
<pre>
<Button id="@+id/tiny"
android:layout_width="wrap_content"
@@ -318,11 +507,12 @@
android:textSize="30sp"
android:background="@drawable/my_button_background"/>
</pre>
-<p>Note that the width and height are set to "wrap_content" to make the button fit neatly around the text.
+<p>Note that the width and height are set to "wrap_content" to make the button fit neatly around the
+text.
</p>
-<p>Below are the two buttons rendered from the XML and NinePatch image shown above.
-Notice how the width and height of the button varies with the text, and the background image
+<p>Below are the two buttons rendered from the XML and NinePatch image shown above.
+Notice how the width and height of the button varies with the text, and the background image
stretches to accommodate it.
</p>
diff --git a/docs/html/guide/topics/graphics/animation.jd b/docs/html/guide/topics/graphics/animation.jd
index e7a07e0..561369d 100644
--- a/docs/html/guide/topics/graphics/animation.jd
+++ b/docs/html/guide/topics/graphics/animation.jd
@@ -1,949 +1,64 @@
-page.title=Property Animation
-parent.title=Graphics
-parent.link=index.html
+page.title=Animation
@jd:body
<div id="qv-wrapper">
<div id="qv">
- <h2>In this document</h2>
+ <h2>See also</h2>
<ol>
- <li><a href="#what">What is Property Animation?</a>
- <ol>
- <li><a href="#how">How property animation works</a></li>
- </ol>
- </li>
-
- <li><a href="#value-animator">Animating with ValueAnimator</a></li>
-
- <li><a href="#object-animator">Animating with ObjectAnimator</a></li>
-
- <li><a href="#choreography">Choreographing Multiple Animations with
- AnimatorSet</a></li>
-
- <li><a href="#listeners">Animation Listeners</a></li>
-
- <li><a href="#type-evaluator">Using a TypeEvaluator</a></li>
-
- <li><a href="#interpolators">Using Interpolators</a></li>
-
- <li><a href="#keyframes">Specifying Keyframes</a></li>
-
- <li><a href="#layout">Animating Layout Changes to ViewGroups</a></li>
-
- <li><a href="#views">Animating Views</a>
- <ol>
- <li><a href="#view-prop-animator">ViewPropertyAnimator</a></li>
- </ol>
- </li>
-
- <li><a href="#declaring-xml">Declaring Animations in XML</a></li>
- </ol>
-
- <h2>Key classes</h2>
-
+ <li><a href="{@docRoot}guide/topics/graphics/prop-animation.html">Property
+Animation</a></li>
+ <li><a href="{@docRoot}guide/topics/graphics/view-animation.html">View Animation</a></li>
+ <li><a href="{@docRoot}guide/topics/graphics/drawable-animation.html">Drawable Animation</a></li>
<ol>
- <li><code><a href=
- "/reference/android/animation/ValueAnimator.html">ValueAnimator</a></code></li>
-
- <li><code><a href=
- "/reference/android/animation/ObjectAnimator.html">ObjectAnimator</a></code></li>
-
- <li><code><a href=
- "/reference/android/animation/TypeEvaluator.html">TypeEvaluator</a></code></li>
- </ol>
-
- <h2>Related samples</h2>
-
- <ol>
- <li><a href=
- "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">API
- Demos</a></li>
- </ol>
</div>
</div>
- <p>Introduced in Android 3.0, the property animation system is a robust framework that allows you
- to animate almost anything. Property animation is not confined to objects drawn on the screen.
- You can define an animation to change any object property over time, regardless of whether it
- draws to the screen or not.The property animation system also has a few advantages over the view
- animation system, which makes it more flexible to use.</p>
+ <p>The Android framework provides two animation systems: property animation
+ (introduced in Android 3.0) and view animation. Both animation systems are viable options,
+ but the property animation system, in general, is the preferred method to use, because it
+ is more flexible and offers more features. In addition to these two systems, you can utilize Drawable
+animation, which allows you to load drawable resources and display them one frame after
+another.</p>
- <p>The view animation system provides the capability to only animate View objects, so if
- you wanted to animate non-View objects, you had to implement your own code to do so. The view
- animation system also was constrained in the fact that it only exposed a few aspects of a View
- object to animate, such as the scaling and rotation of a View but not the background color for
- instance.</p>
+ <p>The view animation system provides the capability to only animate {@link android.view.View}
+objects, so if you wanted to animate non-{@link android.view.View} objects, you have to implement
+your own code to do so. The view animation system is also constrained in the fact that it only
+exposes a few aspects of a {@link android.view.View} object to animate, such as the scaling and
+rotation of a View but not the background color, for instance.</p>
<p>Another disadvantage of the view animation system is that it only modified where the
View was drawn, and not the actual View itself. For instance, if you animated a button to move
across the screen, the button draws correctly, but the actual location where you can click the
- button does not change, so you have to implement your own logic to handle this. With the property
- animation system, these constraints are completely removed, and you can animate any property of
- any object, including View objects, and the object itself is actually modified.</p>
+ button does not change, so you have to implement your own logic to handle this.</p>
+
+ <p>With the property animation system, these constraints are completely removed, and you can animate
+ any property of any object (Views and non-Views) and the object itself is actually modified.
+ The property animation system is also more robust in the way it carries out animation. At
+ a high level, you assign animators to the properties that you want to animate, such as color,
+ position, or size and can define aspects of the animation such as interpolation and
+ synchronization of multiple animators.</p>
<p>The view animation system, however, takes less time to setup and requires less code to write.
If view animation accomplishes everything that you need to do, or if your existing code already
- works the way you want, there is no need to use the property animation system.</p>
+ works the way you want, there is no need to use the property animation system. It also might
+ make sense to use both animation systems for different situations if the use case arises.</p>
- <p class="note"><strong>Tip:</strong> To see how the ADT layout editor allows you to develop and
-preview animations in your layout, watch the <a
-href="http://www.youtube.com/watch?v=Oq05KqjXTvs&feature=player_detailpage#t=1709s">Android
-Developer Tools session</a> from Google I/O '11</p>
+<dl>
+<dt><strong><a href="{@docRoot}guide/topics/graphics/prop-animation.html">Property
+Animation</a></strong></dt>
+<dd>Introduced in Android 3.0 (API level 11), the property animation system lets you
+animate properties of any object, including ones that are not rendered to the screen. The system is
+extensible and lets you animate properties of custom types as well.</dd>
+<dt><strong><a href="{@docRoot}guide/topics/graphics/view-animation.html">View
+Animation</a></strong></dt>
+<dd>View Animation is the older system and can only be used for Views. It is relatively easy to
+setup and offers enough capabilities to meet many application's needs.</dd>
+</dl>
- <h2 id="what">What is Property Animation?</h2>
- A property animation changes a property's (a field in
- an object) value over a specified length of time. To animate something, you specify the
- object property that you want to animate, such as an object's position on the screen, how long
- you want to animate it for, and what values you want to animate between. </p>
-
- <p>The property animation system lets you define the following characteristics of an
- animation:</p>
-
- <ul>
- <li>Duration: You can specify the duration of an animation. The default length is 300 ms.</li>
-
- <li>Time interpolation: You can specify how the values for the property are calculated as a
- function of the animation's current elapsed time.</li>
-
- <li>Repeat count and behavior: You can specify whether or not to have an animation repeat when
- it reaches the end of a duration and how many times to repeat the animation. You can also
- specify whether you want the animation to play back in reverse. Setting it to reverse plays
- the animation forwards then backwards repeatedly, until the number of repeats is reached.</li>
-
- <li>Animator sets: You can group animations into logical sets that play together or
- sequentially or after specified delays.</li>
-
- <li>Frame refresh delay: You can specify how often to refresh frames of your animation. The
- default is set to refresh every 10 ms, but the speed in which your application can refresh frames is
- ultimately dependent on how busy the system is overall and how fast the system can service the underlying timer.</li>
- </ul>
-
-
- <h3 id="how">How the property animation system works</h3>
-
- <p>First, let's go over how an animation works with a simple example. Figure 1 depicts a
- hypothetical object that is animated with its <code>x</code> property, which represents its
- horizontal location on a screen. The duration of the animation is set to 40 ms and the distance
- to travel is 40 pixels. Every 10 ms, which is the default frame refresh rate, the object moves
- horizontally by 10 pixels. At the end of 40ms, the animation stops, and the object ends at
- horizontal position 40. This is an example of an animation with linear interpolation, meaning the
- object moves at a constant speed.</p><img src="{@docRoot}images/animation/animation-linear.png">
-
- <p class="img-caption"><strong>Figure 1.</strong> Example of a linear animation</p>
-
- <p>You can also specify animations to have a non-linear interpolation. Figure 2 illustrates a
- hypothetical object that accelerates at the beginning of the animation, and decelerates at the
- end of the animation. The object still moves 40 pixels in 40 ms, but non-linearly. In the
- beginning, this animation accelerates up to the halfway point then decelerates from the
- halfway point until the end of the animation. As Figure 2 shows, the distance traveled
- at the beginning and end of the animation is less than in the middle.</p><img src=
- "{@docRoot}images/animation/animation-nonlinear.png">
-
- <p class="img-caption"><strong>Figure 2.</strong> Example of a non-linear animation</p>
-
- <p>Let's take a detailed look at how the important components of the property animation system
- would calculate animations like the ones illustrated above. Figure 3 depicts how the main classes
- work with one another.</p><img src="{@docRoot}images/animation/valueanimator.png">
-
- <p class="img-caption"><strong>Figure 3.</strong> How animations are calculated</p>
-
- <p>The {@link android.animation.ValueAnimator} object keeps track of your animation's timing,
- such as how long the animation has been running, and the current value of the property that it is
- animating.</p>
-
- <p>The {@link android.animation.ValueAnimator} encapsulates a {@link
- android.animation.TimeInterpolator}, which defines animation interpolation, and a {@link
- android.animation.TypeEvaluator}, which defines how to calculate values for the property being
- animated. For example, in Figure 2, the {@link android.animation.TimeInterpolator} used would be
- {@link android.view.animation.AccelerateDecelerateInterpolator} and the {@link
- android.animation.TypeEvaluator} would be {@link android.animation.IntEvaluator}.</p>
-
- <p>To start an animation, create a {@link android.animation.ValueAnimator} and give it the
- starting and ending values for the property that you want to animate, along with the duration of
- the animation. When you call {@link android.animation.ValueAnimator#start start()} the animation
- begins. During the whole animation, the {@link android.animation.ValueAnimator} calculates an <em>elapsed fraction</em>
- between 0 and 1, based on the duration of the animation and how much time has elapsed. The
- elapsed fraction represents the percentage of time that the animation has completed, 0 meaning 0%
- and 1 meaning 100%. For example, in Figure 1, the elapsed fraction at t = 10 ms would be .25
- because the total duration is t = 40 ms.</p>
-
- <p>When the {@link android.animation.ValueAnimator} is done calculating an elapsed fraction, it
- calls the {@link android.animation.TimeInterpolator} that is currently set, to calculate an
- <em>interpolated fraction</em>. An interpolated fraction maps the elapsed fraction to a new
- fraction that takes into account the time interpolation that is set. For example, in Figure 2,
- because the animation slowly accelerates, the interpolated fraction, about .15, is less than the
- elapsed fraction, .25, at t = 10 ms. In Figure 1, the interpolated fraction is always the same as
- the elapsed fraction.</p>
-
- <p>When the interpolated fraction is calculated, {@link android.animation.ValueAnimator} calls
- the appropriate {@link android.animation.TypeEvaluator}, to calculate the value of the
- property that you are animating, based on the interpolated fraction, the starting value, and the
- ending value of the animation. For example, in Figure 2, the interpolated fraction was .15 at t =
- 10 ms, so the value for the property at that time would be .15 X (40 - 0), or 6.</p>
-
- <!-- <p>When the final value is calculated, the {@link android.animation.ValueAnimator} calls the
- {@link android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate
- onAnimationUpdate()} method. Implement this callback to obtain the property value by
- calling {@link android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()} and set the
- value for the property in the object that you are animating. Setting the property doesn't redraw
- the object on the screen, so you need to call {@link
- android.view.View#invalidate invalidate()} to refresh the View that the object
- resides in. If the object is actually a View object, then the system calls {@link
- android.view.View#invalidate invalidate()} when the property is changed.
- The system redraws the window and the {@link android.animation.ValueAnimator}
- repeats the process.</p>-->
-
- <p>The <code>com.example.android.apis.animation</code> package in the <a href=
- "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">API
- Demos</a> sample project provides many examples on how to use the property
- animation system.</p>
-
- <h2>API Overview</h2>
-
- <p>You can find most of the property animation system's APIs in {@link android.animation
- android.animation}. Because the view animation system already
- defines many interpolators in {@link android.view.animation android.view.animation}, you can use
- those interpolators in the property animation system as well. The following tables describe the main
- components of the property animation system.</p>
-
- <p>The {@link android.animation.Animator} class provides the basic structure for creating
- animations. You normally do not use this class directly as it only provides minimal
- functionality that must be extended to fully support animating values. The following
- subclasses extend {@link android.animation.Animator}:
- </p>
- <p class="table-caption"><strong>Table 1.</strong> Animators</p>
- <table>
- <tr>
- <th>Class</th>
-
- <th>Description</th>
- </tr>
-
- <tr>
- <td>{@link android.animation.ValueAnimator}</td>
-
- <td>The main timing engine for property animation that also computes the values for the
- property to be animated. It has all of the core functionality that calculates animation
- values and contains the timing details of each animation, information about whether an
- animation repeats, listeners that receive update events, and the ability to set custom
- types to evaluate. There are two pieces to animating properties: calculating the animated
- values and setting those values on the object and property that is being animated. {@link
- android.animation.ValueAnimator} does not carry out the second piece, so you must listen
- for updates to values calculated by the {@link android.animation.ValueAnimator} and
- modify the objects that you want to animate with your own logic. See the section about
- <a href="#value-animator">Animating with ValueAnimator</a> for more information.</td>
- </tr>
-
- <tr>
- <td>{@link android.animation.ObjectAnimator}</td>
-
- <td>A subclass of {@link android.animation.ValueAnimator} that allows you to set a target
- object and object property to animate. This class updates the property accordingly when
- it computes a new value for the animation. You want to use
- {@link android.animation.ObjectAnimator} most of the time,
- because it makes the process of animating values on target objects much easier. However,
- you sometimes want to use {@link android.animation.ValueAnimator} directly because {@link
- android.animation.ObjectAnimator} has a few more restrictions, such as requiring specific
- acessor methods to be present on the target object.</td>
- </tr>
-
- <tr>
- <td>{@link android.animation.AnimatorSet}</td>
-
- <td>Provides a mechanism to group animations together so that they run in
- relation to one another. You can set animations to play together, sequentially, or after
- a specified delay. See the section about <a href="#choreography">Choreographing multiple
- animations with Animator Sets</a> for more information.</td>
- </tr>
- </table>
-
-
- <p>Evaluators tell the property animation system how to calculate values for a given
- property. They take the timing data that is provided by an {@link android.animation.Animator}
- class, the animation's start and end value, and calculate the animated values of the property
- based on this data. The property animation system provides the following evaluators:</p>
- <p class="table-caption"><strong>Table 2.</strong> Evaluators</p>
- <table>
- <tr>
- <th>Class/Interface</th>
-
- <th>Description</th>
- </tr>
-
- <tr>
- <td>{@link android.animation.IntEvaluator}</td>
-
- <td>The default evaluator to calculate values for <code>int</code> properties.</td>
- </tr>
-
- <tr>
- <td>{@link android.animation.FloatEvaluator}</td>
-
- <td>The default evaluator to calculate values for <code>float</code> properties.</td>
- </tr>
-
- <tr>
- <td>{@link android.animation.ArgbEvaluator}</td>
-
- <td>The default evaluator to calculate values for color properties that are represented
- as hexidecimal values.</td>
- </tr>
-
- <tr>
- <td>{@link android.animation.TypeEvaluator}</td>
-
- <td>An interface that allows you to create your own evaluator. If you are animating an
- object property that is <em>not</em> an <code>int</code>, <code>float</code>, or color,
- you must implement the {@link android.animation.TypeEvaluator} interface to specify how
- to compute the object property's animated values. You can also specify a custom {@link
- android.animation.TypeEvaluator} for <code>int</code>, <code>float</code>, and color
- values as well, if you want to process those types differently than the default behavior.
- See the section about <a href="#type-evaluator">Using a TypeEvaluator</a> for more
- information on how to write a custom evaluator.</td>
- </tr>
- </table>
-
-
-
-
- <p>A time interpolator defines how specific values in an animation are calculated as a
- function of time. For example, you can specify animations to happen linearly across the whole
- animation, meaning the animation moves evenly the entire time, or you can specify animations
- to use non-linear time, for example, accelerating at the beginning and decelerating at the
- end of the animation. Table 3 describes the interpolators that are contained in {@link
- android.view.animation android.view.animation}. If none of the provided interpolators suits
- your needs, implement the {@link android.animation.TimeInterpolator} interface and create your own. See <a href=
- "#interpolators">Using interpolators</a> for more information on how to write a custom
- interpolator.</p>
- <p class="table-caption"><strong>Table 3.</strong> Interpolators</p>
- <table>
- <tr>
- <th>Class/Interface</th>
-
- <th>Description</th>
- </tr>
-
- <tr>
- <td>{@link android.view.animation.AccelerateDecelerateInterpolator}</td>
-
- <td>An interpolator whose rate of change starts and ends slowly but accelerates
- through the middle.</td>
- </tr>
-
- <tr>
- <td>{@link android.view.animation.AccelerateInterpolator}</td>
-
- <td>An interpolator whose rate of change starts out slowly and then
- accelerates.</td>
- </tr>
-
- <tr>
- <td>{@link android.view.animation.AnticipateInterpolator}</td>
-
- <td>An interpolator whose change starts backward then flings forward.</td>
- </tr>
-
- <tr>
- <td>{@link android.view.animation.AnticipateOvershootInterpolator}</td>
-
- <td>An interpolator whose change starts backward, flings forward and overshoots
- the target value, then finally goes back to the final value.</td>
- </tr>
-
- <tr>
- <td>{@link android.view.animation.BounceInterpolator}</td>
-
- <td>An interpolator whose change bounces at the end.</td>
- </tr>
-
- <tr>
- <td>{@link android.view.animation.CycleInterpolator}</td>
-
- <td>An interpolator whose animation repeats for a specified number of cycles.</td>
- </tr>
-
- <tr>
- <td>{@link android.view.animation.DecelerateInterpolator}</td>
-
- <td>An interpolator whose rate of change starts out quickly and and then
- decelerates.</td>
- </tr>
-
- <tr>
- <td>{@link android.view.animation.LinearInterpolator}</td>
-
- <td>An interpolator whose rate of change is constant.</td>
- </tr>
-
- <tr>
- <td>{@link android.view.animation.OvershootInterpolator}</td>
-
- <td>An interpolator whose change flings forward and overshoots the last value then
- comes back.</td>
- </tr>
-
- <tr>
- <td>{@link android.animation.TimeInterpolator}</td>
-
- <td>An interface that allows you to implement your own interpolator.</td>
- </tr>
- </table>
-
- <h2 id="value-animator">Animating with ValueAnimator</h2>
-
- <p>The {@link android.animation.ValueAnimator} class lets you animate values of some type for the
- duration of an animation by specifying a set of <code>int</code>, <code>float</code>, or color
- values to animate through. You obtain a {@link android.animation.ValueAnimator} by calling one of
- its factory methods: {@link android.animation.ValueAnimator#ofInt ofInt()}, {@link
- android.animation.ValueAnimator#ofFloat ofFloat()}, or {@link
- android.animation.ValueAnimator#ofObject ofObject()}. For example:</p>
- <pre>
-ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
-animation.setDuration(1000);
-animation.start();
-</pre>
-
- <p>In this code, the {@link android.animation.ValueAnimator} starts calculating the values of the
- animation, between 0 and 1, for a duration of 1000 ms, when the <code>start()</code> method
- runs.</p>
-
- <p>You can also specify a custom type to animate by doing the following:</p>
- <pre>
-ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
-animation.setDuration(1000);
-animation.start();
-</pre>
-
- <p>In this code, the {@link android.animation.ValueAnimator} starts calculating the values of the
- animation, between <code>startPropertyValue</code> and <code>endPropertyValue</code> using the
- logic supplied by <code>MyTypeEvaluator</code> for a duration of 1000 ms, when the {@link
- android.animation.ValueAnimator#start start()} method runs.</p>
-
- <p>The previous code snippets, however, has no real effect on an object, because the {@link
- android.animation.ValueAnimator} does not operate on objects or properties directly. The most likely thing
- that you want to do is modify the objects that you want to animate with these calculated values. You do
- this by defining listeners in the {@link android.animation.ValueAnimator} to appropriately handle important events
- during the animation's lifespan, such as frame updates. When implementing the listeners, you can
- obtain the calculated value for that specific frame refresh by calling {@link
- android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()}. For more information on listeners,
- see the section about <a href="#listeners">Animation Listeners</a>.
-
- <h2 id="object-animator">Animating with ObjectAnimator</h2>
-
- <p>The {@link android.animation.ObjectAnimator} is a subclass of the {@link
- android.animation.ValueAnimator} (discussed in the previous section) and combines the timing
- engine and value computation of {@link android.animation.ValueAnimator} with the ability to
- animate a named property of a target object. This makes animating any object much easier, as you
- no longer need to implement the {@link android.animation.ValueAnimator.AnimatorUpdateListener},
- because the animated property updates automatically.</p>
-
- <p>Instantiating an {@link android.animation.ObjectAnimator} is similar to a {@link
- android.animation.ValueAnimator}, but you also specify the object and the name of that object's property (as
- a String) along with the values to animate between:</p>
- <pre>
-ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f);
-anim.setDuration(1000);
-anim.start();
-</pre>
-
- <p>To have the {@link android.animation.ObjectAnimator} update properties correctly, you must do
- the following:</p>
-
- <ul>
- <li>The object property that you are animating must have a setter function (in camel case) in the form of
- <code>set<propertyName>()</code>. Because the {@link android.animation.ObjectAnimator}
- automatically updates the property during animation, it must be able to access the property
- with this setter method. For example, if the property name is <code>foo</code>, you need to
- have a <code>setFoo()</code> method. If this setter method does not exist, you have three
- options:
-
- <ul>
- <li>Add the setter method to the class if you have the rights to do so.</li>
-
- <li>Use a wrapper class that you have rights to change and have that wrapper receive the
- value with a valid setter method and forward it to the original object.</li>
-
- <li>Use {@link android.animation.ValueAnimator} instead.</li>
- </ul>
- </li>
-
- <li>If you specify only one value for the <code>values...</code> parameter in one of the {@link
- android.animation.ObjectAnimator} factory methods, it is assumed to be the ending value of the
- animation. Therefore, the object property that you are animating must have a getter function
- that is used to obtain the starting value of the animation. The getter function must be in the
- form of <code>get<propertyName>()</code>. For example, if the property name is
- <code>foo</code>, you need to have a <code>getFoo()</code> method.</li>
-
- <li>The getter (if needed) and setter methods of the property that you are animating must
- operate on the same type as the starting and ending values that you specify to {@link
- android.animation.ObjectAnimator}. For example, you must have
- <code>targetObject.setPropName(float)</code> and <code>targetObject.getPropName(float)</code>
- if you construct the following {@link android.animation.ObjectAnimator}:
- <pre>
-ObjectAnimator.ofFloat(targetObject, "propName", 1f)
-</pre>
- </li>
-
- <li>Depending on what property or object you are animating, you might need to call the {@link
- android.view.View#invalidate invalidate()} method on a View force the screen to redraw itself with the
- updated animated values. You do this in the
- {@link android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate onAnimationUpdate()}
- callback. For example, animating the color property of a Drawable object only cause updates to the
- screen when that object redraws itself. All of the property setters on View, such as
- {@link android.view.View#setAlpha setAlpha()} and {@link android.view.View#setTranslationX setTranslationX()}
- invalidate the View properly, so you do not need to invalidate the View when calling these
- methods with new values. For more information on listeners, see the section about <a href="#listeners">Animation Listeners</a>.
- </li>
- </ul>
-
- <h2 id="choreography">Choreographing Multiple Animations with AnimatorSet</h2>
-
- <p>In many cases, you want to play an animation that depends on when another animation starts or
- finishes. The Android system lets you bundle animations together into an {@link
- android.animation.AnimatorSet}, so that you can specify whether to start animations
- simultaneously, sequentially, or after a specified delay. You can also nest {@link
- android.animation.AnimatorSet} objects within each other.</p>
-
- <p>The following sample code taken from the <a href=
- "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">Bouncing
- Balls</a> sample (modified for simplicity) plays the following {@link android.animation.Animator}
- objects in the following manner:</p>
-
- <ol>
- <li>Plays <code>bounceAnim</code>.</li>
-
- <li>Plays <code>squashAnim1</code>, <code>squashAnim2</code>, <code>stretchAnim1</code>, and
- <code>stretchAnim2</code> at the same time.</li>
-
- <li>Plays <code>bounceBackAnim</code>.</li>
-
- <li>Plays <code>fadeAnim</code>.</li>
- </ol>
- <pre>
-AnimatorSet bouncer = new AnimatorSet();
-bouncer.play(bounceAnim).before(squashAnim1);
-bouncer.play(squashAnim1).with(squashAnim2);
-bouncer.play(squashAnim1).with(stretchAnim1);
-bouncer.play(squashAnim1).with(stretchAnim2);
-bouncer.play(bounceBackAnim).after(stretchAnim2);
-ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
-fadeAnim.setDuration(250);
-AnimatorSet animatorSet = new AnimatorSet();
-animatorSet.play(bouncer).before(fadeAnim);
-animatorSet.start();
-</pre>
-
- <p>For a more complete example on how to use animator sets, see the <a href=
- "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">Bouncing
- Balls</a> sample in APIDemos.</p>
-
-<h2 id="listeners">Animation Listeners</h2>
-<p>
-You can listen for important events during an animation's duration with the listeners described below.
-</p>
-
- <ul>
- <li>{@link android.animation.Animator.AnimatorListener}
-
- <ul>
- <li>{@link android.animation.Animator.AnimatorListener#onAnimationStart onAnimationStart()}
- - Called when the animation starts.</li>
-
- <li>{@link android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()} -
- Called when the animation ends.</li>
-
- <li>{@link android.animation.Animator.AnimatorListener#onAnimationRepeat
- onAnimationRepeat()} - Called when the animation repeats itself.</li>
-
- <li>{@link android.animation.Animator.AnimatorListener#onAnimationCancel
- onAnimationCancel()} - Called when the animation is canceled. A cancelled animation
- also calls {@link android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()},
- regardless of how they were ended.</li>
- </ul>
- </li>
-
- <li>{@link android.animation.ValueAnimator.AnimatorUpdateListener}
-
- <ul>
- <li>
- <p>{@link android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate
- onAnimationUpdate()} - called on every frame of the animation. Listen to this event to
- use the calculated values generated by {@link android.animation.ValueAnimator} during an
- animation. To use the value, query the {@link android.animation.ValueAnimator} object
- passed into the event to get the current animated value with the {@link
- android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()} method. Implementing this
- listener is required if you use {@link android.animation.ValueAnimator}. </p>
-
- <p>
- Depending on what property or object you are animating, you might need to call
- {@link android.view.View#invalidate invalidate()} on a View to force that area of the
- screen to redraw itself with the new animated values. For example, animating the
- color property of a Drawable object only cause updates to the screen when that object
- redraws itself. All of the property setters on View,
- such as {@link android.view.View#setAlpha setAlpha()} and
- {@link android.view.View#setTranslationX setTranslationX()} invalidate the View
- properly, so you do not need to invalidate the View when calling these methods with new values.
- </p>
-
- </li>
- </ul>
- </li>
- </ul>
-
-<p>You can extend the {@link android.animation.AnimatorListenerAdapter} class instead of
-implementing the {@link android.animation.Animator.AnimatorListener} interface, if you do not
-want to implement all of the methods of the {@link android.animation.Animator.AnimatorListener}
-interface. The {@link android.animation.AnimatorListenerAdapter} class provides empty
-implementations of the methods that you can choose to override.</p>
- <p>For example, the <a href=
- "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">Bouncing
- Balls</a> sample in the API demos creates an {@link android.animation.AnimatorListenerAdapter}
- for just the {@link android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()}
- callback:</p>
- <pre>
-ValueAnimatorAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
-fadeAnim.setDuration(250);
-fadeAnim.addListener(new AnimatorListenerAdapter() {
-public void onAnimationEnd(Animator animation) {
- balls.remove(((ObjectAnimator)animation).getTarget());
-}
-</pre>
-
-
- <h2 id="layout">Animating Layout Changes to ViewGroups</h2>
-
- <p>The property animation system provides the capability to animate changes to ViewGroup objects
- as well as provide an easy way to animate View objects themselves.</p>
-
- <p>You can animate layout changes within a ViewGroup with the {@link
- android.animation.LayoutTransition} class. Views inside a ViewGroup can go through an appearing
- and disappearing animation when you add them to or remove them from a ViewGroup or when you call
- a View's {@link android.view.View#setVisibility setVisibility()} method with {@link
- android.view.View#VISIBLE}, android.view.View#INVISIBLE}, or {@link android.view.View#GONE}. The remaining Views in the
- ViewGroup can also animate into their new positions when you add or remove Views. You can define
- the following animations in a {@link android.animation.LayoutTransition} object by calling {@link
- android.animation.LayoutTransition#setAnimator setAnimator()} and passing in an {@link
- android.animation.Animator} object with one of the following {@link
- android.animation.LayoutTransition} constants:</p>
-
- <ul>
- <li><code>APPEARING</code> - A flag indicating the animation that runs on items that are
- appearing in the container.</li>
-
- <li><code>CHANGE_APPEARING</code> - A flag indicating the animation that runs on items that are
- changing due to a new item appearing in the container.</li>
-
- <li><code>DISAPPEARING</code> - A flag indicating the animation that runs on items that are
- disappearing from the container.</li>
-
- <li><code>CHANGE_DISAPPEARING</code> - A flag indicating the animation that runs on items that
- are changing due to an item disappearing from the container.</li>
- </ul>
-
- <p>You can define your own custom animations for these four types of events to customize the look
- of your layout transitions or just tell the animation system to use the default animations.</p>
-
- <p>The <a href=
- "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimations.html">
- LayoutAnimations</a> sample in API Demos shows you how to define animations for layout
- transitions and then set the animations on the View objects that you want to animate.</p>
-
- <p>The <a href=
- "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsByDefault.html">
- LayoutAnimationsByDefault</a> and its corresponding <a href=
- "{@docRoot}resources/samples/ApiDemos/res/layout/layout_animations_by_default.html">layout_animations_by_default.xml</a>
- layout resource file show you how to enable the default layout transitions for ViewGroups in XML.
- The only thing that you need to do is to set the <code>android:animateLayoutchanges</code>
- attribute to <code>true</code> for the ViewGroup. For example:</p>
- <pre>
-<LinearLayout
- android:orientation="vertical"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:id="@+id/verticalContainer"
- android:animateLayoutChanges="true" />
-</pre>
-
- <p>Setting this attribute to true automatically animates Views that are added or removed from the
- ViewGroup as well as the remaining Views in the ViewGroup.</p>
-
- <h2 id="type-evaluator">Using a TypeEvaluator</h2>
-
- <p>If you want to animate a type that is unknown to the Android system, you can create your own
- evaluator by implementing the {@link android.animation.TypeEvaluator} interface. The types that
- are known by the Android system are <code>int</code>, <code>float</code>, or a color, which are
- supported by the {@link android.animation.IntEvaluator}, {@link
- android.animation.FloatEvaluator}, and {@link android.animation.ArgbEvaluator} type
- evaluators.</p>
-
- <p>There is only one method to implement in the {@link android.animation.TypeEvaluator}
- interface, the {@link android.animation.TypeEvaluator#evaluate evaluate()} method. This allows
- the animator that you are using to return an appropriate value for your animated property at the
- current point of the animation. The {@link android.animation.FloatEvaluator} class demonstrates
- how to do this:</p>
- <pre>
-public class FloatEvaluator implements TypeEvaluator {
-
- public Object evaluate(float fraction, Object startValue, Object endValue) {
- float startFloat = ((Number) startValue).floatValue();
- return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
- }
-}
-</pre>
-
- <p class="note"><strong>Note:</strong> When {@link android.animation.ValueAnimator} (or {@link
- android.animation.ObjectAnimator}) runs, it calculates a current elapsed fraction of the
- animation (a value between 0 and 1) and then calculates an interpolated version of that depending
- on what interpolator that you are using. The interpolated fraction is what your {@link
- android.animation.TypeEvaluator} receives through the <code>fraction</code> parameter, so you do
- not have to take into account the interpolator when calculating animated values.</p>
-
- <h2 id="interpolators">Using Interpolators</h2>
-
- <p>An interpolator define how specific values in an animation are calculated as a function of
- time. For example, you can specify animations to happen linearly across the whole animation,
- meaning the animation moves evenly the entire time, or you can specify animations to use
- non-linear time, for example, using acceleration or deceleration at the beginning or end of the
- animation.</p>
-
- <p>Interpolators in the animation system receive a fraction from Animators that represent the
- elapsed time of the animation. Interpolators modify this fraction to coincide with the type of
- animation that it aims to provide. The Android system provides a set of common interpolators in
- the {@link android.view.animation android.view.animation package}. If none of these suit your
- needs, you can implement the {@link android.animation.TimeInterpolator} interface and create your
- own.</p>
-
- <p>As an example, how the default interpolator {@link
- android.view.animation.AccelerateDecelerateInterpolator} and the {@link
- android.view.animation.LinearInterpolator} calculate interpolated fractions are compared below.
- The {@link android.view.animation.LinearInterpolator} has no effect on the elapsed fraction. The {@link
- android.view.animation.AccelerateDecelerateInterpolator} accelerates into the animation and
- decelerates out of it. The following methods define the logic for these interpolators:</p>
-
- <p><strong>AccelerateDecelerateInterpolator</strong></p>
- <pre>
-public float getInterpolation(float input) {
- return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
-}
-</pre>
-
- <p><strong>LinearInterpolator</strong></p>
- <pre>
-public float getInterpolation(float input) {
- return input;
-}
-</pre>
-
- <p>The following table represents the approximate values that are calculated by these
- interpolators for an animation that lasts 1000ms:</p>
-
- <table>
- <tr>
- <th>ms elapsed</th>
-
- <th>Elapsed fraction/Interpolated fraction (Linear)</th>
-
- <th>Interpolated fraction (Accelerate/Decelerate)</th>
- </tr>
-
- <tr>
- <td>0</td>
-
- <td>0</td>
-
- <td>0</td>
- </tr>
-
- <tr>
- <td>200</td>
-
- <td>.2</td>
-
- <td>.1</td>
- </tr>
-
- <tr>
- <td>400</td>
-
- <td>.4</td>
-
- <td>.345</td>
- </tr>
-
- <tr>
- <td>600</td>
-
- <td>.6</td>
-
- <td>.8</td>
- </tr>
-
- <tr>
- <td>800</td>
-
- <td>.8</td>
-
- <td>.9</td>
- </tr>
-
- <tr>
- <td>1000</td>
-
- <td>1</td>
-
- <td>1</td>
- </tr>
- </table>
-
- <p>As the table shows, the {@link android.view.animation.LinearInterpolator} changes the values
- at the same speed, .2 for every 200ms that passes. The {@link
- android.view.animation.AccelerateDecelerateInterpolator} changes the values faster than {@link
- android.view.animation.LinearInterpolator} between 200ms and 600ms and slower between 600ms and
- 1000ms.</p>
-
- <h2 id="keyframes">Specifying Keyframes</h2>
-
- <p>A {@link android.animation.Keyframe} object consists of a time/value pair that lets you define
- a specific state at a specific time of an animation. Each keyframe can also have its own
- interpolator to control the behavior of the animation in the interval between the previous
- keyframe's time and the time of this keyframe.</p>
-
- <p>To instantiate a {@link android.animation.Keyframe} object, you must use one of the factory
- methods, {@link android.animation.Keyframe#ofInt ofInt()}, {@link
- android.animation.Keyframe#ofFloat ofFloat()}, or {@link android.animation.Keyframe#ofObject
- ofObject()} to obtain the appropriate type of {@link android.animation.Keyframe}. You then call
- the {@link android.animation.PropertyValuesHolder#ofKeyframe ofKeyframe()} factory method to
- obtain a {@link android.animation.PropertyValuesHolder} object. Once you have the object, you can
- obtain an animator by passing in the {@link android.animation.PropertyValuesHolder} object and
- the object to animate. The following code snippet demonstrates how to do this:</p>
- <pre>
-Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
-Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
-Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
-PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
-ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation)
-rotationAnim.setDuration(5000ms);
-</pre>
-
- <p>For a more complete example on how to use keyframes, see the <a href=
- "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/MultiPropertyAnimation.html">
- MultiPropertyAnimation</a> sample in APIDemos.</p>
-
- <h2 id="views">Animating Views</h2>
-
- <p>The property animation system allow streamlined animation of View objects and offerse
- a few advantages over the view animation system. The view
- animation system transformed View objects by changing the way that they were drawn. This was
- handled in the container of each View, because the View itself had no properties to manipulate.
- This resulted in the View being animated, but caused no change in the View object itself. This
- led to behavior such as an object still existing in its original location, even though it was
- drawn on a different location on the screen. In Android 3.0, new properties and the corresponding
- getter and setter methods were added to eliminate this drawback.</p>
- <p>The property animation system
- can animate Views on the screen by changing the actual properties in the View objects. In
- addition, Views also automatically call the {@link android.view.View#invalidate invalidate()}
- method to refresh the screen whenever its properties are changed. The new properties in the {@link
- android.view.View} class that facilitate property animations are:</p>
-
- <ul>
- <li><code>translationX</code> and <code>translationY</code>: These properties control where the
- View is located as a delta from its left and top coordinates which are set by its layout
- container.</li>
-
- <li><code>rotation</code>, <code>rotationX</code>, and <code>rotationY</code>: These properties
- control the rotation in 2D (<code>rotation</code> property) and 3D around the pivot point.</li>
-
- <li><code>scaleX</code> and <code>scaleY</code>: These properties control the 2D scaling of a
- View around its pivot point.</li>
-
- <li><code>pivotX</code> and <code>pivotY</code>: These properties control the location of the
- pivot point, around which the rotation and scaling transforms occur. By default, the pivot
- point is located at the center of the object.</li>
-
- <li><code>x</code> and <code>y</code>: These are simple utility properties to describe the
- final location of the View in its container, as a sum of the left and top values and
- translationX and translationY values.</li>
-
- <li><code>alpha</code>: Represents the alpha transparency on the View. This value is 1 (opaque)
- by default, with a value of 0 representing full transparency (not visible).</li>
- </ul>
-
- <p>To animate a property of a View object, such as its color or rotation value, all you need to
- do is create a property animator and specify the View property that you want to
- animate. For example:</p>
- <pre>
-ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);
-</pre>
-
-<p>For more information on creating animators, see the sections on animating with
-<a href="#value-animator">ValueAnimator</a> and <a href="#object-animator">ObjectAnimator</a>.
-</p>
-
-<h3 id="view-prop-animator">Animating with ViewPropertyAnimator</h3>
-<p>The {@link android.view.ViewPropertyAnimator} provides a simple way to animate several
-properties of a {@link android.view.View} in parallel, using a single underlying {@link
-android.animation.Animator}
-object. It behaves much like an {@link android.animation.ObjectAnimator}, because it modifies the
-actual values of the view's properties, but is more efficient when animating many properties at
-once. In addition, the code for using the {@link android.view.ViewPropertyAnimator} is much
-more concise and easier to read. The following code snippets show the differences in using multiple
-{@link android.animation.ObjectAnimator} objects, a single
-{@link android.animation.ObjectAnimator}, and the {@link android.view.ViewPropertyAnimator} when
-simultaneously animating the <code>x</code> and <code>y</code> property of a view.</p>
-
-<p><strong>Multiple ObjectAnimator objects</strong></p>
-<pre>
-ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
-ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
-AnimatorSet animSetXY = new AnimatorSet();
-animSetXY.playTogether(animX, animY);
-animSetXY.start();
-</pre>
-
-<p><strong>One ObjectAnimator</strong></p>
-<pre>
-PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
-PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
-ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();
-</pre>
-
-<p><strong>ViewPropertyAnimator</strong></p>
-<pre>
-myView.animate().x(50f).y(100f);
-</pre>
-
-<p>
-For more detailed information about {@link
-android.view.ViewPropertyAnimator}, see the corresponding Android Developers
-<a href="http://android-developers.blogspot.com/2011/05/introducing-viewpropertyanimator.html">blog
-post</a>.</p>
-
-<h2 id="declaring-xml">Declaring Animations in XML</h2>
-
- <p>The property animation system lets you declare property animations with XML instead of doing
- it programmatically. By defining your animations in XML, you can easily reuse your animations
-in multiple activities and more easily edit the animation sequence.</p>
-
-<p>To distinguish animation files that use the new property animation APIs from those that use the
-legacy <a href="{@docRoot}guide/topics/graphics/view-animation.html">view animation</a> framework,
-starting with Android 3.1, you should save the XML files for property animations in the {@code
-res/animator/} directory (instead of {@code res/anim/}). Using the {@code animator} directory name
-is optional, but necessary if you want to use the layout editor tools in the Eclipse ADT plugin (ADT
-11.0.0+), because ADT only searches the {@code res/animator/} directory for property animation
-resources.</p>
-
-<p>The following property animation classes have XML declaration support with the
- following XML tags:</p>
-
- <ul>
- <li>{@link android.animation.ValueAnimator} - <code><animator></code></li>
-
- <li>{@link android.animation.ObjectAnimator} - <code><objectAnimator></code></li>
-
- <li>{@link android.animation.AnimatorSet} - <code><set></code></li>
- </ul>
-
-<p>See <a href="{@docRoot}guide/topics/resources/animation-resource.html#Property">Animation Resources</a>
-
+<dt><strong><a href="{@docRoot}guide/topics/graphics/drawable-animation.html">Drawable
+Animation</a></strong></dt>
+<dd>Drawable animation involves displaying {@link android.graphics.drawable.Drawable} resources one
+after another, like a roll of film. This method of animation is useful if you want to animate
+things that are easier to represent with Drawable resources, such as a progression of bitmaps.</dd>
diff --git a/docs/html/guide/topics/graphics/drawable-animation.jd b/docs/html/guide/topics/graphics/drawable-animation.jd
new file mode 100644
index 0000000..65bf02f
--- /dev/null
+++ b/docs/html/guide/topics/graphics/drawable-animation.jd
@@ -0,0 +1,66 @@
+page.title=Drawable Animation
+parent.title=Animation
+parent.link=animation.html
+@jd:body
+
+ <p>Drawable animation lets you load a series of Drawable resources one after
+ another to create an animation. This is a traditional animation in the sense that it is created with a sequence of different
+ images, played in order, like a roll of film. The {@link
+ android.graphics.drawable.AnimationDrawable} class is the basis for Drawable animations.</p>
+
+ <p>While you can define the frames of an animation in your code, using the {@link
+ android.graphics.drawable.AnimationDrawable} class API, it's more simply accomplished with a
+ single XML file that lists the frames that compose the animation. The XML file for this kind
+ of animation belongs in the <code>res/drawable/</code> directory of
+ your Android project. In this case, the instructions are the order and duration for each frame of
+ the animation.</p>
+
+ <p>The XML file consists of an <code><animation-list></code> element as the root node and a
+ series of child <code><item></code> nodes that each define a frame: a drawable resource for
+ the frame and the frame duration. Here's an example XML file for a Drawable animation:</p>
+ <pre>
+<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
+ android:oneshot="true">
+ <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
+ <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
+ <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
+</animation-list>
+</pre>
+
+ <p>This animation runs for just three frames. By setting the <code>android:oneshot</code>
+ attribute of the list to <var>true</var>, it will cycle just once then stop and hold on the last
+ frame. If it is set <var>false</var> then the animation will loop. With this XML saved as
+ <code>rocket_thrust.xml</code> in the <code>res/drawable/</code> directory of the project, it can
+ be added as the background image to a View and then called to play. Here's an example Activity,
+ in which the animation is added to an {@link android.widget.ImageView} and then animated when the
+ screen is touched:</p>
+ <pre>
+AnimationDrawable rocketAnimation;
+
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
+ rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
+ rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
+}
+
+public boolean onTouchEvent(MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ rocketAnimation.start();
+ return true;
+ }
+ return super.onTouchEvent(event);
+}
+</pre>
+
+ <p>It's important to note that the <code>start()</code> method called on the AnimationDrawable
+ cannot be called during the <code>onCreate()</code> method of your Activity, because the
+ AnimationDrawable is not yet fully attached to the window. If you want to play the animation
+ immediately, without requiring interaction, then you might want to call it from the <code>{@link
+ android.app.Activity#onWindowFocusChanged(boolean) onWindowFocusChanged()}</code> method in your
+ Activity, which will get called when Android brings your window into focus.</p>
+
+ <p>For more information on the XML syntax, available tags and attributes, see <a href=
+ "{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
diff --git a/docs/html/guide/topics/graphics/hardware-accel.jd b/docs/html/guide/topics/graphics/hardware-accel.jd
new file mode 100644
index 0000000..c8703a5
--- /dev/null
+++ b/docs/html/guide/topics/graphics/hardware-accel.jd
@@ -0,0 +1,522 @@
+page.title=Hardware Acceleration
+parent.title=Graphics
+parent.link=index.html
+@jd:body
+
+
+ <div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+
+ <ol>
+ <li><a href="#controlling">Controlling Hardware Acceleration</a></li>
+ <li><a href="#determining">Determining if a View is Hardware Accelerated</a></li>
+ <li><a href="#model">Android Drawing Models</a>
+
+ <ol>
+ <li><a href="#software-model">Software-based drawing model</a></li>
+ <li><a href="#hardware-model">Hardware accelerated drawing model</a></li>
+ </ol>
+ </li>
+
+ <li>
+ <a href="#unsupported">Unsupported Drawing Operations</a>
+ </li>
+
+
+
+ <li>
+ <a href="#layers">View Layers</a>
+
+ <ol>
+ <li><a href="#layers-anims">View Layers and Animations</a></li>
+ </ol>
+ </li>
+
+ <li><a href="#tips">Tips and Tricks</a></li>
+ </ol>
+
+ <h2>See also</h2>
+
+ <ol>
+ <li><a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL with the Framework
+ APIs</a></li>
+
+ <li><a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a></li>
+ </ol>
+ </div>
+ </div>
+
+ <p>Beginning in Android 3.0 (API level 11), the Android 2D rendering pipeline is designed to
+ better support hardware acceleration. Hardware acceleration carries out all drawing operations
+ that are performed on a {@link android.view.View}'s canvas using the GPU.</p>
+
+ <p>The easiest way to enable hardware acceleration is to turn it on
+ globally for your entire application. If your application uses only standard views and {@link
+ android.graphics.drawable.Drawable}s, turning it on globally should not cause any adverse
+ effects. However, because hardware acceleration is not supported for all of the 2D drawing
+ operations, turning it on might affect some of your applications that use custom views or drawing
+ calls. Problems usually manifest themselves as invisible elements, exceptions, or wrongly
+ rendered pixels. To remedy this, Android gives you the option to enable or disable hardware
+ acceleration at the following levels:</p>
+
+ <ul>
+ <li>Application</li>
+
+ <li>Activity</li>
+
+ <li>Window</li>
+
+ <li>View</li>
+ </ul>
+
+ <p>If your application performs custom drawing, test your application on actual hardware
+devices with hardware acceleration turned on to find any problems. The <a
+href="#drawing-support">Unsupported drawing operations</a> section describes known issues with
+drawing operations that cannot be hardware accelerated and how to work around them.</p>
+
+
+ <h2 id="controlling">Controlling Hardware Acceleration</h2>
+ <p>You can control hardware acceleration at the following levels:</p>
+ <ul>
+ <li>Application</li>
+
+ <li>Activity</li>
+
+ <li>Window</li>
+
+ <li>View</li>
+ </ul>
+
+ <h4>Application level</h4>
+ <p>In your Android manifest file, add the following attribute to the
+ <a href="{@docRoot}guide/topics/manifest/application-element.html">
+ <code><application></code></a> tag to enable hardware acceleration for your entire
+ application:</p>
+
+<pre>
+<application android:hardwareAccelerated="true" ...>
+</pre>
+
+ <h4>Activity level</h4>
+ <p>If your application does not behave properly with hardware acceleration turned on globally,
+ you can control it for individual activities as well. To enable or disable hardware acceleration
+ at the activity level, you can use the <code>android:hardwareAccelerated</code>
+ attribute for the <a href="{@docRoot}guide/topics/manifest/activity-element.html">
+ <code><activity></code></a> element. The following example enables hardware acceleration
+for the entire application but disables it for one activity:</p>
+
+<pre>
+<application android:hardwareAccelerated="true">
+ <activity ... />
+ <activity android:hardwareAccelerated="false" />
+</application>
+</pre>
+
+ <h4>Window level</h4>
+ <p>If you need even more fine-grained control, you can enable hardware acceleration for a given
+ window with the following code:</p>
+
+<pre>
+getWindow().setFlags(
+ WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
+ WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
+
+</pre>
+
+<p class="note"><strong>Note</strong>: You currently cannot disable hardware acceleration at
+the window level.</p>
+
+ <h4>View level</h4>
+
+ <p>You can disable hardware acceleration for an individual view at runtime with the
+following code:</p>
+
+<pre>
+myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+</pre>
+
+<p class="note"><strong>Note</strong>: You currently cannot enable hardware acceleration at
+the view level. View layers have other functions besides disabling hardware acceleration. See <a
+href="#layers">View layers</a> for more information about their uses.</p>
+
+ <h2 id="determining">Determining if a View is Hardware Accelerated</h2>
+
+ <p>It is sometimes useful for an application to know whether it is currently hardware
+ accelerated, especially for things such as custom views. This is particularly useful if your
+ application does a lot of custom drawing and not all operations are properly supported by the new
+ rendering pipeline.</p>
+
+ <p>There are two different ways to check whether the application is hardware accelerated:</p>
+
+ <ul>
+ <li>{@link android.view.View#isHardwareAccelerated View.isHardwareAccelerated()} returns
+ <code>true</code> if the {@link android.view.View} is attached to a hardware accelerated
+ window.</li>
+
+ <li>{@link android.graphics.Canvas#isHardwareAccelerated Canvas.isHardwareAccelerated()}
+ returns <code>true</code> if the {@link android.graphics.Canvas} is hardware accelerated</li>
+ </ul>
+
+ <p>If you must do this check in your drawing code, use {@link
+ android.graphics.Canvas#isHardwareAccelerated Canvas.isHardwareAccelerated()} instead of {@link
+ android.view.View#isHardwareAccelerated View.isHardwareAccelerated()} when possible. When a view
+ is attached to a hardware accelerated window, it can still be drawn using a non-hardware
+ accelerated Canvas. This happens, for instance, when drawing a view into a bitmap for caching
+ purposes.</p>
+
+
+ <h2 id="model">Android Drawing Models</h2>
+
+ <p>When hardware acceleration is enabled, the Android framework utilizes a new drawing model that
+ utilizes <em>display lists</em> to render your application to the screen. To fully understand
+ display lists and how they might affect your application, it is useful to understand how Android
+ draws views without hardware acceleration as well. The following sections describe the
+ software-based and hardware-accelerated drawing models.</p>
+
+<h3>Software-based drawing model</h3>
+<p>In the software drawing model, views are drawn with the following two steps:</p>
+ <ol>
+ <li>Invalidate the hierarchy</li>
+
+ <li>Draw the hierarchy</li>
+ </ol>
+
+ <p>Whenever an application needs to update a part of its UI, it invokes {@link
+ android.view.View#invalidate invalidate()} (or one of its variants) on any view that has changed
+ content. The invalidation messages are propagated all the way up the view hierarchy to compute
+ the regions of the screen that need to be redrawn (the dirty region). The Android system then
+ draws any view in the hierarchy that intersects with the dirty region. Unfortunately, there are
+ two drawbacks to this drawing model:</p>
+ <ul>
+ <li>First, this model requires execution of a lot of code on every draw pass. For example, if
+your application calls {@link android.view.View#invalidate invalidate()} on a button and that
+button sits on top of another view, the Android system redraws the view even though it hasn't
+changed.</li>
+ <li>The second issue is that the drawing model can hide bugs in your application. Since the
+ Android system redraws views when they intersect the dirty region, a view whose content you
+ changed might be redrawn even though {@link android.view.View#invalidate invalidate()} was not
+ called on it. When this happens, you are relying on another view being invalidated to obtain the
+ proper behavior. This behavior can change every time you modify your application. Because of
+ this, you should always call {@link android.view.View#invalidate invalidate()} on your custom
+ views whenever you modify data or state that affects the view’s drawing code.</li>
+</ul>
+
+ <p class="note"><strong>Note</strong>: Android views automatically call {@link
+ android.view.View#invalidate invalidate()} when their properties change, such as the background
+ color or the text in a {@link android.widget.TextView}.</p>
+
+ <h3>Hardware accelerated drawing model</h3>
+ <p>The Android system still uses {@link android.view.View#invalidate invalidate()} and {@link
+ android.view.View#draw draw()} to request screen updates and to render views, but handles the
+ actual drawing differently. Instead of executing the drawing commands immediately, the Android
+ system records them inside display lists, which contain the output of the view hierarchy’s
+ drawing code. Another optimization is that the Android system only needs to record and update
+ display lists for views marked dirty by an {@link android.view.View#invalidate invalidate()}
+ call. Views that have not been invalidated can be redrawn simply by re-issuing the previously
+ recorded display list. The new drawing model contains three stages:</p>
+
+ <ol>
+ <li>Invalidate the hierarchy</li>
+
+ <li>Record and update display lists</li>
+
+ <li>Draw the display lists</li>
+ </ol>
+
+ <p>With this model, you cannot rely on a view intersecting the dirty region to have its {@link
+ android.view.View#draw draw()} method executed. To ensure that the Android system records a
+ view’s display list, you must call {@link android.view.View#invalidate invalidate()}. Forgetting
+ to do so causes a view to look the same even after changing it, which is an easier bug to find if
+ it happens.</p>
+
+ <p>Using display lists also benefits animation performance because setting specific properties,
+ such as alpha or rotation, does not require invalidating the targeted view (it is done
+ automatically). This optimization also applies to views with display lists (any view when your
+ application is hardware accelerated.) For example, assume there is a {@link
+ android.widget.LinearLayout} that contains a {@link android.widget.ListView} above a {@link
+ android.widget.Button}. The display list for the {@link android.widget.LinearLayout} looks like
+ this:</p>
+
+ <ul>
+ <li>DrawDisplayList(ListView)</li>
+
+ <li>DrawDisplayList(Button)</li>
+ </ul>
+
+ <p>Assume now that you want to change the {@link android.widget.ListView}'s opacity. After
+ invoking <code>setAlpha(0.5f)</code> on the {@link android.widget.ListView}, the display list now
+ contains this:</p>
+
+ <ul>
+ <li>SaveLayerAlpha(0.5)</li>
+
+ <li>DrawDisplayList(ListView)</li>
+
+ <li>Restore</li>
+
+ <li>DrawDisplayList(Button)</li>
+ </ul>
+
+ <p>The complex drawing code of {@link android.widget.ListView} was not executed. Instead, the
+ system only updated the display list of the much simpler {@link android.widget.LinearLayout}. In
+ an application without hardware acceleration enabled, the drawing code of both the list and its
+ parent are executed again.</p>
+
+ <h2 id="unsupported">Unsupported Drawing Operations</h2>
+
+ <p>When hardware accelerated, the 2D rendering pipeline supports the most commonly used {@link
+ android.graphics.Canvas} drawing operations as well as many less-used operations. All of the
+ drawing operations that are used to render applications that ship with Android, default widgets
+ and layouts, and common advanced visual effects such as reflections and tiled textures are
+ supported. The following list describes known operations that are <strong>not supported</strong>
+ with hardware acceleration:</p>
+
+ <ul>
+ <li>
+ <strong>Canvas</strong>
+
+ <ul>
+ <li>{@link android.graphics.Canvas#clipPath clipPath()}</li>
+
+ <li>{@link android.graphics.Canvas#clipRegion clipRegion()}</li>
+
+ <li>{@link android.graphics.Canvas#drawPicture drawPicture()}</li>
+
+ <li>{@link android.graphics.Canvas#drawPosText drawPosText()}</li>
+
+ <li>{@link android.graphics.Canvas#drawTextOnPath drawTextOnPath()}</li>
+
+ <li>{@link android.graphics.Canvas#drawVertices drawVertices()}</li>
+ </ul>
+ </li>
+
+ <li>
+ <strong>Paint</strong>
+
+ <ul>
+ <li>{@link android.graphics.Paint#setLinearText setLinearText()}</li>
+
+ <li>{@link android.graphics.Paint#setMaskFilter setMaskFilter()}</li>
+
+ <li>{@link android.graphics.Paint#setRasterizer setRasterizer()}</li>
+ </ul>
+ </li>
+ </ul>
+
+ <p>In addition, some operations behave differently with hardware acceleration enabled:</p>
+
+ <ul>
+ <li>
+ <strong>Canvas</strong>
+
+ <ul>
+ <li>{@link android.graphics.Canvas#clipRect clipRect()}: <code>XOR</code>,
+ <code>Difference</code> and <code>ReverseDifference</code> clip modes are ignored. 3D
+ transforms do not apply to the clip rectangle</li>
+
+ <li>{@link android.graphics.Canvas#drawBitmapMesh drawBitmapMesh()}: colors array is
+ ignored</li>
+
+ <li>{@link android.graphics.Canvas#drawLines drawLines()}: anti-aliasing is not
+ supported</li>
+
+ <li>{@link android.graphics.Canvas#setDrawFilter setDrawFilter()}: can be set, but is
+ ignored</li>
+ </ul>
+ </li>
+
+ <li>
+ <strong>Paint</strong>
+
+ <ul>
+ <li>{@link android.graphics.Paint#setDither setDither()}: ignored</li>
+
+ <li>{@link android.graphics.Paint#setFilterBitmap setFilterBitmap()}: filtering is always
+ on</li>
+
+ <li>{@link android.graphics.Paint#setShadowLayer setShadowLayer()}: works with text
+ only</li>
+ </ul>
+ </li>
+
+ <li>
+ <strong>ComposeShader</strong>
+
+ <ul>
+ <li>{@link android.graphics.ComposeShader} can only contain shaders of different types (a
+ {@link android.graphics.BitmapShader} and a {@link android.graphics.LinearGradient} for
+ instance, but not two instances of {@link android.graphics.BitmapShader} )</li>
+
+ <li>{@link android.graphics.ComposeShader} cannot contain a {@link
+ android.graphics.ComposeShader}</li>
+ </ul>
+ </li>
+ </ul>
+
+ <p>If your application is affected by any of these missing features or limitations, you can turn
+ off hardware acceleration for just the affected portion of your application by calling
+ {@link android.view.View#setLayerType setLayerType(View.LAYER_TYPE_SOFTWARE, null)}. This way,
+you can still take advantage of hardware acceleratin everywhere else. See <a
+href="#controlling">Controlling Hardware Acceleration</a> for more information on how to enable and
+disable hardware acceleration at different levels in your application.
+
+
+
+ <h2 id="layers">View Layers</h2>
+
+ <p>In all versions of Android, views have had the ability to render into off-screen buffers,
+either by using a view's drawing cache, or by using {@link android.graphics.Canvas#saveLayer
+ Canvas.saveLayer()}. Off-screen buffers, or layers, have several uses. You can use them to get
+ better performance when animating complex views or to apply composition effects. For instance,
+ you can implement fade effects using <code>Canvas.saveLayer()</code> to temporarily render a view
+ into a layer and then composite it back on screen with an opacity factor.</p>
+
+ <p>Beginning in Android 3.0 (API level 11), you have more control on how and when to use layers
+ with the {@link android.view.View#setLayerType View.setLayerType()} method. This API takes two
+ parameters: the type of layer you want to use and an optional {@link android.graphics.Paint}
+ object that describes how the layer should be composited. You can use the {@link
+ android.graphics.Paint} parameter to apply color filters, special blending modes, or opacity to a
+ layer. A view can use one of three layer types:</p>
+
+ <ul>
+ <li>{@link android.view.View#LAYER_TYPE_NONE}: The view is rendered normally and is not backed
+ by an off-screen buffer. This is the default behavior.</li>
+
+ <li>{@link android.view.View#LAYER_TYPE_HARDWARE}: The view is rendered in hardware into a
+ hardware texture if the application is hardware accelerated. If the application is not hardware
+ accelerated, this layer type behaves the same as {@link
+ android.view.View#LAYER_TYPE_SOFTWARE}.</li>
+
+ <li>{@link android.view.View#LAYER_TYPE_SOFTWARE}: The view is rendered in software into a
+ bitmap.</li>
+ </ul>
+
+ <p>The type of layer you use depends on your goal:</p>
+
+ <ul>
+ <li><strong>Performance</strong>: Use a hardware layer type to render a view into a hardware
+ texture. Once a view is rendered into a layer, its drawing code does not have to be executed
+ until the view calls {@link android.view.View#invalidate invalidate()}. Some animations, such as
+ alpha animations, can then be applied directly onto the layer, which is very efficient
+ for the GPU to do.</li>
+
+ <li><strong>Visual effects</strong>: Use a hardware or software layer type and a {@link
+ android.graphics.Paint} to apply special visual treatments to a view. For instance, you can
+ draw a view in black and white using a {@link
+ android.graphics.ColorMatrixColorFilter}.</li>
+
+ <li><strong>Compatibility</strong>: Use a software layer type to force a view to be rendered in
+ software. If a view that is hardware accelerated (for instance, if your whole
+ application is hardware acclerated), is having rendering problems, this is an easy way to work
+around limitations of the hardware rendering
+ pipeline.</li>
+ </ul>
+
+ <h3 id="layers-anims">View layers and animations</h3>
+
+ <p>Hardware layers can deliver faster and smoother animations when your application
+is hardware accelerated. Running an animation at 60 frames per second is not always possible when
+animating complex views that issue a lot of drawing operations. This can be alleviated by
+using hardware layers to render the view to a hardware texture. The hardware texture can
+then be used to animate the view, eliminating the need for the view to constantly redraw itself
+when it is being animated. The view is not redrawn unless you change the view's
+properties, which calls {@link android.view.View#invalidate invalidate()}, or if you call {@link
+android.view.View#invalidate invalidate()} manually. If you are running an animation in
+your application and do not obtain the smooth results you want, consider enabling hardware layers on
+your animated views.</p>
+
+ <p>When a view is backed by a hardware layer, some of its properties are handled by the way the
+ layer is composited on screen. Setting these properties will be efficient because they do not
+ require the view to be invalidated and redrawn. The following list of properties affect the way
+ the layer is composited. Calling the setter for any of these properties results in optimal
+ invalidation and no redrawing of the targeted view:</p>
+
+ <ul>
+ <li><code>alpha</code>: Changes the layer's opacity</li>
+
+ <li><code>x</code>, <code>y</code>, <code>translationX</code>, <code>translationY</code>:
+Changes the layer's position</li>
+
+ <li><code>scaleX</code>, <code>scaleY</code>: Changes the layer's size</li>
+
+ <li><code>rotation</code>, <code>rotationX</code>, <code>rotationY</code>: Changes the
+ layer's orientation in 3D space</li>
+
+ <li><code>pivotX</code>, <code>pivotY</code>: Changes the layer's transformations origin</li>
+ </ul>
+
+ <p>These properties are the names used when animating a view with an {@link
+ android.animation.ObjectAnimator}. If you want to access these properties, call the appropriate
+ setter or getter. For instance, to modify the alpha property, call {@link
+ android.view.View#setAlpha setAlpha()}. The following code snippet shows the most efficient way
+ to rotate a viewiew in 3D around the Y-axis:</p>
+ <pre>
+view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ObjectAnimator.ofFloat(view, "rotationY", 180).start();
+</pre>
+
+ <p>Because hardware layers consume video memory, it is highly recommended that you enable them
+only for the duration of the animation and then disable them after the animation is done. You
+can accomplish this using animation listeners:</p>
+ <pre>
+View.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationY", 180);
+animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ view.setLayerType(View.LAYER_TYPE_NONE, null);
+ }
+});
+animator.start();
+</pre>
+
+ <p>For more information on property animation, see <a href=
+ "{@docRoot}guide/topics/graphics/prop-animation.html">Property Animation</a>.</p>
+
+ <h2 id="tips">Tips and Tricks</h2>
+
+ <p>Switching to hardware accelerated 2D graphics can instantly increase performance, but you
+ should still design your application to use the GPU effectively by following these
+ recommendations:</p>
+
+ <dl>
+ <dt><strong>Reduce the number of views in your application</strong></dt>
+
+ <dd>The more views the system has to draw, the slower it will be. This applies to the software
+ rendering pipeline as well. Reducing views is one of the easiest ways to optimize your UI.</dd>
+
+ <dt><strong>Avoid overdraw</strong></dt>
+
+ <dd>Do not draw too many layers on top of each other. Remove any views that are completely
+ obscured by other opaque views on top of it. If you need to draw several layers blended on top
+ of each other, consider merging them into a single layer. A good rule of thumb with current
+ hardware is to not draw more than 2.5 times the number of pixels on screen per frame
+ (transparent pixels in a bitmap count!).</dd>
+
+ <dt><strong>Don't create render objects in draw methods</strong></dt>
+
+ <dd>A common mistake is to create a new {@link android.graphics.Paint} or a new {@link
+android.graphics.Path} every time a rendering method is invoked. This forces the garbage
+collector to run more often and also bypasses caches and optimizations in the hardware
+pipeline.</dd>
+
+ <dt><strong>Don't modify shapes too often</strong></dt>
+
+ <dd>Complex shapes, paths, and circles for instance, are rendered using texture masks. Every
+ time you create or modify a path, the hardware pipeline creates a new mask, which can be
+ expensive.</dd>
+
+ <dt><strong>Don't modify bitmaps too often</strong></dt>
+
+ <dd>Every time you change the content of a bitmap, it is uploaded again as a GPU texture the
+ next time you draw it.</dd>
+
+ <dt><strong>Use alpha with care</strong></dt>
+
+ <dd>When you make a view translucent using {@link android.view.View#setAlpha setAlpha()},
+ {@link android.view.animation.AlphaAnimation}, or {@link android.animation.ObjectAnimator}, it
+ is rendered in an off-screen buffer which doubles the required fill-rate. When applying alpha
+ on very large views, consider setting the view's layer type to
+ <code>LAYER_TYPE_HARDWARE</code>.</dd>
+ </dl>
diff --git a/docs/html/guide/topics/graphics/index.jd b/docs/html/guide/topics/graphics/index.jd
index f0a923a..ab623c2 100644
--- a/docs/html/guide/topics/graphics/index.jd
+++ b/docs/html/guide/topics/graphics/index.jd
@@ -3,208 +3,49 @@
<div id="qv-wrapper">
<div id="qv">
- <h2>In this document</h2>
+ <h2>Topics</h2>
<ol>
- <li><a href="#options">Consider your Options</a></li>
- <li><a href="#draw-to-view">Simple Graphics Inside a View</a></li>
- <li><a href="#draw-with-canvas">Draw with a Canvas</a>
- <ol>
- <li><a href="#on-view">On a View</a></li>
- <li><a href="#on-surfaceview">On a SurfaceView</a></li>
- </ol>
- </li>
- </ol>
- <h2>See also</h2>
- <ol>
- <li><a href="{@docRoot}guide/topics/graphics/opengl.html">3D with OpenGL</a></li>
- <li><a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a></li>
+ <li><a href="{@docRoot}guide/topics/graphics/2d-graphics.html">Canvas and Drawables</a></li>
+ <li><a href="{@docRoot}guide/topics/graphics/hardware-accel.html">Hardware Acceleration</a></li>
+ <li><a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL</a></li>
</ol>
</div>
</div>
-<p>Android graphics are powered by a custom 2D graphics library, and the framework provides
-support for high performance 3D graphics in the form of OpenGL ES and RenderScript. The most
-common 2D graphics APIs can be found in the {@link android.graphics.drawable drawable package}.
-OpenGL APIs are available from the Khronos {@link javax.microedition.khronos.opengles OpenGL ES} and
-the {@link android.opengl} packages. The RenderScript APIs are available in the
-{@link android.renderscript} package.</p>
-
-<p>When starting a project, it's important to consider exactly what your graphical demands will be.
+<p>When writing an application, it's important to consider exactly what your graphical demands will be.
Varying graphical tasks are best accomplished with varying techniques. For example, graphics and animations
for a rather static application should be implemented much differently than graphics and animations
-for an interactive game or 3D rendering.</p>
-
-<p>Here, we'll discuss a few of the options you have for drawing graphics on Android,
-and which tasks they're best suited for.</p>
-
-<p>If you're specifically looking for information on drawing 3D graphics, this page won't
-help a lot. However, the information below about how to <a href="#draw-with-canvas">Draw with a
-Canvas</a> (and the section on SurfaceView), will give you a quick idea of how you should draw to
-the View hierarchy. For more information on Android's 3D graphics APIs, see
-the <a href="opengl.html">3D with OpenGL</a> and
-<a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> documents.</p>
-
-
-<h2 id="options">Consider your Options</h2>
-
-<p>When drawing 2D graphics, you'll typically do so in one of two ways:</p>
-<ol type="a">
- <li>Draw your graphics or animations into a View object from your layout. In this manner,
- the drawing (and any animation) of your graphics is handled by the system's
- normal View hierarchy drawing process — you simply define the graphics to go inside the View.</li>
- <li>Draw your graphics directly to a Canvas. This way, you personally call the appropriate class's
- <code>draw()</code> method (passing it your Canvas), or one of the Canvas <code>draw...()</code> methods (like
- <code>{@link android.graphics.Canvas#drawPicture(Picture,Rect) drawPicture()}</code>). In doing so, you are also in
- control of any animation.</li>
-</ol>
-
-<p>Option "a," drawing to a View, is your best choice when you want to draw simple graphics that do not
-need to change dynamically and are not part of a performance-intensive game. For example, you should
-draw your graphics into a View when you want to display a static graphic or predefined animation, within
-an otherwise static application. Read <a href="#draw-to-view">Simple Graphics Inside a View</a>.</li>
-
-<p>Option "b," drawing to a Canvas, is better when your application needs to regularly re-draw itself.
-Basically, any video game should be drawing to the Canvas on its own. However, there's more than
-one way to do this: </p>
-<ul>
- <li>In the same thread as your UI Activity, wherein you create a custom View component in
- your layout, call <code>{@link android.view.View#invalidate()}</code> and then handle the
- <code>{@link android.view.View#onDraw(Canvas) onDraw()}</code> callback..</li>
- <li>Or, in a separate thread, wherein you manage a {@link android.view.SurfaceView} and
- perform draws to the Canvas as fast as your thread is capable
- (you do not need to request <code>invalidate()</code>).</li>
-</ul>
-<p>...Begin by reading <a href="#draw-with-canvas">Draw with a Canvas</a>.</p>
-
-<h2 id="draw-to-view">Simple Graphics Inside a View</h2>
-
-<p>If you'll be drawing some simple graphics (images, shapes, colors, pre-defined animations, etc.),
-then you should probably just draw to the background of a View or
-to the content of an {@link android.widget.ImageView} in your layout.
-In this case, you can skip the rest of this document and learn how to
-draw graphics and animations in the <a href="2d-graphics.html">2D Graphics</a> document.
+for an interactive game. Here, we'll discuss a few of the options you have for drawing graphics
+on Android and which tasks they're best suited for.
</p>
+<dl>
+<dt><strong><a href="{@docRoot}guide/topics/graphics/2d-graphics.html">Canvas and
+Drawables</a></strong></dt>
+<dd>Android provides a set of {@link android.view.View} widgets that provide general functionality
+for a wide array of user interfaces. You can also extend these widgets to modify the way they
+look or behave. In addition, you can do your own custom 2D rendering using the various drawing
+methods contained in the {@link android.graphics.Canvas} class or create {@link
+android.graphics.drawable.Drawable} objects for things such as textured buttons or frame-by-frame
+animations.</dd>
-<h2 id="draw-with-canvas">Draw with a Canvas</h2>
+<dt><strong><a href="{@docRoot}guide/topics/graphics/hardware-accel.html">Hardware
+Acceleration</a></strong></dt>
+<dd>Beginning in Android 3.0, you can hardware accelerate the majority of
+the drawing done by the Canvas APIs to further increase their performance.</dd>
-<p>When you're writing an application in which you would like to perform specialized drawing
-and/or control the animation of graphics,
-you should do so by drawing through a {@link android.graphics.Canvas}. A Canvas works for you as
-a pretense, or interface, to the actual surface upon which your graphics will be drawn — it
-holds all of your "draw" calls. Via the Canvas, your drawing is actually performed upon an
-underlying {@link android.graphics.Bitmap}, which is placed into the window.</p>
-
-<p>In the event that you're drawing within the <code>{@link android.view.View#onDraw(Canvas) onDraw()}</code>
-callback method, the Canvas is provided for you and you need only place your drawing calls upon it.
-You can also acquire a Canvas from <code>{@link android.view.SurfaceHolder#lockCanvas() SurfaceHolder.lockCanvas()}</code>,
-when dealing with a SurfaceView object. (Both of these scenarios are discussed in the following sections.)
-However, if you need to create a new Canvas, then you must define the {@link android.graphics.Bitmap}
-upon which drawing will actually be performed. The Bitmap is always required for a Canvas. You can set up
-a new Canvas like this:</p>
-<pre>
-Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
-Canvas c = new Canvas(b);
-</pre>
-
-<p>Now your Canvas will draw onto the defined Bitmap. After drawing upon it with the Canvas, you can then carry your
-Bitmap to another Canvas with one of the <code>{@link android.graphics.Canvas#drawBitmap(Bitmap,Matrix,Paint)
-Canvas.drawBitmap(Bitmap,...)}</code> methods. It's recommended that you ultimately draw your final
-graphics through a Canvas offered to you
-by <code>{@link android.view.View#onDraw(Canvas) View.onDraw()}</code> or
-<code>{@link android.view.SurfaceHolder#lockCanvas() SurfaceHolder.lockCanvas()}</code> (see the following sections).</p>
-
-<p>The {@link android.graphics.Canvas} class has its own set of drawing methods that you can use,
-like <code>drawBitmap(...)</code>, <code>drawRect(...)</code>, <code>drawText(...)</code>, and many more.
-Other classes that you might use also have <code>draw()</code> methods. For example, you'll probably
-have some {@link android.graphics.drawable.Drawable} objects that you want to put on the Canvas. Drawable
-has its own <code>{@link android.graphics.drawable.Drawable#draw(Canvas) draw()}</code> method
-that takes your Canvas as an argument.</p>
-
-
-<h3 id="on-view">On a View</h3>
-
-<p>If your application does not require a significant amount of processing or
-frame-rate speed (perhaps for a chess game, a snake game,
-or another slowly-animated application), then you should consider creating a custom View component
-and drawing with a Canvas in <code>{@link android.view.View#onDraw(Canvas) View.onDraw()}</code>.
-The most convenient aspect of doing so is that the Android framework will
-provide you with a pre-defined Canvas to which you will place your drawing calls.</p>
-
-<p>To start, extend the {@link android.view.View} class (or descendant thereof) and define
-the <code>{@link android.view.View#onDraw(Canvas) onDraw()}</code> callback method. This method will be called by the Android
-framework to request that your View draw itself. This is where you will perform all your calls
-to draw through the {@link android.graphics.Canvas}, which is passed to you through the <code>onDraw()</code> callback.</p>
-
-<p>The Android framework will only call <code>onDraw()</code> as necessary. Each time that
-your application is prepared to be drawn, you must request your View be invalidated by calling
-<code>{@link android.view.View#invalidate()}</code>. This indicates that you'd like your View to be drawn and
-Android will then call your <code>onDraw()</code> method (though is not guaranteed that the callback will
-be instantaneous). </p>
-
-<p>Inside your View component's <code>onDraw()</code>, use the Canvas given to you for all your drawing,
-using various <code>Canvas.draw...()</code> methods, or other class <code>draw()</code> methods that
-take your Canvas as an argument. Once your <code>onDraw()</code> is complete, the Android framework will
-use your Canvas to draw a Bitmap handled by the system.</p>
-
-<p class="note"><strong>Note: </strong> In order to request an invalidate from a thread other than your main
-Activity's thread, you must call <code>{@link android.view.View#postInvalidate()}</code>.</p>
-
-<p>Also read <a href="{@docRoot}guide/topics/ui/custom-components.html">Custom Components</a>
-for a guide to extending a View class, and <a href="2d-graphics.html">2D Graphics: Drawables</a> for
-information on using Drawable objects like images from your resources and other primitive shapes.</p>
-
-<p>For a sample application, see the Snake game, in the SDK samples folder:
-<code><your-sdk-directory>/samples/Snake/</code>.</p>
-
-<h3 id="on-surfaceview">On a SurfaceView</h3>
-
-<p>The {@link android.view.SurfaceView} is a special subclass of View that offers a dedicated
-drawing surface within the View hierarchy. The aim is to offer this drawing surface to
-an application's secondary thread, so that the application isn't required
-to wait until the system's View hierarchy is ready to draw. Instead, a secondary thread
-that has reference to a SurfaceView can draw to its own Canvas at its own pace.</p>
-
-<p>To begin, you need to create a new class that extends {@link android.view.SurfaceView}. The class should also
-implement {@link android.view.SurfaceHolder.Callback}. This subclass is an interface that will notify you
-with information about the underlying {@link android.view.Surface}, such as when it is created, changed, or destroyed.
-These events are important so that you know when you can start drawing, whether you need
-to make adjustments based on new surface properties, and when to stop drawing and potentially
-kill some tasks. Inside your SurfaceView class is also a good place to define your secondary Thread class, which will
-perform all the drawing procedures to your Canvas.</p>
-
-<p>Instead of handling the Surface object directly, you should handle it via
-a {@link android.view.SurfaceHolder}. So, when your SurfaceView is initialized, get the SurfaceHolder by calling
-<code>{@link android.view.SurfaceView#getHolder()}</code>. You should then notify the SurfaceHolder that you'd
-like to receive SurfaceHolder callbacks (from {@link android.view.SurfaceHolder.Callback}) by calling
-{@link android.view.SurfaceHolder#addCallback(SurfaceHolder.Callback) addCallback()}
-(pass it <var>this</var>). Then override each of the
-{@link android.view.SurfaceHolder.Callback} methods inside your SurfaceView class.</p>
-
-<p>In order to draw to the Surface Canvas from within your second thread, you must pass the thread your SurfaceHandler
-and retrieve the Canvas with <code>{@link android.view.SurfaceHolder#lockCanvas() lockCanvas()}</code>.
-You can now take the Canvas given to you by the SurfaceHolder and do your necessary drawing upon it.
-Once you're done drawing with the Canvas, call
-<code>{@link android.view.SurfaceHolder#unlockCanvasAndPost(Canvas) unlockCanvasAndPost()}</code>, passing it
-your Canvas object. The Surface will now draw the Canvas as you left it. Perform this sequence of locking and
-unlocking the canvas each time you want to redraw.</p>
-
-<p class="note"><strong>Note:</strong> On each pass you retrieve the Canvas from the SurfaceHolder,
-the previous state of the Canvas will be retained. In order to properly animate your graphics, you must re-paint the
-entire surface. For example, you can clear the previous state of the Canvas by filling in a color
-with <code>{@link android.graphics.Canvas#drawColor(int) drawColor()}</code> or setting a background image
-with <code>{@link android.graphics.Canvas#drawBitmap(Bitmap,Rect,RectF,Paint) drawBitmap()}</code>. Otherwise,
-you will see traces of the drawings you previously performed.</p>
-
-
-<p>For a sample application, see the Lunar Lander game, in the SDK samples folder:
-<code><your-sdk-directory>/samples/LunarLander/</code>. Or,
-browse the source in the <a href="{@docRoot}guide/samples/index.html">Sample Code</a> section.</p>
-
-
-
-
-
-
+<dt><strong><a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL</a></strong></dt>
+<dd>Android supports OpenGL ES 1.0 and 2.0, with Android framework APIs as well as natively
+with the Native Development Kit (NDK). Using the framework APIs is desireable when you want to add a
+few graphical enhancements to your application that are not supported with the Canvas APIs, or if
+you desire platform independence and don't demand high performance. There is a performance hit in
+using the framework APIs compared to the NDK, so for many graphic intensive applications such as
+games, using the NDK is beneficial (It is important to note though that you can still get adequate
+performance using the framework APIs. For example, the Google Body app is developed entirely
+using the framework APIs). OpenGL with the NDK is also useful if you have a lot of native
+code that you want to port over to Android. For more information about using the NDK, read the
+docs in the <code>docs/</code> directory of the <a href="{@docRoot}sdk/ndk/index.html">NDK
+download.</a></dd>
+</dl>
diff --git a/docs/html/guide/topics/graphics/opengl.jd b/docs/html/guide/topics/graphics/opengl.jd
index b750858..6a2a20f 100644
--- a/docs/html/guide/topics/graphics/opengl.jd
+++ b/docs/html/guide/topics/graphics/opengl.jd
@@ -1,4 +1,4 @@
-page.title=3D with OpenGL
+page.title=OpenGL
parent.title=Graphics
parent.link=index.html
@jd:body
@@ -6,7 +6,7 @@
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
-
+
<ol>
<li><a href="#basics">The Basics</a>
<ol>
@@ -14,7 +14,7 @@
</ol>
<li><a href="#manifest">Declaring OpenGL Requirements</a></li>
</li>
- <li><a href="#coordinate-mapping">Mapping Coordinates for Drawn Objects</a>
+ <li><a href="#coordinate-mapping">Mapping Coordinates for Drawn Objects</a>
<ol>
<li><a href="#proj-es1">Projection and camera in ES 1.0</a></li>
<li><a href="#proj-es1">Projection and camera in ES 2.0</a></li>
@@ -40,14 +40,11 @@
</ol>
<h2>Related samples</h2>
<ol>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
-GLSurfaceViewActivity.html">GLSurfaceViewActivity</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
-GLES20Activity.html">GLES20Activity</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
-TouchRotateActivity.html">TouchRotateActivity</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
-CompressedTextureActivity.html">Compressed Textures</a></li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/GLSurfaceViewActivity.html">GLSurfaceViewActivity</a></li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/GLES20Activity.html">GLES20Activity</a></li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.html">TouchRotateActivity</a></li>
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/CompressedTextureActivity.html">Compressed Textures</a></li>
</ol>
<h2>See also</h2>
<ol>
@@ -78,8 +75,7 @@
Kit (NDK). This topic focuses on the Android framework interfaces. For more information about the
NDK, see the <a href="{@docRoot}sdk/ndk/index.html">Android NDK</a>.
-<p>
- There are two foundational classes in the Android framework that let you create and manipulate
+<p>There are two foundational classes in the Android framework that let you create and manipulate
graphics with the OpenGL ES API: {@link android.opengl.GLSurfaceView} and {@link
android.opengl.GLSurfaceView.Renderer}. If your goal is to use OpenGL in your Android application,
understanding how to implement these classes in an activity should be your first objective.
@@ -89,22 +85,22 @@
<dt><strong>{@link android.opengl.GLSurfaceView}</strong></dt>
<dd>This class is a {@link android.view.View} where you can draw and manipulate objects using
OpenGL API calls and is similar in function to a {@link android.view.SurfaceView}. You can use
- this class by creating an instance of {@link android.opengl.GLSurfaceView} and adding your
+ this class by creating an instance of {@link android.opengl.GLSurfaceView} and adding your
{@link android.opengl.GLSurfaceView.Renderer Renderer} to it. However, if you want to capture
touch screen events, you should extend the {@link android.opengl.GLSurfaceView} class to
- implement the touch listeners, as shown in OpenGL Tutorials for
- <a href="{@docRoot}resources/tutorials/opengl/opengl-es10.html#touch">ES 1.0</a>,
+ implement the touch listeners, as shown in OpenGL Tutorials for
+ <a href="{@docRoot}resources/tutorials/opengl/opengl-es10.html#touch">ES 1.0</a>,
<a href="{@docRoot}resources/tutorials/opengl/opengl-es20.html#touch">ES 2.0</a> and the <a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity
-.html">TouchRotateActivity</a> sample.</dd>
-
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.html"
+>TouchRotateActivity</a> sample.</dd>
+
<dt><strong>{@link android.opengl.GLSurfaceView.Renderer}</strong></dt>
<dd>This interface defines the methods required for drawing graphics in an OpenGL {@link
android.opengl.GLSurfaceView}. You must provide an implementation of this interface as a
separate class and attach it to your {@link android.opengl.GLSurfaceView} instance using
{@link android.opengl.GLSurfaceView#setRenderer(android.opengl.GLSurfaceView.Renderer)
GLSurfaceView.setRenderer()}.
-
+
<p>The {@link android.opengl.GLSurfaceView.Renderer} interface requires that you implement the
following methods:</p>
<ul>
@@ -129,7 +125,7 @@
android.opengl.GLSurfaceView} geometry changes, including changes in size of the {@link
android.opengl.GLSurfaceView} or orientation of the device screen. For example, the system calls
this method when the device changes from portrait to landscape orientation. Use this method to
- respond to changes in the {@link android.opengl.GLSurfaceView} container.
+ respond to changes in the {@link android.opengl.GLSurfaceView} container.
</li>
</ul>
</dd>
@@ -173,13 +169,13 @@
</ul>
<p>If you'd like to start building an app with OpenGL right away, have a look at the tutorials for
-<a href="{@docRoot}resources/tutorials/opengl/opengl-es10.html">OpenGL ES 1.0</a> or
+<a href="{@docRoot}resources/tutorials/opengl/opengl-es10.html">OpenGL ES 1.0</a> or
<a href="{@docRoot}resources/tutorials/opengl/opengl-es20.html">OpenGL ES 2.0</a>!
</p>
<h2 id="manifest">Declaring OpenGL Requirements</h2>
<p>If your application uses OpenGL features that are not available on all devices, you must include
-these requirements in your <a
+these requirements in your <a
href="{@docRoot}guide/topics/manifest/manifest-intro.html">AndroidManifest.xml</a></code> file.
Here are the most common OpenGL manifest declarations:</p>
@@ -200,14 +196,14 @@
compression formats, you must declare the formats your application supports in your manifest file
using <a href="{@docRoot}guide/topics/manifest/supports-gl-texture-element.html">{@code
<supports-gl-texture>}</a>. For more information about available texture compression
-formats, see <a href="#textures">Texture compression support</a>.
+formats, see <a href="#textures">Texture compression support</a>.
<p>Declaring texture compression requirements in your manifest hides your application from users
with devices that do not support at least one of your declared compression types. For more
information on how Android Market filtering works for texture compressions, see the <a
href="{@docRoot}guide/topics/manifest/supports-gl-texture-element.html#market-texture-filtering">
Android Market and texture compression filtering</a> section of the {@code
-<supports-gl-texture>} documentation.</p>
+<supports-gl-texture>} documentation.</p>
</li>
</ul>
@@ -237,7 +233,7 @@
<h3 id="proj-es1">Projection and camera view in OpenGL ES 1.0</h3>
<p>In the ES 1.0 API, you apply projection and camera view by creating each matrix and then
adding them to the OpenGL environment.</p>
-
+
<ol>
<li><strong>Projection matrix</strong> - Create a projection matrix using the geometry of the
device screen in order to recalculate object coordinates so they are drawn with correct proportions.
@@ -250,19 +246,19 @@
<pre>
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
-
+
// make adjustments for screen ratio
float ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION); // set matrix to projection mode
gl.glLoadIdentity(); // reset the matrix to its default state
gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7); // apply the projection matrix
- }
+ }
</pre>
</li>
<li><strong>Camera transformation matrix</strong> - Once you have adjusted the coordinate system
using a projection matrix, you must also apply a camera view. The following example code shows how
-to modify the {@link
+to modify the {@link
android.opengl.GLSurfaceView.Renderer#onDrawFrame(javax.microedition.khronos.opengles.GL10)
onDrawFrame()} method of a {@link android.opengl.GLSurfaceView.Renderer}
implementation to apply a model view and use the
@@ -276,12 +272,12 @@
// Set GL_MODELVIEW transformation mode
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity(); // reset the matrix to its default state
-
+
// When using GL_MODELVIEW, you must set the camera view
- GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+ GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
...
}
-</pre>
+</pre>
</li>
</ol>
@@ -294,26 +290,26 @@
<p>In the ES 2.0 API, you apply projection and camera view by first adding a matrix member to
the vertex shaders of your graphics objects. With this matrix member added, you can then
generate and apply projection and camera viewing matrices to your objects.</p>
-
+
<ol>
<li><strong>Add matrix to vertex shaders</strong> - Create a variable for the view projection matrix
and include it as a multiplier of the shader's position. In the following example vertex shader
-code, the included {@code uMVPMatrix} member allows you to apply projection and camera viewing
+code, the included {@code uMVPMatrix} member allows you to apply projection and camera viewing
matrices to the coordinates of objects that use this shader.
<pre>
- private final String vertexShaderCode =
-
+ private final String vertexShaderCode =
+
// This matrix member variable provides a hook to manipulate
// the coordinates of objects that use this vertex shader
"uniform mat4 uMVPMatrix; \n" +
-
+
"attribute vec4 vPosition; \n" +
"void main(){ \n" +
-
+
// the matrix must be included as part of gl_Position
" gl_Position = uMVPMatrix * vPosition; \n" +
-
+
"} \n";
</pre>
<p class="note"><strong>Note:</strong> The example above defines a single transformation matrix
@@ -340,7 +336,7 @@
</li>
<li><strong>Create projection and camera viewing matrices</strong> - Generate the projection and
viewing matrices to be applied the graphic objects. The following example code shows how to modify
-the {@link
+the {@link
android.opengl.GLSurfaceView.Renderer#onSurfaceCreated(javax.microedition.khronos.opengles.GL10,
javax.microedition.khronos.egl.EGLConfig) onSurfaceCreated()} and {@link
android.opengl.GLSurfaceView.Renderer#onSurfaceChanged(javax.microedition.khronos.opengles.GL10,
@@ -353,16 +349,16 @@
...
// Create a camera view matrix
Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
- }
-
+ }
+
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
-
+
float ratio = (float) width / height;
-
+
// create a projection matrix from device screen geometry
Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
- }
+ }
</pre>
</li>
@@ -373,16 +369,16 @@
onDrawFrame()} method of a {@link android.opengl.GLSurfaceView.Renderer} implementation to combine
the projection matrix and camera view created in the code above and then apply it to the graphic
objects to be rendered by OpenGL.
-
+
<pre>
public void onDrawFrame(GL10 unused) {
...
// Combine the projection and camera view matrices
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
-
+
// Apply the combined projection and camera view transformations
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
-
+
// Draw objects
...
}
@@ -411,9 +407,8 @@
android.opengl.ETC1Util} utility class and the {@code etc1tool} compression tool (located in the
Android SDK at {@code <sdk>/tools/}). For an example of an Android application that uses
texture compression, see the <a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
-CompressedTextureActivity.html">CompressedTextureActivity</a> code sample.
-</p>
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/CompressedTextureActivity.html"
+>CompressedTextureActivity</a> code sample.</p>
<p>To check if the ETC1 format is supported on a device, call the {@link
android.opengl.ETC1Util#isETC1Supported() ETC1Util.isETC1Supported()} method.</p>
@@ -498,7 +493,7 @@
supported.</p>
</li>
<li>Review the output of this method to determine what OpenGL extensions are supported on the
-device.</li>
+device.</li>
</ol>
@@ -514,7 +509,7 @@
than the ES 1.0/1.1 APIs. However, the performance difference can vary depending on the Android
device your OpenGL application is running on, due to differences in the implementation of the OpenGL
graphics pipeline.</li>
- <li><strong>Device Compatibility</strong> - Developers should consider the types of devices,
+ <li><strong>Device Compatibility</strong> - Developers should consider the types of devices,
Android versions and the OpenGL ES versions available to their customers. For more information
on OpenGL compatibility across devices, see the <a href="#compatibility">OpenGL Versions and Device
Compatibility</a> section.</li>
@@ -526,7 +521,7 @@
direct control of the graphics processing pipeline, developers can create effects that would be
very difficult to generate using the 1.0/1.1 API.</li>
</ul>
-
+
<p>While performance, compatibility, convenience, control and other factors may influence your
decision, you should pick an OpenGL API version based on what you think provides the best experience
for your users.</p>
diff --git a/docs/html/guide/topics/graphics/prop-animation.jd b/docs/html/guide/topics/graphics/prop-animation.jd
new file mode 100644
index 0000000..be24788
--- /dev/null
+++ b/docs/html/guide/topics/graphics/prop-animation.jd
@@ -0,0 +1,953 @@
+page.title=Property Animation
+parent.title=Animation
+parent.link=animation.html
+@jd:body
+
+ <div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+
+ <ol>
+ <li><a href="#how">How Property Animation Works</a></li>
+
+ <li><a href="#value-animator">Animating with ValueAnimator</a></li>
+
+ <li><a href="#object-animator">Animating with ObjectAnimator</a></li>
+
+ <li><a href="#choreography">Choreographing Multiple Animations with
+ AnimatorSet</a></li>
+
+ <li><a href="#listeners">Animation Listeners</a></li>
+
+ <li><a href="#type-evaluator">Using a TypeEvaluator</a></li>
+
+ <li><a href="#interpolators">Using Interpolators</a></li>
+
+ <li><a href="#keyframes">Specifying Keyframes</a></li>
+
+ <li><a href="#layout">Animating Layout Changes to ViewGroups</a></li>
+
+ <li><a href="#views">Animating Views</a>
+ <ol>
+ <li><a href="#view-prop-animator">ViewPropertyAnimator</a></li>
+ </ol>
+ </li>
+
+ <li><a href="#declaring-xml">Declaring Animations in XML</a></li>
+ </ol>
+
+ <h2>Key classes</h2>
+
+ <ol>
+ <li><code><a href=
+ "/reference/android/animation/ValueAnimator.html">ValueAnimator</a></code></li>
+
+ <li><code><a href=
+ "/reference/android/animation/ObjectAnimator.html">ObjectAnimator</a></code></li>
+
+ <li><code><a href=
+ "/reference/android/animation/TypeEvaluator.html">TypeEvaluator</a></code></li>
+ </ol>
+
+ <h2>Related samples</h2>
+
+ <ol>
+ <li><a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">API
+ Demos</a></li>
+ </ol>
+ </div>
+ </div>
+ <p>The property animation system is a robust framework that allows you
+ to animate almost anything. You can define an animation to change any object property over time,
+ regardless of whether it draws to the screen or not. A property animation changes a property's
+ (a field in an object) value over a specified length of time. To animate something, you specify the
+ object property that you want to animate, such as an object's position on the screen, how long
+ you want to animate it for, and what values you want to animate between. </p>
+
+ <p>The property animation system lets you define the following characteristics of an
+ animation:</p>
+
+ <ul>
+ <li>Duration: You can specify the duration of an animation. The default length is 300 ms.</li>
+
+ <li>Time interpolation: You can specify how the values for the property are calculated as a
+ function of the animation's current elapsed time.</li>
+
+ <li>Repeat count and behavior: You can specify whether or not to have an animation repeat when
+ it reaches the end of a duration and how many times to repeat the animation. You can also
+ specify whether you want the animation to play back in reverse. Setting it to reverse plays
+ the animation forwards then backwards repeatedly, until the number of repeats is reached.</li>
+
+ <li>Animator sets: You can group animations into logical sets that play together or
+ sequentially or after specified delays.</li>
+
+ <li>Frame refresh delay: You can specify how often to refresh frames of your animation. The
+ default is set to refresh every 10 ms, but the speed in which your application can refresh frames is
+ ultimately dependent on how busy the system is overall and how fast the system can service the underlying timer.</li>
+ </ul>
+
+
+ <h2 id="how">How Property Animation Works</h2>
+
+ <p>First, let's go over how an animation works with a simple example. Figure 1 depicts a
+ hypothetical object that is animated with its <code>x</code> property, which represents its
+ horizontal location on a screen. The duration of the animation is set to 40 ms and the distance
+ to travel is 40 pixels. Every 10 ms, which is the default frame refresh rate, the object moves
+ horizontally by 10 pixels. At the end of 40ms, the animation stops, and the object ends at
+ horizontal position 40. This is an example of an animation with linear interpolation, meaning the
+ object moves at a constant speed.</p><img src="{@docRoot}images/animation/animation-linear.png">
+
+ <p class="img-caption"><strong>Figure 1.</strong> Example of a linear animation</p>
+
+ <p>You can also specify animations to have a non-linear interpolation. Figure 2 illustrates a
+ hypothetical object that accelerates at the beginning of the animation, and decelerates at the
+ end of the animation. The object still moves 40 pixels in 40 ms, but non-linearly. In the
+ beginning, this animation accelerates up to the halfway point then decelerates from the
+ halfway point until the end of the animation. As Figure 2 shows, the distance traveled
+ at the beginning and end of the animation is less than in the middle.</p><img src=
+ "{@docRoot}images/animation/animation-nonlinear.png">
+
+ <p class="img-caption"><strong>Figure 2.</strong> Example of a non-linear animation</p>
+
+ <p>Let's take a detailed look at how the important components of the property animation system
+ would calculate animations like the ones illustrated above. Figure 3 depicts how the main classes
+ work with one another.</p><img src="{@docRoot}images/animation/valueanimator.png">
+
+ <p class="img-caption"><strong>Figure 3.</strong> How animations are calculated</p>
+
+ <p>The {@link android.animation.ValueAnimator} object keeps track of your animation's timing,
+ such as how long the animation has been running, and the current value of the property that it is
+ animating.</p>
+
+ <p>The {@link android.animation.ValueAnimator} encapsulates a {@link
+ android.animation.TimeInterpolator}, which defines animation interpolation, and a {@link
+ android.animation.TypeEvaluator}, which defines how to calculate values for the property being
+ animated. For example, in Figure 2, the {@link android.animation.TimeInterpolator} used would be
+ {@link android.view.animation.AccelerateDecelerateInterpolator} and the {@link
+ android.animation.TypeEvaluator} would be {@link android.animation.IntEvaluator}.</p>
+
+ <p>To start an animation, create a {@link android.animation.ValueAnimator} and give it the
+ starting and ending values for the property that you want to animate, along with the duration of
+ the animation. When you call {@link android.animation.ValueAnimator#start start()} the animation
+ begins. During the whole animation, the {@link android.animation.ValueAnimator} calculates an <em>elapsed fraction</em>
+ between 0 and 1, based on the duration of the animation and how much time has elapsed. The
+ elapsed fraction represents the percentage of time that the animation has completed, 0 meaning 0%
+ and 1 meaning 100%. For example, in Figure 1, the elapsed fraction at t = 10 ms would be .25
+ because the total duration is t = 40 ms.</p>
+
+ <p>When the {@link android.animation.ValueAnimator} is done calculating an elapsed fraction, it
+ calls the {@link android.animation.TimeInterpolator} that is currently set, to calculate an
+ <em>interpolated fraction</em>. An interpolated fraction maps the elapsed fraction to a new
+ fraction that takes into account the time interpolation that is set. For example, in Figure 2,
+ because the animation slowly accelerates, the interpolated fraction, about .15, is less than the
+ elapsed fraction, .25, at t = 10 ms. In Figure 1, the interpolated fraction is always the same as
+ the elapsed fraction.</p>
+
+ <p>When the interpolated fraction is calculated, {@link android.animation.ValueAnimator} calls
+ the appropriate {@link android.animation.TypeEvaluator}, to calculate the value of the
+ property that you are animating, based on the interpolated fraction, the starting value, and the
+ ending value of the animation. For example, in Figure 2, the interpolated fraction was .15 at t =
+ 10 ms, so the value for the property at that time would be .15 X (40 - 0), or 6.</p>
+
+ <!-- <p>When the final value is calculated, the {@link android.animation.ValueAnimator} calls the
+ {@link android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate
+ onAnimationUpdate()} method. Implement this callback to obtain the property value by
+ calling {@link android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()} and set the
+ value for the property in the object that you are animating. Setting the property doesn't redraw
+ the object on the screen, so you need to call {@link
+ android.view.View#invalidate invalidate()} to refresh the View that the object
+ resides in. If the object is actually a View object, then the system calls {@link
+ android.view.View#invalidate invalidate()} when the property is changed.
+ The system redraws the window and the {@link android.animation.ValueAnimator}
+ repeats the process.</p>-->
+
+ <p>The <code>com.example.android.apis.animation</code> package in the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">API
+ Demos</a> sample project provides many examples on how to use the property
+ animation system.</p>
+
+ <h2>API Overview</h2>
+
+ <p>You can find most of the property animation system's APIs in {@link android.animation
+ android.animation}. Because the view animation system already
+ defines many interpolators in {@link android.view.animation android.view.animation}, you can use
+ those interpolators in the property animation system as well. The following tables describe the main
+ components of the property animation system.</p>
+
+ <p>The {@link android.animation.Animator} class provides the basic structure for creating
+ animations. You normally do not use this class directly as it only provides minimal
+ functionality that must be extended to fully support animating values. The following
+ subclasses extend {@link android.animation.Animator}:
+ </p>
+ <p class="table-caption"><strong>Table 1.</strong> Animators</p>
+ <table>
+ <tr>
+ <th>Class</th>
+
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>{@link android.animation.ValueAnimator}</td>
+
+ <td>The main timing engine for property animation that also computes the values for the
+ property to be animated. It has all of the core functionality that calculates animation
+ values and contains the timing details of each animation, information about whether an
+ animation repeats, listeners that receive update events, and the ability to set custom
+ types to evaluate. There are two pieces to animating properties: calculating the animated
+ values and setting those values on the object and property that is being animated. {@link
+ android.animation.ValueAnimator} does not carry out the second piece, so you must listen
+ for updates to values calculated by the {@link android.animation.ValueAnimator} and
+ modify the objects that you want to animate with your own logic. See the section about
+ <a href="#value-animator">Animating with ValueAnimator</a> for more information.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.animation.ObjectAnimator}</td>
+
+ <td>A subclass of {@link android.animation.ValueAnimator} that allows you to set a target
+ object and object property to animate. This class updates the property accordingly when
+ it computes a new value for the animation. You want to use
+ {@link android.animation.ObjectAnimator} most of the time,
+ because it makes the process of animating values on target objects much easier. However,
+ you sometimes want to use {@link android.animation.ValueAnimator} directly because {@link
+ android.animation.ObjectAnimator} has a few more restrictions, such as requiring specific
+ acessor methods to be present on the target object.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.animation.AnimatorSet}</td>
+
+ <td>Provides a mechanism to group animations together so that they run in
+ relation to one another. You can set animations to play together, sequentially, or after
+ a specified delay. See the section about <a href="#choreography">Choreographing multiple
+ animations with Animator Sets</a> for more information.</td>
+ </tr>
+ </table>
+
+
+ <p>Evaluators tell the property animation system how to calculate values for a given
+ property. They take the timing data that is provided by an {@link android.animation.Animator}
+ class, the animation's start and end value, and calculate the animated values of the property
+ based on this data. The property animation system provides the following evaluators:</p>
+ <p class="table-caption"><strong>Table 2.</strong> Evaluators</p>
+ <table>
+ <tr>
+ <th>Class/Interface</th>
+
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>{@link android.animation.IntEvaluator}</td>
+
+ <td>The default evaluator to calculate values for <code>int</code> properties.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.animation.FloatEvaluator}</td>
+
+ <td>The default evaluator to calculate values for <code>float</code> properties.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.animation.ArgbEvaluator}</td>
+
+ <td>The default evaluator to calculate values for color properties that are represented
+ as hexidecimal values.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.animation.TypeEvaluator}</td>
+
+ <td>An interface that allows you to create your own evaluator. If you are animating an
+ object property that is <em>not</em> an <code>int</code>, <code>float</code>, or color,
+ you must implement the {@link android.animation.TypeEvaluator} interface to specify how
+ to compute the object property's animated values. You can also specify a custom {@link
+ android.animation.TypeEvaluator} for <code>int</code>, <code>float</code>, and color
+ values as well, if you want to process those types differently than the default behavior.
+ See the section about <a href="#type-evaluator">Using a TypeEvaluator</a> for more
+ information on how to write a custom evaluator.</td>
+ </tr>
+ </table>
+
+
+
+
+ <p>A time interpolator defines how specific values in an animation are calculated as a
+ function of time. For example, you can specify animations to happen linearly across the whole
+ animation, meaning the animation moves evenly the entire time, or you can specify animations
+ to use non-linear time, for example, accelerating at the beginning and decelerating at the
+ end of the animation. Table 3 describes the interpolators that are contained in {@link
+ android.view.animation android.view.animation}. If none of the provided interpolators suits
+ your needs, implement the {@link android.animation.TimeInterpolator} interface and create your own. See <a href=
+ "#interpolators">Using interpolators</a> for more information on how to write a custom
+ interpolator.</p>
+ <p class="table-caption"><strong>Table 3.</strong> Interpolators</p>
+ <table>
+ <tr>
+ <th>Class/Interface</th>
+
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.AccelerateDecelerateInterpolator}</td>
+
+ <td>An interpolator whose rate of change starts and ends slowly but accelerates
+ through the middle.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.AccelerateInterpolator}</td>
+
+ <td>An interpolator whose rate of change starts out slowly and then
+ accelerates.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.AnticipateInterpolator}</td>
+
+ <td>An interpolator whose change starts backward then flings forward.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.AnticipateOvershootInterpolator}</td>
+
+ <td>An interpolator whose change starts backward, flings forward and overshoots
+ the target value, then finally goes back to the final value.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.BounceInterpolator}</td>
+
+ <td>An interpolator whose change bounces at the end.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.CycleInterpolator}</td>
+
+ <td>An interpolator whose animation repeats for a specified number of cycles.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.DecelerateInterpolator}</td>
+
+ <td>An interpolator whose rate of change starts out quickly and and then
+ decelerates.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.LinearInterpolator}</td>
+
+ <td>An interpolator whose rate of change is constant.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.view.animation.OvershootInterpolator}</td>
+
+ <td>An interpolator whose change flings forward and overshoots the last value then
+ comes back.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.animation.TimeInterpolator}</td>
+
+ <td>An interface that allows you to implement your own interpolator.</td>
+ </tr>
+ </table>
+
+ <h2 id="value-animator">Animating with ValueAnimator</h2>
+
+ <p>The {@link android.animation.ValueAnimator} class lets you animate values of some type for the
+ duration of an animation by specifying a set of <code>int</code>, <code>float</code>, or color
+ values to animate through. You obtain a {@link android.animation.ValueAnimator} by calling one of
+ its factory methods: {@link android.animation.ValueAnimator#ofInt ofInt()}, {@link
+ android.animation.ValueAnimator#ofFloat ofFloat()}, or {@link
+ android.animation.ValueAnimator#ofObject ofObject()}. For example:</p>
+ <pre>
+ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
+animation.setDuration(1000);
+animation.start();
+</pre>
+
+ <p>In this code, the {@link android.animation.ValueAnimator} starts calculating the values of the
+ animation, between 0 and 1, for a duration of 1000 ms, when the <code>start()</code> method
+ runs.</p>
+
+ <p>You can also specify a custom type to animate by doing the following:</p>
+ <pre>
+ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
+animation.setDuration(1000);
+animation.start();
+</pre>
+
+ <p>In this code, the {@link android.animation.ValueAnimator} starts calculating the values of the
+ animation, between <code>startPropertyValue</code> and <code>endPropertyValue</code> using the
+ logic supplied by <code>MyTypeEvaluator</code> for a duration of 1000 ms, when the {@link
+ android.animation.ValueAnimator#start start()} method runs.</p>
+
+ <p>The previous code snippets, however, has no real effect on an object, because the {@link
+ android.animation.ValueAnimator} does not operate on objects or properties directly. The most likely thing
+ that you want to do is modify the objects that you want to animate with these calculated values. You do
+ this by defining listeners in the {@link android.animation.ValueAnimator} to appropriately handle important events
+ during the animation's lifespan, such as frame updates. When implementing the listeners, you can
+ obtain the calculated value for that specific frame refresh by calling {@link
+ android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()}. For more information on listeners,
+ see the section about <a href="#listeners">Animation Listeners</a>.
+
+ <h2 id="object-animator">Animating with ObjectAnimator</h2>
+
+ <p>The {@link android.animation.ObjectAnimator} is a subclass of the {@link
+ android.animation.ValueAnimator} (discussed in the previous section) and combines the timing
+ engine and value computation of {@link android.animation.ValueAnimator} with the ability to
+ animate a named property of a target object. This makes animating any object much easier, as you
+ no longer need to implement the {@link android.animation.ValueAnimator.AnimatorUpdateListener},
+ because the animated property updates automatically.</p>
+
+ <p>Instantiating an {@link android.animation.ObjectAnimator} is similar to a {@link
+ android.animation.ValueAnimator}, but you also specify the object and the name of that object's property (as
+ a String) along with the values to animate between:</p>
+ <pre>
+ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f);
+anim.setDuration(1000);
+anim.start();
+</pre>
+
+ <p>To have the {@link android.animation.ObjectAnimator} update properties correctly, you must do
+ the following:</p>
+
+ <ul>
+ <li>The object property that you are animating must have a setter function (in camel case) in the form of
+ <code>set<propertyName>()</code>. Because the {@link android.animation.ObjectAnimator}
+ automatically updates the property during animation, it must be able to access the property
+ with this setter method. For example, if the property name is <code>foo</code>, you need to
+ have a <code>setFoo()</code> method. If this setter method does not exist, you have three
+ options:
+
+ <ul>
+ <li>Add the setter method to the class if you have the rights to do so.</li>
+
+ <li>Use a wrapper class that you have rights to change and have that wrapper receive the
+ value with a valid setter method and forward it to the original object.</li>
+
+ <li>Use {@link android.animation.ValueAnimator} instead.</li>
+ </ul>
+ </li>
+
+ <li>If you specify only one value for the <code>values...</code> parameter in one of the {@link
+ android.animation.ObjectAnimator} factory methods, it is assumed to be the ending value of the
+ animation. Therefore, the object property that you are animating must have a getter function
+ that is used to obtain the starting value of the animation. The getter function must be in the
+ form of <code>get<propertyName>()</code>. For example, if the property name is
+ <code>foo</code>, you need to have a <code>getFoo()</code> method.</li>
+
+ <li>The getter (if needed) and setter methods of the property that you are animating must
+ operate on the same type as the starting and ending values that you specify to {@link
+ android.animation.ObjectAnimator}. For example, you must have
+ <code>targetObject.setPropName(float)</code> and <code>targetObject.getPropName(float)</code>
+ if you construct the following {@link android.animation.ObjectAnimator}:
+ <pre>
+ObjectAnimator.ofFloat(targetObject, "propName", 1f)
+</pre>
+ </li>
+
+ <li>Depending on what property or object you are animating, you might need to call the {@link
+ android.view.View#invalidate invalidate()} method on a View force the screen to redraw itself with the
+ updated animated values. You do this in the
+ {@link android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate onAnimationUpdate()}
+ callback. For example, animating the color property of a Drawable object only cause updates to the
+ screen when that object redraws itself. All of the property setters on View, such as
+ {@link android.view.View#setAlpha setAlpha()} and {@link android.view.View#setTranslationX setTranslationX()}
+ invalidate the View properly, so you do not need to invalidate the View when calling these
+ methods with new values. For more information on listeners, see the section about <a href="#listeners">Animation Listeners</a>.
+ </li>
+ </ul>
+
+ <h2 id="choreography">Choreographing Multiple Animations with AnimatorSet</h2>
+
+ <p>In many cases, you want to play an animation that depends on when another animation starts or
+ finishes. The Android system lets you bundle animations together into an {@link
+ android.animation.AnimatorSet}, so that you can specify whether to start animations
+ simultaneously, sequentially, or after a specified delay. You can also nest {@link
+ android.animation.AnimatorSet} objects within each other.</p>
+
+ <p>The following sample code taken from the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">Bouncing
+ Balls</a> sample (modified for simplicity) plays the following {@link android.animation.Animator}
+ objects in the following manner:</p>
+
+ <ol>
+ <li>Plays <code>bounceAnim</code>.</li>
+
+ <li>Plays <code>squashAnim1</code>, <code>squashAnim2</code>, <code>stretchAnim1</code>, and
+ <code>stretchAnim2</code> at the same time.</li>
+
+ <li>Plays <code>bounceBackAnim</code>.</li>
+
+ <li>Plays <code>fadeAnim</code>.</li>
+ </ol>
+ <pre>
+AnimatorSet bouncer = new AnimatorSet();
+bouncer.play(bounceAnim).before(squashAnim1);
+bouncer.play(squashAnim1).with(squashAnim2);
+bouncer.play(squashAnim1).with(stretchAnim1);
+bouncer.play(squashAnim1).with(stretchAnim2);
+bouncer.play(bounceBackAnim).after(stretchAnim2);
+ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
+fadeAnim.setDuration(250);
+AnimatorSet animatorSet = new AnimatorSet();
+animatorSet.play(bouncer).before(fadeAnim);
+animatorSet.start();
+</pre>
+
+ <p>For a more complete example on how to use animator sets, see the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">Bouncing
+ Balls</a> sample in APIDemos.</p>
+
+<h2 id="listeners">Animation Listeners</h2>
+<p>
+You can listen for important events during an animation's duration with the listeners described below.
+</p>
+
+ <ul>
+ <li>{@link android.animation.Animator.AnimatorListener}
+
+ <ul>
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationStart onAnimationStart()}
+ - Called when the animation starts.</li>
+
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()} -
+ Called when the animation ends.</li>
+
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationRepeat
+ onAnimationRepeat()} - Called when the animation repeats itself.</li>
+
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationCancel
+ onAnimationCancel()} - Called when the animation is canceled. A cancelled animation
+ also calls {@link android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()},
+ regardless of how they were ended.</li>
+ </ul>
+ </li>
+
+ <li>{@link android.animation.ValueAnimator.AnimatorUpdateListener}
+
+ <ul>
+ <li>
+ <p>{@link android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate
+ onAnimationUpdate()} - called on every frame of the animation. Listen to this event to
+ use the calculated values generated by {@link android.animation.ValueAnimator} during an
+ animation. To use the value, query the {@link android.animation.ValueAnimator} object
+ passed into the event to get the current animated value with the {@link
+ android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()} method. Implementing this
+ listener is required if you use {@link android.animation.ValueAnimator}. </p>
+
+ <p>
+ Depending on what property or object you are animating, you might need to call
+ {@link android.view.View#invalidate invalidate()} on a View to force that area of the
+ screen to redraw itself with the new animated values. For example, animating the
+ color property of a Drawable object only cause updates to the screen when that object
+ redraws itself. All of the property setters on View,
+ such as {@link android.view.View#setAlpha setAlpha()} and
+ {@link android.view.View#setTranslationX setTranslationX()} invalidate the View
+ properly, so you do not need to invalidate the View when calling these methods with new values.
+ </p>
+
+ </li>
+ </ul>
+ </li>
+ </ul>
+
+<p>You can extend the {@link android.animation.AnimatorListenerAdapter} class instead of
+implementing the {@link android.animation.Animator.AnimatorListener} interface, if you do not
+want to implement all of the methods of the {@link android.animation.Animator.AnimatorListener}
+interface. The {@link android.animation.AnimatorListenerAdapter} class provides empty
+implementations of the methods that you can choose to override.</p>
+ <p>For example, the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">Bouncing
+ Balls</a> sample in the API demos creates an {@link android.animation.AnimatorListenerAdapter}
+ for just the {@link android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()}
+ callback:</p>
+ <pre>
+ValueAnimatorAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
+fadeAnim.setDuration(250);
+fadeAnim.addListener(new AnimatorListenerAdapter() {
+public void onAnimationEnd(Animator animation) {
+ balls.remove(((ObjectAnimator)animation).getTarget());
+}
+</pre>
+
+
+ <h2 id="layout">Animating Layout Changes to ViewGroups</h2>
+
+ <p>The property animation system provides the capability to animate changes to ViewGroup objects
+ as well as provide an easy way to animate View objects themselves.</p>
+
+ <p>You can animate layout changes within a ViewGroup with the {@link
+ android.animation.LayoutTransition} class. Views inside a ViewGroup can go through an appearing
+ and disappearing animation when you add them to or remove them from a ViewGroup or when you call
+ a View's {@link android.view.View#setVisibility setVisibility()} method with {@link
+ android.view.View#VISIBLE}, android.view.View#INVISIBLE}, or {@link android.view.View#GONE}. The remaining Views in the
+ ViewGroup can also animate into their new positions when you add or remove Views. You can define
+ the following animations in a {@link android.animation.LayoutTransition} object by calling {@link
+ android.animation.LayoutTransition#setAnimator setAnimator()} and passing in an {@link
+ android.animation.Animator} object with one of the following {@link
+ android.animation.LayoutTransition} constants:</p>
+
+ <ul>
+ <li><code>APPEARING</code> - A flag indicating the animation that runs on items that are
+ appearing in the container.</li>
+
+ <li><code>CHANGE_APPEARING</code> - A flag indicating the animation that runs on items that are
+ changing due to a new item appearing in the container.</li>
+
+ <li><code>DISAPPEARING</code> - A flag indicating the animation that runs on items that are
+ disappearing from the container.</li>
+
+ <li><code>CHANGE_DISAPPEARING</code> - A flag indicating the animation that runs on items that
+ are changing due to an item disappearing from the container.</li>
+ </ul>
+
+ <p>You can define your own custom animations for these four types of events to customize the look
+ of your layout transitions or just tell the animation system to use the default animations.</p>
+
+ <p>The <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimations.html">
+ LayoutAnimations</a> sample in API Demos shows you how to define animations for layout
+ transitions and then set the animations on the View objects that you want to animate.</p>
+
+ <p>The <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsByDefault.html">
+ LayoutAnimationsByDefault</a> and its corresponding <a href=
+ "{@docRoot}resources/samples/ApiDemos/res/layout/layout_animations_by_default.html">layout_animations_by_default.xml</a>
+ layout resource file show you how to enable the default layout transitions for ViewGroups in XML.
+ The only thing that you need to do is to set the <code>android:animateLayoutchanges</code>
+ attribute to <code>true</code> for the ViewGroup. For example:</p>
+ <pre>
+<LinearLayout
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:id="@+id/verticalContainer"
+ android:animateLayoutChanges="true" />
+</pre>
+
+ <p>Setting this attribute to true automatically animates Views that are added or removed from the
+ ViewGroup as well as the remaining Views in the ViewGroup.</p>
+
+ <h2 id="type-evaluator">Using a TypeEvaluator</h2>
+
+ <p>If you want to animate a type that is unknown to the Android system, you can create your own
+ evaluator by implementing the {@link android.animation.TypeEvaluator} interface. The types that
+ are known by the Android system are <code>int</code>, <code>float</code>, or a color, which are
+ supported by the {@link android.animation.IntEvaluator}, {@link
+ android.animation.FloatEvaluator}, and {@link android.animation.ArgbEvaluator} type
+ evaluators.</p>
+
+ <p>There is only one method to implement in the {@link android.animation.TypeEvaluator}
+ interface, the {@link android.animation.TypeEvaluator#evaluate evaluate()} method. This allows
+ the animator that you are using to return an appropriate value for your animated property at the
+ current point of the animation. The {@link android.animation.FloatEvaluator} class demonstrates
+ how to do this:</p>
+ <pre>
+public class FloatEvaluator implements TypeEvaluator {
+
+ public Object evaluate(float fraction, Object startValue, Object endValue) {
+ float startFloat = ((Number) startValue).floatValue();
+ return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
+ }
+}
+</pre>
+
+ <p class="note"><strong>Note:</strong> When {@link android.animation.ValueAnimator} (or {@link
+ android.animation.ObjectAnimator}) runs, it calculates a current elapsed fraction of the
+ animation (a value between 0 and 1) and then calculates an interpolated version of that depending
+ on what interpolator that you are using. The interpolated fraction is what your {@link
+ android.animation.TypeEvaluator} receives through the <code>fraction</code> parameter, so you do
+ not have to take into account the interpolator when calculating animated values.</p>
+
+ <h2 id="interpolators">Using Interpolators</h2>
+
+ <p>An interpolator define how specific values in an animation are calculated as a function of
+ time. For example, you can specify animations to happen linearly across the whole animation,
+ meaning the animation moves evenly the entire time, or you can specify animations to use
+ non-linear time, for example, using acceleration or deceleration at the beginning or end of the
+ animation.</p>
+
+ <p>Interpolators in the animation system receive a fraction from Animators that represent the
+ elapsed time of the animation. Interpolators modify this fraction to coincide with the type of
+ animation that it aims to provide. The Android system provides a set of common interpolators in
+ the {@link android.view.animation android.view.animation package}. If none of these suit your
+ needs, you can implement the {@link android.animation.TimeInterpolator} interface and create your
+ own.</p>
+
+ <p>As an example, how the default interpolator {@link
+ android.view.animation.AccelerateDecelerateInterpolator} and the {@link
+ android.view.animation.LinearInterpolator} calculate interpolated fractions are compared below.
+ The {@link android.view.animation.LinearInterpolator} has no effect on the elapsed fraction. The {@link
+ android.view.animation.AccelerateDecelerateInterpolator} accelerates into the animation and
+ decelerates out of it. The following methods define the logic for these interpolators:</p>
+
+ <p><strong>AccelerateDecelerateInterpolator</strong></p>
+ <pre>
+public float getInterpolation(float input) {
+ return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
+}
+</pre>
+
+ <p><strong>LinearInterpolator</strong></p>
+ <pre>
+public float getInterpolation(float input) {
+ return input;
+}
+</pre>
+
+ <p>The following table represents the approximate values that are calculated by these
+ interpolators for an animation that lasts 1000ms:</p>
+
+ <table>
+ <tr>
+ <th>ms elapsed</th>
+
+ <th>Elapsed fraction/Interpolated fraction (Linear)</th>
+
+ <th>Interpolated fraction (Accelerate/Decelerate)</th>
+ </tr>
+
+ <tr>
+ <td>0</td>
+
+ <td>0</td>
+
+ <td>0</td>
+ </tr>
+
+ <tr>
+ <td>200</td>
+
+ <td>.2</td>
+
+ <td>.1</td>
+ </tr>
+
+ <tr>
+ <td>400</td>
+
+ <td>.4</td>
+
+ <td>.345</td>
+ </tr>
+
+ <tr>
+ <td>600</td>
+
+ <td>.6</td>
+
+ <td>.8</td>
+ </tr>
+
+ <tr>
+ <td>800</td>
+
+ <td>.8</td>
+
+ <td>.9</td>
+ </tr>
+
+ <tr>
+ <td>1000</td>
+
+ <td>1</td>
+
+ <td>1</td>
+ </tr>
+ </table>
+
+ <p>As the table shows, the {@link android.view.animation.LinearInterpolator} changes the values
+ at the same speed, .2 for every 200ms that passes. The {@link
+ android.view.animation.AccelerateDecelerateInterpolator} changes the values faster than {@link
+ android.view.animation.LinearInterpolator} between 200ms and 600ms and slower between 600ms and
+ 1000ms.</p>
+
+ <h2 id="keyframes">Specifying Keyframes</h2>
+
+ <p>A {@link android.animation.Keyframe} object consists of a time/value pair that lets you define
+ a specific state at a specific time of an animation. Each keyframe can also have its own
+ interpolator to control the behavior of the animation in the interval between the previous
+ keyframe's time and the time of this keyframe.</p>
+
+ <p>To instantiate a {@link android.animation.Keyframe} object, you must use one of the factory
+ methods, {@link android.animation.Keyframe#ofInt ofInt()}, {@link
+ android.animation.Keyframe#ofFloat ofFloat()}, or {@link android.animation.Keyframe#ofObject
+ ofObject()} to obtain the appropriate type of {@link android.animation.Keyframe}. You then call
+ the {@link android.animation.PropertyValuesHolder#ofKeyframe ofKeyframe()} factory method to
+ obtain a {@link android.animation.PropertyValuesHolder} object. Once you have the object, you can
+ obtain an animator by passing in the {@link android.animation.PropertyValuesHolder} object and
+ the object to animate. The following code snippet demonstrates how to do this:</p>
+ <pre>
+Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
+Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
+Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
+PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
+ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation)
+rotationAnim.setDuration(5000ms);
+</pre>
+
+ <p>For a more complete example on how to use keyframes, see the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/MultiPropertyAnimation.html">
+ MultiPropertyAnimation</a> sample in APIDemos.</p>
+
+ <h2 id="views">Animating Views</h2>
+
+ <p>The property animation system allow streamlined animation of View objects and offerse
+ a few advantages over the view animation system. The view
+ animation system transformed View objects by changing the way that they were drawn. This was
+ handled in the container of each View, because the View itself had no properties to manipulate.
+ This resulted in the View being animated, but caused no change in the View object itself. This
+ led to behavior such as an object still existing in its original location, even though it was
+ drawn on a different location on the screen. In Android 3.0, new properties and the corresponding
+ getter and setter methods were added to eliminate this drawback.</p>
+ <p>The property animation system
+ can animate Views on the screen by changing the actual properties in the View objects. In
+ addition, Views also automatically call the {@link android.view.View#invalidate invalidate()}
+ method to refresh the screen whenever its properties are changed. The new properties in the {@link
+ android.view.View} class that facilitate property animations are:</p>
+
+ <ul>
+ <li><code>translationX</code> and <code>translationY</code>: These properties control where the
+ View is located as a delta from its left and top coordinates which are set by its layout
+ container.</li>
+
+ <li><code>rotation</code>, <code>rotationX</code>, and <code>rotationY</code>: These properties
+ control the rotation in 2D (<code>rotation</code> property) and 3D around the pivot point.</li>
+
+ <li><code>scaleX</code> and <code>scaleY</code>: These properties control the 2D scaling of a
+ View around its pivot point.</li>
+
+ <li><code>pivotX</code> and <code>pivotY</code>: These properties control the location of the
+ pivot point, around which the rotation and scaling transforms occur. By default, the pivot
+ point is located at the center of the object.</li>
+
+ <li><code>x</code> and <code>y</code>: These are simple utility properties to describe the
+ final location of the View in its container, as a sum of the left and top values and
+ translationX and translationY values.</li>
+
+ <li><code>alpha</code>: Represents the alpha transparency on the View. This value is 1 (opaque)
+ by default, with a value of 0 representing full transparency (not visible).</li>
+ </ul>
+
+ <p>To animate a property of a View object, such as its color or rotation value, all you need to
+ do is create a property animator and specify the View property that you want to
+ animate. For example:</p>
+ <pre>
+ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);
+</pre>
+
+<p>For more information on creating animators, see the sections on animating with
+<a href="#value-animator">ValueAnimator</a> and <a href="#object-animator">ObjectAnimator</a>.
+</p>
+
+<h3 id="view-prop-animator">Animating with ViewPropertyAnimator</h3>
+<p>The {@link android.view.ViewPropertyAnimator} provides a simple way to animate several
+properties of a {@link android.view.View} in parallel, using a single underlying {@link
+android.animation.Animator}
+object. It behaves much like an {@link android.animation.ObjectAnimator}, because it modifies the
+actual values of the view's properties, but is more efficient when animating many properties at
+once. In addition, the code for using the {@link android.view.ViewPropertyAnimator} is much
+more concise and easier to read. The following code snippets show the differences in using multiple
+{@link android.animation.ObjectAnimator} objects, a single
+{@link android.animation.ObjectAnimator}, and the {@link android.view.ViewPropertyAnimator} when
+simultaneously animating the <code>x</code> and <code>y</code> property of a view.</p>
+
+<p><strong>Multiple ObjectAnimator objects</strong></p>
+<pre>
+ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
+ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
+AnimatorSet animSetXY = new AnimatorSet();
+animSetXY.playTogether(animX, animY);
+animSetXY.start();
+</pre>
+
+<p><strong>One ObjectAnimator</strong></p>
+<pre>
+PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
+PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
+ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();
+</pre>
+
+<p><strong>ViewPropertyAnimator</strong></p>
+<pre>
+myView.animate().x(50f).y(100f);
+</pre>
+
+<p>
+For more detailed information about {@link
+android.view.ViewPropertyAnimator}, see the corresponding Android Developers
+<a href="http://android-developers.blogspot.com/2011/05/introducing-viewpropertyanimator.html">blog
+post</a>.</p>
+
+<h2 id="declaring-xml">Declaring Animations in XML</h2>
+
+ <p>The property animation system lets you declare property animations with XML instead of doing
+ it programmatically. By defining your animations in XML, you can easily reuse your animations
+in multiple activities and more easily edit the animation sequence.</p>
+
+<p>To distinguish animation files that use the new property animation APIs from those that use the
+legacy <a href="{@docRoot}guide/topics/graphics/view-animation.html">view animation</a> framework,
+starting with Android 3.1, you should save the XML files for property animations in the {@code
+res/animator/} directory (instead of {@code res/anim/}). Using the {@code animator} directory name
+is optional, but necessary if you want to use the layout editor tools in the Eclipse ADT plugin (ADT
+11.0.0+), because ADT only searches the {@code res/animator/} directory for property animation
+resources.</p>
+
+<p>The following property animation classes have XML declaration support with the
+ following XML tags:</p>
+
+ <ul>
+ <li>{@link android.animation.ValueAnimator} - <code><animator></code></li>
+
+ <li>{@link android.animation.ObjectAnimator} - <code><objectAnimator></code></li>
+
+ <li>{@link android.animation.AnimatorSet} - <code><set></code></li>
+ </ul>
+
+<p>The following example plays the two sets of object animations sequentially, with the first nested
+set playing two object animations together:</p>
+
+<pre>
+<set android:ordering="sequentially">
+ <set>
+ <objectAnimator
+ android:propertyName="x"
+ android:duration="500"
+ android:valueTo="400"
+ android:valueType="intType"/>
+ <objectAnimator
+ android:propertyName="y"
+ android:duration="500"
+ android:valueTo="300"
+ android:valueType="intType"/>
+ </set>
+ <objectAnimator
+ android:propertyName="alpha"
+ android:duration="500"
+ android:valueTo="1f"/>
+</set>
+</pre>
+ <p>In order to run this animation, you must inflate the XML resources in your code to an {@link
+ android.animation.AnimatorSet} object, and then set the target objects for all of the animations
+ before starting the animation set. Calling {@link android.animation.AnimatorSet#setTarget
+ setTarget()} sets a single target object for all children of the {@link
+ android.animation.AnimatorSet} as a convenience. The following code shows how to do this:</p>
+
+<pre>
+AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
+ R.anim.property_animator);
+set.setTarget(myObject);
+set.start();
+</pre>
+
+<p>For information about the XML syntax for defining property animations, see <a
+href="{@docRoot}guide/topics/resources/animation-resource.html#Property">Animation Resources</a>.
+
diff --git a/docs/html/guide/topics/graphics/view-animation.jd b/docs/html/guide/topics/graphics/view-animation.jd
index eff6f70..3ccda8b 100644
--- a/docs/html/guide/topics/graphics/view-animation.jd
+++ b/docs/html/guide/topics/graphics/view-animation.jd
@@ -1,27 +1,14 @@
page.title=View Animation
-parent.title=Graphics
-parent.link=index.html
+parent.title=Animation
+parent.link=animation.html
@jd:body
- <div id="qv-wrapper">
- <div id="qv">
- <h2>In this document</h2>
- <ol>
- <li><a href="#tween-animation">Tween animation</a></li>
- <li><a href="#frame-animation">Frame animation</a></li>
- </ol>
- </div>
- </div>
-
- You can use View Animation in any View object to
- perform tweened animation and frame by frame animation. Tween animation calculates the animation
- given information such as the start point, end point, size, rotation, and other common aspects of
- an animation. Frame by frame animation lets you load a series of Drawable resources one after
- another to create an animation.
-
- <h2 id="tween-animation">Tween Animation</h2>
+ <p>You can use the view animation system to perform tweened animation on Views. Tween animation
+ calculates the animation with information such as the start point, end point, size, rotation, and
+ other common aspects of an animation.
+ </p>
<p>A tween animation can perform a series of simple transformations (position, size, rotation,
and transparency) on the contents of a View object. So, if you have a {@link
@@ -126,67 +113,3 @@
Even so, the animation will still be drawn beyond the bounds of its View and will not be clipped.
However, clipping <em>will occur</em> if the animation exceeds the bounds of the parent View.</p>
- <h2 id="frame-animation">Frame Animation</h2>
-
- <p>This is a traditional animation in the sense that it is created with a sequence of different
- images, played in order, like a roll of film. The {@link
- android.graphics.drawable.AnimationDrawable} class is the basis for frame animations.</p>
-
- <p>While you can define the frames of an animation in your code, using the {@link
- android.graphics.drawable.AnimationDrawable} class API, it's more simply accomplished with a
- single XML file that lists the frames that compose the animation. Like the tween animation above,
- the XML file for this kind of animation belongs in the <code>res/drawable/</code> directory of
- your Android project. In this case, the instructions are the order and duration for each frame of
- the animation.</p>
-
- <p>The XML file consists of an <code><animation-list></code> element as the root node and a
- series of child <code><item></code> nodes that each define a frame: a drawable resource for
- the frame and the frame duration. Here's an example XML file for a frame-by-frame animation:</p>
- <pre>
-<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
- android:oneshot="true">
- <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
- <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
- <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
-</animation-list>
-</pre>
-
- <p>This animation runs for just three frames. By setting the <code>android:oneshot</code>
- attribute of the list to <var>true</var>, it will cycle just once then stop and hold on the last
- frame. If it is set <var>false</var> then the animation will loop. With this XML saved as
- <code>rocket_thrust.xml</code> in the <code>res/drawable/</code> directory of the project, it can
- be added as the background image to a View and then called to play. Here's an example Activity,
- in which the animation is added to an {@link android.widget.ImageView} and then animated when the
- screen is touched:</p>
- <pre>
-AnimationDrawable rocketAnimation;
-
-public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
- rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
- rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
-}
-
-public boolean onTouchEvent(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- rocketAnimation.start();
- return true;
- }
- return super.onTouchEvent(event);
-}
-</pre>
-
- <p>It's important to note that the <code>start()</code> method called on the AnimationDrawable
- cannot be called during the <code>onCreate()</code> method of your Activity, because the
- AnimationDrawable is not yet fully attached to the window. If you want to play the animation
- immediately, without requiring interaction, then you might want to call it from the <code>{@link
- android.app.Activity#onWindowFocusChanged(boolean) onWindowFocusChanged()}</code> method in your
- Activity, which will get called when Android brings your window into focus.</p>
-
- <p>For more information on the XML syntax, available tags and attributes, see <a href=
- "{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
-</body>
-</html>
diff --git a/docs/html/guide/topics/manifest/activity-element.jd b/docs/html/guide/topics/manifest/activity-element.jd
index b2a78fe..02a8a8e 100644
--- a/docs/html/guide/topics/manifest/activity-element.jd
+++ b/docs/html/guide/topics/manifest/activity-element.jd
@@ -10,8 +10,8 @@
android:<a href="#clear">clearTaskOnLaunch</a>=["true" | "false"]
android:<a href="#config">configChanges</a>=["mcc", "mnc", "locale",
"touchscreen", "keyboard", "keyboardHidden",
- "navigation", "orientation", "screenLayout",
- "fontScale", "uiMode"]
+ "navigation", "screenLayout", "fontScale", "uiMode",
+ "orientation", "screenSize", "smallestScreenSize"]
android:<a href="#enabled">enabled</a>=["true" | "false"]
android:<a href="#exclude">excludeFromRecents</a>=["true" | "false"]
android:<a href="#exported">exported</a>=["true" | "false"]
@@ -205,10 +205,6 @@
<td>"{@code navigation}"</td>
<td>The navigation type (trackball/dpad) has changed. (This should never normally happen.)</td>
</tr><tr>
- <td>"{@code orientation}"</td>
- <td>The screen orientation has changed — the user has rotated
- the device.</td>
- </tr><tr>
<td>"{@code screenLayout}"</td>
<td>The screen layout has changed — this might be caused by a
different display being activated.</td>
@@ -221,7 +217,34 @@
<td>The user interface mode has changed — this can be caused when the user places the
device into a desk/car dock or when the the night mode changes. See {@link
android.app.UiModeManager}. <em>Introduced in API Level 8</em>.</td>
- </tr>
+ </tr><tr>
+ <td>"{@code orientation}"</td>
+ <td>The screen orientation has changed — the user has rotated the device.
+ <p class="note"><strong>Note:</strong> If your application targets API level 13 or higher (as
+declared by the <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+minSdkVersion}</a> and <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+targetSdkVersion}</a> attributes), then you should also declare the {@code "screenSize"}
+configuration, because it also changes when a device switches between portrait and landscape
+orientations.</p></td>
+ </tr><tr>
+ <td>"{@code screenSize}"</td>
+ <td>The current available screen size has changed. This represents a change in the currently
+available size, relative to the current aspect ratio, so will change when the user switches between
+landscape and portrait. However, if your application targets API level 12 or lower, then your
+activity always handles this configuration change itself (this configuration change does not restart
+your activity, even when running on an Android 3.2 or higher device).
+ <p><em>Added in API level 13.</em></p></td>
+ </tr><tr>
+ <td>"{@code smallestScreenSize}"</td>
+ <td>The physical screen size has changed. This represents a change in size regardless of
+orientation, so will only change when the actual physical screen size has changed such as switching
+to an external display. A change to this configuration corresponds to a change in the <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#SmallestScreenWidthQualifier">
+smallestWidth configuration</a>. However, if your application targets API level 12 or lower, then
+your activity always handles this configuration change itself (this configuration change does not
+restart your activity, even when running on an Android 3.2 or higher device).
+ <p><em>Added in API level 13.</em></p></td>
+ </tr>
</table>
<p>
@@ -581,8 +604,9 @@
</p></dd>
<dt><a name="screen"></a>{@code android:screenOrientation}</dt>
-<dd>The orientation of the activity's display on the device.
-The value can be any one of the following strings:
+<dd>The orientation of the activity's display on the device.
+
+<p>The value can be any one of the following strings:</p>
<table>
<tr>
@@ -640,7 +664,23 @@
distinction, the system chooses the orientation using the same policy as for the "{@code
unspecified}" setting.</td>
</tr>
-</table></dd>
+</table>
+
+<p class="note"><strong>Note:</strong> When you declare one of the landscape or portrait values,
+it is considered a hard requirement for the orientation in which the activity runs. As such,
+the value you declare enables filtering by services such as Android Market so your application is
+available only to devices that support the orientation required by your activities. For
+example, if you declare either {@code "landscape"}, {@code "reverseLandscape"}, or
+{@code "sensorLandscape"}, then your application will be available only to devices that support
+landscape orientation. However, you should also explicitly declare that
+your application requires either portrait or landscape orientation with the <a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code <uses-feature>}</a>
+element. For example, <code><uses-feature
+android:name="android.hardware.screen.portrait"/></code>. This is purely a filtering behavior
+provided by Android Market (and other services that support it) and the platform itself does not
+control whether your app can be installed when a device supports only certain orientations.</p>
+
+</dd>
<dt><a name="state"></a>{@code android:stateNotNeeded}</dt>
<dd>Whether or not the activity can be killed and successfully restarted
diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd
index 49d6b62..9f80638 100644
--- a/docs/html/guide/topics/manifest/uses-feature-element.jd
+++ b/docs/html/guide/topics/manifest/uses-feature-element.jd
@@ -111,7 +111,7 @@
with your application. For this reason, it's very important that you declare all of
the features (from the list below) that your application uses. </p>
-<p>For some features, there may exist a specfic attribute that allows you to define
+<p>For some features, there may exist a specific attribute that allows you to define
a version of the feature, such as the version of Open GL used (declared with
<a href="#glEsVersion"><code>glEsVersion</code></a>). Other features that either do or do not
exist for a device, such as a camera, are declared using the
@@ -277,7 +277,7 @@
it (<code>"true"</code>), or whether the application prefers to use the feature
if available, but is designed to run without it (<code>"false"</code>).</p>
-<p>Android Market handles explictly declared features in this way: </p>
+<p>Android Market handles explicitly declared features in this way: </p>
<ul>
<li>If a feature is explicitly declared as being required, Android Market adds
@@ -287,7 +287,7 @@
<pre><uses-feature android:name="android.hardware.camera" android:required="true" /></pre></li>
<li>If a feature is explicitly declared as <em>not</em> being required, Android
Market <em>does not</em> add the feature to the list of required features. For
-that reason, an explicity declared non-required feature is never considered when
+that reason, an explicitly declared non-required feature is never considered when
filtering the application. Even if the device does not provide the declared
feature, Android Market will still consider the application compatible with the
device and will show it to the user, unless other filtering rules apply. For
@@ -650,6 +650,40 @@
<td>The application uses the device's proximity sensor.</td>
<td></td>
</tr>
+
+<tr>
+ <td rowspan="2">Screen</td>
+ <td><code>android.hardware.screen.landscape</code></td>
+ <td>The application requires landscape orientation.</td>
+ <td rowspan="2">
+ <p>For example, if your app requires portrait orientation, you should declare
+<code><uses-feature android:name="android.hardware.screen.portrait"/></code> so that only devices
+that support portrait orientation (whether always or by user choice) can install your app. If your
+application <em>supports</em> both orientations, then you don't need to declare either.</p>
+ <p>Both orientations are assumed <em>not required</em>, by default, so your app may be installed
+on devices that support one or both orientations. However, if any of your activities request that
+they run in a specific orientation, using the <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#screen">{@code
+android:screenOrientation}</a> attribute, then this also declares that the application requires that
+orientation. For example, if you declare <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#screen">{@code
+android:screenOrientation}</a> with either {@code "landscape"}, {@code "reverseLandscape"}, or
+{@code "sensorLandscape"}, then your application will be available only to devices that support
+landscape orientation. As a best practice, you should still declare your requirement for this
+orientation using a {@code <uses-feature>} element. If you declare an orientation for your
+activity using <a href="{@docRoot}guide/topics/manifest/activity-element.html#screen">{@code
+android:screenOrientation}</a>, but don't actually <em>require</em> it, you can disable the
+requirement by declaring the orientation with a {@code <uses-feature>} element and include
+{@code android:required="false"}.</p>
+ <p>For backwards compatibility, any device running a platform version that supports only API
+level 12 or lower is assumed to support both landscape and portrait.</p>
+ </td>
+</tr>
+<tr>
+ <td><code>android.hardware.screen.portrait</code></td>
+ <td>The application requires portrait orientation.</td>
+</tr>
+
<tr>
<td rowspan="3">Telephony</td>
<td><code>android.hardware.telephony</code></td>
@@ -672,17 +706,18 @@
</tr>
<tr>
- <td rowspan="5">Touchscreen</td>
+ <td rowspan="7">Touchscreen</td>
<td><code>android.hardware.faketouch</code></td>
<td>The application uses basic touch interaction events, such as "click down", "click
up", and drag.</td>
- <td>When declared, this indicates that the application is compatible with a device that offers an
-emulated touchscreen ("fake touch" interface), or better. A device that offers a fake touch
-interface provides a user input system that emulates a subset of touchscreen capabilities. For
-example, a mouse or remote control that drives an on-screen cursor provides a fake touch interface.
-If your application requires only basic point and click interaction, you should declare this
-feature. Because this is the minimum level of touch interaction, your app will also be compatible
-with devices that offer more complex touch interfaces.
+ <td><p>When declared as required, this indicates that the application is compatible with a device
+only if it offers an emulated touchscreen ("fake touch" interface), or better. A device that offers
+a fake touch interface provides a user input system that emulates a subset of touchscreen
+capabilities. For example, a mouse or remote control that drives an on-screen cursor provides a fake
+touch interface. If your application requires basic point and click interaction (in other
+words, it won't work with <em>only</em> a d-pad controller), you should declare this feature.
+Because this is the minimum level of touch interaction, your app will also be compatible with
+devices that offer more complex touch interfaces.</p>
<p class="note"><strong>Note:</strong> Because applications require the {@code
android.hardware.touchscreen} feature by default, if you want your application to be available to
devices that provide a fake touch interface, you must also explicitly declare that a touch screen is
@@ -690,18 +725,53 @@
android:name="android.hardware.touchscreen" <strong>android:required="false"</strong>
/>}</p></td>
</tr>
+
+<tr>
+ <td><code>android.hardware.faketouch.multitouch.distinct</code></td>
+ <td>The application performs distinct tracking of two or more "fingers" on a fake touch
+interface. This is a superset of the faketouch feature.</td>
+ <td><p>When declared as required, this indicates that the application is compatible with a device
+only if it supports touch emulation for events that supports distinct tracking of two or more
+fingers, or better.</p>
+ <p>Unlike the distinct multitouch defined by {@code
+android.hardware.touchscreen.multitouch.distinct}, input devices that support distinct multi-touch
+with a fake touch interface will not support all two-finger gestures, because the input is
+being transformed to cursor movement on the screen. That is, single finger gestures on such a device
+move a cursor; two-finger swipes will result in single-finger touch events; other two-finger
+gestures will result in the corresponding two-finger touch event. An example device that supports
+distinct multi-touch with a fake touch interface is one that provides a trackpad for cursor movement
+which also supports two or more fingers.</p></td>
+</tr>
+
+<tr>
+ <td><code>android.hardware.faketouch.multitouch.jazzhand</code></td>
+ <td>The application performs distinct tracking of five or more "fingers" on a fake touch
+interface. This is a superset of the faketouch feature.</td>
+ <td><p>When declared as required, this indicates that the application is compatible with a device
+only if it supports touch emulation for events that supports distinct tracking of five or more
+fingers.</p>
+ <p>Unlike the distinct multitouch defined by {@code
+android.hardware.touchscreen.multitouch.jazzhand}, input devices that support jazzhand multi-touch
+with a fake touch interface will not support all five-finger gestures, because the input is being
+transformed to cursor movement on the screen. That is, single finger gestures on such a device move
+a cursor; multi-finger gestures will result in single-finger touch events; other multi-finger
+gestures will result in the corresponding multi-finger touch event. An example device that supports
+distinct multi-touch with a fake touch interface is one that provides a trackpad for cursor movement
+which also supports five or more fingers.</p></td>
+</tr>
+
<tr>
<td><code>android.hardware.touchscreen</code></td>
<td>The application uses touchscreen capabilities for gestures that are more interactive
-than basic touch events, such as a fling. This is a superset of the faketouch features.</td>
- <td>By default, your application requires this. As such, your application is
-<em>not</em> available to devices that provide only an emulated touch interface ("fake touch"), by
-default. If you want your application available to devices that provide a fake touch interface,
-you must explicitly declare that a touch screen is not required, by
-declaring {@code android.hardware.touchscreen} with {@code android:required="false"}. You should
-do so even if your application uses—but does not <em>require</em>—a real touch screen
-interface.
-<p>If your application <em>does require</em> a basic touch interface (in order to perform touch
+than basic touch events, such as a fling. This is a superset of the basic faketouch feature.</td>
+ <td><p>By default, your application requires this. As such, your application is <em>not</em>
+available to devices that provide only an emulated touch interface ("fake touch"), by default. If
+you want your application available to devices that provide a fake touch interface (or even devices
+that provide only a d-pad controller), you must explicitly declare that a touch screen is not
+required, by declaring {@code android.hardware.touchscreen} with {@code android:required="false"}.
+You should do so even if your application uses—but does not <em>require</em>—a real
+touch screen interface.</p>
+<p>If your application <em>does require</em> a touch interface (in order to perform touch
gestures such as a fling), then you don't need to do anything, because this is required by default.
However, it's best if you explicitly declare all features used by your application, so you should
still declare this if your app uses it.</p>
@@ -712,7 +782,7 @@
<td><code>android.hardware.touchscreen.multitouch</code></td>
<td>The application uses basic two-point multitouch capabilities on the device
screen, such as for pinch gestures, but does not need to track touches independently. This
-is a superset of touchscreen features.</td>
+is a superset of touchscreen feature.</td>
<td>This implicitly declares the <code>android.hardware.touchscreen</code> parent feature, unless
declared with <code>android:required="false"</code>. </td>
</tr>
@@ -720,7 +790,7 @@
<td><code>android.hardware.touchscreen.multitouch.distinct</code></td>
<td>Subfeature. The application uses advanced multipoint multitouch
capabilities on the device screen, such as for tracking two or more points fully
-independently. This is a superset of multitouch features.</td>
+independently. This is a superset of multitouch feature.</td>
<td rowspan="2">This implicitly declares the <code>android.hardware.touchscreen.multitouch</code>
parent feature, unless declared with <code>android:required="false"</code>. </td>
</tr>
@@ -728,7 +798,7 @@
<td><code>android.hardware.touchscreen.multitouch.jazzhand</code></td>
<td>The application uses advanced multipoint multitouch
capabilities on the device screen, for tracking up to five points fully
-independently. This is a superset of distinct multitouch features.</td>
+independently. This is a superset of distinct multitouch feature.</td>
</tr>
<tr>
diff --git a/docs/html/guide/topics/media/audio-capture.jd b/docs/html/guide/topics/media/audio-capture.jd
new file mode 100644
index 0000000..75d294b
--- /dev/null
+++ b/docs/html/guide/topics/media/audio-capture.jd
@@ -0,0 +1,253 @@
+page.title=Audio Capture
+parent.title=Multimedia and Camera
+parent.link=index.html
+@jd:body
+
+ <div id="qv-wrapper">
+ <div id="qv">
+
+<h2>In this document</h2>
+<ol>
+<li><a href="#audiocapture">Performing Audio Capture</a>
+ <ol>
+ <li><a href='#example'>Code Example</a></li>
+ </ol>
+</li>
+</ol>
+
+<h2>Key classes</h2>
+<ol>
+<li>{@link android.media.MediaRecorder}</li>
+</ol>
+
+<h2>See also</h2>
+<ol>
+ <li><a href="{@docRoot}guide/appendix/media-formats.html">Android Supported Media Formats</a></li>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a></li>
+ <li><a href="{@docRoot}guide/topics/media/mediaplayer.html">MediaPlayer</a>
+</ol>
+
+</div>
+</div>
+
+<p>The Android multimedia framework includes support for capturing and encoding a variety of common
+audio formats, so that you can easily integrate audio into your applications. You can record audio
+using the {@link android.media.MediaRecorder} APIs if supported by the device hardware.</p>
+
+<p>This document shows you how to write an application that captures audio from a device
+microphone, save the audio and play it back.</p>
+
+<p class="note"><strong>Note:</strong> The Android Emulator does not have the ability to capture
+audio, but actual devices are likely to provide these capabilities.</p>
+
+<h2 id="audiocapture">Performing Audio Capture</h2>
+
+<p>Audio capture from the device is a bit more complicated than audio and video playback, but still
+fairly simple:</p>
+<ol>
+ <li>Create a new instance of {@link android.media.MediaRecorder android.media.MediaRecorder}.</li>
+ <li>Set the audio source using
+ {@link android.media.MediaRecorder#setAudioSource MediaRecorder.setAudioSource()}. You will
+probably want to use
+ <code>MediaRecorder.AudioSource.MIC</code>.</li>
+ <li>Set output file format using
+ {@link android.media.MediaRecorder#setOutputFormat MediaRecorder.setOutputFormat()}.
+ </li>
+ <li>Set output file name using
+ {@link android.media.MediaRecorder#setOutputFile MediaRecorder.setOutputFile()}.
+ </li>
+ <li>Set the audio encoder using
+ {@link android.media.MediaRecorder#setAudioEncoder MediaRecorder.setAudioEncoder()}.
+ </li>
+ <li>Call {@link android.media.MediaRecorder#prepare MediaRecorder.prepare()}
+ on the MediaRecorder instance.</li>
+ <li>To start audio capture, call
+ {@link android.media.MediaRecorder#start MediaRecorder.start()}. </li>
+ <li>To stop audio capture, call {@link android.media.MediaRecorder#stop MediaRecorder.stop()}.
+ <li>When you are done with the MediaRecorder instance, call
+{@link android.media.MediaRecorder#release MediaRecorder.release()} on it. Calling
+{@link android.media.MediaRecorder#release MediaRecorder.release()} is always recommended to
+free the resource immediately.</li>
+</ol>
+
+<h3 id="example">Example: Record audio and play the recorded audio</h3>
+<p>The example class below illustrates how to set up, start and stop audio capture, and to play the
+recorded audio file.</p>
+<pre>
+/*
+ * The application needs to have the permission to write to external storage
+ * if the output file is written to the external storage, and also the
+ * permission to record audio. These permissions must be set in the
+ * application's AndroidManifest.xml file, with something like:
+ *
+ * <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ * <uses-permission android:name="android.permission.RECORD_AUDIO" />
+ *
+ */
+package com.android.audiorecordtest;
+
+import android.app.Activity;
+import android.widget.LinearLayout;
+import android.os.Bundle;
+import android.os.Environment;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.content.Context;
+import android.util.Log;
+import android.media.MediaRecorder;
+import android.media.MediaPlayer;
+
+import java.io.IOException;
+
+
+public class AudioRecordTest extends Activity
+{
+ private static final String LOG_TAG = "AudioRecordTest";
+ private static String mFileName = null;
+
+ private RecordButton mRecordButton = null;
+ private MediaRecorder mRecorder = null;
+
+ private PlayButton mPlayButton = null;
+ private MediaPlayer mPlayer = null;
+
+ private void onRecord(boolean start) {
+ if (start) {
+ startRecording();
+ } else {
+ stopRecording();
+ }
+ }
+
+ private void onPlay(boolean start) {
+ if (start) {
+ startPlaying();
+ } else {
+ stopPlaying();
+ }
+ }
+
+ private void startPlaying() {
+ mPlayer = new MediaPlayer();
+ try {
+ mPlayer.setDataSource(mFileName);
+ mPlayer.prepare();
+ mPlayer.start();
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "prepare() failed");
+ }
+ }
+
+ private void stopPlaying() {
+ mPlayer.release();
+ mPlayer = null;
+ }
+
+ private void startRecording() {
+ mRecorder = new MediaRecorder();
+ mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ mRecorder.setOutputFile(mFileName);
+ mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+
+ try {
+ mRecorder.prepare();
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "prepare() failed");
+ }
+
+ mRecorder.start();
+ }
+
+ private void stopRecording() {
+ mRecorder.stop();
+ mRecorder.release();
+ mRecorder = null;
+ }
+
+ class RecordButton extends Button {
+ boolean mStartRecording = true;
+
+ OnClickListener clicker = new OnClickListener() {
+ public void onClick(View v) {
+ onRecord(mStartRecording);
+ if (mStartRecording) {
+ setText("Stop recording");
+ } else {
+ setText("Start recording");
+ }
+ mStartRecording = !mStartRecording;
+ }
+ };
+
+ public RecordButton(Context ctx) {
+ super(ctx);
+ setText("Start recording");
+ setOnClickListener(clicker);
+ }
+ }
+
+ class PlayButton extends Button {
+ boolean mStartPlaying = true;
+
+ OnClickListener clicker = new OnClickListener() {
+ public void onClick(View v) {
+ onPlay(mStartPlaying);
+ if (mStartPlaying) {
+ setText("Stop playing");
+ } else {
+ setText("Start playing");
+ }
+ mStartPlaying = !mStartPlaying;
+ }
+ };
+
+ public PlayButton(Context ctx) {
+ super(ctx);
+ setText("Start playing");
+ setOnClickListener(clicker);
+ }
+ }
+
+ public AudioRecordTest() {
+ mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
+ mFileName += "/audiorecordtest.3gp";
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ LinearLayout ll = new LinearLayout(this);
+ mRecordButton = new RecordButton(this);
+ ll.addView(mRecordButton,
+ new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ 0));
+ mPlayButton = new PlayButton(this);
+ ll.addView(mPlayButton,
+ new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ 0));
+ setContentView(ll);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ if (mRecorder != null) {
+ mRecorder.release();
+ mRecorder = null;
+ }
+
+ if (mPlayer != null) {
+ mPlayer.release();
+ mPlayer = null;
+ }
+ }
+}
+</pre>
\ No newline at end of file
diff --git a/docs/html/guide/topics/media/camera.jd b/docs/html/guide/topics/media/camera.jd
new file mode 100644
index 0000000..877bded
--- /dev/null
+++ b/docs/html/guide/topics/media/camera.jd
@@ -0,0 +1,1055 @@
+page.title=Camera
+parent.title=Multimedia and Camera
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#considerations">Considerations</a></li>
+ <li><a href="#basics">The Basics</a>
+ <li><a href="#manifest">Manifest Declarations</a></li>
+ <li><a href="#intents">Using Existing Camera Apps</a>
+ <ol>
+ <li><a href="#intent-image">Image capture intent</a></li>
+ <li><a href="#intent-video">Video capture intent</a></li>
+ <li><a href="#intent-receive">Receiving camera intent result</a></li>
+ </ol>
+ <li><a href="#custom-camera">Building a Camera App</a>
+ <ol>
+ <li><a href="#detect-camera">Detecting camera hardware</a></li>
+ <li><a href="#access-camera">Accessing cameras</a></li>
+ <li><a href="#check-camera-features">Checking camera features</a></li>
+ <li><a href="#camera-preview">Creating a preview class</a></li>
+ <li><a href="#preview-layout">Placing preview in a layout</a></li>
+ <li><a href="#capture-picture">Capturing pictures</a></li>
+ <li><a href="#capture-video">Capturing videos</a></li>
+ <li><a href="#release-camera">Releasing the camera</a></li>
+ </ol>
+ </li>
+ <li><a href="#saving-media">Saving Media Files</a></li>
+ </ol>
+ <h2>Key Classes</h2>
+ <ol>
+ <li>{@link android.hardware.Camera}</li>
+ <li>{@link android.view.SurfaceView}</li>
+ <li>{@link android.media.MediaRecorder}</li>
+ <li>{@link android.content.Intent}</li>
+ </ol>
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}reference/android/hardware/Camera.html">Camera</a></li>
+ <li><a href="{@docRoot}reference/android/media/MediaRecorder.html">MediaRecorder</a></li>
+ <li><a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a></li>
+ </ol>
+ </div>
+</div>
+
+
+<p>The Android framework includes support for various cameras and camera features available on
+devices, allowing you to capture pictures and videos in your applications. This document discusses a
+quick, simple approach to image and video capture and outlines an advanced approach for creating
+custom camera experiences for your users.</p>
+
+<h2 id="considerations">Considerations</h2>
+<p>Before enabling your application to use cameras on Android devices, you should consider a few
+questions about how your app intends to use this hardware feature.</p>
+
+<ul>
+ <li><strong>Camera Requirement</strong> - Is the use of a camera so important to your
+application that you do not want your application installed on a device that does not have a
+camera? If so, you should declare the <a href="#manifest">camera requirement in your
+manifest</a>.</li>
+
+ <li><strong>Quick Picture or Customized Camera</strong> - How will your application use the
+camera? Are you just interested in snapping a quick picture or video clip, or will your application
+provide a new way to use cameras? For a getting a quick snap or clip, consider
+<a href="#intents">Using Existing Camera Apps</a>. For developing a customized camera feature, check
+out the <a href="#custom-camera">Building a Camera App</a> section.</li>
+
+ <li><strong>Storage</strong> - Are the images or videos your application generates intended to be
+only visible to your application or shared so that other applications such as Gallery or other
+media and social apps can use them? Do you want the pictures and videos to be available even if your
+application is uninstalled? Check out the <a href="#saving-media">Saving Media Files</a> section to
+see how to implement these options.</li>
+</ul>
+
+
+
+<h2 id="basics">The Basics</h2>
+<p>The Android framework supports capturing images and video through the
+{@link android.hardware.Camera} API or camera {@link android.content.Intent}. Here are the relevant
+classes:</p>
+
+<dl>
+ <dt>{@link android.hardware.Camera}</dt>
+ <dd>This class is the primary API for controlling device cameras. This class is used to take
+pictures or videos when you are building a camera application.</a>.</dd>
+
+ <dt>{@link android.view.SurfaceView}</dt>
+ <dd>This class is used to present a live camera preview to the user.</dd>
+
+ <dt>{@link android.media.MediaRecorder}</dt>
+ <dd>This class is used to record video from the camera.</dd>
+
+ <dt>{@link android.content.Intent}</dt>
+ <dd>An intent action type of {@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE
+MediaStore.ACTION_IMAGE_CAPTURE} or {@link android.provider.MediaStore#ACTION_VIDEO_CAPTURE
+MediaStore.ACTION_VIDEO_CAPTURE} can be used to capture images or videos without directly
+using the {@link android.hardware.Camera} object.</dd>
+</dl>
+
+
+<h2 id="manifest">Manifest Declarations</h2>
+<p>Before starting development on your application with the Camera API, you should make sure
+your manifest has the appropriate declarations to allow use of camera hardware and other
+related features.</p>
+
+<ul>
+ <li><strong>Camera Permission</strong> - Your application must request permission to use a device
+camera.
+<pre>
+<uses-permission android:name="android.permission.CAMERA" />
+</pre>
+ <p class="note"><strong>Note:</strong> If you are using the camera <a href="#intents">via an
+intent</a>, your application does not need to request this permission.</p>
+ </li>
+ <li><strong>Camera Features</strong> - Your application must also declare use of camera features,
+for example:
+<pre>
+<uses-feature android:name="android.hardware.camera" />
+</pre>
+ <p>For a list of camera features, see the manifest <a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html#features-reference">Features
+Reference</a>.</p>
+ <p>Adding camera features to your manifest causes Android Market to prevent your application from
+being installed to devices that do not include a camera or do not support the camera features you
+specify. For more information about using feature-based filtering with Android Market, see <a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html#market-feature-filtering">Android
+Market and Feature-Based Filtering</a>.</p>
+ <p>If your application <em>can use</em> a camera or camera feature for proper operation, but does
+not <em>require</em> it, you should specify this in the manifest by including the {@code
+android:required} attribute, and setting it to {@code false}:</p>
+<pre>
+<uses-feature android:name="android.hardware.camera" android:required="false" />
+</pre>
+
+ </li>
+ <li><strong>Storage Permission</strong> - If your application saves images or videos to the
+device's external storage (SD Card), you must also specify this in the manifest.
+<pre>
+<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+</pre>
+ </li>
+ <li><strong>Audio Recording Permission</strong> - For recording audio with video capture, your
+application must request the audio capture permission.
+<pre>
+<uses-permission android:name="android.permission.RECORD_AUDIO" />
+</pre>
+ </li>
+</ul>
+
+
+<h2 id="intents">Using Existing Camera Apps</h2>
+<p>A quick way to enable taking pictures or videos in your application without a lot of extra code
+is to use an {@link android.content.Intent} to invoke an existing Android camera application. A
+camera intent makes a request to capture a picture or video clip through an existing camera app and
+then returns control back to your application. This section shows you how to capture an image or
+video using this technique.</p>
+
+<p>The procedure for invoking a camera intent follows these general steps:</p>
+
+<ol>
+ <li><strong>Compose a Camera Intent</strong> - Create an {@link android.content.Intent} that
+requests an image or video, using one of these intent types:
+ <ul>
+ <li>{@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE MediaStore.ACTION_IMAGE_CAPTURE} -
+Intent action type for requesting an image from an existing camera application.</li>
+ <li>{@link android.provider.MediaStore#ACTION_VIDEO_CAPTURE MediaStore.ACTION_VIDEO_CAPTURE} -
+Intent action type for requesting a video from an existing camera application. </li>
+ </ul>
+ </li>
+ <li><strong>Start the Camera Intent</strong> - Use the {@link
+android.app.Activity#startActivityForResult(android.content.Intent, int) startActivityForResult()}
+method to execute the camera intent. After you start the intent, the Camera application user
+interface appears on the device screen and the user can take a picture or video.</li>
+ <li><strong>Receive the Intent Result</strong> - Set up an {@link
+android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()} method
+in your application to receive the callback and data from the camera intent. When the user
+finishes taking a picture or video (or cancels the operation), the system calls this method.</li>
+</ol>
+
+
+<h3 id="intent-image">Image capture intent</h3>
+<p>Capturing images using a camera intent is quick way to enable your application to take pictures
+with minimal coding. An image capture intent can include the following extra information:</p>
+
+<ul>
+ <li>{@link android.provider.MediaStore#EXTRA_OUTPUT MediaStore.EXTRA_OUTPUT} - This setting
+requires a {@link android.net.Uri} object specifying a path and file name where you'd like to
+save the picture. This setting is optional but strongly recommended. If you do not specify this
+value, the camera application saves the requested picture in the default location with a default
+name, specified in the returned intent's {@link android.content.Intent#getData() Intent.getData()}
+field.</li>
+</ul>
+
+<p>The following example demonstrates how to construct a image capture intent and execute it.
+The {@code getOutputMediaFileUri()} method in this example refers to the sample code shown in <a
+href= "#saving-media">Saving Media Files</a>.</p>
+
+<pre>
+private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
+private Uri fileUri;
+
+@Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ // create Intent to take a picture and return control to the calling application
+ Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+
+ fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
+ intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
+
+ // start the image capture Intent
+ startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
+}
+</pre>
+
+<p>When the {@link android.app.Activity#startActivityForResult(android.content.Intent, int)
+startActivityForResult()} method is executed, users see a camera application interface.
+After the user finishes taking a picture (or cancels the operation), the user interface returns to
+your application, and you must intercept the {@link
+android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()}
+method to receive the result of the intent and continue your application execution. For information
+on how to receive the completed intent, see <a href="#intent-receive">Receiving Camera Intent
+Result</a>.</p>
+
+
+<h3 id="intent-video">Video capture intent</h3>
+<p>Capturing video using a camera intent is a quick way to enable your application to take videos
+with minimal coding. A video capture intent can include the following extra information:</p>
+
+<ul>
+ <li>{@link android.provider.MediaStore#EXTRA_OUTPUT MediaStore.EXTRA_OUTPUT} - This setting
+requires a {@link android.net.Uri} specifying a path and file name where you'd like to save the
+video. This setting is optional but strongly recommended. If you do not specify this value, the
+Camera application saves the requested video in the default location with a default name, specified
+in the returned intent's {@link android.content.Intent#getData() Intent.getData()} field.</li>
+ <li>{@link android.provider.MediaStore#EXTRA_VIDEO_QUALITY MediaStore.EXTRA_VIDEO_QUALITY} -
+This value can be 0 for lowest quality and smallest file size or 1 for highest quality and
+larger file size.</li>
+ <li>{@link android.provider.MediaStore#EXTRA_DURATION_LIMIT MediaStore.EXTRA_DURATION_LIMIT} -
+Set this value to limit the length, in seconds, of the video being captured.</li>
+ <li>{@link android.provider.MediaStore#EXTRA_SIZE_LIMIT MediaStore.EXTRA_SIZE_LIMIT} -
+Set this value to limit the file size, in bytes, of the video being captured.
+</li>
+</ul>
+
+<p>The following example demonstrates how to construct a video capture intent and execute it.
+The {@code getOutputMediaFileUri()} method in this example refers to the sample code shown in <a
+href= "#saving-media">Saving Media Files</a>.</p>
+
+<pre>
+private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
+private Uri fileUri;
+
+@Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ //create new Intent
+ Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
+
+ fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO); // create a file to save the video
+ intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
+
+ intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high
+
+ // start the Video Capture Intent
+ startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
+}
+</pre>
+
+<p>When the {@link
+android.app.Activity#startActivityForResult(android.content.Intent, int)
+startActivityForResult()} method is executed, users see a modified camera application interface.
+After the user finishes taking a video (or cancels the operation), the user interface
+returns to your application, and you must intercept the {@link
+android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()}
+method to receive the result of the intent and continue your application execution. For information
+on how to receive the completed intent, see the next section.</p>
+
+<h3 id="intent-receive">Receiving camera intent result</h3>
+<p>Once you have constructed and executed an image or video camera intent, your application must be
+configured to receive the result of the intent. This section shows you how to intercept the callback
+from a camera intent so your application can do further processing of the captured image or
+video.</p>
+
+<p>In order to receive the result of an intent, you must override the {@link
+android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()} in the
+activity that started the intent. The following example demonstrates how to override {@link
+android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()} to
+capture the result of the <a href="#intent-image">image camera intent</a> or <a
+href="#intent-video">video camera intent</a> examples shown in the previous sections.</p>
+
+<pre>
+private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
+private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
+
+@Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
+ if (resultCode == RESULT_OK) {
+ // Image captured and saved to fileUri specified in the Intent
+ Toast.makeText(this, "Image saved to:\n" +
+ data.getData(), Toast.LENGTH_LONG).show();
+ } else if (resultCode == RESULT_CANCELED) {
+ // User cancelled the image capture
+ } else {
+ // Image capture failed, advise user
+ }
+ }
+
+ if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
+ if (resultCode == RESULT_OK) {
+ // Video captured and saved to fileUri specified in the Intent
+ Toast.makeText(this, "Video saved to:\n" +
+ data.getData(), Toast.LENGTH_LONG).show();
+ } else if (resultCode == RESULT_CANCELED) {
+ // User cancelled the video capture
+ } else {
+ // Video capture failed, advise user
+ }
+ }
+}
+</pre>
+
+<p>Once your activity receives a successful result, the captured image or video is available in the
+specified location for your application to access.</p>
+
+
+
+<h2 id="custom-camera">Building a Camera App</h2>
+<p>Some developers may require a camera user interface that is customized to the look of their
+application or provides special features. Creating a customized camera activity requires more
+code than <a href="#intents">using an intent</a>, but it can provide a more compelling experience
+for your users.</p>
+
+<p>The general steps for creating a custom camera interface for your application are as follows:</p>
+
+<ul>
+ <li><strong>Detect and Access Camera</strong> - Create code to check for the existence of
+cameras and request access.</li>
+ <li><strong>Create a Preview Class</strong> - Create a camera preview class that extends {@link
+android.view.SurfaceView} and implements the {@link android.view.SurfaceHolder} interface. This
+class previews the live images from the camera.</li>
+ <li><strong>Build a Preview Layout</strong> - Once you have the camera preview class, create a
+view layout that incorporates the preview and the user interface controls you want.</li>
+ <li><strong>Setup Listeners for Capture</strong> - Connect listeners for your interface
+controls to start image or video capture in response to user actions, such as pressing a
+button.</li>
+ <li><strong>Capture and Save Files</strong> - Setup the code for capturing pictures or
+videos and saving the output.</li>
+ <li><strong>Release the Camera</strong> - After using the camera, your application must
+properly release it for use by other applications.</li>
+</ul>
+
+<p>Camera hardware is a shared resource that must be carefully managed so your application does
+not collide with other applications that may also want to use it. The following sections discusses
+how to detect camera hardware, how to request access to a camera and how to release it when your
+application is done using it.</p>
+
+<p class="caution"><strong>Caution:</strong> Remember to release the {@link android.hardware.Camera}
+object by calling the {@link android.hardware.Camera#release() Camera.release()} when your
+application is done using it! If your application does not properly release the camera, all
+subsequent attempts to access the camera, including those by your own application, will fail and may
+cause your or other applications to be shut down.</p>
+
+
+<h3 id="detect-camera">Detecting camera hardware</h3>
+<p>If your application does not specifically require a camera using a manifest declaration, you
+should check to see if a camera is available at runtime. To perform this check, use the {@link
+android.content.pm.PackageManager#hasSystemFeature(java.lang.String)
+PackageManager.hasSystemFeature()} method, as shown in the example code below:</p>
+
+<pre>
+/** Check if this device has a camera */
+private boolean checkCameraHardware(Context context) {
+ if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
+ // this device has a camera
+ return true;
+ } else {
+ // no camera on this device
+ return false;
+ }
+}
+</pre>
+
+<p>Android devices can have multiple cameras, for example a back-facing camera for photography and a
+front-facing camera for video calls. Android 2.3 (API Level 9) and later allows you to check the
+number of cameras available on a device using the {@link
+android.hardware.Camera#getNumberOfCameras() Camera.getNumberOfCameras()} method.</p>
+
+<h3 id="access-camera">Accessing cameras</h3>
+<p>If you have determined that the device on which your application is running has a camera, you
+must request to access it by getting an instance of {@link android.hardware.Camera} (unless you
+are using an <a href="#intents">intent to access the camera</a>). </p>
+
+<p>To access the primary camera, use the {@link android.hardware.Camera#open() Camera.open()} method
+and be sure to catch any exceptions, as shown in the code below:</p>
+
+<pre>
+/** A safe way to get an instance of the Camera object. */
+public static Camera getCameraInstance(){
+ Camera c = null;
+ try {
+ c = Camera.open(); // attempt to get a Camera instance
+ }
+ catch (Exception e){
+ // Camera is not available (in use or does not exist)
+ }
+ return c; // returns null if camera is unavailable
+}
+</pre>
+
+<p class="caution"><strong>Caution:</strong> Always check for exceptions when using {@link
+android.hardware.Camera#open() Camera.open()}. Failing to check for exceptions if the camera is in
+use or does not exist will cause your application to be shut down by the system.</p>
+
+<p>On devices running Android 2.3 (API Level 9) or higher, you can access specific cameras using
+{@link android.hardware.Camera#open(int) Camera.open(int)}. The example code above will access
+the first, back-facing camera on a device with more than one camera.</p>
+
+<h3 id="check-camera-features">Checking camera features</h3>
+<p>Once you obtain access to a camera, you can get further information about its capabilties using
+the {@link android.hardware.Camera#getParameters() Camera.getParameters()} method and checking the
+returned {@link android.hardware.Camera.Parameters} object for supported capabilities. When using
+API Level 9 or higher, use the {@link android.hardware.Camera#getCameraInfo(int,
+android.hardware.Camera.CameraInfo) Camera.getCameraInfo()} to determine if a camera is on the front
+or back of the device, and the orientation of the image.</p>
+
+
+
+<h3 id="camera-preview">Creating a preview class</h3>
+<p>For users to effectively take pictures or video, they must be able to see what the device camera
+sees. A camera preview class is a {@link android.view.SurfaceView} that can display the live image
+data coming from a camera, so users can frame and capture a picture or video.</p>
+
+<p>The following example code demonstrates how to create a basic camera preview class that can be
+included in a {@link android.view.View} layout. This class implements {@link
+android.view.SurfaceHolder.Callback SurfaceHolder.Callback} in order to capture the callback events
+for creating and destroying the view, which are needed for assigning the camera preview input.</p>
+
+<pre>
+/** A basic Camera preview class */
+public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
+ private SurfaceHolder mHolder;
+ private Camera mCamera;
+
+ public CameraPreview(Context context, Camera camera) {
+ super(context);
+ mCamera = camera;
+
+ // Install a SurfaceHolder.Callback so we get notified when the
+ // underlying surface is created and destroyed.
+ mHolder = getHolder();
+ mHolder.addCallback(this);
+ // deprecated setting, but required on Android versions prior to 3.0
+ mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+ }
+
+ public void surfaceCreated(SurfaceHolder holder) {
+ // The Surface has been created, now tell the camera where to draw the preview.
+ try {
+ mCamera.setPreviewDisplay(holder);
+ mCamera.startPreview();
+ } catch (IOException e) {
+ Log.d(TAG, "Error setting camera preview: " + e.getMessage());
+ }
+ }
+
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ // empty. Take care of releasing the Camera preview in your activity.
+ }
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+ // If your preview can change or rotate, take care of those events here.
+ // Make sure to stop the preview before resizing or reformatting it.
+
+ if (mHolder.getSurface() == null){
+ // preview surface does not exist
+ return;
+ }
+
+ // stop preview before making changes
+ try {
+ mCamera.stopPreview();
+ } catch (Exception e){
+ // ignore: tried to stop a non-existent preview
+ }
+
+ // make any resize, rotate or reformatting changes here
+
+ // start preview with new settings
+ try {
+ mCamera.setPreviewDisplay(mHolder);
+ mCamera.startPreview();
+
+ } catch (Exception e){
+ Log.d(TAG, "Error starting camera preview: " + e.getMessage());
+ }
+ }
+}
+</pre>
+
+
+<h3 id="preview-layout">Placing preview in a layout</h3>
+<p>A camera preview class, such as the example shown in the previous section, must be placed in the
+layout of an activity along with other user interface controls for taking a picture or video. This
+section shows you how to build a basic layout and activity for the preview.</p>
+
+<p>The following layout code provides a very basic view that can be used to display a camera
+preview. In this example, the {@link android.widget.FrameLayout} element is meant to be the
+container for the camera preview class. This layout type is used so that additional picture
+information or controls can be overlayed on the live camera preview images.</p>
+
+<pre>
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+ <FrameLayout
+ android:id="@+id/camera_preview"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ />
+
+ <Button
+ android:id="@+id/button_capture"
+ android:text="Capture"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ />
+</LinearLayout>
+</pre>
+
+<p>On most devices, the default orientation of the camera preview is landscape. This example layout
+specifies a horizontal (landscape) layout and the code below fixes the orientation of the
+application to landscape. For simplicity in rendering a camera preview, you should change your
+application's preview activity orientation to landscape by adding the following to your
+manifest.</p>
+
+<pre>
+<activity android:name=".CameraActivity"
+ android:label="@string/app_name"
+
+ android:screenOrientation="landscape">
+ <!-- configure this activity to use landscape orientation -->
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+</activity>
+</pre>
+
+<p class="note"><strong>Note:</strong> A camera preview does not have to be in landscape mode.
+Starting in Android 2.2 (API Level 8), you can use the {@link
+android.hardware.Camera#setDisplayOrientation(int) setDisplayOrientation()} method to set the
+rotation of the preview image. In order to change preview orientation as the user re-orients the
+phone, within the {@link
+android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder, int, int, int)
+surfaceChanged()} method of your preview class, first stop the preview with {@link
+android.hardware.Camera#stopPreview() Camera.stopPreview()} change the orientation and then
+start the preview again with {@link android.hardware.Camera#startPreview()
+Camera.startPreview()}.</p>
+
+<p>In the activity for your camera view, add your preview class to the {@link
+android.widget.FrameLayout} element shown in the example above. Your camera activity must also
+ensure that it releases the camera when it is paused or shut down. The following example shows how
+to modify a camera activity to attach the preview class shown in <a href="#camera-preview">Creating
+a preview class</a>.</p>
+
+<pre>
+public class CameraActivity extends Activity {
+
+ private Camera mCamera;
+ private CameraPreview mPreview;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ // Create an instance of Camera
+ mCamera = getCameraInstance();
+
+ // Create our Preview view and set it as the content of our activity.
+ mPreview = new CameraPreview(this, mCamera);
+ FrameLayout preview = (FrameLayout) findViewById(id.camera_preview);
+ preview.addView(mPreview);
+ }
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> The {@code getCameraInstance()} method in the example above
+refers to the example method shown in <a href="#access-camera">Accessing cameras</a>.</p>
+
+
+<h3 id="capture-picture">Capturing pictures</h3>
+<p>Once you have built a preview class and a view layout in which to display it, you are ready to
+start capturing images with your application. In your application code, you must set up listeners
+for your user interface controls to respond to a user action by taking a picture.</p>
+
+<p>In order to retrieve a picture, use the {@link
+android.hardware.Camera#takePicture(android.hardware.Camera.ShutterCallback,
+android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback)
+Camera.takePicture()} method. This method takes three parameters which receive data from the camera.
+In order to receive data in a JPEG format, you must implement an {@link
+android.hardware.Camera.PictureCallback} interface to receive the image data and
+write it to a file. The following code shows a basic implementation of the {@link
+android.hardware.Camera.PictureCallback} interface to save an image received from the camera.</p>
+
+<pre>
+private PictureCallback mPicture = new PictureCallback() {
+
+ @Override
+ public void onPictureTaken(byte[] data, Camera camera) {
+
+ File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
+ if (pictureFile == null){
+ Log.d(TAG, "Error creating media file, check storage permissions: " +
+ e.getMessage());
+ return;
+ }
+
+ try {
+ FileOutputStream fos = new FileOutputStream(pictureFile);
+ fos.write(data);
+ fos.close();
+ } catch (FileNotFoundException e) {
+ Log.d(TAG, "File not found: " + e.getMessage());
+ } catch (IOException e) {
+ Log.d(TAG, "Error accessing file: " + e.getMessage());
+ }
+ }
+};
+</pre>
+
+<p>Trigger capturing an image by calling the {@link
+android.hardware.Camera#takePicture(android.hardware.Camera.ShutterCallback,
+android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback)
+Camera.takePicture()} method. The following example code shows how to call this method from a
+button {@link android.view.View.OnClickListener}.</p>
+
+<pre>
+// Add a listener to the Capture button
+Button captureButton = (Button) findViewById(id.button_capture);
+ captureButton.setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // get an image from the camera
+ mCamera.takePicture(null, null, mPicture);
+ }
+ }
+);
+</pre>
+
+<p class="note"><strong>Note:</strong> The {@code mPicture} member in the following example refers
+to the example code above.</p>
+
+<p class="caution"><strong>Caution:</strong> Remember to release the {@link android.hardware.Camera}
+object by calling the {@link android.hardware.Camera#release() Camera.release()} when your
+application is done using it! For information about how to release the camera, see <a
+href="#release-camera">Releasing the camera</a>.</p>
+
+
+<h3 id="capture-video">Capturing videos</h3>
+
+<p>Video capture using the Android framework requires careful management of the {@link
+android.hardware.Camera} object and coordination with the {@link android.media.MediaRecorder}
+class. When recording video with {@link android.hardware.Camera}, you must manage the {@link
+android.hardware.Camera#lock() Camera.lock()} and {@link android.hardware.Camera#unlock()
+Camera.unlock()} calls to allow {@link android.media.MediaRecorder} access to the camera hardware,
+in addition to the {@link android.hardware.Camera#open() Camera.open()} and {@link
+android.hardware.Camera#release() Camera.release()} calls.</p>
+
+<p class="note"><strong>Note:</strong> Starting with Android 4.0 (API level 14), the {@link
+android.hardware.Camera#lock() Camera.lock()} and {@link android.hardware.Camera#unlock()
+Camera.unlock()} calls are managed for you automatically.</p>
+
+<p>Unlike taking pictures with a device camera, capturing video requires a very particular call
+order. You must follow a specific order of execution to successfully prepare for and capture video
+with your application, as detailed below.</p>
+
+<ol>
+ <li><strong>Open Camera</strong> - Use the {@link android.hardware.Camera#open() Camera.open()}
+to get an instance of the camera object.</li>
+ <li><strong>Connect Preview</strong> - Prepare a live camera image preview by connecting a {@link
+android.view.SurfaceView} to the camera using {@link
+android.hardware.Camera#setPreviewDisplay(android.view.SurfaceHolder) Camera.setPreviewDisplay()}.
+ </li>
+ <li><strong>Start Preview</strong> - Call {@link android.hardware.Camera#startPreview()
+Camera.startPreview()} to begin displaying the live camera images.</li>
+ <li><strong>Start Recording Video</strong> - The following steps must be completed <em>in
+order</em> to successfully record video:
+ <ol style="list-style-type: lower-alpha;">
+ <li><strong>Unlock the Camera</strong> - Unlock the camera for use by {@link
+android.media.MediaRecorder} by calling {@link android.hardware.Camera#unlock()
+Camera.unlock()}.</li>
+ <li><strong>Configure MediaRecorder</strong> - Call in the following {@link
+android.media.MediaRecorder} methods <em>in this order</em>. For more information, see the {@link
+android.media.MediaRecorder} reference documentation.
+ <ol>
+ <li>{@link android.media.MediaRecorder#setCamera(android.hardware.Camera)
+setCamera()} - Set the camera to be used for video capture, use your application's current instance
+of {@link android.hardware.Camera}.</li>
+ <li>{@link android.media.MediaRecorder#setAudioSource(int) setAudioSource()} - Set the
+audio source, use {@link android.media.MediaRecorder.AudioSource#CAMCORDER
+MediaRecorder.AudioSource.CAMCORDER}. </li>
+ <li>{@link android.media.MediaRecorder#setVideoSource(int) setVideoSource()} - Set
+the video source, use {@link android.media.MediaRecorder.VideoSource#CAMERA
+MediaRecorder.VideoSource.CAMERA}.</li>
+ <li>Set the video output format and encoding. For Android 2.2 (API Level 8) and
+higher, use the {@link android.media.MediaRecorder#setProfile(android.media.CamcorderProfile)
+MediaRecorder.setProfile} method, and get a profile instance using {@link
+android.media.CamcorderProfile#get(int) CamcorderProfile.get()}. For versions of Android prior to
+2.2, you must set the video output format and encoding parameters:
+ <ol style="list-style-type: lower-roman;">
+ <li>{@link android.media.MediaRecorder#setOutputFormat(int) setOutputFormat()} - Set
+the output format, specify the default setting or {@link
+android.media.MediaRecorder.OutputFormat#MPEG_4 MediaRecorder.OutputFormat.MPEG_4}.</li>
+ <li>{@link android.media.MediaRecorder#setAudioEncoder(int) setAudioEncoder()} - Set
+the sound encoding type, specify the default setting or {@link
+android.media.MediaRecorder.AudioEncoder#AMR_NB MediaRecorder.AudioEncoder.AMR_NB}.</li>
+ <li>{@link android.media.MediaRecorder#setVideoEncoder(int) setVideoEncoder()} - Set
+the video encoding type, specify the default setting or {@link
+android.media.MediaRecorder.VideoEncoder#MPEG_4_SP MediaRecorder.VideoEncoder.MPEG_4_SP}.</li>
+ </ol>
+ </li>
+ <li>{@link android.media.MediaRecorder#setOutputFile(java.lang.String) setOutputFile()} -
+Set the output file, use {@code getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()} from the example
+method in the <a href="#saving-media">Saving Media Files</a> section.</li>
+ <li>{@link android.media.MediaRecorder#setPreviewDisplay(android.view.Surface)
+setPreviewDisplay()} - Specify the {@link android.view.SurfaceView} preview layout element for
+your application. Use the same object you specified for <strong>Connect Preview</strong>.</li>
+ </ol>
+ <p class="caution"><strong>Caution:</strong> You must call these {@link
+android.media.MediaRecorder} configuration methods <em>in this order</em>, otherwise your
+application will encounter errors and the recording will fail.</p>
+ </li>
+ <li><strong>Prepare MediaRecorder</strong> - Prepare the {@link android.media.MediaRecorder}
+with provided configuration settings by calling {@link android.media.MediaRecorder#prepare()
+MediaRecorder.prepare()}.</li>
+ <li><strong>Start MediaRecorder</strong> - Start recording video by calling {@link
+android.media.MediaRecorder#start() MediaRecorder.start()}.</li>
+ </ol>
+ </li>
+ <li><strong>Stop Recording Video</strong> - Call the following methods <em>in order</em>, to
+successfully complete a video recording:
+ <ol style="list-style-type: lower-alpha;">
+ <li><strong>Stop MediaRecorder</strong> - Stop recording video by calling {@link
+android.media.MediaRecorder#stop() MediaRecorder.stop()}.</li>
+ <li><strong>Reset MediaRecorder</strong> - Optionally, remove the configuration settings from
+the recorder by calling {@link android.media.MediaRecorder#reset() MediaRecorder.reset()}.</li>
+ <li><strong>Release MediaRecorder</strong> - Release the {@link android.media.MediaRecorder}
+by calling {@link android.media.MediaRecorder#release() MediaRecorder.release()}.</li>
+ <li><strong>Lock the Camera</strong> - Lock the camera so that future {@link
+android.media.MediaRecorder} sessions can use it by calling {@link android.hardware.Camera#lock()
+Camera.lock()}. Starting with Android 4.0 (API level 14), this call is not required unless the
+{@link android.media.MediaRecorder#prepare() MediaRecorder.prepare()} call fails.</li>
+ </ol>
+ </li>
+ <li><strong>Stop the Preview</strong> - When your activity has finished using the camera, stop the
+preview using {@link android.hardware.Camera#stopPreview() Camera.stopPreview()}.</li>
+ <li><strong>Release Camera</strong> - Release the camera so that other applications can use
+it by calling {@link android.hardware.Camera#release() Camera.release()}.</li>
+</ol>
+
+<p class="note"><strong>Note:</strong> It is possible to use {@link android.media.MediaRecorder}
+without creating a camera preview first and skip the first few steps of this process. However,
+since users typically prefer to see a preview before starting a recording, that process is not
+discussed here.</p>
+
+<h4 id="configuring-mediarecorder">Configuring MediaRecorder</h4>
+<p>When using the {@link android.media.MediaRecorder} class to record video, you must perform
+configuration steps in a <em>specific order</em> and then call the {@link
+android.media.MediaRecorder#prepare() MediaRecorder.prepare()} method to check and implement the
+configuration. The following example code demonstrates how to properly configure and prepare the
+{@link android.media.MediaRecorder} class for video recording.</p>
+
+<pre>
+private boolean prepareVideoRecorder(){
+
+ mCamera = getCameraInstance();
+ mMediaRecorder = new MediaRecorder();
+
+ // Step 1: Unlock and set camera to MediaRecorder
+ mCamera.unlock();
+ mMediaRecorder.setCamera(mCamera);
+
+ // Step 2: Set sources
+ mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
+ mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+
+ // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
+ mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
+
+ // Step 4: Set output file
+ mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
+
+ // Step 5: Set the preview output
+ mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
+
+ // Step 6: Prepare configured MediaRecorder
+ try {
+ mMediaRecorder.prepare();
+ } catch (IllegalStateException e) {
+ Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
+ releaseMediaRecorder();
+ return false;
+ } catch (IOException e) {
+ Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
+ releaseMediaRecorder();
+ return false;
+ }
+ return true;
+}
+</pre>
+
+<p>Prior to Android 2.2 (API Level 8), you must set the output format and encoding formats
+parameters directly, instead of using {@link android.media.CamcorderProfile}. This approach is
+demonstrated in the following code:</p>
+
+<pre>
+ // Step 3: Set output format and encoding (for versions prior to API Level 8)
+ mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
+ mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
+ mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
+</pre>
+
+<p>The following video recording parameters for {@link android.media.MediaRecorder} are given
+default settings, however, you may want to adjust these settings for your application:</p>
+
+<ul>
+ <li>{@link android.media.MediaRecorder#setVideoEncodingBitRate(int)
+setVideoEncodingBitRate()}</li>
+ <li>{@link android.media.MediaRecorder#setVideoSize(int, int) setVideoSize()}</li>
+ <li>{@link android.media.MediaRecorder#setVideoFrameRate(int) setVideoFrameRate()}</li>
+ <li>{@link android.media.MediaRecorder#setAudioEncodingBitRate(int)
+setAudioEncodingBitRate()}</li> <li>{@link android.media.MediaRecorder#setAudioChannels(int)
+setAudioChannels()}</li>
+ <li>{@link android.media.MediaRecorder#setAudioSamplingRate(int) setAudioSamplingRate()}</li>
+</ul>
+
+<h4 id="start-stop-mediarecorder">Starting and Stopping MediaRecorder</h4>
+<p>When starting and stopping video recording using the {@link android.media.MediaRecorder} class,
+you must follow a specific order, as listed below.</p>
+
+<ol>
+ <li>Unlock the camera with {@link android.hardware.Camera#unlock() Camera.unlock()}</li>
+ <li>Configure {@link android.media.MediaRecorder} as shown in the code example above</li>
+ <li>Start recording using {@link android.media.MediaRecorder#start()
+MediaRecorder.start()}</li>
+ <li>Record the video</li>
+ <li>Stop recording using {@link
+android.media.MediaRecorder#stop() MediaRecorder.stop()}</li>
+ <li>Release the media recorder with {@link android.media.MediaRecorder#release()
+MediaRecorder.release()}</li>
+ <li>Lock the camera using {@link android.hardware.Camera#lock() Camera.lock()}</li>
+</ol>
+
+<p>The following example code demonstrates how to wire up a button to properly start and stop
+video recording using the camera and the {@link android.media.MediaRecorder} class.</p>
+
+<p class="note"><strong>Note:</strong> When completing a video recording, do not release the camera
+or else your preview will be stopped.</p>
+
+<pre>
+private boolean isRecording = false;
+
+// Add a listener to the Capture button
+Button captureButton = (Button) findViewById(id.button_capture);
+captureButton.setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (isRecording) {
+ // stop recording and release camera
+ mMediaRecorder.stop(); // stop the recording
+ releaseMediaRecorder(); // release the MediaRecorder object
+ mCamera.lock(); // take camera access back from MediaRecorder
+
+ // inform the user that recording has stopped
+ setCaptureButtonText("Capture");
+ isRecording = false;
+ } else {
+ // initialize video camera
+ if (prepareVideoRecorder()) {
+ // Camera is available and unlocked, MediaRecorder is prepared,
+ // now you can start recording
+ mMediaRecorder.start();
+
+ // inform the user that recording has started
+ setCaptureButtonText("Stop");
+ isRecording = true;
+ } else {
+ // prepare didn't work, release the camera
+ releaseMediaRecorder();
+ // inform user
+ }
+ }
+ }
+ }
+);
+</pre>
+
+<p class="note"><strong>Note:</strong> In the above example, the {@code prepareVideoRecorder()}
+method refers to the example code shown in <a
+href="#configuring-mediarecorder">Configuring MediaRecorder</a>. This method takes care of locking
+the camera, configuring and preparing the {@link android.media.MediaRecorder} instance.</p>
+
+
+<h3 id="release-camera">Releasing the camera</h3>
+<p>Cameras are a resource that is shared by applications on a device. Your application can make
+use of the camera after getting an instance of {@link android.hardware.Camera}, and you must be
+particularly careful to release the camera object when your application stops using it, and as
+soon as your application is paused ({@link android.app.Activity#onPause() Activity.onPause()}). If
+your application does not properly release the camera, all subsequent attempts to access the camera,
+including those by your own application, will fail and may cause your or other applications to be
+shut down.</p>
+
+<p>To release an instance of the {@link android.hardware.Camera} object, use the {@link
+android.hardware.Camera#release() Camera.release()} method, as shown in the example code below.</p>
+
+<pre>
+public class CameraActivity extends Activity {
+ private Camera mCamera;
+ private SurfaceView mPreview;
+ private MediaRecorder mMediaRecorder;
+
+ ...
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ releaseMediaRecorder(); // if you are using MediaRecorder, release it first
+ releaseCamera(); // release the camera immediately on pause event
+ }
+
+ private void releaseMediaRecorder(){
+ if (mMediaRecorder != null) {
+ mMediaRecorder.reset(); // clear recorder configuration
+ mMediaRecorder.release(); // release the recorder object
+ mMediaRecorder = null;
+ mCamera.lock(); // lock camera for later use
+ }
+ }
+
+ private void releaseCamera(){
+ if (mCamera != null){
+ mCamera.release(); // release the camera for other applications
+ mCamera = null;
+ }
+ }
+}
+</pre>
+
+<p class="caution"><strong>Caution:</strong> If your application does not properly release the
+camera, all subsequent attempts to access the camera, including those by your own application, will
+fail and may cause your or other applications to be shut down.</p>
+
+
+<h2 id="saving-media">Saving Media Files</h2>
+<p>Media files created by users such as pictures and videos should be saved to a device's external
+storage directory (SD Card) to conserve system space and to allow users to access these files
+without their device. There are many possible directory locations to save media files on a device,
+however there are only two standard locations you should consider as a developer:</p>
+
+<ul>
+ <li><strong>{@link android.os.Environment#getExternalStoragePublicDirectory(java.lang.String)
+Environment.getExternalStoragePublicDirectory}({@link android.os.Environment#DIRECTORY_PICTURES
+Environment.DIRECTORY_PICTURES})</strong> - This method returns the standard, shared and recommended
+location for saving pictures and videos. This directory is shared (public), so other applications
+can easily discover, read, change and delete files saved in this location. If your application is
+uninstalled by the user, media files saved to this location will not be removed. To avoid
+interfering with users existing pictures and videos, you should create a sub-directory for your
+application's media files within this directory, as shown in the code sample below. This method is
+available in Android 2.2 (API Level 8), for equivalent calls in earlier API versions, see <a
+href="{@docRoot}guide/topics/data/data-storage.html#SavingSharedFiles">Saving Shared Files</a>.</li>
+ <li><strong>{@link android.content.Context#getExternalFilesDir(java.lang.String)
+Context.getExternalFilesDir}({@link android.os.Environment#DIRECTORY_PICTURES
+Environment.DIRECTORY_PICTURES})</strong> - This method returns a standard location for saving
+pictures and videos which are associated with your application. If your application is uninstalled,
+any files saved in this location are removed. Security is not enforced for files in this
+location and other applications may read, change and delete them.</li>
+</ul>
+
+<p>The following example code demonstrates how to create a {@link java.io.File} or {@link
+android.net.Uri} location for a media file that can be used when invoking a device's camera with
+an {@link android.content.Intent} or as part of a <a href="#custom-camera">Building a Camera
+App</a>.</p>
+
+<pre>
+public static final int MEDIA_TYPE_IMAGE = 1;
+public static final int MEDIA_TYPE_VIDEO = 2;
+
+/** Create a file Uri for saving an image or video */
+private static Uri getOutputMediaFileUri(int type){
+ return Uri.fromFile(getOutputMediaFile(type));
+}
+
+/** Create a File for saving an image or video */
+private static Uri getOutputMediaFile(int type){
+ // To be safe, you should check that the SDCard is mounted
+ // using Environment.getExternalStorageState() before doing this.
+
+ File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES), "MyCameraApp");
+ // This location works best if you want the created images to be shared
+ // between applications and persist after your app has been uninstalled.
+
+ // Create the storage directory if it does not exist
+ if (! mediaStorageDir.exists()){
+ if (! mediaStorageDir.mkdirs()){
+ Log.d("MyCameraApp", "failed to create directory");
+ return null;
+ }
+ }
+
+ // Create a media file name
+ String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
+ File mediaFile;
+ if (type == MEDIA_TYPE_IMAGE){
+ mediaFile = new File(mediaStorageDir.getPath() + File.separator +
+ "IMG_"+ timeStamp + ".jpg");
+ } else if(type == MEDIA_TYPE_VIDEO) {
+ mediaFile = new File(mediaStorageDir.getPath() + File.separator +
+ "VID_"+ timeStamp + ".mp4");
+ } else {
+ return null;
+ }
+
+ return mediaFile;
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> {@link
+android.os.Environment#getExternalStoragePublicDirectory(java.lang.String)
+Environment.getExternalStoragePublicDirectory()} is available in Android 2.2 (API Level 8) or
+higher. If you are targeting devices with earlier versions of Android, use {@link
+android.os.Environment#getExternalStorageDirectory() Environment.getExternalStorageDirectory()}
+instead. For more information, see <a
+href="{@docRoot}guide/topics/data/data-storage.html#SavingSharedFiles">Saving Shared Files</a>.</p>
+
+<p>For more information about saving files on an Android device, see <a
+href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a>.</p>
\ No newline at end of file
diff --git a/docs/html/guide/topics/media/index.jd b/docs/html/guide/topics/media/index.jd
index 06e6208..7c1754fe 100644
--- a/docs/html/guide/topics/media/index.jd
+++ b/docs/html/guide/topics/media/index.jd
@@ -1,971 +1,62 @@
-page.title=Media
+page.title=Multimedia and Camera
@jd:body
<div id="qv-wrapper">
<div id="qv">
-<h2>Quickview</h2>
-<ul>
-<li>MediaPlayer APIs allow you to play and record media</li>
-<li>You can handle data from raw resources, files, and streams</li>
-<li>The platform supports a variety of media formats. See <a
-href="{@docRoot}guide/appendix/media-formats.html">Android Supported Media Formats</a></li>
-</ul>
-
-<h2>In this document</h2>
+<h2>Topics</h2>
<ol>
-<li><a href="#mediaplayer">Using MediaPlayer</a>
- <ol>
- <li><a href='#preparingasync'>Asynchronous Preparation</a></li>
- <li><a href='#managestate'>Managing State</a></li>
- <li><a href='#releaseplayer'>Releasing the MediaPlayer</a></li>
- </ol>
-</li>
-<li><a href="#mpandservices">Using a Service with MediaPlayer</a>
- <ol>
- <li><a href="#asyncprepare">Running asynchronously</a></li>
- <li><a href="#asyncerror">Handling asynchronous errors</a></li>
- <li><a href="#wakelocks">Using wake locks</a></li>
- <li><a href="#foregroundserv">Running as a foreground service</a></li>
- <li><a href="#audiofocus">Handling audio focus</a></li>
- <li><a href="#cleanup">Performing cleanup</a></li>
- </ol>
-</li>
-<li><a href="#noisyintent">Handling the AUDIO_BECOMING_NOISY Intent</a>
-<li><a href="#viacontentresolver">Retrieving Media from a Content Resolver</a>
-<li><a href="#jetcontent">Playing JET content</a>
-<li><a href="#audiocapture">Performing Audio Capture</a>
+<li><a href="{@docRoot}guide/topics/media/mediaplayer.html">MediaPlayer</a></li>
+<li><a href="{@docRoot}guide/topics/media/jetplayer.html">JetPlayer</a></li>
+<li><a href="{@docRoot}guide/topics/media/camera.html">Camera</a></li>
+<li><a href="{@docRoot}guide/topics/media/audio-capture.html">Audio Capture</a></li>
</ol>
<h2>Key classes</h2>
<ol>
<li>{@link android.media.MediaPlayer}</li>
+<li>{@link android.media.JetPlayer}</li>
+<li>{@link android.hardware.Camera}</li>
<li>{@link android.media.MediaRecorder}</li>
<li>{@link android.media.AudioManager}</li>
-<li>{@link android.media.JetPlayer}</li>
<li>{@link android.media.SoundPool}</li>
</ol>
<h2>See also</h2>
<ol>
-<li><a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a></li>
-<li><a href="{@docRoot}guide/topics/media/jet/jetcreator_manual.html">JetCreator User Manual</a></li>
+<li></li>
+<li><a href="{@docRoot}guide/appendix/media-formats.html">Android Supported Media Formats</a></li>
+<li><a href="{@docRoot}guide/topics/media/jet/jetcreator_manual.html">JetCreator User
+Manual</a></li>
</ol>
</div>
</div>
-<p>The Android multimedia framework includes support for encoding and decoding a
-variety of common media types, so that you can easily integrate audio,
-video and images into your applications. You can play audio or video from media files stored in your
-application's resources (raw resources), from standalone files in the filesystem, or from a data
-stream arriving over a network connection, all using {@link android.media.MediaPlayer} APIs.</p>
+<p>The Android multimedia framework includes support for capturing and playing audio, video and
+images in a variety of common media types, so that you can easily integrate them into your
+applications. You can play audio or video from media files stored in your application's resources,
+from standalone files in the file system, or from a data stream arriving over a
+network connection, all using the {@link android.media.MediaPlayer} or {@link
+android.media.JetPlayer} APIs. You can also record audio, video and take pictures using the {@link
+android.media.MediaRecorder} and {@link android.hardware.Camera} APIs if supported by the device
+hardware.</p>
-<p>You can also record audio and video using the {@link android.media.MediaRecorder} APIs if
-supported by the device hardware. Note that the emulator doesn't have hardware to capture audio or
-video, but actual mobile devices are likely to provide these capabilities.</p>
+<p>The following topics show you how to use the Android framework to implement multimedia capture
+and playback.</p>
-<p>This document shows you how to write a media-playing application that interacts with the user and
-the system in order to obtain good performance and a pleasant user experience.</p>
+<dl>
+ <dt><strong><a href="{@docRoot}guide/topics/media/mediaplayer.html">MediaPlayer</a></strong></dt>
+ <dd>How to play audio and video in your application.</dd>
-<p class="note"><strong>Note:</strong> You can play back the audio data only to the standard output
-device. Currently, that is the mobile device speaker or a Bluetooth headset. You cannot play sound
-files in the conversation audio during a call.</p>
+ <dt><strong><a href="{@docRoot}guide/topics/media/jetplayer.html">JetPlayer</a></strong></dt>
+ <dd>How to play interactive audio and video in your application using content created with
+JetCreator.</dd>
+ <dt><strong><a href="{@docRoot}guide/topics/media/camera.html">Camera</a></strong></dt>
+ <dd>How to use a device camera to take pictures or video in your application.</dd>
-<h2 id="mediaplayer">Using MediaPlayer</h2>
-
-<p>One of the most important components of the media framework is the
-{@link android.media.MediaPlayer MediaPlayer}
-class. An object of this class can fetch, decode, and play both audio and video
-with minimal setup. It supports several different media sources such as:
-<ul>
- <li>Local resources</li>
- <li>Internal URIs, such as one you might obtain from a Content Resolver</li>
- <li>External URLs (streaming)</li>
-</ul>
-</p>
-
-<p>For a list of media formats that Android supports,
-see the <a href="{@docRoot}guide/appendix/media-formats.html">Android Supported Media
-Formats</a> document. </p>
-
-<p>Here is an example
-of how to play audio that's available as a local raw resource (saved in your application's
-{@code res/raw/} directory):</p>
-
-<pre>MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
-mediaPlayer.start(); // no need to call prepare(); create() does that for you
-</pre>
-
-<p>In this case, a "raw" resource is a file that the system does not
-try to parse in any particular way. However, the content of this resource should not
-be raw audio. It should be a properly encoded and formatted media file in one
-of the supported formats.</p>
-
-<p>And here is how you might play from a URI available locally in the system
-(that you obtained through a Content Resolver, for instance):</p>
-
-<pre>Uri myUri = ....; // initialize Uri here
-MediaPlayer mediaPlayer = new MediaPlayer();
-mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
-mediaPlayer.setDataSource(getApplicationContext(), myUri);
-mediaPlayer.prepare();
-mediaPlayer.start();</pre>
-
-<p>Playing from a remote URL via HTTP streaming looks like this:</p>
-
-<pre>String url = "http://........"; // your URL here
-MediaPlayer mediaPlayer = new MediaPlayer();
-mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
-mediaPlayer.setDataSource(url);
-mediaPlayer.prepare(); // might take long! (for buffering, etc)
-mediaPlayer.start();</pre>
-
-<p class="note"><strong>Note:</strong>
-If you're passing a URL to stream an online media file, the file must be capable of
-progressive download.</p>
-
-<p class="caution"><strong>Caution:</strong> You must either catch or pass
-{@link java.lang.IllegalArgumentException} and {@link java.io.IOException} when using
-{@link android.media.MediaPlayer#setDataSource setDataSource()}, because
-the file you are referencing might not exist.</p>
-
-<h3 id='#preparingasync'>Asynchronous Preparation</h3>
-
-<p>Using {@link android.media.MediaPlayer MediaPlayer} can be straightforward in
-principle. However, it's important to keep in mind that a few more things are
-necessary to integrate it correctly with a typical Android application. For
-example, the call to {@link android.media.MediaPlayer#prepare prepare()} can
-take a long time to execute, because
-it might involve fetching and decoding media data. So, as is the case with any
-method that may take long to execute, you should <strong>never call it from your
-application's UI thread</strong>. Doing that will cause the UI to hang until the method returns,
-which is a very bad user experience and can cause an ANR (Application Not Responding) error. Even if
-you expect your resource to load quickly, remember that anything that takes more than a tenth
-of a second to respond in the UI will cause a noticeable pause and will give
-the user the impression that your application is slow.</p>
-
-<p>To avoid hanging your UI thread, spawn another thread to
-prepare the {@link android.media.MediaPlayer} and notify the main thread when done. However, while
-you could write the threading logic
-yourself, this pattern is so common when using {@link android.media.MediaPlayer} that the framework
-supplies a convenient way to accomplish this task by using the
-{@link android.media.MediaPlayer#prepareAsync prepareAsync()} method. This method
-starts preparing the media in the background and returns immediately. When the media
-is done preparing, the {@link android.media.MediaPlayer.OnPreparedListener#onPrepared onPrepared()}
-method of the {@link android.media.MediaPlayer.OnPreparedListener
-MediaPlayer.OnPreparedListener}, configured through
-{@link android.media.MediaPlayer#setOnPreparedListener setOnPreparedListener()} is called.</p>
-
-<h3 id='#managestate'>Managing State</h3>
-
-<p>Another aspect of a {@link android.media.MediaPlayer} that you should keep in mind is
-that it's state-based. That is, the {@link android.media.MediaPlayer} has an internal state
-that you must always be aware of when writing your code, because certain operations
-are only valid when then player is in specific states. If you perform an operation while in the
-wrong state, the system may throw an exception or cause other undesireable behaviors.</p>
-
-<p>The documentation in the
-{@link android.media.MediaPlayer MediaPlayer} class shows a complete state diagram,
-that clarifies which methods move the {@link android.media.MediaPlayer} from one state to another.
-For example, when you create a new {@link android.media.MediaPlayer}, it is in the <em>Idle</em>
-state. At that point, you should initialize it by calling
-{@link android.media.MediaPlayer#setDataSource setDataSource()}, bringing it
-to the <em>Initialized</em> state. After that, you have to prepare it using either the
-{@link android.media.MediaPlayer#prepare prepare()} or
-{@link android.media.MediaPlayer#prepareAsync prepareAsync()} method. When
-the {@link android.media.MediaPlayer} is done preparing, it will then enter the <em>Prepared</em>
-state, which means you can call {@link android.media.MediaPlayer#start start()}
-to make it play the media. At that point, as the diagram illustrates,
-you can move between the <em>Started</em>, <em>Paused</em> and <em>PlaybackCompleted</em> states by
-calling such methods as
-{@link android.media.MediaPlayer#start start()},
-{@link android.media.MediaPlayer#pause pause()}, and
-{@link android.media.MediaPlayer#seekTo seekTo()},
-amongst others. When you
-call {@link android.media.MediaPlayer#stop stop()}, however, notice that you
-cannot call {@link android.media.MediaPlayer#start start()} again until you
-prepare the {@link android.media.MediaPlayer} again.</p>
-
-<p>Always keep <a href='{@docRoot}images/mediaplayer_state_diagram.gif'>the state diagram</a>
-in mind when writing code that interacts with a
-{@link android.media.MediaPlayer} object, because calling its methods from the wrong state is a
-common cause of bugs.</p>
-
-<h3 id='#releaseplayer'>Releasing the MediaPlayer</h3>
-
-<p>A {@link android.media.MediaPlayer MediaPlayer} can consume valuable
-system resources.
-Therefore, you should always take extra precautions to make sure you are not
-hanging on to a {@link android.media.MediaPlayer} instance longer than necessary. When you
-are done with it, you should always call
-{@link android.media.MediaPlayer#release release()} to make sure any
-system resources allocated to it are properly released. For example, if you are
-using a {@link android.media.MediaPlayer} and your activity receives a call to {@link
-android.app.Activity#onStop onStop()}, you must release the {@link android.media.MediaPlayer},
-because it
-makes little sense to hold on to it while your activity is not interacting with
-the user (unless you are playing media in the background, which is discussed in the next section).
-When your activity is resumed or restarted, of course, you need to
-create a new {@link android.media.MediaPlayer} and prepare it again before resuming playback.</p>
-
-<p>Here's how you should release and then nullify your {@link android.media.MediaPlayer}:</p>
-<pre>
-mediaPlayer.release();
-mediaPlayer = null;
-</pre>
-
-<p>As an example, consider the problems that could happen if you
-forgot to release the {@link android.media.MediaPlayer} when your activity is stopped, but create a
-new one when the activity starts again. As you may know, when the user changes the
-screen orientation (or changes the device configuration in another way),
-the system handles that by restarting the activity (by default), so you might quickly
-consume all of the system resources as the user
-rotates the device back and forth between portrait and landscape, because at each
-orientation change, you create a new {@link android.media.MediaPlayer} that you never
-release. (For more information about runtime restarts, see <a
-href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a>.)</p>
-
-<p>You may be wondering what happens if you want to continue playing
-"background media" even when the user leaves your activity, much in the same
-way that the built-in Music application behaves. In this case, what you need is
-a {@link android.media.MediaPlayer MediaPlayer} controlled by a {@link android.app.Service}, as
-discussed in <a href="mpandservices">Using a Service with MediaPlayer</a>.</p>
-
-<h2 id="mpandservices">Using a Service with MediaPlayer</h2>
-
-<p>If you want your media to play in the background even when your application
-is not onscreen—that is, you want it to continue playing while the user is
-interacting with other applications—then you must start a
-{@link android.app.Service Service} and control the
-{@link android.media.MediaPlayer MediaPlayer} instance from there.
-You should be careful about this setup, because the user and the system have expectations
-about how an application running a background service should interact with the rest of the
-system. If your application does not fulfil those expectations, the user may
-have a bad experience. This section describes the main issues that you should be
-aware of and offers suggestions about how to approach them.</p>
-
-
-<h3 id="asyncprepare">Running asynchronously</h3>
-
-<p>First of all, like an {@link android.app.Activity Activity}, all work in a
-{@link android.app.Service Service} is done in a single thread by
-default—in fact, if you're running an activity and a service from the same application, they
-use the same thread (the "main thread") by default. Therefore, services need to
-process incoming intents quickly
-and never perform lengthy computations when responding to them. If any heavy
-work or blocking calls are expected, you must do those tasks asynchronously: either from
-another thread you implement yourself, or using the framework's many facilities
-for asynchronous processing.</p>
-
-<p>For instance, when using a {@link android.media.MediaPlayer} from your main thread,
-you should call {@link android.media.MediaPlayer#prepareAsync prepareAsync()} rather than
-{@link android.media.MediaPlayer#prepare prepare()}, and implement
-a {@link android.media.MediaPlayer.OnPreparedListener MediaPlayer.OnPreparedListener}
-in order to be notified when the preparation is complete and you can start playing.
-For example:</p>
-
-<pre>
-public class MyService extends Service implements MediaPlayer.OnPreparedListener {
- private static final ACTION_PLAY = "com.example.action.PLAY";
- MediaPlayer mMediaPlayer = null;
-
- public int onStartCommand(Intent intent, int flags, int startId) {
- ...
- if (intent.getAction().equals(ACTION_PLAY)) {
- mMediaPlayer = ... // initialize it here
- mMediaPlayer.setOnPreparedListener(this);
- mMediaPlayer.prepareAsync(); // prepare async to not block main thread
- }
- }
-
- /** Called when MediaPlayer is ready */
- public void onPrepared(MediaPlayer player) {
- player.start();
- }
-}
-</pre>
-
-
-<h3 id="asyncerror">Handling asynchronous errors</h3>
-
-<p>On synchronous operations, errors would normally
-be signaled with an exception or an error code, but whenever you use asynchronous
-resources, you should make sure your application is notified
-of errors appropriately. In the case of a {@link android.media.MediaPlayer MediaPlayer},
-you can accomplish this by implementing a
-{@link android.media.MediaPlayer.OnErrorListener MediaPlayer.OnErrorListener} and
-setting it in your {@link android.media.MediaPlayer} instance:</p>
-
-<pre>
-public class MyService extends Service implements MediaPlayer.OnErrorListener {
- MediaPlayer mMediaPlayer;
-
- public void initMediaPlayer() {
- // ...initialize the MediaPlayer here...
-
- mMediaPlayer.setOnErrorListener(this);
- }
-
- @Override
- public boolean onError(MediaPlayer mp, int what, int extra) {
- // ... react appropriately ...
- // The MediaPlayer has moved to the Error state, must be reset!
- }
-}
-</pre>
-
-<p>It's important to remember that when an error occurs, the {@link android.media.MediaPlayer}
-moves to the <em>Error</em> state (see the documentation for the
-{@link android.media.MediaPlayer MediaPlayer} class for the full state diagram)
-and you must reset it before you can use it again.
-
-
-<h3 id="wakelocks">Using wake locks</h3>
-
-<p>When designing applications that play media
-in the background, the device may go to sleep
-while your service is running. Because the Android system tries to conserve
-battery while the device is sleeping, the system tries to shut off any
-of the phone's features that are
-not necessary, including the CPU and the WiFi hardware.
-However, if your service is playing or streaming music, you want to prevent
-the system from interfering with your playback.</p>
-
-<p>In order to ensure that your service continues to run under
-those conditions, you have to use "wake locks." A wake lock is a way to signal to
-the system that your application is using some feature that should
-stay available even if the phone is idle.</p>
-
-<p class="caution"><strong>Notice:</strong> You should always use wake locks sparingly and hold them
-only for as long as truly necessary, because they significantly reduce the battery life of the
-device.</p>
-
-<p>To ensure that the CPU continues running while your {@link android.media.MediaPlayer} is
-playing, call the {@link android.media.MediaPlayer#setWakeMode
-setWakeMode()} method when initializing your {@link android.media.MediaPlayer}. Once you do,
-the {@link android.media.MediaPlayer} holds the specified lock while playing and releases the lock
-when paused or stopped:</p>
-
-<pre>
-mMediaPlayer = new MediaPlayer();
-// ... other initialization here ...
-mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
-</pre>
-
-<p>However, the wake lock acquired in this example guarantees only that the CPU remains awake. If
-you are streaming media over the
-network and you are using Wi-Fi, you probably want to hold a
-{@link android.net.wifi.WifiManager.WifiLock WifiLock} as
-well, which you must acquire and release manually. So, when you start preparing the
-{@link android.media.MediaPlayer} with the remote URL, you should create and acquire the Wi-Fi lock.
-For example:</p>
-
-<pre>
-WifiLock wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE))
- .createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");
-
-wifiLock.acquire();
-</pre>
-
-<p>When you pause or stop your media, or when you no longer need the
-network, you should release the lock:</p>
-
-<pre>
-wifiLock.release();
-</pre>
-
-
-<h3 id="foregroundserv">Running as a foreground service</h3>
-
-<p>Services are often used for performing background tasks, such as fetching emails,
-synchronizing data, downloading content, amongst other possibilities. In these
-cases, the user is not actively aware of the service's execution, and probably
-wouldn't even notice if some of these services were interrupted and later restarted.</p>
-
-<p>But consider the case of a service that is playing music. Clearly this is a service that the user
-is actively aware of and the experience would be severely affected by any interruptions.
-Additionally, it's a service that the user will likely wish to interact with during its execution.
-In this case, the service should run as a "foreground service." A
-foreground service holds a higher level of importance within the system—the system will
-almost never kill the service, because it is of immediate importance to the user. When running
-in the foreground, the service also must provide a status bar notification to ensure that users are
-aware of the running service and allow them to open an activity that can interact with the
-service.</p>
-
-<p>In order to turn your service into a foreground service, you must create a
-{@link android.app.Notification Notification} for the status bar and call
-{@link android.app.Service#startForeground startForeground()} from the {@link
-android.app.Service}. For example:</p>
-
-<pre>String songName;
-// assign the song name to songName
-PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0,
- new Intent(getApplicationContext(), MainActivity.class),
- PendingIntent.FLAG_UPDATE_CURRENT);
-Notification notification = new Notification();
-notification.tickerText = text;
-notification.icon = R.drawable.play0;
-notification.flags |= Notification.FLAG_ONGOING_EVENT;
-notification.setLatestEventInfo(getApplicationContext(), "MusicPlayerSample",
- "Playing: " + songName, pi);
-startForeground(NOTIFICATION_ID, notification);
-</pre>
-
-<p>While your service is running in the foreground, the notification you
-configured is visible in the notification area of the device. If the user
-selects the notification, the system invokes the {@link android.app.PendingIntent} you supplied. In
-the example above, it opens an activity ({@code MainActivity}).</p>
-
-<p>Figure 1 shows how your notification appears to the user:</p>
-
-<img src='images/notification1.png' />
-
-<img src='images/notification2.png' />
-<p class="img-caption"><strong>Figure 1.</strong> Screenshots of a foreground service's notification, showing the notification icon in the status bar (left) and the expanded view (right).</p>
-
-<p>You should only hold on to the "foreground service" status while your
-service is actually performing something the user is actively aware of. Once
-that is no longer true, you should release it by calling
-{@link android.app.Service#stopForeground stopForeground()}:</p>
-
-<pre>
-stopForeground(true);
-</pre>
-
-<p>For more information, see the documentation about <a
-href="{@docRoot}guide/topics/fundamentals/services.html#Foreground">Services</a> and
-<a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>.</p>
-
-
-<h3 id="audiofocus">Handling audio focus</h3>
-
-<p>Even though only one activity can run at any given time, Android is a
-multi-tasking environment. This poses a particular challenge to applications
-that use audio, because there is only one audio output and there may be several
-media services competing for its use. Before Android 2.2, there was no built-in
-mechanism to address this issue, which could in some cases lead to a bad user
-experience. For example, when a user is listening to
-music and another application needs to notify the user of something very important,
-the user might not hear the notification tone due to the loud music. Starting with
-Android 2.2, the platform offers a way for applications to negotiate their
-use of the device's audio output. This mechanism is called Audio Focus.</p>
-
-<p>When your application needs to output audio such as music or a notification,
-you should always request audio focus. Once it has focus, it can use the sound output freely, but it should
-always listen for focus changes. If it is notified that it has lost the audio
-focus, it should immediately either kill the audio or lower it to a quiet level
-(known as "ducking"—there is a flag that indicates which one is appropriate) and only resume
-loud playback after it receives focus again.</p>
-
-<p>Audio Focus is cooperative in nature. That is, applications are expected
-(and highly encouraged) to comply with the audio focus guidelines, but the
-rules are not enforced by the system. If an application wants to play loud
-music even after losing audio focus, nothing in the system will prevent that.
-However, the user is more likely to have a bad experience and will be more
-likely to uninstall the misbehaving application.</p>
-
-<p>To request audio focus, you must call
-{@link android.media.AudioManager#requestAudioFocus requestAudioFocus()} from the {@link
-android.media.AudioManager}, as the example below demonstrates:</p>
-
-<pre>
-AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
- AudioManager.AUDIOFOCUS_GAIN);
-
-if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
- // could not get audio focus.
-}
-</pre>
-
-<p>The first parameter to {@link android.media.AudioManager#requestAudioFocus requestAudioFocus()}
-is an {@link android.media.AudioManager.OnAudioFocusChangeListener
-AudioManager.OnAudioFocusChangeListener},
-whose {@link android.media.AudioManager.OnAudioFocusChangeListener#onAudioFocusChange
-onAudioFocusChange()} method is called whenever there is a change in audio focus. Therefore, you
-should also implement this interface on your service and activities. For example:</p>
-
-<pre>
-class MyService extends Service
- implements AudioManager.OnAudioFocusChangeListener {
- // ....
- public void onAudioFocusChange(int focusChange) {
- // Do something based on focus change...
- }
-}
-</pre>
-
-<p>The <code>focusChange</code> parameter tells you how the audio focus has changed, and
-can be one of the following values (they are all constants defined in
-{@link android.media.AudioManager AudioManager}):</p>
-
-<ul>
-<li>{@link android.media.AudioManager#AUDIOFOCUS_GAIN}: You have gained the audio focus.</li>
-
-<li>{@link android.media.AudioManager#AUDIOFOCUS_LOSS}: You have lost the audio focus for a
-presumably long time.
-You must stop all audio playback. Because you should expect not to have focus back
-for a long time, this would be a good place to clean up your resources as much
-as possible. For example, you should release the {@link android.media.MediaPlayer}.</li>
-
-<li>{@link android.media.AudioManager#AUDIOFOCUS_LOSS_TRANSIENT}: You have
-temporarily lost audio focus, but should receive it back shortly. You must stop
-all audio playback, but you can keep your resources because you will probably get
-focus back shortly.</li>
-
-<li>{@link android.media.AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}: You have temporarily
-lost audio focus,
-but you are allowed to continue to play audio quietly (at a low volume) instead
-of killing audio completely.</li>
-</ul>
-
-<p>Here is an example implementation:</p>
-
-<pre>
-public void onAudioFocusChange(int focusChange) {
- switch (focusChange) {
- case AudioManager.AUDIOFOCUS_GAIN:
- // resume playback
- if (mMediaPlayer == null) initMediaPlayer();
- else if (!mMediaPlayer.isPlaying()) mMediaPlayer.start();
- mMediaPlayer.setVolume(1.0f, 1.0f);
- break;
-
- case AudioManager.AUDIOFOCUS_LOSS:
- // Lost focus for an unbounded amount of time: stop playback and release media player
- if (mMediaPlayer.isPlaying()) mMediaPlayer.stop();
- mMediaPlayer.release();
- mMediaPlayer = null;
- break;
-
- case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
- // Lost focus for a short time, but we have to stop
- // playback. We don't release the media player because playback
- // is likely to resume
- if (mMediaPlayer.isPlaying()) mMediaPlayer.pause();
- break;
-
- case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
- // Lost focus for a short time, but it's ok to keep playing
- // at an attenuated level
- if (mMediaPlayer.isPlaying()) mMediaPlayer.setVolume(0.1f, 0.1f);
- break;
- }
-}
-</pre>
-
-<p>Keep in mind that the audio focus APIs are available only with API level 8 (Android 2.2)
-and above, so if you want to support previous
-versions of Android, you should adopt a backward compatibility strategy that
-allows you to use this feature if available, and fall back seamlessly if not.</p>
-
-<p>You can achieve backward compatibility either by calling the audio focus methods by reflection
-or by implementing all the audio focus features in a separate class (say,
-<code>AudioFocusHelper</code>). Here is an example of such a class:</p>
-
-<pre>
-public class AudioFocusHelper implements AudioManager.OnAudioFocusChangeListener {
- AudioManager mAudioManager;
-
- // other fields here, you'll probably hold a reference to an interface
- // that you can use to communicate the focus changes to your Service
-
- public AudioFocusHelper(Context ctx, /* other arguments here */) {
- mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
- // ...
- }
-
- public boolean requestFocus() {
- return AudioManager.AUDIOFOCUS_REQUEST_GRANTED ==
- mAudioManager.requestAudioFocus(mContext, AudioManager.STREAM_MUSIC,
- AudioManager.AUDIOFOCUS_GAIN);
- }
-
- public boolean abandonFocus() {
- return AudioManager.AUDIOFOCUS_REQUEST_GRANTED ==
- mAudioManager.abandonAudioFocus(this);
- }
-
- @Override
- public void onAudioFocusChange(int focusChange) {
- // let your service know about the focus change
- }
-}
-</pre>
-
-
-<p>You can create an instance of <code>AudioFocusHelper</code> class only if you detect that
-the system is running API level 8 or above. For example:</p>
-
-<pre>
-if (android.os.Build.VERSION.SDK_INT >= 8) {
- mAudioFocusHelper = new AudioFocusHelper(getApplicationContext(), this);
-} else {
- mAudioFocusHelper = null;
-}
-</pre>
-
-
-<h3 id="cleanup">Performing cleanup</h3>
-
-<p>As mentioned earlier, a {@link android.media.MediaPlayer} object can consume a significant
-amount of system resources, so you should keep it only for as long as you need and call
-{@link android.media.MediaPlayer#release release()} when you are done with it. It's important
-to call this cleanup method explicitly rather than rely on system garbage collection because
-it might take some time before the garbage collector reclaims the {@link android.media.MediaPlayer},
-as it's only sensitive to memory needs and not to shortage of other media-related resources.
-So, in the case when you're using a service, you should always override the
-{@link android.app.Service#onDestroy onDestroy()} method to make sure you are releasing
-the {@link android.media.MediaPlayer}:</p>
-
-<pre>
-public class MyService extends Service {
- MediaPlayer mMediaPlayer;
- // ...
-
- @Override
- public void onDestroy() {
- if (mMediaPlayer != null) mMediaPlayer.release();
- }
-}
-</pre>
-
-<p>You should always look for other opportunities to release your {@link android.media.MediaPlayer}
-as well, apart from releasing it when being shut down. For example, if you expect not
-to be able to play media for an extended period of time (after losing audio focus, for example),
-you should definitely release your existing {@link android.media.MediaPlayer} and create it again
-later. On the
-other hand, if you only expect to stop playback for a very short time, you should probably
-hold on to your {@link android.media.MediaPlayer} to avoid the overhead of creating and preparing it
-again.</p>
-
-
-
-<h2 id="noisyintent">Handling the AUDIO_BECOMING_NOISY Intent</h2>
-
-<p>Many well-written applications that play audio automatically stop playback when an event
-occurs that causes the audio to become noisy (ouput through external speakers). For instance,
-this might happen when a user is listening to music through headphones and accidentally
-disconnects the headphones from the device. However, this behavior does not happen automatically.
-If you don't implement this feature, audio plays out of the device's external speakers, which
-might not be what the user wants.</p>
-
-<p>You can ensure your app stops playing music in these situations by handling
-the {@link android.media.AudioManager#ACTION_AUDIO_BECOMING_NOISY} intent, for which you can register a receiver by
-adding the following to your manifest:</p>
-
-<pre>
-<receiver android:name=".MusicIntentReceiver">
- <intent-filter>
- <action android:name="android.media.AUDIO_BECOMING_NOISY" />
- </intent-filter>
-</receiver>
-</pre>
-
-<p>This registers the <code>MusicIntentReceiver</code> class as a broadcast receiver for that
-intent. You should then implement this class:</p>
-
-<pre>
-public class MusicIntentReceiver implements android.content.BroadcastReceiver {
- @Override
- public void onReceive(Context ctx, Intent intent) {
- if (intent.getAction().equals(
- android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
- // signal your service to stop playback
- // (via an Intent, for instance)
- }
- }
-}
-</pre>
-
-
-
-
-<h2 id="viacontentresolver">Retrieving Media from a Content Resolver</h2>
-
-<p>Another feature that may be useful in a media player application is the ability to
-retrieve music that the user has on the device. You can do that by querying the {@link
-android.content.ContentResolver} for external media:</p>
-
-<pre>
-ContentResolver contentResolver = getContentResolver();
-Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
-Cursor cursor = contentResolver.query(uri, null, null, null, null);
-if (cursor == null) {
- // query failed, handle error.
-} else if (!cursor.moveToFirst()) {
- // no media on the device
-} else {
- int titleColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
- int idColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
- do {
- long thisId = cursor.getLong(idColumn);
- String thisTitle = cursor.getString(titleColumn);
- // ...process entry...
- } while (cursor.moveToNext());
-}
-</pre>
-
-<p>To use this with the {@link android.media.MediaPlayer}, you can do this:</p>
-
-<pre>
-long id = /* retrieve it from somewhere */;
-Uri contentUri = ContentUris.withAppendedId(
- android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
-
-mMediaPlayer = new MediaPlayer();
-mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
-mMediaPlayer.setDataSource(getApplicationContext(), contentUri);
-
-// ...prepare and start...
-</pre>
-
-
-
-<h2 id="jetcontent">Playing JET content</h2>
-
-<p>The Android platform includes a JET engine that lets you add interactive playback of JET audio
-content in your applications. You can create JET content for interactive playback using the
-JetCreator authoring application that ships with the SDK. To play and manage JET content from your
-application, use the {@link android.media.JetPlayer JetPlayer} class.</p>
-
-<p>For a description of JET concepts and instructions on how to use the JetCreator authoring tool,
-see the <a href="{@docRoot}guide/topics/media/jet/jetcreator_manual.html">JetCreator User
-Manual</a>. The tool is available on Windows, OS X, and Linux platforms (Linux does not
-support auditioning of imported assets like with the Windows and OS X versions).
-</p>
-
-<p>Here's an example of how to set up JET playback from a <code>.jet</code> file stored on the SD card:</p>
-
-<pre>
-JetPlayer jetPlayer = JetPlayer.getJetPlayer();
-jetPlayer.loadJetFile("/sdcard/level1.jet");
-byte segmentId = 0;
-
-// queue segment 5, repeat once, use General MIDI, transpose by -1 octave
-jetPlayer.queueJetSegment(5, -1, 1, -1, 0, segmentId++);
-// queue segment 2
-jetPlayer.queueJetSegment(2, -1, 0, 0, 0, segmentId++);
-
-jetPlayer.play();
-</pre>
-
-<p>The SDK includes an example application — JetBoy — that shows how to use {@link
-android.media.JetPlayer JetPlayer} to create an interactive music soundtrack in your game. It also
-illustrates how to use JET events to synchronize music and game logic. The application is located at
-<code><sdk>/platforms/android-1.5/samples/JetBoy</code>.</p>
-
-
-<h2 id="audiocapture">Performing Audio Capture</h2>
-
-<p>Audio capture from the device is a bit more complicated than audio and video playback, but still fairly simple:</p>
-<ol>
- <li>Create a new instance of {@link android.media.MediaRecorder android.media.MediaRecorder}.</li>
- <li>Set the audio source using
- {@link android.media.MediaRecorder#setAudioSource MediaRecorder.setAudioSource()}. You will probably want to use
- <code>MediaRecorder.AudioSource.MIC</code>.</li>
- <li>Set output file format using
- {@link android.media.MediaRecorder#setOutputFormat MediaRecorder.setOutputFormat()}.
- </li>
- <li>Set output file name using
- {@link android.media.MediaRecorder#setOutputFile MediaRecorder.setOutputFile()}.
- </li>
- <li>Set the audio encoder using
- {@link android.media.MediaRecorder#setAudioEncoder MediaRecorder.setAudioEncoder()}.
- </li>
- <li>Call {@link android.media.MediaRecorder#prepare MediaRecorder.prepare()}
- on the MediaRecorder instance.</li>
- <li>To start audio capture, call
- {@link android.media.MediaRecorder#start MediaRecorder.start()}. </li>
- <li>To stop audio capture, call {@link android.media.MediaRecorder#stop MediaRecorder.stop()}.
- <li>When you are done with the MediaRecorder instance, call
-{@link android.media.MediaRecorder#release MediaRecorder.release()} on it. Calling
-{@link android.media.MediaRecorder#release MediaRecorder.release()} is always recommended to
-free the resource immediately.</li>
-</ol>
-
-<h3>Example: Record audio and play the recorded audio</h3>
-<p>The example class below illustrates how to set up, start and stop audio capture, and to play the recorded audio file.</p>
-<pre>
-/*
- * The application needs to have the permission to write to external storage
- * if the output file is written to the external storage, and also the
- * permission to record audio. These permissions must be set in the
- * application's AndroidManifest.xml file, with something like:
- *
- * <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- * <uses-permission android:name="android.permission.RECORD_AUDIO" />
- *
- */
-package com.android.audiorecordtest;
-
-import android.app.Activity;
-import android.widget.LinearLayout;
-import android.os.Bundle;
-import android.os.Environment;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.content.Context;
-import android.util.Log;
-import android.media.MediaRecorder;
-import android.media.MediaPlayer;
-
-import java.io.IOException;
-
-
-public class AudioRecordTest extends Activity
-{
- private static final String LOG_TAG = "AudioRecordTest";
- private static String mFileName = null;
-
- private RecordButton mRecordButton = null;
- private MediaRecorder mRecorder = null;
-
- private PlayButton mPlayButton = null;
- private MediaPlayer mPlayer = null;
-
- private void onRecord(boolean start) {
- if (start) {
- startRecording();
- } else {
- stopRecording();
- }
- }
-
- private void onPlay(boolean start) {
- if (start) {
- startPlaying();
- } else {
- stopPlaying();
- }
- }
-
- private void startPlaying() {
- mPlayer = new MediaPlayer();
- try {
- mPlayer.setDataSource(mFileName);
- mPlayer.prepare();
- mPlayer.start();
- } catch (IOException e) {
- Log.e(LOG_TAG, "prepare() failed");
- }
- }
-
- private void stopPlaying() {
- mPlayer.release();
- mPlayer = null;
- }
-
- private void startRecording() {
- mRecorder = new MediaRecorder();
- mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
- mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
- mRecorder.setOutputFile(mFileName);
- mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
-
- try {
- mRecorder.prepare();
- } catch (IOException e) {
- Log.e(LOG_TAG, "prepare() failed");
- }
-
- mRecorder.start();
- }
-
- private void stopRecording() {
- mRecorder.stop();
- mRecorder.release();
- mRecorder = null;
- }
-
- class RecordButton extends Button {
- boolean mStartRecording = true;
-
- OnClickListener clicker = new OnClickListener() {
- public void onClick(View v) {
- onRecord(mStartRecording);
- if (mStartRecording) {
- setText("Stop recording");
- } else {
- setText("Start recording");
- }
- mStartRecording = !mStartRecording;
- }
- };
-
- public RecordButton(Context ctx) {
- super(ctx);
- setText("Start recording");
- setOnClickListener(clicker);
- }
- }
-
- class PlayButton extends Button {
- boolean mStartPlaying = true;
-
- OnClickListener clicker = new OnClickListener() {
- public void onClick(View v) {
- onPlay(mStartPlaying);
- if (mStartPlaying) {
- setText("Stop playing");
- } else {
- setText("Start playing");
- }
- mStartPlaying = !mStartPlaying;
- }
- };
-
- public PlayButton(Context ctx) {
- super(ctx);
- setText("Start playing");
- setOnClickListener(clicker);
- }
- }
-
- public AudioRecordTest() {
- mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
- mFileName += "/audiorecordtest.3gp";
- }
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- LinearLayout ll = new LinearLayout(this);
- mRecordButton = new RecordButton(this);
- ll.addView(mRecordButton,
- new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT,
- 0));
- mPlayButton = new PlayButton(this);
- ll.addView(mPlayButton,
- new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT,
- 0));
- setContentView(ll);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- if (mRecorder != null) {
- mRecorder.release();
- mRecorder = null;
- }
-
- if (mPlayer != null) {
- mPlayer.release();
- mPlayer = null;
- }
- }
-}
-</pre>
-
-
-
+ <dt><strong><a href="{@docRoot}guide/topics/media/audio-capture.html">Audio
+Capture</a></strong></dt>
+ <dd>How to record sound in your application.</dd>
+</dl>
\ No newline at end of file
diff --git a/docs/html/guide/topics/media/jetplayer.jd b/docs/html/guide/topics/media/jetplayer.jd
new file mode 100644
index 0000000..f3d55f9
--- /dev/null
+++ b/docs/html/guide/topics/media/jetplayer.jd
@@ -0,0 +1,70 @@
+page.title=JetPlayer
+parent.title=Multimedia and Camera
+parent.link=index.html
+@jd:body
+
+ <div id="qv-wrapper">
+ <div id="qv">
+
+<h2>In this document</h2>
+<ol>
+<li><a href="#jetcontent">Playing JET content</a>
+</ol>
+
+<h2>Key classes</h2>
+<ol>
+<li>{@link android.media.JetPlayer}</li>
+</ol>
+
+<h2>Related Samples</h2>
+<ol>
+<li><a href="{@docRoot}resources/samples/JetBoy/index.html">JetBoy</a></li>
+</ol>
+
+<h2>See also</h2>
+<ol>
+<li><a href="{@docRoot}guide/topics/media/jet/jetcreator_manual.html">JetCreator User
+Manual</a></li>
+<li><a href="{@docRoot}guide/appendix/media-formats.html">Android Supported Media Formats</a></li>
+<li><a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a></li>
+<li><a href="{@docRoot}guide/topics/media/mediaplayer.html">MediaPlayer</a></li>
+</ol>
+
+</div>
+</div>
+
+<p>The Android platform includes a JET engine that lets you add interactive playback of JET audio
+content in your applications. You can create JET content for interactive playback using the
+JetCreator authoring application that ships with the SDK. To play and manage JET content from your
+application, use the {@link android.media.JetPlayer JetPlayer} class.</p>
+
+
+<h2 id="jetcontent">Playing JET content</h2>
+
+<p>This section shows you how to write, set up and play JET content. For a description of JET
+concepts and instructions on how to use the JetCreator authoring tool, see the <a
+href="{@docRoot}guide/topics/media/jet/jetcreator_manual.html">JetCreator User
+Manual</a>. The tool is available on Windows, OS X, and Linux platforms (Linux does not
+support auditioning of imported assets like with the Windows and OS X versions).
+</p>
+
+<p>Here's an example of how to set up JET playback from a <code>.jet</code> file stored on the SD
+card:</p>
+
+<pre>
+JetPlayer jetPlayer = JetPlayer.getJetPlayer();
+jetPlayer.loadJetFile("/sdcard/level1.jet");
+byte segmentId = 0;
+
+// queue segment 5, repeat once, use General MIDI, transpose by -1 octave
+jetPlayer.queueJetSegment(5, -1, 1, -1, 0, segmentId++);
+// queue segment 2
+jetPlayer.queueJetSegment(2, -1, 0, 0, 0, segmentId++);
+
+jetPlayer.play();
+</pre>
+
+<a>The SDK includes an example application — JetBoy — that shows how to use {@link
+android.media.JetPlayer JetPlayer} to create an interactive music soundtrack in your game. It also
+illustrates how to use JET events to synchronize music and game logic. The application is located at
+<a href="{@docRoot}resources/samples/JetBoy/index.html">JetBoy</a>.</p>
\ No newline at end of file
diff --git a/docs/html/guide/topics/media/mediaplayer.jd b/docs/html/guide/topics/media/mediaplayer.jd
new file mode 100644
index 0000000..b3ca7dd
--- /dev/null
+++ b/docs/html/guide/topics/media/mediaplayer.jd
@@ -0,0 +1,747 @@
+page.title=Media Playback
+parent.title=Multimedia and Camera
+parent.link=index.html
+@jd:body
+
+ <div id="qv-wrapper">
+ <div id="qv">
+
+<h2>In this document</h2>
+<ol>
+<li><a href="#basics">The Basics</a>
+<li><a href="#manifest">Manifest Declarations</a></li>
+<li><a href="#mediaplayer">Using MediaPlayer</a>
+ <ol>
+ <li><a href='#preparingasync'>Asynchronous Preparation</a></li>
+ <li><a href='#managestate'>Managing State</a></li>
+ <li><a href='#releaseplayer'>Releasing the MediaPlayer</a></li>
+ </ol>
+</li>
+<li><a href="#mpandservices">Using a Service with MediaPlayer</a>
+ <ol>
+ <li><a href="#asyncprepare">Running asynchronously</a></li>
+ <li><a href="#asyncerror">Handling asynchronous errors</a></li>
+ <li><a href="#wakelocks">Using wake locks</a></li>
+ <li><a href="#foregroundserv">Running as a foreground service</a></li>
+ <li><a href="#audiofocus">Handling audio focus</a></li>
+ <li><a href="#cleanup">Performing cleanup</a></li>
+ </ol>
+</li>
+<li><a href="#noisyintent">Handling the AUDIO_BECOMING_NOISY Intent</a>
+<li><a href="#viacontentresolver">Retrieving Media from a Content Resolver</a>
+</ol>
+
+<h2>Key classes</h2>
+<ol>
+<li>{@link android.media.MediaPlayer}</li>
+<li>{@link android.media.AudioManager}</li>
+<li>{@link android.media.SoundPool}</li>
+</ol>
+
+<h2>See also</h2>
+<ol>
+<li><a href="{@docRoot}guide/topics/media/jetplayer.html">JetPlayer</a></li>
+<li><a href="{@docRoot}guide/topics/media/audio-capture.html">Audio Capture</a></li>
+<li><a href="{@docRoot}guide/appendix/media-formats.html">Android Supported Media Formats</a></li>
+<li><a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a></li>
+</ol>
+
+</div>
+</div>
+
+<p>The Android multimedia framework includes support for playing variety of common media types, so
+that you can easily integrate audio, video and images into your applications. You can play audio or
+video from media files stored in your application's resources (raw resources), from standalone files
+in the filesystem, or from a data stream arriving over a network connection, all using {@link
+android.media.MediaPlayer} APIs.</p>
+
+<p>This document shows you how to write a media-playing application that interacts with the user and
+the system in order to obtain good performance and a pleasant user experience.</p>
+
+<p class="note"><strong>Note:</strong> You can play back the audio data only to the standard output
+device. Currently, that is the mobile device speaker or a Bluetooth headset. You cannot play sound
+files in the conversation audio during a call.</p>
+
+<h2 id="basics">The Basics</h2>
+<p>The following classes are used to play sound and video in the Android framework:</p>
+
+<dl>
+ <dt>{@link android.media.MediaPlayer}</dt>
+ <dd>This class is the primary API for playing sound and video.</dd>
+ <dt>{@link android.media.AudioManager}</dt>
+ <dd>This class manages audio sources and audio output on a device.</dd>
+</dl>
+
+<h2 id="manifest">Manifest Declarations</h2>
+<p>Before starting development on your application using MediaPlayer, make sure your manifest has
+the appropriate declarations to allow use of related features.</p>
+
+<ul>
+ <li><strong>Internet Permission</strong> - If you are using MediaPlayer to stream network-based
+content, your application must request network access.
+<pre>
+<uses-permission android:name="android.permission.INTERNET" />
+</pre>
+ </li>
+ <li><strong>Wake Lock Permission</strong> - If your player application needs to keep the screen
+from dimming or the processor from sleeping, or uses the {@link
+android.media.MediaPlayer#setScreenOnWhilePlaying(boolean) MediaPlayer.setScreenOnWhilePlaying()} or
+{@link android.media.MediaPlayer#setWakeMode(android.content.Context, int)
+MediaPlayer.setWakeMode()} methods, you must request this permission.
+<pre>
+<uses-permission android:name="android.permission.WAKE_LOCK" />
+</pre>
+ </li>
+</ul>
+
+<h2 id="mediaplayer">Using MediaPlayer</h2>
+<p>One of the most important components of the media framework is the
+{@link android.media.MediaPlayer MediaPlayer}
+class. An object of this class can fetch, decode, and play both audio and video
+with minimal setup. It supports several different media sources such as:
+<ul>
+ <li>Local resources</li>
+ <li>Internal URIs, such as one you might obtain from a Content Resolver</li>
+ <li>External URLs (streaming)</li>
+</ul>
+</p>
+
+<p>For a list of media formats that Android supports,
+see the <a href="{@docRoot}guide/appendix/media-formats.html">Android Supported Media
+Formats</a> document. </p>
+
+<p>Here is an example
+of how to play audio that's available as a local raw resource (saved in your application's
+{@code res/raw/} directory):</p>
+
+<pre>MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
+mediaPlayer.start(); // no need to call prepare(); create() does that for you
+</pre>
+
+<p>In this case, a "raw" resource is a file that the system does not
+try to parse in any particular way. However, the content of this resource should not
+be raw audio. It should be a properly encoded and formatted media file in one
+of the supported formats.</p>
+
+<p>And here is how you might play from a URI available locally in the system
+(that you obtained through a Content Resolver, for instance):</p>
+
+<pre>Uri myUri = ....; // initialize Uri here
+MediaPlayer mediaPlayer = new MediaPlayer();
+mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+mediaPlayer.setDataSource(getApplicationContext(), myUri);
+mediaPlayer.prepare();
+mediaPlayer.start();</pre>
+
+<p>Playing from a remote URL via HTTP streaming looks like this:</p>
+
+<pre>String url = "http://........"; // your URL here
+MediaPlayer mediaPlayer = new MediaPlayer();
+mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+mediaPlayer.setDataSource(url);
+mediaPlayer.prepare(); // might take long! (for buffering, etc)
+mediaPlayer.start();</pre>
+
+<p class="note"><strong>Note:</strong>
+If you're passing a URL to stream an online media file, the file must be capable of
+progressive download.</p>
+
+<p class="caution"><strong>Caution:</strong> You must either catch or pass
+{@link java.lang.IllegalArgumentException} and {@link java.io.IOException} when using
+{@link android.media.MediaPlayer#setDataSource setDataSource()}, because
+the file you are referencing might not exist.</p>
+
+<h3 id='preparingasync'>Asynchronous Preparation</h3>
+
+<p>Using {@link android.media.MediaPlayer MediaPlayer} can be straightforward in
+principle. However, it's important to keep in mind that a few more things are
+necessary to integrate it correctly with a typical Android application. For
+example, the call to {@link android.media.MediaPlayer#prepare prepare()} can
+take a long time to execute, because
+it might involve fetching and decoding media data. So, as is the case with any
+method that may take long to execute, you should <strong>never call it from your
+application's UI thread</strong>. Doing that will cause the UI to hang until the method returns,
+which is a very bad user experience and can cause an ANR (Application Not Responding) error. Even if
+you expect your resource to load quickly, remember that anything that takes more than a tenth
+of a second to respond in the UI will cause a noticeable pause and will give
+the user the impression that your application is slow.</p>
+
+<p>To avoid hanging your UI thread, spawn another thread to
+prepare the {@link android.media.MediaPlayer} and notify the main thread when done. However, while
+you could write the threading logic
+yourself, this pattern is so common when using {@link android.media.MediaPlayer} that the framework
+supplies a convenient way to accomplish this task by using the
+{@link android.media.MediaPlayer#prepareAsync prepareAsync()} method. This method
+starts preparing the media in the background and returns immediately. When the media
+is done preparing, the {@link android.media.MediaPlayer.OnPreparedListener#onPrepared onPrepared()}
+method of the {@link android.media.MediaPlayer.OnPreparedListener
+MediaPlayer.OnPreparedListener}, configured through
+{@link android.media.MediaPlayer#setOnPreparedListener setOnPreparedListener()} is called.</p>
+
+<h3 id='managestate'>Managing State</h3>
+
+<p>Another aspect of a {@link android.media.MediaPlayer} that you should keep in mind is
+that it's state-based. That is, the {@link android.media.MediaPlayer} has an internal state
+that you must always be aware of when writing your code, because certain operations
+are only valid when then player is in specific states. If you perform an operation while in the
+wrong state, the system may throw an exception or cause other undesireable behaviors.</p>
+
+<p>The documentation in the
+{@link android.media.MediaPlayer MediaPlayer} class shows a complete state diagram,
+that clarifies which methods move the {@link android.media.MediaPlayer} from one state to another.
+For example, when you create a new {@link android.media.MediaPlayer}, it is in the <em>Idle</em>
+state. At that point, you should initialize it by calling
+{@link android.media.MediaPlayer#setDataSource setDataSource()}, bringing it
+to the <em>Initialized</em> state. After that, you have to prepare it using either the
+{@link android.media.MediaPlayer#prepare prepare()} or
+{@link android.media.MediaPlayer#prepareAsync prepareAsync()} method. When
+the {@link android.media.MediaPlayer} is done preparing, it will then enter the <em>Prepared</em>
+state, which means you can call {@link android.media.MediaPlayer#start start()}
+to make it play the media. At that point, as the diagram illustrates,
+you can move between the <em>Started</em>, <em>Paused</em> and <em>PlaybackCompleted</em> states by
+calling such methods as
+{@link android.media.MediaPlayer#start start()},
+{@link android.media.MediaPlayer#pause pause()}, and
+{@link android.media.MediaPlayer#seekTo seekTo()},
+amongst others. When you
+call {@link android.media.MediaPlayer#stop stop()}, however, notice that you
+cannot call {@link android.media.MediaPlayer#start start()} again until you
+prepare the {@link android.media.MediaPlayer} again.</p>
+
+<p>Always keep <a href='{@docRoot}images/mediaplayer_state_diagram.gif'>the state diagram</a>
+in mind when writing code that interacts with a
+{@link android.media.MediaPlayer} object, because calling its methods from the wrong state is a
+common cause of bugs.</p>
+
+<h3 id='releaseplayer'>Releasing the MediaPlayer</h3>
+
+<p>A {@link android.media.MediaPlayer MediaPlayer} can consume valuable
+system resources.
+Therefore, you should always take extra precautions to make sure you are not
+hanging on to a {@link android.media.MediaPlayer} instance longer than necessary. When you
+are done with it, you should always call
+{@link android.media.MediaPlayer#release release()} to make sure any
+system resources allocated to it are properly released. For example, if you are
+using a {@link android.media.MediaPlayer} and your activity receives a call to {@link
+android.app.Activity#onStop onStop()}, you must release the {@link android.media.MediaPlayer},
+because it
+makes little sense to hold on to it while your activity is not interacting with
+the user (unless you are playing media in the background, which is discussed in the next section).
+When your activity is resumed or restarted, of course, you need to
+create a new {@link android.media.MediaPlayer} and prepare it again before resuming playback.</p>
+
+<p>Here's how you should release and then nullify your {@link android.media.MediaPlayer}:</p>
+<pre>
+mediaPlayer.release();
+mediaPlayer = null;
+</pre>
+
+<p>As an example, consider the problems that could happen if you
+forgot to release the {@link android.media.MediaPlayer} when your activity is stopped, but create a
+new one when the activity starts again. As you may know, when the user changes the
+screen orientation (or changes the device configuration in another way),
+the system handles that by restarting the activity (by default), so you might quickly
+consume all of the system resources as the user
+rotates the device back and forth between portrait and landscape, because at each
+orientation change, you create a new {@link android.media.MediaPlayer} that you never
+release. (For more information about runtime restarts, see <a
+href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a>.)</p>
+
+<p>You may be wondering what happens if you want to continue playing
+"background media" even when the user leaves your activity, much in the same
+way that the built-in Music application behaves. In this case, what you need is
+a {@link android.media.MediaPlayer MediaPlayer} controlled by a {@link android.app.Service}, as
+discussed in <a href="mpandservices">Using a Service with MediaPlayer</a>.</p>
+
+<h2 id="mpandservices">Using a Service with MediaPlayer</h2>
+
+<p>If you want your media to play in the background even when your application
+is not onscreen—that is, you want it to continue playing while the user is
+interacting with other applications—then you must start a
+{@link android.app.Service Service} and control the
+{@link android.media.MediaPlayer MediaPlayer} instance from there.
+You should be careful about this setup, because the user and the system have expectations
+about how an application running a background service should interact with the rest of the
+system. If your application does not fulfil those expectations, the user may
+have a bad experience. This section describes the main issues that you should be
+aware of and offers suggestions about how to approach them.</p>
+
+
+<h3 id="asyncprepare">Running asynchronously</h3>
+
+<p>First of all, like an {@link android.app.Activity Activity}, all work in a
+{@link android.app.Service Service} is done in a single thread by
+default—in fact, if you're running an activity and a service from the same application, they
+use the same thread (the "main thread") by default. Therefore, services need to
+process incoming intents quickly
+and never perform lengthy computations when responding to them. If any heavy
+work or blocking calls are expected, you must do those tasks asynchronously: either from
+another thread you implement yourself, or using the framework's many facilities
+for asynchronous processing.</p>
+
+<p>For instance, when using a {@link android.media.MediaPlayer} from your main thread,
+you should call {@link android.media.MediaPlayer#prepareAsync prepareAsync()} rather than
+{@link android.media.MediaPlayer#prepare prepare()}, and implement
+a {@link android.media.MediaPlayer.OnPreparedListener MediaPlayer.OnPreparedListener}
+in order to be notified when the preparation is complete and you can start playing.
+For example:</p>
+
+<pre>
+public class MyService extends Service implements MediaPlayer.OnPreparedListener {
+ private static final ACTION_PLAY = "com.example.action.PLAY";
+ MediaPlayer mMediaPlayer = null;
+
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ ...
+ if (intent.getAction().equals(ACTION_PLAY)) {
+ mMediaPlayer = ... // initialize it here
+ mMediaPlayer.setOnPreparedListener(this);
+ mMediaPlayer.prepareAsync(); // prepare async to not block main thread
+ }
+ }
+
+ /** Called when MediaPlayer is ready */
+ public void onPrepared(MediaPlayer player) {
+ player.start();
+ }
+}
+</pre>
+
+
+<h3 id="asyncerror">Handling asynchronous errors</h3>
+
+<p>On synchronous operations, errors would normally
+be signaled with an exception or an error code, but whenever you use asynchronous
+resources, you should make sure your application is notified
+of errors appropriately. In the case of a {@link android.media.MediaPlayer MediaPlayer},
+you can accomplish this by implementing a
+{@link android.media.MediaPlayer.OnErrorListener MediaPlayer.OnErrorListener} and
+setting it in your {@link android.media.MediaPlayer} instance:</p>
+
+<pre>
+public class MyService extends Service implements MediaPlayer.OnErrorListener {
+ MediaPlayer mMediaPlayer;
+
+ public void initMediaPlayer() {
+ // ...initialize the MediaPlayer here...
+
+ mMediaPlayer.setOnErrorListener(this);
+ }
+
+ @Override
+ public boolean onError(MediaPlayer mp, int what, int extra) {
+ // ... react appropriately ...
+ // The MediaPlayer has moved to the Error state, must be reset!
+ }
+}
+</pre>
+
+<p>It's important to remember that when an error occurs, the {@link android.media.MediaPlayer}
+moves to the <em>Error</em> state (see the documentation for the
+{@link android.media.MediaPlayer MediaPlayer} class for the full state diagram)
+and you must reset it before you can use it again.
+
+
+<h3 id="wakelocks">Using wake locks</h3>
+
+<p>When designing applications that play media
+in the background, the device may go to sleep
+while your service is running. Because the Android system tries to conserve
+battery while the device is sleeping, the system tries to shut off any
+of the phone's features that are
+not necessary, including the CPU and the WiFi hardware.
+However, if your service is playing or streaming music, you want to prevent
+the system from interfering with your playback.</p>
+
+<p>In order to ensure that your service continues to run under
+those conditions, you have to use "wake locks." A wake lock is a way to signal to
+the system that your application is using some feature that should
+stay available even if the phone is idle.</p>
+
+<p class="caution"><strong>Notice:</strong> You should always use wake locks sparingly and hold them
+only for as long as truly necessary, because they significantly reduce the battery life of the
+device.</p>
+
+<p>To ensure that the CPU continues running while your {@link android.media.MediaPlayer} is
+playing, call the {@link android.media.MediaPlayer#setWakeMode
+setWakeMode()} method when initializing your {@link android.media.MediaPlayer}. Once you do,
+the {@link android.media.MediaPlayer} holds the specified lock while playing and releases the lock
+when paused or stopped:</p>
+
+<pre>
+mMediaPlayer = new MediaPlayer();
+// ... other initialization here ...
+mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
+</pre>
+
+<p>However, the wake lock acquired in this example guarantees only that the CPU remains awake. If
+you are streaming media over the
+network and you are using Wi-Fi, you probably want to hold a
+{@link android.net.wifi.WifiManager.WifiLock WifiLock} as
+well, which you must acquire and release manually. So, when you start preparing the
+{@link android.media.MediaPlayer} with the remote URL, you should create and acquire the Wi-Fi lock.
+For example:</p>
+
+<pre>
+WifiLock wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE))
+ .createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");
+
+wifiLock.acquire();
+</pre>
+
+<p>When you pause or stop your media, or when you no longer need the
+network, you should release the lock:</p>
+
+<pre>
+wifiLock.release();
+</pre>
+
+
+<h3 id="foregroundserv">Running as a foreground service</h3>
+
+<p>Services are often used for performing background tasks, such as fetching emails,
+synchronizing data, downloading content, amongst other possibilities. In these
+cases, the user is not actively aware of the service's execution, and probably
+wouldn't even notice if some of these services were interrupted and later restarted.</p>
+
+<p>But consider the case of a service that is playing music. Clearly this is a service that the user
+is actively aware of and the experience would be severely affected by any interruptions.
+Additionally, it's a service that the user will likely wish to interact with during its execution.
+In this case, the service should run as a "foreground service." A
+foreground service holds a higher level of importance within the system—the system will
+almost never kill the service, because it is of immediate importance to the user. When running
+in the foreground, the service also must provide a status bar notification to ensure that users are
+aware of the running service and allow them to open an activity that can interact with the
+service.</p>
+
+<p>In order to turn your service into a foreground service, you must create a
+{@link android.app.Notification Notification} for the status bar and call
+{@link android.app.Service#startForeground startForeground()} from the {@link
+android.app.Service}. For example:</p>
+
+<pre>String songName;
+// assign the song name to songName
+PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0,
+ new Intent(getApplicationContext(), MainActivity.class),
+ PendingIntent.FLAG_UPDATE_CURRENT);
+Notification notification = new Notification();
+notification.tickerText = text;
+notification.icon = R.drawable.play0;
+notification.flags |= Notification.FLAG_ONGOING_EVENT;
+notification.setLatestEventInfo(getApplicationContext(), "MusicPlayerSample",
+ "Playing: " + songName, pi);
+startForeground(NOTIFICATION_ID, notification);
+</pre>
+
+<p>While your service is running in the foreground, the notification you
+configured is visible in the notification area of the device. If the user
+selects the notification, the system invokes the {@link android.app.PendingIntent} you supplied. In
+the example above, it opens an activity ({@code MainActivity}).</p>
+
+<p>Figure 1 shows how your notification appears to the user:</p>
+
+<img src='images/notification1.png' />
+
+<img src='images/notification2.png' />
+<p class="img-caption"><strong>Figure 1.</strong> Screenshots of a foreground service's
+notification, showing the notification icon in the status bar (left) and the expanded view
+(right).</p>
+
+<p>You should only hold on to the "foreground service" status while your
+service is actually performing something the user is actively aware of. Once
+that is no longer true, you should release it by calling
+{@link android.app.Service#stopForeground stopForeground()}:</p>
+
+<pre>
+stopForeground(true);
+</pre>
+
+<p>For more information, see the documentation about <a
+href="{@docRoot}guide/topics/fundamentals/services.html#Foreground">Services</a> and
+<a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>.</p>
+
+
+<h3 id="audiofocus">Handling audio focus</h3>
+
+<p>Even though only one activity can run at any given time, Android is a
+multi-tasking environment. This poses a particular challenge to applications
+that use audio, because there is only one audio output and there may be several
+media services competing for its use. Before Android 2.2, there was no built-in
+mechanism to address this issue, which could in some cases lead to a bad user
+experience. For example, when a user is listening to
+music and another application needs to notify the user of something very important,
+the user might not hear the notification tone due to the loud music. Starting with
+Android 2.2, the platform offers a way for applications to negotiate their
+use of the device's audio output. This mechanism is called Audio Focus.</p>
+
+<p>When your application needs to output audio such as music or a notification,
+you should always request audio focus. Once it has focus, it can use the sound output freely, but it
+should
+always listen for focus changes. If it is notified that it has lost the audio
+focus, it should immediately either kill the audio or lower it to a quiet level
+(known as "ducking"—there is a flag that indicates which one is appropriate) and only resume
+loud playback after it receives focus again.</p>
+
+<p>Audio Focus is cooperative in nature. That is, applications are expected
+(and highly encouraged) to comply with the audio focus guidelines, but the
+rules are not enforced by the system. If an application wants to play loud
+music even after losing audio focus, nothing in the system will prevent that.
+However, the user is more likely to have a bad experience and will be more
+likely to uninstall the misbehaving application.</p>
+
+<p>To request audio focus, you must call
+{@link android.media.AudioManager#requestAudioFocus requestAudioFocus()} from the {@link
+android.media.AudioManager}, as the example below demonstrates:</p>
+
+<pre>
+AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
+ AudioManager.AUDIOFOCUS_GAIN);
+
+if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
+ // could not get audio focus.
+}
+</pre>
+
+<p>The first parameter to {@link android.media.AudioManager#requestAudioFocus requestAudioFocus()}
+is an {@link android.media.AudioManager.OnAudioFocusChangeListener
+AudioManager.OnAudioFocusChangeListener},
+whose {@link android.media.AudioManager.OnAudioFocusChangeListener#onAudioFocusChange
+onAudioFocusChange()} method is called whenever there is a change in audio focus. Therefore, you
+should also implement this interface on your service and activities. For example:</p>
+
+<pre>
+class MyService extends Service
+ implements AudioManager.OnAudioFocusChangeListener {
+ // ....
+ public void onAudioFocusChange(int focusChange) {
+ // Do something based on focus change...
+ }
+}
+</pre>
+
+<p>The <code>focusChange</code> parameter tells you how the audio focus has changed, and
+can be one of the following values (they are all constants defined in
+{@link android.media.AudioManager AudioManager}):</p>
+
+<ul>
+<li>{@link android.media.AudioManager#AUDIOFOCUS_GAIN}: You have gained the audio focus.</li>
+
+<li>{@link android.media.AudioManager#AUDIOFOCUS_LOSS}: You have lost the audio focus for a
+presumably long time.
+You must stop all audio playback. Because you should expect not to have focus back
+for a long time, this would be a good place to clean up your resources as much
+as possible. For example, you should release the {@link android.media.MediaPlayer}.</li>
+
+<li>{@link android.media.AudioManager#AUDIOFOCUS_LOSS_TRANSIENT}: You have
+temporarily lost audio focus, but should receive it back shortly. You must stop
+all audio playback, but you can keep your resources because you will probably get
+focus back shortly.</li>
+
+<li>{@link android.media.AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}: You have temporarily
+lost audio focus,
+but you are allowed to continue to play audio quietly (at a low volume) instead
+of killing audio completely.</li>
+</ul>
+
+<p>Here is an example implementation:</p>
+
+<pre>
+public void onAudioFocusChange(int focusChange) {
+ switch (focusChange) {
+ case AudioManager.AUDIOFOCUS_GAIN:
+ // resume playback
+ if (mMediaPlayer == null) initMediaPlayer();
+ else if (!mMediaPlayer.isPlaying()) mMediaPlayer.start();
+ mMediaPlayer.setVolume(1.0f, 1.0f);
+ break;
+
+ case AudioManager.AUDIOFOCUS_LOSS:
+ // Lost focus for an unbounded amount of time: stop playback and release media player
+ if (mMediaPlayer.isPlaying()) mMediaPlayer.stop();
+ mMediaPlayer.release();
+ mMediaPlayer = null;
+ break;
+
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+ // Lost focus for a short time, but we have to stop
+ // playback. We don't release the media player because playback
+ // is likely to resume
+ if (mMediaPlayer.isPlaying()) mMediaPlayer.pause();
+ break;
+
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+ // Lost focus for a short time, but it's ok to keep playing
+ // at an attenuated level
+ if (mMediaPlayer.isPlaying()) mMediaPlayer.setVolume(0.1f, 0.1f);
+ break;
+ }
+}
+</pre>
+
+<p>Keep in mind that the audio focus APIs are available only with API level 8 (Android 2.2)
+and above, so if you want to support previous
+versions of Android, you should adopt a backward compatibility strategy that
+allows you to use this feature if available, and fall back seamlessly if not.</p>
+
+<p>You can achieve backward compatibility either by calling the audio focus methods by reflection
+or by implementing all the audio focus features in a separate class (say,
+<code>AudioFocusHelper</code>). Here is an example of such a class:</p>
+
+<pre>
+public class AudioFocusHelper implements AudioManager.OnAudioFocusChangeListener {
+ AudioManager mAudioManager;
+
+ // other fields here, you'll probably hold a reference to an interface
+ // that you can use to communicate the focus changes to your Service
+
+ public AudioFocusHelper(Context ctx, /* other arguments here */) {
+ mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ // ...
+ }
+
+ public boolean requestFocus() {
+ return AudioManager.AUDIOFOCUS_REQUEST_GRANTED ==
+ mAudioManager.requestAudioFocus(mContext, AudioManager.STREAM_MUSIC,
+ AudioManager.AUDIOFOCUS_GAIN);
+ }
+
+ public boolean abandonFocus() {
+ return AudioManager.AUDIOFOCUS_REQUEST_GRANTED ==
+ mAudioManager.abandonAudioFocus(this);
+ }
+
+ @Override
+ public void onAudioFocusChange(int focusChange) {
+ // let your service know about the focus change
+ }
+}
+</pre>
+
+
+<p>You can create an instance of <code>AudioFocusHelper</code> class only if you detect that
+the system is running API level 8 or above. For example:</p>
+
+<pre>
+if (android.os.Build.VERSION.SDK_INT >= 8) {
+ mAudioFocusHelper = new AudioFocusHelper(getApplicationContext(), this);
+} else {
+ mAudioFocusHelper = null;
+}
+</pre>
+
+
+<h3 id="cleanup">Performing cleanup</h3>
+
+<p>As mentioned earlier, a {@link android.media.MediaPlayer} object can consume a significant
+amount of system resources, so you should keep it only for as long as you need and call
+{@link android.media.MediaPlayer#release release()} when you are done with it. It's important
+to call this cleanup method explicitly rather than rely on system garbage collection because
+it might take some time before the garbage collector reclaims the {@link android.media.MediaPlayer},
+as it's only sensitive to memory needs and not to shortage of other media-related resources.
+So, in the case when you're using a service, you should always override the
+{@link android.app.Service#onDestroy onDestroy()} method to make sure you are releasing
+the {@link android.media.MediaPlayer}:</p>
+
+<pre>
+public class MyService extends Service {
+ MediaPlayer mMediaPlayer;
+ // ...
+
+ @Override
+ public void onDestroy() {
+ if (mMediaPlayer != null) mMediaPlayer.release();
+ }
+}
+</pre>
+
+<p>You should always look for other opportunities to release your {@link android.media.MediaPlayer}
+as well, apart from releasing it when being shut down. For example, if you expect not
+to be able to play media for an extended period of time (after losing audio focus, for example),
+you should definitely release your existing {@link android.media.MediaPlayer} and create it again
+later. On the
+other hand, if you only expect to stop playback for a very short time, you should probably
+hold on to your {@link android.media.MediaPlayer} to avoid the overhead of creating and preparing it
+again.</p>
+
+
+
+<h2 id="noisyintent">Handling the AUDIO_BECOMING_NOISY Intent</h2>
+
+<p>Many well-written applications that play audio automatically stop playback when an event
+occurs that causes the audio to become noisy (ouput through external speakers). For instance,
+this might happen when a user is listening to music through headphones and accidentally
+disconnects the headphones from the device. However, this behavior does not happen automatically.
+If you don't implement this feature, audio plays out of the device's external speakers, which
+might not be what the user wants.</p>
+
+<p>You can ensure your app stops playing music in these situations by handling
+the {@link android.media.AudioManager#ACTION_AUDIO_BECOMING_NOISY} intent, for which you can
+register a receiver by
+adding the following to your manifest:</p>
+
+<pre>
+<receiver android:name=".MusicIntentReceiver">
+ <intent-filter>
+ <action android:name="android.media.AUDIO_BECOMING_NOISY" />
+ </intent-filter>
+</receiver>
+</pre>
+
+<p>This registers the <code>MusicIntentReceiver</code> class as a broadcast receiver for that
+intent. You should then implement this class:</p>
+
+<pre>
+public class MusicIntentReceiver implements android.content.BroadcastReceiver {
+ @Override
+ public void onReceive(Context ctx, Intent intent) {
+ if (intent.getAction().equals(
+ android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
+ // signal your service to stop playback
+ // (via an Intent, for instance)
+ }
+ }
+}
+</pre>
+
+
+
+
+<h2 id="viacontentresolver">Retrieving Media from a Content Resolver</h2>
+
+<p>Another feature that may be useful in a media player application is the ability to
+retrieve music that the user has on the device. You can do that by querying the {@link
+android.content.ContentResolver} for external media:</p>
+
+<pre>
+ContentResolver contentResolver = getContentResolver();
+Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
+Cursor cursor = contentResolver.query(uri, null, null, null, null);
+if (cursor == null) {
+ // query failed, handle error.
+} else if (!cursor.moveToFirst()) {
+ // no media on the device
+} else {
+ int titleColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
+ int idColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
+ do {
+ long thisId = cursor.getLong(idColumn);
+ String thisTitle = cursor.getString(titleColumn);
+ // ...process entry...
+ } while (cursor.moveToNext());
+}
+</pre>
+
+<p>To use this with the {@link android.media.MediaPlayer}, you can do this:</p>
+
+<pre>
+long id = /* retrieve it from somewhere */;
+Uri contentUri = ContentUris.withAppendedId(
+ android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
+
+mMediaPlayer = new MediaPlayer();
+mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+mMediaPlayer.setDataSource(getApplicationContext(), contentUri);
+
+// ...prepare and start...
+</pre>
\ No newline at end of file
diff --git a/docs/html/guide/topics/nfc/advanced-nfc.jd b/docs/html/guide/topics/nfc/advanced-nfc.jd
new file mode 100644
index 0000000..b43b559
--- /dev/null
+++ b/docs/html/guide/topics/nfc/advanced-nfc.jd
@@ -0,0 +1,300 @@
+page.title=Advanced NFC
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#tag-tech">Working with Supported Tag Technologies</a>
+ <ol>
+ <li><a href="#tech-intent">Working with tag technologies and the ACTION_TECH_DISCOVERED
+ intent</a></li>
+ <li><a href="#read-write">Reading and writing to tags</a></li>
+ </ol></li>
+ <li><a href="#foreground-dispatch">Using the Foreground Dispatch System</a></li>
+ </ol>
+</div>
+</div>
+
+<p>This document describes advanced NFC topics, such as working with various tag technologies,
+writing to NFC tags, and foreground dispatching, which allows an application in the foreground to
+handle intents even when other applications filter for the same ones.</p>
+
+<h2 id="tag-tech">Working with Supported Tag Technologies</h2>
+<p>When working with NFC tags and Android-powered devices, the main format you use to read
+and write data on tags is NDEF. When a device scans a tag with NDEF data, Android provides support
+in parsing the message and delivering it in an {@link android.nfc.NdefMessage} when
+possible. There are cases, however, when you scan a tag that does not contain
+NDEF data or when the NDEF data could not be mapped to a MIME type or URI.
+In these cases, you need to open communication directly with the tag and read and write to it with
+your own protocol (in raw bytes). Android provides generic support for these use cases with the
+{@link android.nfc.tech} package, which is described in <a href="#tech-table">Table 1</a>. You can
+use the {@link android.nfc.Tag#getTechList getTechList()} method to determine the technologies
+supported by the tag and create the corresponding {@link android.nfc.tech.TagTechnology}
+object with one of classes provided by {@link android.nfc.tech} </p>
+
+<p class="table-caption" id="table1">
+<strong>Table 1.</strong> Supported tag technologies</p>
+<table id="tech-table">
+
+ <tr>
+ <th>Class</th>
+
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>{@link android.nfc.tech.TagTechnology}</td>
+
+ <td>The interface that all tag technology classes must implement.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.nfc.tech.NfcA}</td>
+
+ <td>Provides access to NFC-A (ISO 14443-3A) properties and I/O operations.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.nfc.tech.NfcB}</td>
+
+ <td>Provides access to NFC-B (ISO 14443-3B) properties and I/O operations.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.nfc.tech.NfcF}</td>
+
+ <td>Provides access to NFC-F (JIS 6319-4) properties and I/O operations.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.nfc.tech.NfcV}</td>
+
+ <td>Provides access to NFC-V (ISO 15693) properties and I/O operations.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.nfc.tech.IsoDep}</td>
+
+ <td>Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.nfc.tech.Ndef}</td>
+
+ <td>Provides access to NDEF data and operations on NFC tags that have been formatted as
+ NDEF.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.nfc.tech.NdefFormatable}</td>
+
+ <td>Provides a format operations for tags that may be NDEF formattable.</td>
+ </tr>
+ </table>
+<p>The following tag technlogies are not required to be supported by Android-powered devices.</p>
+ <p class="table-caption" id="table2">
+<strong>Table 2.</strong> Optional supported tag technologies</p>
+ <table>
+ <tr>
+ <th>Class</th>
+
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>{@link android.nfc.tech.MifareClassic}</td>
+
+ <td>Provides access to MIFARE Classic properties and I/O operations, if this Android device
+ supports MIFARE.</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.nfc.tech.MifareUltralight}</td>
+
+ <td>Provides access to MIFARE Ultralight properties and I/O operations, if this Android
+ device supports MIFARE.</td>
+ </tr>
+ </table>
+
+<h3 id="tech-intent">Working with tag technologies and the ACTION_TECH_DISCOVERED intent</h3>
+<p>When a device scans a tag that has NDEF data on it, but could not be mapped to a MIME or URI,
+the tag dispatch system tries to start an activity with the {@link
+android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}
+intent. The {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} is also used when a tag
+with non-NDEF data is scanned. Having this fallback allows you to work with the data on the tag
+directly if the tag dispatch system could not parse it for you. The basic steps when working with
+tag technologies are as follows:</p>
+
+<ol>
+ <li>Filter for an {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent specifying the
+tag technologies that you want to handle. See <a
+href="{@docRoot}guide/topics/nfc/nfc.html#tech-disc">Filtering for NFC
+intents</a> for more information. In general, the tag dispatch system tries to start a {@link
+android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent when an NDEF message
+cannot be mapped to a MIME type or URI, or if the tag scanned did not contain NDEF data. For
+more information on how this is determined, see <a
+href="{@docRoot}guide/topics/nfc/nfc.html#tag-dispatch">The Tag Dispatch System</a>.</li>
+ <li>When your application receives the intent, obtain the {@link android.nfc.Tag} object from
+the intent:
+<pre>Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);</pre></li>
+<li>Obtain an instance of a {@link android.nfc.tech.TagTechnology}, by calling one of the
+<code>get</code> factory methods of the classes in the {@link android.nfc.tech} package. You can
+enumerate the supported technologies of the tag by calling {@link android.nfc.Tag#getTechList
+getTechList()} before calling a <code>get</code> factory method. For example, to obtain an instance
+of {@link android.nfc.tech.MifareUltralight} from a {@link android.nfc.Tag}, do the following:
+
+<pre>
+MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
+</pre>
+</li>
+</ol>
+
+
+
+<h3 id="read-write">Reading and writing to tags</h3>
+
+<p>Reading and writing to an NFC tag involves obtaining the tag from the intent and
+opening communication with the tag. You must define your own protocol stack to read and write data
+to the tag. Keep in mind, however, that you can still read and write NDEF data when working
+directly with a tag. It is up to you how you want to structure things. The
+following example shows how to work with a MIFARE Ultralight tag.</p>
+
+<pre>
+package com.example.android.nfc;
+
+import android.nfc.Tag;
+import android.nfc.tech.MifareUltralight;
+import android.util.Log;
+import java.io.IOException;
+import java.nio.charset.Charset;
+
+public class MifareUltralightTagTester {
+
+ private static final String TAG = MifareUltralightTagTester.class.getSimpleName();
+
+ public void writeTag(Tag tag, String tagText) {
+ MifareUltralight ultralight = MifareUltralight.get(tag);
+ try {
+ ultralight.connect();
+ ultralight.writePage(4, "abcd".getBytes(Charset.forName("US-ASCII")));
+ ultralight.writePage(5, "efgh".getBytes(Charset.forName("US-ASCII")));
+ ultralight.writePage(6, "ijkl".getBytes(Charset.forName("US-ASCII")));
+ ultralight.writePage(7, "mnop".getBytes(Charset.forName("US-ASCII")));
+ } catch (IOException e) {
+ Log.e(TAG, "IOException while closing MifareUltralight...", e);
+ } finally {
+ try {
+ ultralight.close();
+ } catch (IOException e) {
+ Log.e(TAG, "IOException while closing MifareUltralight...", e);
+ }
+ }
+ }
+
+ public String readTag(Tag tag) {
+ MifareUltralight mifare = MifareUltralight.get(tag);
+ try {
+ mifare.connect();
+ byte[] payload = mifare.readPages(4);
+ return new String(payload, Charset.forName("US-ASCII"));
+ } catch (IOException e) {
+ Log.e(TAG, "IOException while writing MifareUltralight
+ message...", e);
+ } finally {
+ if (mifare != null) {
+ try {
+ mifare.close();
+ }
+ catch (IOException e) {
+ Log.e(TAG, "Error closing tag...", e);
+ }
+ }
+ }
+ return null;
+ }
+}
+</pre>
+
+</pre>
+
+ <h2 id="foreground-dispatch">Using the Foreground Dispatch System</h2>
+
+ <p>The foreground dispatch system allows an activity to intercept an intent and claim
+priority over other activities that handle the same intent. Using this system involves
+ constructing a few data structures for the Android system to be able to send the appropriate
+ intents to your application. To enable the foreground dispatch system:</p>
+
+ <ol>
+ <li>Add the following code in the <code>onCreate()</code> method of your activity:
+
+ <ol>
+ <li>Create a {@link android.app.PendingIntent} object so the Android system can populate it
+ with the details of the tag when it is scanned.
+ <pre>
+PendingIntent pendingIntent = PendingIntent.getActivity(
+ this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
+</pre>
+ </li>
+
+ <li>Declare intent filters to handle the intents that you want to intercept. The foreground
+ dispatch system checks the specified intent filters with the intent that is received when
+ the device scans a tag. If it matches, then your application handles the intent. If it does
+ not match, the foreground dispatch system falls back to the intent dispatch system.
+ Specifying a <code>null</code> array of intent filters and technology filters, specifies
+ that you want to filter for all tags that fallback to the <code>TAG_DISCOVERED</code>
+ intent. The code snippet below handles all MIME types for <code>NDEF_DISCOVERED</code>. You
+ should only handle the ones that you need.
+<pre>
+IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
+ try {
+ ndef.addDataType("*/*"); /* Handles all MIME based dispatches.
+ You should specify only the ones that you need. */
+ }
+ catch (MalformedMimeTypeException e) {
+ throw new RuntimeException("fail", e);
+ }
+ intentFiltersArray = new IntentFilter[] {ndef, };
+</pre>
+ </li>
+
+ <li>Set up an array of tag technologies that your application wants to handle. Call the
+ <code>Object.class.getName()</code> method to obtain the class of the technology that you
+ want to support.
+<pre>
+techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
+</pre>
+ </li>
+ </ol>
+ </li>
+
+ <li>Override the following activity lifecycle callbacks and add logic to enable and disable the
+ foreground dispatch when the activity loses ({@link android.app.Activity#onPause onPause()})
+ and regains ({@link android.app.Activity#onResume onResume()}) focus. {@link
+ android.nfc.NfcAdapter#enableForegroundDispatch enableForegroundDispatch()} must be called from
+the main thread and only when the activity is in the foreground (calling in {@link
+android.app.Activity#onResume onResume()} guarantees this). You also need to implement the {@link
+ android.app.Activity#onNewIntent onNewIntent} callback to process the data from the scanned NFC
+ tag.</li>
+
+<pre>
+public void onPause() {
+ super.onPause();
+ mAdapter.disableForegroundDispatch(this);
+}
+
+public void onResume() {
+ super.onResume();
+ mAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray);
+}
+
+public void onNewIntent(Intent intent) {
+ Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
+ //do something with tagFromIntent
+}
+</pre>
+ </li>
+ </ol>
+
+ <p>See the <a href=
+"{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundDispatch.html">
+ForegroundDispatch</a> sample from API Demos for the complete sample.</p>
\ No newline at end of file
diff --git a/docs/html/guide/topics/nfc/index.jd b/docs/html/guide/topics/nfc/index.jd
index b486d3b..b86d72d 100644
--- a/docs/html/guide/topics/nfc/index.jd
+++ b/docs/html/guide/topics/nfc/index.jd
@@ -1,601 +1,33 @@
page.title=Near Field Communication
@jd:body
-<div id="qv-wrapper">
-<div id="qv">
- <h2>In this document</h2>
- <ol>
- <li><a href="#api">API Overview</a></li>
- <li><a href="#manifest">Declaring Android Manifest elements</a></li>
- <li><a href="#dispatch">The Tag Dispatch System</a>
- <ol>
- <li><a href="#intent-dispatch">Using the intent dispatch system</a></li>
- <li><a href="#foreground-dispatch">Using the foreground dispatch system</a></li>
- </ol></li>
- <li><a href="#ndef">Working with Data on NFC Tags</a></li>
- <li><a href="#read">Reading an NFC Tag</a></li>
- <li><a href="#write">Writing to an NFC Tag</a></li>
- <li><a href="#p2p">Peer-to-Peer Data Exchange</a></li>
- </ol>
-</div>
-</div>
-
<p>Near Field Communication (NFC) is a set of short-range wireless technologies, typically
- requiring a distance of 4cm or less. NFC operates at 13.56mhz, and at rates ranging from 106
- kbit/s to 848 kbit/s. NFC communication always involves an initiator and a target. The initiator
- actively generates an RF field that can power a passive target. This enables NFC targets to take
- very simple form factors such as tags, stickers or cards that do not require power. NFC
- peer-to-peer communication is also possible, where both devices are powered.</p>
+ requiring a distance of 4cm or less to initiate a connection. NFC allows you to share small
+ payloads of data between an NFC tag and an Android-powered device, or between two Android-powered
+ devices.
- <p>Compared to other wireless technologies such as Bluetooth or WiFi, NFC provides much lower
- bandwidth and range, but enables low-cost, un-powered targets and does not require discovery or
- pairing. Interactions can be initiated with just a tap.</p>
-
- <p>An Android device with NFC hardware will typically act as an initiator when the screen is on.
- This mode is also known as NFC reader/writer. It will actively look for NFC tags and start
- activities to handle them. Android 2.3.3 also has some limited P2P support.</p>
-
- <p>Tags can range in complexity, simple tags just offer read/write semantics, sometimes with
+ <p>Tags can range in complexity. Simple tags offer just read and write semantics, sometimes with
one-time-programmable areas to make the card read-only. More complex tags offer math operations,
and have cryptographic hardware to authenticate access to a sector. The most sophisticated tags
- contain operating environments, allowing complex interactions with code executing on the tag.</p>
+ contain operating environments, allowing complex interactions with code executing on the tag.
+ The data stored in the tag can also be written in a variety of formats, but many of the Android
+ framework APIs are based around a <a href="http://www.nfc-forum.org/">NFC Forum</a> standard
+ called NDEF (NFC Data Exchange Format).</p>
- <h2 id="api">API Overview</h2>
+ <dl>
+ <dt><strong><a href="{@docRoot}guide/topics/nfc/nfc.html">NFC Basics</a></strong></dt>
+ <dd>This document describes how Android handles discovered NFC tags and how it notifies
+applications of data that is relevant to the application. It also goes over how to work with the
+NDEF data in your applications and gives an overview of the framework APIs that support the basic
+NFC feature set of Android.</dd>
- <p>The {@link android.nfc} package contains the high-level classes to interact with the local
- device's NFC adapter, to represent discovered tags, and to use the NDEF data format.</p>
-
- <table>
- <tr>
- <th>Class</th>
-
- <th>Description</th>
- </tr>
-
- <tr>
- <td>{@link android.nfc.NfcManager}</td>
-
- <td>A high level manager class that enumerates the NFC adapters on this Android device. Since
- most Android devices only have one NFC adapter, you can just use the static helper {@link
- android.nfc.NfcAdapter#getDefaultAdapter(Context)} for most situations.</td>
- </tr>
-
- <tr>
- <td>{@link android.nfc.NfcAdapter}</td>
-
- <td>Represents the local NFC adapter. Defines the intent's used to request tag dispatch to
- your activity, and provides methods to register for foreground tag dispatch and foreground
- NDEF push. Foreground NDEF push is the only peer-to-peer support that is currently provided
- in Android.</td>
- </tr>
-
- <tr>
- <td>{@link android.nfc.NdefMessage} and {@link android.nfc.NdefRecord}</td>
-
- <td>NDEF is an NFC Forum defined data structure, designed to efficiently store data on NFC
- tags, such as text, URL's, and other MIME types. A {@link android.nfc.NdefMessage} acts as a
- container for the data that you want to transmit or read. One {@link android.nfc.NdefMessage}
- object contains zero or more {@link android.nfc.NdefRecord}s. Each NDEF record has a type
- such as text, URL, smart poster, or any MIME data. The type of the first NDEF record in the
- NDEF message is used to dispatch a tag to an activity on Android.</td>
- </tr>
-
- <tr>
- <td>{@link android.nfc.Tag}</td>
-
- <td>Represents a passive NFC target. These can come in many form factors such as a tag, card,
- key fob, or even a phone doing card emulation. When a tag is discovered, a {@link
- android.nfc.Tag} object is created and wrapped inside an Intent. The NFC dispatch system
- sends the intent to a compatible activity using <code>startActivity()</code>. You can use the
- {@link android.nfc.Tag#getTechList getTechList()} method to determine the technologies
- supported by this tag and create the corresponding {@link android.nfc.tech.TagTechnology}
- object with one of classes provided by {@link android.nfc.tech}.</td>
- </tr>
- </table>
-
- <p>The {@link android.nfc.tech} package contains classes to query properties and perform I/O
- operations on a tag. The classes are divided to represent different NFC technologies that can be
- available on a Tag:</p>
-
- <table>
- <tr>
- <th>Class</th>
-
- <th>Description</th>
- </tr>
-
- <tr>
- <td>{@link android.nfc.tech.TagTechnology}</td>
-
- <td>The interface that all tag technology classes must implement.</td>
- </tr>
-
- <tr>
- <td>{@link android.nfc.tech.NfcA}</td>
-
- <td>Provides access to NFC-A (ISO 14443-3A) properties and I/O operations.</td>
- </tr>
-
- <tr>
- <td>{@link android.nfc.tech.NfcB}</td>
-
- <td>Provides access to NFC-B (ISO 14443-3B) properties and I/O operations.</td>
- </tr>
-
- <tr>
- <td>{@link android.nfc.tech.NfcF}</td>
-
- <td>Provides access to NFC-F (JIS 6319-4) properties and I/O operations.</td>
- </tr>
-
- <tr>
- <td>{@link android.nfc.tech.NfcV}</td>
-
- <td>Provides access to NFC-V (ISO 15693) properties and I/O operations.</td>
- </tr>
-
- <tr>
- <td>{@link android.nfc.tech.IsoDep}</td>
-
- <td>Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations.</td>
- </tr>
-
- <tr>
- <td>{@link android.nfc.tech.Ndef}</td>
-
- <td>Provides access to NDEF data and operations on NFC tags that have been formatted as
- NDEF.</td>
- </tr>
-
- <tr>
- <td>{@link android.nfc.tech.NdefFormatable}</td>
-
- <td>Provides a format operations for tags that may be NDEF formattable.</td>
- </tr>
-
- <tr>
- <td>{@link android.nfc.tech.MifareClassic}</td>
-
- <td>Provides access to MIFARE Classic properties and I/O operations, if this Android device
- supports MIFARE.</td>
- </tr>
-
- <tr>
- <td>{@link android.nfc.tech.MifareUltralight}</td>
-
- <td>Provides access to MIFARE Ultralight properties and I/O operations, if this Android
- device supports MIFARE.</td>
- </tr>
- </table>
-
- <h2 id="manifest">Declaring Android Manifest elements</h2>
-
- <p>Before you can access a device's NFC hardware and properly handle NFC intents, declare these
- items in your <code>AndroidManifest.xml</code> file:</p>
-
- <ol>
- <li>The NFC <code><uses-permission></code> element to access the NFC hardware:
- <pre>
-<uses-permission android:name="android.permission.NFC" />
-</pre>
- </li>
-
- <li>The minimum SDK version that your application can support. API level 9 only supports
- limited tag dispatch via {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED}, and only gives
- access to NDEF messages via the {@link android.nfc.NfcAdapter#EXTRA_NDEF_MESSAGES} extra. No
- other tag properties or I/O operations are accessible. You probably want to use API level 10
- which includes comprehensive reader/writer support.
- <pre class="pretty-print">
-<uses-sdk android:minSdkVersion="10"/>
-</pre>
- </li>
-
- <li>The uses-feature element so that your application can show up in the Android Market for
- devices that have NFC hardware:
- <pre>
-<uses-feature android:name="android.hardware.nfc" android:required="true" />
-</pre>
- </li>
-
- <li>The NFC intent filter to tell the Android system your Activity can handle NFC data. Specify
- one or more of these three intent filters:
- <pre>
-<intent-filter>
- <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
- <data android:mimeType="<em>mime/type</em>" />
-</intent-filter>
-
-<intent-filter>
- <action android:name="android.nfc.action.TECH_DISCOVERED"/>
- <meta-data android:name="android.nfc.action.TECH_DISCOVERED"
- android:resource="@xml/<em>nfc_tech_filter</em>.xml" />
-</intent-filter>
-
-<intent-filter>
- <action android:name="android.nfc.action.TAG_DISCOVERED"/>
-</intent-filter>
-</pre>
-
- <p>The three intent filters are prioritized and behave in specific ways. Declare only the
- ones that your Activity needs to handle. For more information on how to handle these filters,
- see the section about <a href="#dispatch">The Tag Dispatch System</a>.</p>
- </li>
- </ol>
-
- <p>View the <a href=
- "../../../resources/samples/NFCDemo/AndroidManifest.html">AndroidManifest.xml</a> from the
- NFCDemo sample to see a complete example.</p>
-
- <h2 id="dispatch">The Tag Dispatch System</h2>
-
- <p>When an Android device scans an NFC tag, the desired behavior is to have the most appropriate
- Activity handle the intent without asking the user what application to use. Because devices scan
- NFC tags at a very short range, it is likely that making users manually select an Activity forces
- them to move the device away from the tag and break the connection. You should develop your
- Activity to only handle the NFC tags that your Activity cares about to prevent the Activity
- Chooser from appearing. Android provides two systems to help you correctly identify an NFC tag
- that your Activity should handle: the Intent dispatch system and the foreground Activity dispatch
- system.</p>
-
- <p>The intent dispatch system checks the intent filters of all the Activities along with the
- types of data that the Activities support to find the best Activity that can handle the NFC tag.
- If multiple Activities specify the same intent filter and data to handle, then the Activity
- Chooser is presented to the user as a last resort.</p>
-
- <p>The foreground dispatch system allows an Activity application to override the intent dispatch
- system and have priority when an NFC tag is scanned. The Activity handling the request must be
- running in the foreground of the device. When an NFC tag is scanned and matches the intent and
- data type that the foreground dispatch Activity defines, the intent is immediately sent to the
- Activity even if another Activity can handle the intent. If the Activity cannot handle the
- intent, the foreground dispatch system falls back to the intent dispatch system.</p>
-
- <h3 id="intent-dispatch">Using the intent dispatch system</h3>
-
- <p>The intent dispatch system specifies three intents that each have a priority. The intents that
- start when a device scans a tag depend on the type of tag scanned. In general, the intents are
- started in the following manner:</p>
-
- <ul>
- <li>
- <code>android.nfc.action.NDEF_DISCOVERED</code>: This intent starts when a tag that contains
- an NDEF payload is scanned. This is the highest priority intent. The Android system does not
- let you specify this intent generically to handle all data types. You must specify
- <code><data></code> elements in the <code>AndroidManifest.xml</code> along with this
- intent to correctly handle NFC tags that start this intent. For example, to handle a
- <code>NDEF_DISCOVERED</code> intent that contains plain text, specify the following filter in
- your <code>AndroidManifest.xml</code> file:
- <pre>
-<intent-filter>
- <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
- <data android:mimeType="text/plain" />
-</intent-filter>
-</pre>
-
- <p>If the <code>NDEF_DISCOVERED</code> intent is started, the <code>TECH_DISCOVERED</code>
- and <code>TAG_DISCOVERED</code> intents are not started. This intent does not start if an
- unknown tag is scanned or if the tag does not contain an NDEF payload.</p>
- </li>
-
- <li><code>android.nfc.action.TECH_DISCOVERED</code>: If the <code>NDEF_DISCOVERED</code> intent
- does not start or is not filtered by any Activity on the device, this intent starts if the tag
- is known. The <code>TECH_DISCOVERED</code> intent requires that you specify the technologies
- that you want to support in an XML resource file. For more information, see the section about
- <a href="#technology-resources">Specifying tag technologies to handle</a>.</li>
-
- <li><code>android.nfc.action.TAG_DISCOVERED</code>: This intent starts if no Activities handle
- the <code>NDEF_DISCOVERED</code> and <code>TECH_DISCOVERED</code> intents or if the tag that is
- scanned is unknown.</li>
- </ul>
-
- <h4 id="tech">Specifying tag technologies to handle</h4>
-
- <p>If your Activity declares the <code>android.nfc.action.TECH_DISCOVERED</code> intent in your
- <code>AndroidManifest.xml</code> file, you must create an XML resource file that specifies the
- technologies that your Activity supports within a <code>tech-list</code> set. Your Activity is
- considered a match if a <code>tech-list</code> set is a subset of the technologies that are
- supported by the tag, which you can obtain by calling {@link android.nfc.Tag#getTechList
- getTechList()}.</p>
-
- <p>For example, if the tag that is scanned supports MifareClassic, NdefFormatable, and NfcA, your
- <code>tech-list</code> set must specify all three, two, or one of the technologies (and nothing
- else) in order for your Activity to be matched.</p>
-
- <p>The following sample defines all of the technologies. You can remove the ones that you do not
- need. Save this file (you can name it anything you wish) in the
- <code><project-root>/res/xml</code> folder.</p>
- <pre>
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <tech-list>
- <tech>android.nfc.tech.IsoDep</tech>
- <tech>android.nfc.tech.NfcA</tech>
- <tech>android.nfc.tech.NfcB</tech>
- <tech>android.nfc.tech.NfcF</tech>
- <tech>android.nfc.tech.NfcV</tech>
- <tech>android.nfc.tech.Ndef</tech>
- <tech>android.nfc.tech.NdefFormatable</tech>
- <tech>android.nfc.tech.MifareClassic</tech>
- <tech>android.nfc.tech.MifareUltralight</tech>
- </tech-list>
-</resources>
-</pre>
-
- <p>You can also specify multiple <code>tech-list</code> sets. Each of the <code>tech-list</code>
- sets is considered independently, and your Activity is considered a match if any single
- <code>tech-list</code> set is a subset of the technologies that are returned by {@link
- android.nfc.Tag#getTechList getTechList()}. This provides <code>AND</code> and <code>OR</code>
- semantics for matching technologies. The following example matches tags that can support the
- NfcA and Ndef technologies or can support the NfcB and Ndef technologies:</p>
- <pre>
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <tech-list>
- <tech>android.nfc.tech.NfcA</tech>
- <tech>android.nfc.tech.Ndef</tech>
- </tech-list>
-</resources>
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <tech-list>
- <tech>android.nfc.tech.NfcB</tech>
- <tech>android.nfc.tech.Ndef</tech>
- </tech-list>
-</resources>
-</pre>
-
- <p>In your <code>AndroidManifest.xml</code> file, specify the resource file that you just created
- in the <code><meta-data></code> element inside the <code><activity></code>
- element like in the following example:</p>
- <pre>
-<activity>
-...
-<intent-filter>
- <action android:name="android.nfc.action.TECH_DISCOVERED"/>
-</intent-filter>
-
-<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
- android:resource="@xml/nfc_tech_filter" />
-...
-</activity>
-</pre>
-
- <h3 id="foreground-dispatch">Using the foreground dispatch system</h3>
-
- <p>The foreground dispatch system allows an Activity to intercept an intent and claim priority
- over other Activities that handle the same intent. The system is easy to use and involves
- constructing a few data structures for the Android system to be able to send the appropriate
- intents to your application. To enable the foreground dispatch system:</p>
-
- <ol>
- <li>Add the following code in the onCreate() method of your Activity:
-
- <ol type="a">
- <li>Create a {@link android.app.PendingIntent} object so the Android system can populate it
- with the details of the tag when it is scanned
- <pre>
-PendingIntent pendingIntent = PendingIntent.getActivity(
- this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
-</pre>
- </li>
-
- <li>Declare intent filters to handle the intents that you want to intercept. The foreground
- dispatch system checks the specified intent filters with the intent that is received when
- the device scans a tag. If they match, then your application handles the intent. If it does
- not match, the foreground dispatch system falls back to the intent dispatch system.
- Specifying a <code>null</code> array of intent filters and for the technology filters, you
- receive a <code>TAG_DISCOVERED</code> intent for all tags discovered. Note that the snippet
- below handles all MIME types. You should only handle the ones that you need.
- <pre>
- IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
- try {
- ndef.addDataType("*/*"); /* Handles all MIME based dispatches.
- You should specify only the ones that you need. */
- }
- catch (MalformedMimeTypeException e) {
- throw new RuntimeException("fail", e);
- }
- intentFiltersArray = new IntentFilter[] {
- ndef,
- };
-</pre>
- </li>
-
- <li>Set up an array of tag technologies that your application wants to handle. Call the
- <code>Object.class.getName()</code> method to obtain the class of the technology that you
- want to support.
- <pre>
-
- techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
-
-</pre>
- </li>
- </ol>
- </li>
-
- <li>Override the following Activity lifecycle callbacks and add logic to enable and disable the
- foreground dispatch when the Activity loses ({@link android.app.Activity#onPause onPause()})
- and regains ({@link android.app.Activity#onResume onResume()}) focus. {@link
- android.nfc.NfcAdapter#enableForegroundDispatch} must be called from the main thread and only
- when the activity is in the foreground (calling in {@link android.app.Activity#onResume
- onResume()} guarantees this). You also need to implement the {@link
- android.app.Activity#onNewIntent onNewIntent} callback to process the data from the scanned NFC
- tag.
- <pre>
-public void onPause() {
- super.onPause();
- mAdapter.disableForegroundDispatch(this);
-}
-
-public void onResume() {
- super.onResume();
- mAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray);
-}
-
-public void onNewIntent(Intent intent) {
- Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
- //do something with tagFromIntent
-}
-</pre>
- </li>
- </ol>
-
- <p>See the <a href=
- "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundDispatch.html">ForegroundDispatch</a>
- sample from API Demos for the complete sample.</p>
-
- <h2 id="ndef">Working with Data on NFC Tags</h2>
-
- <p>Data on NFC tags are encoded in raw bytes, so you must convert the bytes to something human
- readable if you are presenting the data to the user. When writing to NFC tags, you must write
- them in bytes as well. Android provides APIs to help write messages that conform to the NDEF
- standard, which was developed by the <a href="http://www.nfc-forum.org/specs/">NFC Forum</a> to
- standardized data on tags. Using this standard ensures that your data will be supported by all
- Android NFC devices if you are writing to tags. However, many tag technologies use their own
- standard for storing data and are supported by Android as well, but you have to implement your
- own protocol stack to read and write to these tags. You can find a full list of the supported
- technologies in {@link android.nfc.tech} and an overview of the technologies in the {@link
- android.nfc.tech.TagTechnology} interface. This section is a brief overview of how to work with
- NDEF messages in the context of the Android system. It is not meant to be a complete discussion
- of the NDEF specification, but highlights the main things that you need to be aware of when
- working with NDEF messages in Android.</p>
-
- <p>To facilitate working with NDEF messages, Android provides the {@link android.nfc.NdefRecord}
- and {@link android.nfc.NdefMessage} to encapsulate the raw bytes that represent NDEF messages. An
- {@link android.nfc.NdefMessage} is the container for zero or more {@link
- android.nfc.NdefRecord}s. Each {@link android.nfc.NdefRecord} has its own unique type name
- format, record type, and ID to distinguish them from other records within the same {@link
- android.nfc.NdefMessage}. You can store different types of records of varying length in a single
- {@link android.nfc.NdefMessage}. The size constraint of the NFC tag determines how big your
- {@link android.nfc.NdefMessage} can be.</p>
-
- <p>Tags that support the {@link android.nfc.tech.Ndef} and {@link
- android.nfc.tech.NdefFormatable} technologies return and accept {@link android.nfc.NdefMessage}
- objects as parameters for read and write operations. You need to create your own logic to read
- and write bytes for other tag technologies in {@link android.nfc.tech}.</p>
-
- <p>You can download technical specifications for different types of NDEF message standards, such
- as plain text and Smart Posters, at the <a href="http://www.nfc-forum.org/specs/">NFC Forum</a>
- website. The NFCDemo sample application also declares sample <a href=
- "{@docRoot}resources/samples/NFCDemo/src/com/example/android/nfc/simulator/MockNdefMessages.html">
- plain text and SmartPoster NDEF messages.</a></p>
-
- <h2 id="read">Reading an NFC Tag</h2>
-
- <p>When a device comes in proximity to an NFC tag, the appropriate intent is started on the
- device, notifying interested applications that a NFC tag was scanned. By previously declaring the
- appropriate intent filter in your <code>AndroidManifest.xml</code> file or using foreground
- dispatching, your application can request to handle the intent.</p>
-
- <p>The following method (slightly modified from the NFCDemo sample application), handles the
- <code>TAG_DISCOVERED</code> intent and iterates through an array obtained from the intent that
- contains the NDEF payload:</p>
- <pre>
-NdefMessage[] getNdefMessages(Intent intent) {
- // Parse the intent
- NdefMessage[] msgs = null;
- String action = intent.getAction();
- if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
- Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
- if (rawMsgs != null) {
- msgs = new NdefMessage[rawMsgs.length];
- for (int i = 0; i < rawMsgs.length; i++) {
- msgs[i] = (NdefMessage) rawMsgs[i];
- }
- }
- else {
- // Unknown tag type
- byte[] empty = new byte[] {};
- NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
- NdefMessage msg = new NdefMessage(new NdefRecord[] {record});
- msgs = new NdefMessage[] {msg};
- }
- }
- else {
- Log.e(TAG, "Unknown intent " + intent);
- finish();
- }
- return msgs;
-}
-</pre>
-
- <p>Keep in mind that the data that the device reads is in bytes, so you must implement your own
- logic if you need to present the data in a readable format to the user. The classes in
- <code>com.example.android.nfc.record</code> of the NFCDemo sample show you how to parse some
- common types of NDEF messages such as plain text or a SmartPoster.</p>
-
- <h2 id="write">Writing to an NFC Tag</h2>
-
- <p>Writing to an NFC tag involves constructing your NDEF message in bytes and using the
- appropriate tag technology for the tag that you are writing to. The following code sample shows
- you how to write a simple text message to a {@link android.nfc.tech.NdefFormatable} tag:</p>
- <pre>
-NdefFormatable tag = NdefFormatable.get(t);
-Locale locale = Locale.US;
-final byte[] langBytes = locale.getLanguage().getBytes(Charsets.US_ASCII);
-String text = "Tag, you're it!";
-final byte[] textBytes = text.getBytes(Charsets.UTF_8);
-final int utfBit = 0;
-final char status = (char) (utfBit + langBytes.length);
-final byte[] data = Bytes.concat(new byte[] {(byte) status}, langBytes, textBytes);
-NdefRecord record = NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
-try {
- NdefRecord[] records = {text};
- NdefMessage message = new NdefMessage(records);
- tag.connect();
- tag.format(message);
-}
-catch (Exception e){
- //do error handling
-}
-</pre>
-
- <h2 id="p2p">Peer-to-Peer Data Exchange</h2>
-
- <p>Support for simple peer-to-peer data exchange is supported by the foreground push feature,
- which is enabled with the {@link android.nfc.NfcAdapter#enableForegroundNdefPush} method. To use
- this feature:</p>
-
- <ul>
- <li>The Activity that is pushing the data must be in the foreground</li>
-
- <li>You must encapsulate the data that you are sending in an {@link android.nfc.NdefMessage}
- object</li>
-
- <li>The NFC device that is receiving the pushed data (the scanned device) must support the
- <code>com.android.npp</code> NDEF push protocol, which is optional for Android devices.</li>
- </ul>
-
- <p class="note">If your Activity enables the foreground push feature and is in the foreground,
- the standard intent dispatch system is disabled. However, if your Activity also enables
- foreground dispatching, then it can still scan tags that match the intent filters set in the
- foreground dispatching.</p>
-
- <p>To enable foreground dispatching:</p>
-
- <ol>
- <li>Create an NdefMessage that contains the NdefRecords that you want to push onto the other
- device.</li>
-
- <li>Implement the {@link android.app.Activity#onResume onResume()} and {@link
- android.app.Activity#onPause onPause()} callbacks in your Activity to appropriately handle the
- foreground pushing lifecycle. You must call {@link
- android.nfc.NfcAdapter#enableForegroundNdefPush} from the main thread and only when the
- activity is in the foreground (calling in {@link android.app.Activity#onResume onResume()}
- guarantees this).
- <pre>
-public void onResume() {
- super.onResume();
- if (mAdapter != null)
- mAdapter.enableForegroundNdefPush(this, myNdefMessage);
-}
-public void onPause() {
- super.onPause();
- if (mAdapter != null)
- mAdapter.disableForegroundNdefPush(this);
-}
-</pre>
- </li>
- </ol>
-
- <p>When the Activity is in the foreground, you can now tap the device to another device and push
- the data to it. See the <a href=
- "../../../resources/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundNdefPush.html">ForegroundNdefPush</a>
- sample in API Demos for a simple example of peer-to-peer data exchange.</p>
\ No newline at end of file
+ <dt><strong><a href="{@docRoot}guide/topics/nfc/advanced-nfc.html">Advanced
+ NFC</a></strong></dt>
+ <dd>This document goes over the APIs that enable use of the various tag technologies that
+ Android supports. When you are not working with NDEF data, or when you are working with NDEF
+ data that Android cannot fully understand, you have to manually read or write to the tag in raw
+ bytes using your own protocol stack. In these cases, Android provides support to detect
+ certain tag technologies and to open communication with the tag using your own protocol
+ stack.</dd>
+ </dl>
+</p>
\ No newline at end of file
diff --git a/docs/html/guide/topics/nfc/nfc.jd b/docs/html/guide/topics/nfc/nfc.jd
new file mode 100644
index 0000000..175bc7cc
--- /dev/null
+++ b/docs/html/guide/topics/nfc/nfc.jd
@@ -0,0 +1,923 @@
+page.title=NFC Basics
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#tag-dispatch">The Tag Dispatch System</a>
+ <ol>
+ <li><a href="#ndef">How NFC tags are mapped to MIME types and URIs</a></li>
+ <li><a href="#dispatching">How NFC Tags are Dispatched to Applications</a></li>
+ </ol>
+ </li>
+ <li><a href="#manifest">Requesting NFC Access in the Android Manifest</a></li>
+ <li><a href="#filtering-intents">Filtering for Intents</a>
+ <ol>
+ <li><a href="#ndef-disc">ACTION_NDEF_DISCOVERED</a></li>
+ <li><a href="#tech-disc">ACTION_TECH_DISCOVERED</a></li>
+ <li><a href="#tag-disc">ACTION_TAG_DISCOVERED</a></li>
+ <li><a href="#obtain-info">Obtaining information from intents</a></li>
+ </ol>
+ </li>
+ <li><a href="#creating-records">Creating Common Types of NDEF Records</a>
+ <ol>
+ <li><a href="#abs-uri">TNF_ABSOLUTE_URI</a></li>
+ <li><a href="#mime">TNF_MIME_MEDIA</a></li>
+ <li><a href="#well-known-text">TNF_WELL_KNOWN with RTD_TEXT</a></li>
+ <li><a href="#well-known-uri">TNF_WELL_KNOWN with RTD_URI</a></li>
+ <li><a href="#ext-type">TNF_EXTERNAL_TYPE</a></li>
+ <li><a href="#aar">Android Application Records</a></li>
+ </ol>
+ </li>
+ <li><a href="#p2p">Beaming NDEF Messages to Other Devices</a></li>
+ </ol>
+</div>
+</div>
+
+<p>This document describes the basic NFC tasks you perform in Android. It explains how to send and
+receive NFC data in the form of NDEF messages and describes the Android framework APIs that support
+these features. For more advanced topics, including a discussion of working with non-NDEF data,
+see <a href="{@docRoot}guide/topics/nfc/advanced-nfc.html">Advanced NFC</a>.</p>
+
+
+<p>There are two major uses cases when working with NDEF data and Android:</p>
+
+<ul>
+ <li>Reading NDEF data from an NFC tag</li>
+ <li>Beaming NDEF messages from one device to another with <a href="#p2p">Android
+Beam™</a></li>
+</ul>
+
+
+<p>Reading NDEF data from an NFC tag is handled with the <a href="#tag-dispatch">tag dispatch
+system</a>, which analyzes discovered NFC tags, appropriately categorizes the data, and starts
+an application that is interested in the categorized data. An application that wants to handle the
+scanned NFC tag can <a href="#filtering-intents">declare an intent filter</a> and
+request to handle the data.</p>
+
+<p>The Android Beam™ feature allows a device to push an NDEF message onto
+another device by physically tapping the devices together. This interaction provides an easier way
+to send data than other wireless technologies like Bluetooth, because with NFC, no manual device
+discovery or pairing is required. The connection is automatically started when two devices come
+into range. Android Beam is available through a set of NFC APIs, so any application can transmit
+information between devices. For example, the Contacts, Browser, and YouTube applications use
+Android Beam to share contacts, web pages, and videos with other devices.
+</p>
+
+
+<h2 id="tag-dispatch">The Tag Dispatch System</h2>
+
+<p>Android-powered devices are usually looking for NFC tags when the screen
+is unlocked, unless NFC is disabled in the device's Settings menu.
+When an Android-powered device discovers an NFC tag, the desired behavior
+is to have the most appropriate activity handle the intent without asking the user what application
+to use. Because devices scan NFC tags at a very short range, it is likely that making users manually
+select an activity would force them to move the device away from the tag and break the connection.
+You should develop your activity to only handle the NFC tags that your activity cares about to
+prevent the Activity Chooser from appearing.</p>
+
+<p>To help you with this goal, Android provides a special tag dispatch system that analyzes scanned
+NFC tags, parses them, and tries to locate applications that are interested in the scanned data. It
+does this by:</p>
+
+<ol>
+ <li>Parsing the NFC tag and figuring out the MIME type or a URI that identifies the data payload
+ in the tag.</li>
+ <li>Encapsulating the MIME type or URI and the payload into an intent. These first two
+ steps are described in <a href="#ndef">How NFC tags are mapped to MIME types and URIs</a>.</li>
+ <li>Starts an activity based on the intent. This is described in
+ <a href="#dispatching">How NFC Tags are Dispatched to Applications</a>.</li>
+</ol>
+
+<h3 id="ndef">How NFC tags are mapped to MIME types and URIs</h3>
+<p>Before you begin writing your NFC applications, it is important to understand the different
+types of NFC tags, how the tag dispatch system parses NFC tags, and the special work that the tag
+dispatch system does when it detects an NDEF message. NFC tags come in a
+wide array of technologies and can also have data written to them in many different ways.
+Android has the most support for the NDEF standard, which is defined by the <a
+href="http://www.nfc-forum.org/home">NFC Forum</a>.
+</p>
+
+<p>NDEF data is encapsulated inside a message ({@link android.nfc.NdefMessage}) that contains one
+or more records ({@link android.nfc.NdefRecord}). Each NDEF record must be well-formed according to
+the specification of the type of record that you want to create. Android
+also supports other types of tags that do not contain NDEF data, which you can work with by using
+the classes in the {@link android.nfc.tech} package. To learn more
+about these technologies, see the <a href="{@docRoot}guide/topics/nfc/advanced-nfc.html">Advanced
+NFC</a> topic. Working with these other types of tags involves
+writing your own protocol stack to communicate with the tags, so we recommend using NDEF when
+possible for ease of development and maximum support for Android-powered devices.
+</p>
+
+<p class="note"><strong>Note:</strong>
+To download complete NDEF specifications, go to the <a
+href="http://www.nfc-forum.org/specs/spec_license">NFC Forum Specification Download</a> site and see
+<a href="#creating-records">Creating common types of NDEF records</a> for examples of how to
+construct NDEF records. </p>
+
+<p>Now that you have some background in NFC tags, the following sections describe in more detail how
+Android handles NDEF formatted tags. When an Android-powered device scans an NFC tag containing NDEF
+formatted data, it parses the message and tries to figure out the data's MIME type or identifying
+URI. To do this, the system reads the first {@link android.nfc.NdefRecord} inside the {@link
+android.nfc.NdefMessage} to determine how to interpret the entire NDEF message (an NDEF message can
+have multiple NDEF records). In a well-formed NDEF message, the first {@link android.nfc.NdefRecord}
+contains the following fields:
+<dl>
+ <dt><strong>3-bit TNF (Type Name Format)</strong></dt>
+ <dd>Indicates how to interpret the variable length type field. Valid values are described in
+described in <a href="#table1">Table 1</a>.</dd>
+
+ <dt><strong>Variable length type</strong></dt>
+ <dd>Describes the type of the record. If using {@link android.nfc.NdefRecord#TNF_WELL_KNOWN}, use
+this field to specify the Record Type Definition (RTD). Valid RTD values are described in <a
+href="#table2">Table 2</a>.</dd>
+
+<dt><strong>Variable length ID</strong></dt>
+<dd>A unique identifier for the record. This field is not used often, but
+if you need to uniquely identify a tag, you can create an ID for it.</dd>
+
+<dt><strong>Variable length payload</strong></dt>
+<dd>The actual data payload that you want to read or write. An NDEF
+message can contain multiple NDEF records, so don't assume the full payload is in the first NDEF
+record of the NDEF message.</dd>
+
+</dl>
+
+<p>The tag dispatch system uses the TNF and type fields to try to map a MIME type or URI to the
+NDEF message. If successful, it encapsulates that information inside of a {@link
+android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent along with the actual payload. However, there
+are cases when the tag dispatch system cannot determine the type of data based on the first NDEF
+record. This happens when the NDEF data cannot be mapped to a MIME type or URI, or when the
+NFC tag does not contain NDEF data to begin with. In such cases, a {@link
+android.nfc.Tag} object that has information about the tag's technologies and the payload are
+encapsulated inside of a {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent instead.</p>
+
+<p>
+<a href="#table1">Table 1.</a> describes how the tag dispatch system maps TNF and type
+fields to MIME types or URIs. It also describes which TNFs cannot be mapped to a MIME type or URI.
+In these cases, the tag dispatch system falls back to
+{@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}.
+
+<p>For example, if the tag dispatch system encounters a record of type {@link
+android.nfc.NdefRecord#TNF_ABSOLUTE_URI}, it maps the variable length type field of that record
+into a URI. The tag dispatch system encapsulates that URI in the data field of an {@link
+android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent along with other information about the tag,
+such as the payload. On the other hand, if it encounters a record of type {@link
+android.nfc.NdefRecord#TNF_UNKNOWN}, it creates an intent that encapsulates the tag's technologies
+instead.</p>
+
+
+<p class="table-caption" id="table1">
+ <strong>Table 1.</strong> Supported TNFs and their mappings</p>
+<table id="mappings">
+ <tr>
+ <th>Type Name Format (TNF)</th>
+ <th>Mapping</th>
+ </tr>
+ <tr>
+ <td>{@link android.nfc.NdefRecord#TNF_ABSOLUTE_URI}</td>
+ <td>URI based on the type field.</td>
+ </tr>
+ <td>{@link android.nfc.NdefRecord#TNF_EMPTY}</td>
+ <td>Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}.</td>
+ </tr>
+ <td>{@link android.nfc.NdefRecord#TNF_EXTERNAL_TYPE}</td>
+ <td>URI based on the URN in the type field. The URN is encoded into the NDEF type field in
+ a shortened form: <code><em><domain_name>:<service_name></em></code>.
+ Android maps this to a URI in the form:
+ <code>vnd.android.nfc://ext/<em><domain_name>:<service_name></em></code>.</td>
+ </tr>
+ <td>{@link android.nfc.NdefRecord#TNF_MIME_MEDIA}</td>
+ <td>MIME type based on the type field.</td>
+ </tr>
+ <td>{@link android.nfc.NdefRecord#TNF_UNCHANGED}</td>
+ <td>Invalid in the first record, so falls back to
+ {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}.</td>
+ </tr>
+ <td>{@link android.nfc.NdefRecord#TNF_UNKNOWN}</td>
+ <td>Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}.</td>
+ </tr>
+ <td>{@link android.nfc.NdefRecord#TNF_WELL_KNOWN}</td>
+ <td>MIME type or URI depending on the Record Type Definition (RTD), which you set in the
+type field. See <a href="#well_known">Table 2.</a> for more information on
+available RTDs and their mappings.</td>
+ </tr>
+</table>
+
+<p class="table-caption" id="table2">
+ <strong>Table 2.</strong> Supported RTDs for TNF_WELL_KNOWN and their
+mappings</p>
+<table id="well-known">
+ <tr>
+ <th>Record Type Definition (RTD)</th>
+ <th>Mapping</th>
+ </tr>
+ <tr>
+ <td>{@link android.nfc.NdefRecord#RTD_ALTERNATIVE_CARRIER}</td>
+ <td>Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}.</td>
+ </tr>
+ <td>{@link android.nfc.NdefRecord#RTD_HANDOVER_CARRIER}</td>
+ <td>Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}.</td>
+ </tr>
+ <td>{@link android.nfc.NdefRecord#RTD_HANDOVER_REQUEST}</td>
+ <td>Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}.</td>
+ </tr>
+ <td>{@link android.nfc.NdefRecord#RTD_HANDOVER_SELECT}</td>
+ <td>Falls back to {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}.</td>
+ </tr>
+ <td>{@link android.nfc.NdefRecord#RTD_SMART_POSTER}</td>
+ <td>URI based on parsing the payload.</td>
+ </tr>
+ <td>{@link android.nfc.NdefRecord#RTD_TEXT}</td>
+ <td>MIME type of <code>text/plain</code>.</td>
+ </tr>
+ <td>{@link android.nfc.NdefRecord#RTD_URI}</td>
+ <td>URI based on payload.</td>
+ </tr>
+</table>
+
+<h3 id="dispatching">How NFC Tags are Dispatched to Applications</h3>
+
+<p>When the tag dispatch system is done creating an intent that encapsulates the NFC tag and its
+identifying information, it sends the intent to an interested application that
+filters for the intent. If more than one application can handle the intent, the Activity Chooser
+is presented so the user can select the Activity. The tag dispatch system defines three intents,
+which are listed in order of highest to lowest priority:</p>
+
+<ol>
+ <li>
+ {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED}: This intent is used to start an
+Activity when a tag that contains an NDEF payload is scanned and is of a recognized type. This is
+the highest priority intent, and the tag dispatch system tries to start an Activity with this
+intent before any other intent, whenever possible.
+ </li>
+
+ <li>{@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}: If no activities register to
+handle the {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED}
+intent, the tag dispatch system tries to start an application with this intent. This
+intent is also directly started (without starting {@link
+android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} first) if the tag that is scanned
+contains NDEF data that cannot be mapped to a MIME type or URI, or if the tag does not contain NDEF
+data but is of a known tag technology.
+</li>
+
+ <li>{@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED}: This intent is started
+ if no activities handle the {@link
+android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or {@link
+android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}
+ intents.</li>
+ </ol>
+
+<p>The basic way the tag dispatch system works is as follows:</p>
+
+<ol>
+ <li>Try to start an Activity with the intent that was created by the tag dispatch system
+when parsing the NFC tag (either
+{@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or {@link
+android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}).</li>
+ <li>If no activities filter for that intent, try to start an Activity with the next
+ lowest priority intent (either {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} or {@link
+android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED}) until an application filters for the
+ intent or until the tag dispatch system tries all possible intents.</li>
+ <li>If no applications filter for any of the intents, do nothing.</li>
+</ol>
+
+<img src="{@docRoot}images/nfc_tag_dispatch.png" />
+
+<p class="figure"><strong>Figure 1. </strong> Tag Dispatch System</p>
+
+
+<p>Whenever possible, work with NDEF messages and the {@link
+android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent, because it is the most specific out of
+the three. This intent allows you to start your application at a more appropriate time than the
+other two intents, giving the user a better experience.</p>
+
+<h2 id="manifest">Requesting NFC Access in the Android Manifest</h2>
+
+ <p>Before you can access a device's NFC hardware and properly handle NFC intents, declare these
+ items in your <code>AndroidManifest.xml</code> file:</p>
+
+ <ul>
+ <li>The NFC <code><uses-permission></code> element to access the NFC hardware:
+ <pre>
+<uses-permission android:name="android.permission.NFC" />
+</pre>
+ </li>
+
+ <li>The minimum SDK version that your application can support. API level 9 only supports
+ limited tag dispatch via {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED}, and only gives
+ access to NDEF messages via the {@link android.nfc.NfcAdapter#EXTRA_NDEF_MESSAGES} extra. No
+ other tag properties or I/O operations are accessible. API level 10
+ includes comprehensive reader/writer support as well as foreground NDEF pushing, and API level
+ 14 provides an easier way to push NDEF messages to other devices with Android Beam and extra
+ convenience methods to create NDEF records.
+<pre class="pretty-print">
+<uses-sdk android:minSdkVersion="10"/>
+</pre>
+ </li>
+
+ <li>The <code>uses-feature</code> element so that your application shows up in the Android
+Market only for devices that have NFC hardware:
+ <pre>
+<uses-feature android:name="android.hardware.nfc" android:required="true" />
+</pre>
+<p>If your application uses NFC functionality, but that functionality is not crucial to your
+application, you can omit the <code>uses-feature</code> element and check for NFC avalailbility at
+runtime by checking to see if {@link android.nfc.NfcAdapter#getDefaultAdapter getDefaultAdapter()}
+is <code>null</code>.</p>
+ </li>
+ </ul>
+
+ <h2 id="filtering-intents">Filtering for NFC Intents</h2>
+
+ <p>To start your application when an NFC tag that you want to handle is scanned, your application
+can filter for one, two, or all three of the NFC intents in the Android manifest. However, you
+usually want to filter for the {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intent for the
+most control of when your application starts. The {@link
+android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent is a fallback for {@link
+android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} when no applications filter for
+ {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or for when the payload is not
+NDEF. Filtering for {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED} is usually too general of a
+category to filter on. Many applications will filter for {@link
+android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or {@link
+android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} before {@link
+android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED}, so your application has a low probability of
+starting. {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED} is only available as a last resort
+for applications to filter for in the cases where no other applications are installed to handle the
+{@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} or {@link
+android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED}intent.</p>
+
+<p>Because NFC tag deployments vary and are many times not under your control, this is not always
+possible, which is why you can fallback to the other two intents when necessary. When you have
+control over the types of tags and data written, it is recommended that you use NDEF to format your
+tags. The following sections describe how to filter for each type of intent.</p>
+
+
+<h3 id="ndef-disc">ACTION_NDEF_DISCOVERED</h3>
+<p>
+To filter for {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} intents, declare the
+intent filter along with the type of data that you want to filter for. The
+following example filters for {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED}
+intents with a MIME type of <code>text/plain</code>:
+</p>
+<pre>
+<intent-filter>
+ <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:mimeType="text/plain" />
+</intent-filter>
+</pre>
+<p>The following example filters for a URI in the form of
+<code>http://developer.android.com/index.html</code>.
+<pre>
+<intent-filter>
+ <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="http"
+ android:host="developer.android.com"
+ android:pathPrefix="/index.html" />
+</intent-filter>
+</pre>
+
+
+ <h3 id="tech-disc">ACTION_TECH_DISCOVERED</h3>
+
+ <p>If your activity filters for the {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent,
+you must create an XML resource file that specifies the technologies that your activity supports
+within a <code>tech-list</code> set. Your activity is
+ considered a match if a <code>tech-list</code> set is a subset of the technologies that are
+ supported by the tag, which you can obtain by calling {@link android.nfc.Tag#getTechList
+ getTechList()}.</p>
+
+ <p>For example, if the tag that is scanned supports MifareClassic, NdefFormatable, and NfcA, your
+ <code>tech-list</code> set must specify all three, two, or one of the technologies (and nothing
+ else) in order for your activity to be matched.</p>
+
+ <p>The following sample defines all of the technologies. You can remove the ones that you do not
+ need. Save this file (you can name it anything you wish) in the
+ <code><project-root>/res/xml</code> folder.</p>
+ <pre>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <tech-list>
+ <tech>android.nfc.tech.IsoDep</tech>
+ <tech>android.nfc.tech.NfcA</tech>
+ <tech>android.nfc.tech.NfcB</tech>
+ <tech>android.nfc.tech.NfcF</tech>
+ <tech>android.nfc.tech.NfcV</tech>
+ <tech>android.nfc.tech.Ndef</tech>
+ <tech>android.nfc.tech.NdefFormatable</tech>
+ <tech>android.nfc.tech.MifareClassic</tech>
+ <tech>android.nfc.tech.MifareUltralight</tech>
+ </tech-list>
+</resources>
+</pre>
+
+ <p>You can also specify multiple <code>tech-list</code> sets. Each of the <code>tech-list</code>
+ sets is considered independently, and your activity is considered a match if any single
+ <code>tech-list</code> set is a subset of the technologies that are returned by {@link
+ android.nfc.Tag#getTechList getTechList()}. This provides <code>AND</code> and <code>OR</code>
+ semantics for matching technologies. The following example matches tags that can support the
+ NfcA and Ndef technologies or can support the NfcB and Ndef technologies:</p>
+ <pre>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <tech-list>
+ <tech>android.nfc.tech.NfcA</tech>
+ <tech>android.nfc.tech.Ndef</tech>
+ </tech-list>
+</resources>
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <tech-list>
+ <tech>android.nfc.tech.NfcB</tech>
+ <tech>android.nfc.tech.Ndef</tech>
+ </tech-list>
+</resources>
+</pre>
+
+ <p>In your <code>AndroidManifest.xml</code> file, specify the resource file that you just created
+ in the <code><meta-data></code> element inside the <code><activity></code>
+ element like in the following example:</p>
+ <pre>
+<activity>
+...
+<intent-filter>
+ <action android:name="android.nfc.action.TECH_DISCOVERED"/>
+</intent-filter>
+
+<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
+ android:resource="@xml/nfc_tech_filter" />
+...
+</activity>
+</pre>
+
+<p>For more information about working with tag technologies and the {@link
+android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} intent, see <a
+href="{@docRoot}guide/topics/nfc/advanced-nfc.html#tag-tech">Working with Supported Tag
+Technologies</a> in the Advanced NFC document.</p>
+<h3 id="tag-disc">ACTION_TAG_DISCOVERED</h3>
+<p>To filter for {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED} use the following intent
+filter:</p>
+
+
+<pre><intent-filter>
+ <action android:name="android.nfc.action.TAG_DISCOVERED"/>
+</intent-filter>
+</pre>
+
+
+
+<h3 id="obtain-info">Obtaining information from intents</h3>
+
+<p>If an activity starts because of an NFC intent, you can obtain information about the scanned NFC
+tag from the intent. Intents can contain the following extras depending on the tag that was scanned:
+
+<ul>
+ <li>{@link android.nfc.NfcAdapter#EXTRA_TAG} (required): A {@link android.nfc.Tag} object
+representing the scanned tag.</li>
+ <li>{@link android.nfc.NfcAdapter#EXTRA_NDEF_MESSAGES} (optional): An array of NDEF messages
+parsed from the tag. This extra is mandatory on {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED
+intents.</li>
+ <li>{@link android.nfc.NfcAdapter#EXTRA_ID} (optional): The low-level ID of the tag.</li></ul>
+
+<p>To obtain these extras, check to see if your activity was launched with one of
+the NFC intents to ensure that a tag was scanned, and then obtain the extras out of the
+intent. The following example checks for the {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED}
+intent and gets the NDEF messages from an intent extra.</p>
+
+<pre>
+public void onResume() {
+ super.onResume();
+ ...
+ if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
+ Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
+ if (rawMsgs != null) {
+ msgs = new NdefMessage[rawMsgs.length];
+ for (int i = 0; i < rawMsgs.length; i++) {
+ msgs[i] = (NdefMessage) rawMsgs[i];
+ }
+ }
+ }
+ //process the msgs array
+}
+</pre>
+
+<p>Alternatively, you can obtain a {@link android.nfc.Tag} object from the intent, which will
+contain the payload and allow you to enumerate the tag's technologies:</p>
+
+<pre>Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);</pre>
+
+
+<h2 id="creating-records">Creating Common Types of NDEF Records</h2>
+<p>This section describes how to create common types of NDEF records to help you when writing to
+NFC tags or sending data with Android Beam. It also describes how to create the corresponding
+intent filter for the record. All of these NDEF record examples should be in the first NDEF
+record of the NDEF message that you are writing to a tag or beaming.</p>
+
+<h3 id="abs-uri">TNF_ABSOLUTE_URI</h3>
+<p>Given the following {@link android.nfc.NdefRecord#TNF_ABSOLUTE_URI} NDEF record, which is
+stored as the first record inside of an {@link android.nfc.NdefMessage}:</p>
+
+<pre>
+NdefRecord uriRecord = new NdefRecord(
+ NdefRecord.TNF_ABSOLUTE_URI ,
+ "http://developer.android.com/index.html".getBytes(Charset.forName("US-ASCII")),
+ new byte[0], new byte[0]);
+</pre>
+
+<p>the intent filter would look like this:</p>
+<pre>
+<intent-filter>
+ <action android:name="android.nfc.action.NDEF_DISCOVERED" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="http"
+ android:host="developer.android.com"
+ android:pathPrefix="/index.html" />
+</intent-filter>
+</pre>
+
+
+<h3 id="mime">TNF_MIME_MEDIA</h3>
+<p>Given the following {@link android.nfc.NdefRecord#TNF_MIME_MEDIA} NDEF record, which is stored as
+the first record inside
+of an {@link android.nfc.NdefMessage}:</p>
+<pre>
+NdefRecord mimeRecord = new NdefRecord(
+ NdefRecord.TNF_MIME_MEDIA ,
+ "application/com.example.android.beam".getBytes(Charset.forName("US-ASCII")),
+ new byte[0], "Beam me up, Android!".getBytes(Charset.forName("US-ASCII")));
+</pre>
+
+<p>the intent filter would look like this:</p>
+<pre>
+<intent-filter>
+ <action android:name="android.nfc.action.NDEF_DISCOVERED" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="application/com.example.android.beam" />
+</intent-filter>
+</pre>
+
+
+<h3 id="well-known-text">TNF_WELL_KNOWN with RTD_TEXT</h3>
+
+<p>Given the following {@link android.nfc.NdefRecord#TNF_WELL_KNOWN} NDEF record, which is stored as
+the first record inside of an {@link android.nfc.NdefMessage}:</p>
+<pre>
+public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) {
+ byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
+ Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
+ byte[] textBytes = payload.getBytes(utfEncoding);
+ int utfBit = encodeInUtf8 ? 0 : (1 << 7);
+ char status = (char) (utfBit + langBytes.length);
+ byte[] data = new byte[1 + langBytes.length + textBytes.length];
+ data[0] = (byte) status;
+ System.arraycopy(langBytes, 0, data, 1, langBytes.length);
+ System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);
+ NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
+ NdefRecord.RTD_TEXT, new byte[0], data);
+ return record;
+}
+</pre>
+
+<p>the intent filter would look like this:</p>
+<pre>
+<intent-filter>
+ <action android:name="android.nfc.action.NDEF_DISCOVERED" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="text/plain" />
+</intent-filter>
+</pre>
+
+
+<h3 id="well-known-uri">TNF_WELL_KNOWN with RTD_URI</h3>
+
+<p>Given the following {@link android.nfc.NdefRecord#TNF_WELL_KNOWN} NDEF record, which is stored as
+the first record inside of an {@link android.nfc.NdefMessage}:</p>
+
+<pre>
+byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII"));
+byte[] payload = new byte[uriField.length + 1]; //add 1 for the URI Prefix
+byte payload[0] = 0x01; //prefixes http://www. to the URI
+System.arraycopy(uriField, 0, payload, 1, uriField.length); //appends URI to payload
+NdefRecord rtdUriRecord = new NdefRecord(
+ NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload);
+</pre>
+
+<p>the intent filter would look like this:</p>
+
+<pre>
+<intent-filter>
+ <action android:name="android.nfc.action.NDEF_DISCOVERED" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="http"
+ android:host="example.com"
+ android:pathPrefix="" />
+</intent-filter>
+</pre>
+
+<h3 id="ext-type">TNF_EXTERNAL_TYPE</h3>
+<p>Given the following {@link android.nfc.NdefRecord#TNF_EXTERNAL_TYPE} NDEF record, which is stored
+as the first record inside of an {@link android.nfc.NdefMessage}:</p>
+
+<pre>
+byte[] payload;
+...
+NdefRecord mimeRecord = new NdefRecord(
+ NdefRecord.TNF_EXTERNAL_TYPE, "example.com:externalType", new byte[0], payload);
+</pre>
+
+<p>the intent filter would look like this:</p>
+<pre>
+<intent-filter>
+ <action android:name="android.nfc.action.NDEF_DISCOVERED" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="vnd.android.nfc"
+ android:host="ext"
+ android:pathPrefix="/example.com:externalType"/>
+</intent-filter>
+</pre>
+
+
+<p>Use TNF_EXTERNAL_TYPE for more generic NFC tag deployments to better support both
+Android-powered and non-Android-powered devices.</p>
+
+<p class="note"><strong>Note</strong>: URNs for {@link
+android.nfc.NdefRecord#TNF_EXTERNAL_TYPE} have a canonical format of:
+<code>urn:nfc:ext:example.com:externalType</code>, however the NFC Forum RTD specification
+declares that the <code>urn:nfc:ext:</code> portion of the URN must be ommitted from the
+NDEF record. So all you need to provide is the domain (<code>example.com</code> in the example)
+and type (<code>externalType</code> in the example) separated by a colon.
+When dispatching TNF_EXTERNAL_TYPE, Android converts the <code>urn:nfc:ext:example.com:externalType</code> URN to a
+<code>vnd.android.nfc://ext/example.com:externalType</code> URI, which is what the intent filter in the example
+declares.</p>
+
+<h3 id="aar">Android Application Records</h3>
+
+<p>
+Introduced in Android 4.0 (API level 14), an Android Application Record (AAR) provides a stronger
+certainty that your application is started when an NFC tag is scanned. An AAR has the package name
+of an application embedded inside an NDEF record. You can add an AAR to any NDEF record of your NDEF message,
+because Android searches the entire NDEF message for AARs. If it finds an AAR, it starts the application based
+on the package name inside the AAR. If the application is not present on the device,
+Android Market is launched to download the application.</p>
+
+<p>AARs are useful if you want to prevent other applications from filtering for the same intent and
+potentially handling specific tags that you have deployed. AARs are only supported at the
+application level, because of the package name constraint, and not at the Activity level as with
+intent filtering. If you want to handle an intent at the Activity level, <a
+href="filtering-intents">use intent filters</a>.
+</p>
+
+
+
+<p>If a tag contains an AAR, the tag dispatch system dispatches in the following manner:</p>
+<ol>
+ <li>Try to start an Activity using an intent filter as normal. If the Activity that matches
+the intent also matches the AAR, start the Activity.</li>
+ <li>If the Activity that filters for the intent does not match the
+AAR, if multiple Activities can handle the intent, or if no Activity handles the intent, start the
+application specified by the AAR.</li>
+ <li>If no application can start with the AAR, go to the Android Market to download the
+application based on the AAR.</li>
+</ol>
+
+</p>
+
+<p class="note"><strong>Note:</strong> You can override AARs and the intent dispatch system with the <a
+href="{@docRoot}guide/topics/nfc/advanced-nfc.html#foreground-dispatch">foreground dispatch
+system</a>, which allows a foreground activity to have priority when an NFC tag is discovered.
+With this method, the activity must be in the foreground to
+override AARs and the intent dispatch system.</p>
+
+<p>If you still want to filter for scanned tags that do not contain an AAR, you can declare
+intent filters as normal. This is useful if your application is interested in other tags
+that do not contain an AAR. For example, maybe you want to guarantee that your application handles
+proprietary tags that you deploy as well as general tags deployed by third parties. Keep in mind
+that AARs are specific to Android 4.0 devices or later, so when deploying tags, you most likely want
+to use a combination of AARs and MIME types/URIs to support the widest range of devices. In
+addition, when you deploy NFC tags, think about how you want to write your NFC tags to enable
+support for the most devices (Android-powered and other devices). You can do this by
+defining a relatively unique MIME type or URI to make it easier for applications to distinguish.
+</p>
+
+<p>Android provides a simple API to create an AAR,
+{@link android.nfc.NdefRecord#createApplicationRecord createApplicationRecord()}. All you need to
+do is embed the AAR anywhere in your {@link android.nfc.NdefMessage}. You do not want
+to use the first record of your {@link android.nfc.NdefMessage}, unless the AAR is the only
+record in the {@link android.nfc.NdefMessage}. This is because the Android
+system checks the first record of an {@link android.nfc.NdefMessage} to determine the MIME type or
+URI of the tag, which is used to create an intent for applications to filter. The following code
+shows you how to create an AAR:</p>
+
+<pre>
+NdefMessage msg = new NdefMessage(
+ new NdefRecord[] {
+ ...,
+ NdefRecord.createApplicationRecord("com.example.android.beam")}
+</pre>
+
+
+<h2 id="p2p">Beaming NDEF Messages to Other Devices</h2>
+
+<p>Android Beam allows simple peer-to-peer data exchange between two Android-powered devices. The
+application that wants to beam data to another device must be in the foreground and the device
+receiving the data must not be locked. When the beaming device comes in close enough contact with a
+receiving device, the beaming device displays the "Touch to Beam" UI. The user can then choose
+whether or not to beam the message to the receiving device.</p>
+
+<p class="note"><strong>Note:</strong> Foreground NDEF pushing was available at API level 10,
+which provides similar functionality to Android Beam. These APIs have since been deprecated, but
+are available to support older devices. See {@link android.nfc.NfcAdapter#enableForegroundNdefPush
+enableForegroundNdefPush()} for more information.</p>
+
+<p>You can enable Android Beam for your application by calling one of the two methods:</p>
+ <ul>
+ <li>{@link android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()}: Accepts an
+{@link android.nfc.NdefMessage} to set as the message to beam. Automatically beams the message
+when two devices are in close enough proximity.</li>
+ <li>{@link android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()}:
+Accepts a callback that contains a
+{@link android.nfc.NfcAdapter.CreateNdefMessageCallback#createNdefMessage createNdefMessage()}
+which is called when a device is in range to beam data to. The callback lets you create
+the NDEF message only when necessary.</li>
+ </ul>
+
+<p>An activity can only push one NDEF message at a time, so {@link
+android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()} takes precedence
+over {@link android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()} if both are set. To use
+Android Beam, the following general guidelines must be met:
+</p>
+
+ <ul>
+ <li>The activity that is beaming the data must be in the foreground. Both devices must have
+their screens unlocked.</li>
+
+ <li>You must encapsulate the data that you are beaming in an {@link android.nfc.NdefMessage}
+ object.</li>
+
+ <li>The NFC device that is receiving the beamed data must support the
+ <code>com.android.npp</code> NDEF push protocol or NFC Forum's SNEP (Simple NDEF Exchange
+Protocol). The <code>com.android.npp</code> protocol is required for devices on API level 9 (Android
+2.3) to API level 13 (Android 3.2). <code>com.android.npp</code> and SNEP are both required on
+API level 14 (Android 4.0) and later.</li>
+</li>
+ </ul>
+
+ <p class="note"><strong>Note:</strong> If your activity enables Android Beam and is
+in the foreground, the standard intent dispatch system is disabled. However, if your activity also
+enables <a href="{@docRoot}guide/topics/nfc/advanced-nfc.html#foreground-dispatch">foreground
+dispatching</a>, then it can still scan tags that match the intent filters set in the foreground
+dispatching.</p>
+
+ <p>To enable Android Beam:</p>
+
+ <ol>
+ <li>Create an {@link android.nfc.NdefMessage} that contains the {@link android.nfc.NdefRecord}s
+that you want to push onto the other device.</li>
+
+ <li>Call {@link
+android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()} with a {@link
+android.nfc.NdefMessage} or call {@link
+android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback} passing in a {@link
+android.nfc.NfcAdapter.CreateNdefMessageCallback} object in the <code>onCreate()</code> method of
+your activity. These methods require at least one activity that you want to enable with Android
+Beam, along with an optional list of other activities to activate.
+
+<p>In general, you normally use {@link
+android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()} if your Activity only needs to
+push the same NDEF message at all times, when two devices are in range to communicate. You use
+{@link android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback} when your
+application cares about the current context of the application and wants to push an NDEF message
+depending on what the user is doing in your application.</p>
+ </li>
+ </ol>
+
+<p>The following sample shows how a simple activity calls {@link
+android.nfc.NfcAdapter.CreateNdefMessageCallback} in the <code>onCreate()</code> method of an
+activity (see <a href="{@docRoot}resources/samples/AndroidBeam/index.html"></a> for the
+complete sample). This example also has methods to help you create a MIME record:</p>
+
+<pre id="code-example">
+package com.example.android.beam;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.nfc.NdefMessage;
+import android.nfc.NdefRecord;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcAdapter.CreateNdefMessageCallback;
+import android.nfc.NfcEvent;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.widget.TextView;
+import android.widget.Toast;
+import java.nio.charset.Charset;
+
+
+public class Beam extends Activity implements CreateNdefMessageCallback {
+ NfcAdapter mNfcAdapter;
+ TextView textView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ TextView textView = (TextView) findViewById(R.id.textView);
+ // Check for available NFC Adapter
+ mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
+ if (mNfcAdapter == null) {
+ Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
+ finish();
+ return;
+ }
+ // Register callback
+ mNfcAdapter.setNdefPushMessageCallback(this, this);
+ }
+
+ @Override
+ public NdefMessage createNdefMessage(NfcEvent event) {
+ String text = ("Beam me up, Android!\n\n" +
+ "Beam Time: " + System.currentTimeMillis());
+ NdefMessage msg = new NdefMessage(
+ new NdefRecord[] { createMimeRecord(
+ "application/com.example.android.beam", text.getBytes())
+ /**
+ * The Android Application Record (AAR) is commented out. When a device
+ * receives a push with an AAR in it, the application specified in the AAR
+ * is guaranteed to run. The AAR overrides the tag dispatch system.
+ * You can add it back in to guarantee that this
+ * activity starts when receiving a beamed message. For now, this code
+ * uses the tag dispatch system.
+ */
+ //,NdefRecord.createApplicationRecord("com.example.android.beam")
+ });
+ return msg;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ // Check to see that the Activity started due to an Android Beam
+ if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
+ processIntent(getIntent());
+ }
+ }
+
+ @Override
+ public void onNewIntent(Intent intent) {
+ // onResume gets called after this to handle the intent
+ setIntent(intent);
+ }
+
+ /**
+ * Parses the NDEF Message from the intent and prints to the TextView
+ */
+ void processIntent(Intent intent) {
+ textView = (TextView) findViewById(R.id.textView);
+ Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
+ NfcAdapter.EXTRA_NDEF_MESSAGES);
+ // only one message sent during the beam
+ NdefMessage msg = (NdefMessage) rawMsgs[0];
+ // record 0 contains the MIME type, record 1 is the AAR, if present
+ textView.setText(new String(msg.getRecords()[0].getPayload()));
+ }
+
+ /**
+ * Creates a custom MIME type encapsulated in an NDEF record
+ */
+ public NdefRecord createMimeRecord(String mimeType, byte[] payload) {
+ byte[] mimeBytes = mimeType.getBytes(Charset.forName("US-ASCII"));
+ NdefRecord mimeRecord = new NdefRecord(
+ NdefRecord.TNF_MIME_MEDIA, mimeBytes, new byte[0], payload);
+ return mimeRecord;
+ }
+}
+</pre>
+
+<p>Note that this code comments out an AAR, which you can remove. If you enable the AAR, the
+application specified in the AAR always receives the Android Beam message. If the application is not
+present, the Android Market is started to download the application. Therefore, the following intent
+filter is not technically necessary for Android 4.0 devices or later if the AAR is used:
+</p>
+
+<pre>
+<intent-filter>
+ <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:mimeType="application/com.example.android.beam"/>
+</intent-filter>
+</pre>
+<p>With this intent filter, the <code>com.example.android.beam</code> application now can be started
+when it scans an NFC tag or receives an Android Beam with an AAR of
+type <code>com.example.android.beam</code>, or when an NDEF formatted message contains a MIME record
+of type <code>application/com.example.android.beam</code>.</p>
+
+<p>Even though AARs guarantee an application is started or downloaded, intent filters are
+recommended, because they let you start an Activity of your choice in your
+application instead of always starting the main Activity within the package specified by an AAR.
+AARs do not have Activity level granularity. Also, because some Android-powered devices do not
+support AARs, you should also embed identifying information in the first NDEF record of your NDEF
+messages and filter for that as well, just in case. See <a href="#creating-records">Creating Common
+Types of NDEF records</a> for more information on how to create records.
+</p>
diff --git a/docs/html/guide/topics/renderscript/compute.jd b/docs/html/guide/topics/renderscript/compute.jd
index e4c2283..8f08f59 100644
--- a/docs/html/guide/topics/renderscript/compute.jd
+++ b/docs/html/guide/topics/renderscript/compute.jd
@@ -1,6 +1,6 @@
page.title=Compute
parent.title=RenderScript
-parent.link=index.html
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/topics/renderscript/graphics.jd b/docs/html/guide/topics/renderscript/graphics.jd
index d8be85f..2fefecc 100644
--- a/docs/html/guide/topics/renderscript/graphics.jd
+++ b/docs/html/guide/topics/renderscript/graphics.jd
@@ -9,10 +9,26 @@
<ol>
<li>
- <a href="#developing">Developing a RenderScript application</a>
-
+ <a href="#creating-graphics-rs">Creating a Graphics Renderscript</a>
<ol>
- <li><a href="#hello-graphics">The Hello Graphics application</a></li>
+ <li><a href="#creating-native">Creating the native Renderscript file</a></li>
+ <li><a href="#creating-entry">Creating the Renderscript entry point class</a></li>
+ <li><a href="#creating-view">Creating the surface view</a></li>
+ <li><a href="#creating-activity">Creating the activity</a></li>
+ </ol>
+ </li>
+ <li>
+ <a href="#drawing">Drawing</a>
+ <ol>
+ <li><a href="#drawing-rsg">Drawing using the rsgDraw functions</a></li>
+ <li><a href="#drawing-mesh">Drawing with a mesh</a></li>
+ </ol>
+ </li>
+ <li>
+ <a href="#shaders">Shaders</a>
+ <ol>
+ <li><a href="#shader-bindings">Shader bindings</a></li>
+ <li><a href="#shader-sampler">Defining a sampler</a></li>
</ol>
</li>
</ol>
@@ -22,13 +38,13 @@
<ol>
<li><a href="{@docRoot}resources/samples/RenderScript/Balls/index.html">Balls</a></li>
- <li><a href=
- "{@docRoot}resources/samples/Renderscript/Fountain/index.html">Fountain</a></li>
+ <li><a href="{@docRoot}resources/samples/RenderScript/Fountain/index.html">Fountain</a></li>
<li><a href="{@docRoot}resources/samples/RenderScript/HelloWorld/index.html">Hello
World</a></li>
- <li><a href="{@docRoot}resources/samples/RenderScript/Samples/index.html">Samples</a></li>
+ <li><a
+href="{@docRoot}resources/samples/RenderScript/MiscSamples/index.html">Misc Samples</a></li>
</ol>
</div>
</div>
@@ -40,7 +56,7 @@
will need to be familiar with APIs to appropriately render 3D graphics on an Android-powered
device.</p>
- <h2>Creating a Graphics RenderScript</h2>
+ <h2 id="creating-graphics-rs">Creating a Graphics RenderScript</h2>
<p>Because of the various layers of code when writing a RenderScript application, it is useful to
create the following files for a scene that you want to render:</p>
@@ -73,7 +89,7 @@
RenderScript sample that is provided in the SDK as a guide (some code has been modified from its
original form for simplicity).</p>
- <h3>Creating the native RenderScript file</h3>
+ <h3 id="creating-native">Creating the native RenderScript file</h3>
<p>Your native RenderScript code resides in a <code>.rs</code> file in the
<code><project_root>/src/</code> directory. You can also define <code>.rsh</code> header
@@ -102,8 +118,8 @@
enough or more resources to do so, and renders as fast as it can if it does not.</p>
<p>For more
- information on using the RenderScript graphics functions, see <a href=
- "using-graphics-api">Using the Graphics APIs</a>.</p>
+ information on using the RenderScript graphics functions, see the <a href=
+ "#drawing">Drawing</a> section.</p>
</li>
<li>An <code>init()</code> function. This allows you to do any initialization of your
@@ -153,7 +169,7 @@
}
</pre>
- <h3>Creating the RenderScript entry point class</h3>
+ <h3 id="creating-entry">Creating the RenderScript entry point class</h3>
<p>When you create a RenderScript (<code>.rs</code>) file, it is helpful to create a
corresponding Android framework class that is an entry point into the <code>.rs</code> file. In
@@ -218,7 +234,7 @@
</pre>
- <h3>Creating the surface view</h3>
+ <h3 id="creating-view">Creating the surface view</h3>
<p>To create a surface view to render graphics on, create a class that extends {@link
android.renderscript.RSSurfaceView}. This class also creates a RenderScript context object
@@ -293,7 +309,7 @@
</pre>
- <h3>Creating the Activity</h3>
+ <h3 id="creating-activity">Creating the Activity</h3>
<p>Applications that use RenderScript still adhere to activity lifecyle, and are part of the same
view hierarchy as traditional Android applications, which is handled by the Android VM. This
@@ -329,9 +345,9 @@
}
</pre>
- <h2>Drawing</h2>
-
- <h3>Drawing using the rsgDraw functions</h3>
+ <h2 id="drawing">Drawing</h2>
+ <p>The following sections describe how to use the graphics functions to draw with Renderscript.</p>
+ <h3 id="drawing-rsg">Drawing using the rsgDraw functions</h3>
<p>The native RenderScript APIs provide a few convenient functions to easily draw a polygon to
the screen. You call these in your <code>root()</code> function to have them render to the
@@ -348,7 +364,7 @@
the screen.</li>
</ul>
- <h3>Drawing with a mesh</h3>
+ <h3 id="drawing-mesh">Drawing with a mesh</h3>
<p>When you want to draw complex shapes and textures to the screen, instantiate a {@link
android.renderscript.Mesh} and draw it to the screen with <code>rsgDrawMesh()</code>. A {@link
@@ -559,7 +575,7 @@
"{@docRoot}resources/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesRS.html">
RsRenderStatesRS</a> sample has many examples on how to create a shader without writing GLSL.</p>
- <h3>Shader bindings</h3>
+ <h3 id="shader-bindings">Shader bindings</h3>
<p>You can also set four pragmas that control the shaders' default bindings to the {@link
android.renderscript.RenderScriptGL} context when the script is executing:</p>
@@ -599,7 +615,7 @@
#pragma stateStore(parent)
</pre>
- <h3>Defining a sampler</h3>
+ <h3 id="shader-sampler">Defining a sampler</h3>
<p>A {@link android.renderscript.Sampler} object defines how data is extracted from textures.
Samplers are bound to Program objects (currently only a Fragment Program) alongside the texture
diff --git a/docs/html/guide/topics/resources/animation-resource.jd b/docs/html/guide/topics/resources/animation-resource.jd
index 480ca78..eaa698f 100644
--- a/docs/html/guide/topics/resources/animation-resource.jd
+++ b/docs/html/guide/topics/resources/animation-resource.jd
@@ -10,8 +10,8 @@
<li><a href="#Property">Property Animation</a></li>
<li><a href="#View">View Animation</a>
<ol>
- <li><a href="Tween">Tween animation</a></li>
- <li><a href="Frame">Frame animation</a></li>
+ <li><a href="#Tween">Tween animation</a></li>
+ <li><a href="#Frame">Frame animation</a></li>
</ol>
</li>
</ol>
diff --git a/docs/html/guide/topics/resources/runtime-changes.jd b/docs/html/guide/topics/resources/runtime-changes.jd
index 74a9073..871b063 100644
--- a/docs/html/guide/topics/resources/runtime-changes.jd
+++ b/docs/html/guide/topics/resources/runtime-changes.jd
@@ -25,80 +25,78 @@
<p>Some device configurations can change during runtime
(such as screen orientation, keyboard availability, and language). When such a change occurs,
Android restarts the running
-Activity ({@link android.app.Activity#onDestroy()} is called, followed by {@link
+{@link android.app.Activity} ({@link android.app.Activity#onDestroy()} is called, followed by {@link
android.app.Activity#onCreate(Bundle) onCreate()}). The restart behavior is designed to help your
application adapt to new configurations by automatically reloading your application with
-alternative resources.</p>
+alternative resources that match the new device configuration.</p>
-<p>To properly handle a restart, it is important that your Activity restores its previous
+<p>To properly handle a restart, it is important that your activity restores its previous
state through the normal <a
href="{@docRoot}guide/topics/fundamentals/activities.html#Lifecycle">Activity
lifecycle</a>, in which Android calls
{@link android.app.Activity#onSaveInstanceState(Bundle) onSaveInstanceState()} before it destroys
-your Activity so that you can save data about the application state. You can then restore the state
+your activity so that you can save data about the application state. You can then restore the state
during {@link android.app.Activity#onCreate(Bundle) onCreate()} or {@link
-android.app.Activity#onRestoreInstanceState(Bundle) onRestoreInstanceState()}. To test
-that your application restarts itself with the application state intact, you should
-invoke configuration changes (such as changing the screen orientation) while performing various
-tasks in your application.</p>
+android.app.Activity#onRestoreInstanceState(Bundle) onRestoreInstanceState()}.</p>
-<p>Your application should be able to restart at any time without loss of user data or
-state in order to handle events such as when the user receives an incoming phone call and then
-returns to your application (read about the
-<a href="{@docRoot}guide/topics/fundamentals/activities.html#Lifecycle">Activity lifecycle</a>).</p>
+<p>To test that your application restarts itself with the application state intact, you should
+invoke configuration changes (such as changing the screen orientation) while performing various
+tasks in your application. Your application should be able to restart at any time without loss of
+user data or state in order to handle events such as configuration changes or when the user receives
+an incoming phone call and then returns to your application much later after your application
+process may have been destroyed. To learn how you can restore your activity state, read about the <a
+href="{@docRoot}guide/topics/fundamentals/activities.html#Lifecycle">Activity lifecycle</a>.</p>
<p>However, you might encounter a situation in which restarting your application and
restoring significant amounts of data can be costly and create a poor user experience. In such a
-situation, you have two options:</p>
+situation, you have two other options:</p>
<ol type="a">
<li><a href="#RetainingAnObject">Retain an object during a configuration change</a>
- <p>Allow your Activity to restart when a configuration changes, but carry a stateful
-{@link java.lang.Object} to the new instance of your Activity.</p>
+ <p>Allow your activity to restart when a configuration changes, but carry a stateful
+{@link java.lang.Object} to the new instance of your activity.</p>
</li>
<li><a href="#HandlingTheChange">Handle the configuration change yourself</a>
- <p>Prevent the system from restarting your Activity during certain configuration
-changes and receive a callback when the configurations do change, so that you can manually update
-your Activity as necessary.</p>
+ <p>Prevent the system from restarting your activity during certain configuration
+changes, but receive a callback when the configurations do change, so that you can manually update
+your activity as necessary.</p>
</li>
</ol>
<h2 id="RetainingAnObject">Retaining an Object During a Configuration Change</h2>
-<p>If restarting your Activity requires that you recover large sets of data, re-establish a
-network connection, or perform other intensive operations, then a full restart due to a
-configuration change might
-be an unpleasant user experience. Also, it may not be possible for you to completely
-maintain your Activity state with the {@link android.os.Bundle} that the system saves for you during
-the Activity lifecycle—it is not designed to carry large objects (such as bitmaps) and the
-data within it must be serialized then deserialized, which can consume a lot of memory and make the
-configuration change slow. In such a situation, you can alleviate the burden of reinitializing
-your Activity by retaining a stateful Object when your Activity is restarted due to a configuration
-change.</p>
+<p>If restarting your activity requires that you recover large sets of data, re-establish a network
+connection, or perform other intensive operations, then a full restart due to a configuration change
+might be a slow user experience. Also, it might not be possible for you to completely restore your
+activity state with the {@link android.os.Bundle} that the system saves for you with the {@link
+android.app.Activity#onSaveInstanceState(Bundle) onSaveInstanceState()} callback—it is not
+designed to carry large objects (such as bitmaps) and the data within it must be serialized then
+deserialized, which can consume a lot of memory and make the configuration change slow. In such a
+situation, you can alleviate the burden of reinitializing your activity by retaining a stateful
+{@link java.lang.Object} when your activity is restarted due to a configuration change.</p>
-<p>To retain an Object during a runtime configuration change:</p>
+<p>To retain an object during a runtime configuration change:</p>
<ol>
<li>Override the {@link android.app.Activity#onRetainNonConfigurationInstance()} method to return
-the Object you would like to retain.</li>
- <li>When your Activity is created again, call {@link
-android.app.Activity#getLastNonConfigurationInstance()} to recover your Object.</li>
+the object you would like to retain.</li>
+ <li>When your activity is created again, call {@link
+android.app.Activity#getLastNonConfigurationInstance()} to recover your object.</li>
</ol>
-<p>Android calls {@link android.app.Activity#onRetainNonConfigurationInstance()} between {@link
-android.app.Activity#onStop()} and {@link
-android.app.Activity#onDestroy()} when it shuts down your Activity due to a configuration
-change. In your implementation of {@link
-android.app.Activity#onRetainNonConfigurationInstance()}, you can return any {@link
-java.lang.Object} that you need in order to efficiently restore your state after the configuration
-change.</p>
+<p>When the Android system shuts down your activity due to a configuration change, it calls {@link
+android.app.Activity#onRetainNonConfigurationInstance()} between the {@link
+android.app.Activity#onStop()} and {@link android.app.Activity#onDestroy()} callbacks. In your
+implementation of {@link android.app.Activity#onRetainNonConfigurationInstance()}, you can return
+any {@link java.lang.Object} that you need in order to efficiently restore your state after the
+configuration change.</p>
<p>A scenario in which this can be valuable is if your application loads a lot of data from the
-web. If the user changes the orientation of the device and the Activity restarts, your application
+web. If the user changes the orientation of the device and the activity restarts, your application
must re-fetch the data, which could be slow. What you can do instead is implement
{@link android.app.Activity#onRetainNonConfigurationInstance()} to return an object carrying your
-data and then retrieve the data when your Activity starts again with {@link
+data and then retrieve the data when your activity starts again with {@link
android.app.Activity#getLastNonConfigurationInstance()}. For example:</p>
<pre>
@@ -113,11 +111,11 @@
should never pass an object that is tied to the {@link android.app.Activity}, such as a {@link
android.graphics.drawable.Drawable}, an {@link android.widget.Adapter}, a {@link android.view.View}
or any other object that's associated with a {@link android.content.Context}. If you do, it will
-leak all the Views and resources of the original Activity instance. (To leak the resources
+leak all the views and resources of the original activity instance. (Leaking resources
means that your application maintains a hold on them and they cannot be garbage-collected, so
lots of memory can be lost.)</p>
-<p>Then retrieve the {@code data} when your Activity starts again:</p>
+<p>Then retrieve the data when your activity starts again:</p>
<pre>
@Override
@@ -133,11 +131,10 @@
}
</pre>
-<p>In this case, {@link android.app.Activity#getLastNonConfigurationInstance()} retrieves
-the data saved by {@link android.app.Activity#onRetainNonConfigurationInstance()}. If {@code data}
-is null (which happens when the
-Activity starts due to any reason other than a configuration change) then the data object is loaded
-from the original source.</p>
+<p>In this case, {@link android.app.Activity#getLastNonConfigurationInstance()} returns the data
+saved by {@link android.app.Activity#onRetainNonConfigurationInstance()}. If {@code data} is null
+(which happens when the activity starts due to any reason other than a configuration change) then
+this code loads the data object from the original source.</p>
@@ -147,27 +144,27 @@
<p>If your application doesn't need to update resources during a specific configuration
change <em>and</em> you have a performance limitation that requires you to
-avoid the Activity restart, then you can declare that your Activity handles the configuration change
-itself, which prevents the system from restarting your Activity.</p>
+avoid the activity restart, then you can declare that your activity handles the configuration change
+itself, which prevents the system from restarting your activity.</p>
<p class="note"><strong>Note:</strong> Handling the configuration change yourself can make it much
more difficult to use alternative resources, because the system does not automatically apply them
-for you. This technique should be considered a last resort and is not recommended for most
-applications.</p>
+for you. This technique should be considered a last resort when you must avoid restarts due to a
+configuration change and is not recommended for most applications.</p>
-<p>To declare that your Activity handles a configuration change, edit the appropriate <a
-href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element
-in your manifest file to include the <a
+<p>To declare that your activity handles a configuration change, edit the appropriate <a
+href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element in
+your manifest file to include the <a
href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
-android:configChanges}</a> attribute with a string value that represents the configuration that you
-want to handle. Possible values are listed in the documentation for
-the <a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
-android:configChanges}</a> attribute (the most commonly used values are {@code orientation} to
-handle when the screen orientation changes and {@code keyboardHidden} to handle when the
-keyboard availability changes). You can declare multiple configuration values in the attribute
-by separating them with a pipe character ("|").</p>
+android:configChanges}</a> attribute with a value that represents the configuration you want to
+handle. Possible values are listed in the documentation for the <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
+android:configChanges}</a> attribute (the most commonly used values are {@code "orientation"} to
+prevent restarts when the screen orientation changes and {@code "keyboardHidden"} to prevent
+restarts when the keyboard availability changes). You can declare multiple configuration values in
+the attribute by separating them with a pipe {@code |} character.</p>
-<p>For example, the following manifest snippet declares an Activity that handles both the
+<p>For example, the following manifest code declares an activity that handles both the
screen orientation change and keyboard availability change:</p>
<pre>
@@ -176,20 +173,32 @@
android:label="@string/app_name">
</pre>
-<p>Now when one of these configurations change, {@code MyActivity} is not restarted.
-Instead, the Activity receives a call to {@link
+<p>Now, when one of these configurations change, {@code MyActivity} does not restart.
+Instead, the {@code MyActivity} receives a call to {@link
android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()}. This method
is passed a {@link android.content.res.Configuration} object that specifies
the new device configuration. By reading fields in the {@link android.content.res.Configuration},
you can determine the new configuration and make appropriate changes by updating
the resources used in your interface. At the
-time this method is called, your Activity's {@link android.content.res.Resources} object is updated
+time this method is called, your activity's {@link android.content.res.Resources} object is updated
to return resources based on the new configuration, so you can easily
-reset elements of your UI without the system restarting your Activity.</p>
+reset elements of your UI without the system restarting your activity.</p>
+
+<p class="caution"><strong>Caution:</strong> Beginning with Android 3.2 (API level 13), <strong>the
+"screen size" also changes</strong> when the device switches between portrait and landscape
+orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing
+for API level 13 or higher (as declared by the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> and <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a>
+attributes), you must include the {@code "screenSize"} value in addition to the {@code
+"orientation"} value. That is, you must decalare {@code
+android:configChanges="orientation|screenSize"}. However, if your application targets API level
+12 or lower, then your activity always handles this configuration change itself (this configuration
+change does not restart your activity, even when running on an Android 3.2 or higher device).</p>
<p>For example, the following {@link
android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()} implementation
-checks the availability of a hardware keyboard and the current device orientation:</p>
+checks the current device orientation:</p>
<pre>
@Override
@@ -202,12 +211,6 @@
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
- // Checks whether a hardware keyboard is available
- if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
- Toast.makeText(this, "keyboard visible", Toast.LENGTH_SHORT).show();
- } else if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
- Toast.makeText(this, "keyboard hidden", Toast.LENGTH_SHORT).show();
- }
}
</pre>
@@ -216,7 +219,8 @@
the configuration has changed and can simply re-assign all your resources that provide alternatives
to the configuration that you're handling. For example, because the {@link
android.content.res.Resources} object is now updated, you can reset
-any {@link android.widget.ImageView}s with {@link android.widget.ImageView#setImageResource(int)}
+any {@link android.widget.ImageView}s with {@link android.widget.ImageView#setImageResource(int)
+setImageResource()}
and the appropriate resource for the new configuration is used (as described in <a
href="providing-resources.html#AlternateResources">Providing Resources</a>).</p>
@@ -226,9 +230,9 @@
to use with each field, refer to the appropriate field in the {@link
android.content.res.Configuration} reference.</p>
-<p class="note"><strong>Remember:</strong> When you declare your Activity to handle a configuration
+<p class="note"><strong>Remember:</strong> When you declare your activity to handle a configuration
change, you are responsible for resetting any elements for which you provide alternatives. If you
-declare your Activity to handle the orientation change and have images that should change
+declare your activity to handle the orientation change and have images that should change
between landscape and portrait, you must re-assign each resource to each element during {@link
android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()}.</p>
@@ -236,13 +240,14 @@
changes, you can instead <em>not</em> implement {@link
android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()}. In
which case, all of the resources used before the configuration change are still used
-and you've only avoided the restart of your Activity. However, your application should always be
-able to shutdown and restart with its previous state intact. Not only because
-there are other configuration changes that you cannot prevent from restarting your application but
-also in order to handle events such as when the user receives an incoming phone call and then
-returns to your application.</p>
+and you've only avoided the restart of your activity. However, your application should always be
+able to shutdown and restart with its previous state intact, so you should not consider this
+technique an escape from retaining your state during normal activity lifecycle. Not only because
+there are other configuration changes that you cannot prevent from restarting your application, but
+also because you should handle events such as when the user leaves your application and it gets
+destroyed before the user returns to it.</p>
-<p>For more about which configuration changes you can handle in your Activity, see the <a
+<p>For more about which configuration changes you can handle in your activity, see the <a
href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
android:configChanges}</a> documentation and the {@link android.content.res.Configuration}
class.</p>
diff --git a/docs/html/guide/topics/search/search-dialog.jd b/docs/html/guide/topics/search/search-dialog.jd
index 27409d5..e06563d 100644
--- a/docs/html/guide/topics/search/search-dialog.jd
+++ b/docs/html/guide/topics/search/search-dialog.jd
@@ -807,8 +807,8 @@
Bar</a> developer guide.</p>
<p>Also see the <a
-href="{@docRoot}resources/samples/SearchableDictionary/src/com/example/android/searchabledict/
-SearchableDictionary.html">Searchable Dictionary</a> for an example implementation using
+href="{@docRoot}resources/samples/SearchableDictionary/src/com/example/android/searchabledict/SearchableDictionary.html"
+>Searchable Dictionary</a> for an example implementation using
both the dialog and the widget.</p>
diff --git a/docs/html/guide/topics/usb/adk.jd b/docs/html/guide/topics/usb/adk.jd
index 120576b..6c7ab0d 100644
--- a/docs/html/guide/topics/usb/adk.jd
+++ b/docs/html/guide/topics/usb/adk.jd
@@ -396,7 +396,7 @@
<li>Connect the ADK board (USB-A) to your Android-powered device (micro-USB). Ensure that the
power cable to the accessory is plugged in or that the micro-USB port on the accesory is
- connected to your computer for power (this also allows you to <a href="monitoring">monitor the
+ connected to your computer for power (this also allows you to <a href="#monitoring">monitor the
ADK board</a>). When connected, accept the prompt that asks for whether or not to open the
DemoKit application to connect to the accessory. If the prompt does not show up, connect and
reconnect the accessory.</li>
@@ -625,8 +625,8 @@
<code>AndroidAccessory::isAccessoryDevice()</code>. This method checks the vendor and product ID
of the device descriptor. A device in accessory mode has a vendor ID of 0x18D1 and a product ID
of 0x2D00 or 0x2D01. If the device is in accessory mode, then the ADK board can <a href=
- "#establish-a">establish communication with the device</a>. If not, the board <a href=
- "start-a">attempts to start the device in accessory mode</a>.</p>
+ "#establish">establish communication with the device</a>. If not, the board <a href=
+ "#start">attempts to start the device in accessory mode</a>.</p>
<pre>
bool AndroidAccessory::isConnected(void)
{
@@ -699,7 +699,7 @@
</pre>If this method returns false, the board waits until a new device is connected. If it is
successful, the device displays itself on the USB bus as being in accessory mode when the ADK board
re-enumerates the bus. When the device is in accessory mode, the accessory then <a href=
-"establish-a">establishes communication with the device</a>.
+"establish-adk">establishes communication with the device</a>.
<h3 id="establish-adk">Establish communication with the device</h3>
diff --git a/docs/html/guide/topics/usb/index.jd b/docs/html/guide/topics/usb/index.jd
index 6dc8ec5..ef53bdf 100644
--- a/docs/html/guide/topics/usb/index.jd
+++ b/docs/html/guide/topics/usb/index.jd
@@ -42,8 +42,8 @@
dependant on the device's hardware, regardless of platform level. You can filter for devices that
support USB host and accessory through a <a href=
"{@docRoot}guide/topics/manifest/uses-feature-element.html"><uses-feature></a> element. See
- the USB <a href="{@docRoot}guide/topics/USB/accessory.html">accessory</a> and <a href=
- "{@docRoot}guide/topics/USB/host.html">host</a> documentation for more details.</p>
+ the USB <a href="{@docRoot}guide/topics/usb/accessory.html">accessory</a> and <a href=
+ "{@docRoot}guide/topics/usb/host.html">host</a> documentation for more details.</p>
<h2>Debugging considerations</h2>
diff --git a/docs/html/images/nfc_tag_dispatch.png b/docs/html/images/nfc_tag_dispatch.png
new file mode 100644
index 0000000..70ed711
--- /dev/null
+++ b/docs/html/images/nfc_tag_dispatch.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index a8b61bf..bb7721d 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -129,20 +129,17 @@
'sdk': {
'layout':"imgLeft",
'icon':"sdk-small.png",
- 'name':"Android 3.2",
- 'img':"honeycomb-android.png",
- 'title':"Android 3.2 is here!",
- 'desc': "<p>Android 3.2 is a minor feature update that includes new APIs that allow you to "
-+ "better target your layouts for specific screen sizes and other miscellaneous new APIs.</p>"
-+ "<p>For more information about all the changes in Android 3.2, read the "
-+ "<a href='{@docRoot}sdk/android-3.2.html'>version notes</a> and <a "
-+ "href='{@docRoot}sdk/api_diff/13/changes.html'>diff report</a>.</p>"
-/*
-+ "<p>If you have an existing SDK, add Android 3.0 as an "
-+ "<a href='{@docRoot}sdk/adding-components.html'>SDK "
-+ "component</a>. If you're new to Android, install the "
-+ "<a href='{@docRoot}sdk/index.html'>SDK starter package</a>."
-*/
+ 'name':"Android 4.0",
+ 'img':"ics-android.png",
+ 'title':"Ice Cream Sandwich!",
+ 'desc': "<p>Android 4.0 is here, delivering a unified UI for phones and tablets and "
++ "innovative features for users and developers. Check out the <a "
++ "href='http://developer.android.com/sdk/android-4.0-highlights.html'>Platform Highlights</a> "
++ "for an overview of the new features in Android 4.0.</p>"
++ "<p>For more information about API changes, read the "
++ "<a href='{@docRoot}sdk/android-4.0.html'>platform notes</a> and <a "
++ "href='{@docRoot}sdk/api_diff/14/changes.html'>diff report</a>. If you're new to Android, "
++ "get started with the <a href='/sdk/index.html'>SDK starter package</a>.</p>"
},
'tv': {
@@ -159,7 +156,7 @@
+ "<p><a href='http://code.google.com/tv'>Develop for Google TV »</a></p>"
},
-
+/*
'devphone': {
'layout':"imgLeft",
'icon':"devphone-small.png",
@@ -173,6 +170,7 @@
+ "<a href='http://market.android.com/publish'>Visit Android Market "
+ "to learn more »</a></p>"
},
+ */
'mapskey': {
'layout':"imgLeft",
diff --git a/docs/html/offline.jd b/docs/html/offline.jd
index 1064a99..5f8e37ce 100644
--- a/docs/html/offline.jd
+++ b/docs/html/offline.jd
@@ -29,7 +29,7 @@
especially <a href="{@docRoot}resources/samples/ApiDemos/index.html">API Demos</a></li>
<li>Read the <a href="{@docRoot}guide/topics/fundamentals/index.html">Application
Fundamentals</a></li>
- <li>Read the <a href="{@docRoot}guide/developing/index.html">Overview</a> for using the SDK
+ <li>Read the <a href="{@docRoot}guide/developing/index.html">Introduction</a> for using the SDK
tools</li>
</ul>
</div>
@@ -44,9 +44,6 @@
<p>There's no additional setup.</p>
-<p>New Android platforms are saved in the <code><sdk>/platforms/</code> directory of
-your existing SDK and new add-ons are saved in the <code><sdk>/add-ons/</code> directory.</p>
-
<div class="note">
<p><strong>Note:</strong> You are currently viewing the offline version of the Android developer
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index 3e673a5..310310e 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -419,16 +419,16 @@
},
{
tags: ['sample', 'new'],
- path: 'samples/AndroidBeam/index.html',
+ path: 'samples/AndroidBeamDemo/index.html',
title: {
- en: 'Android Beam'
+ en: 'Android Beam Demo'
},
description: {
en: 'An example of how to use the Android Beam feature to send messages between two Android-powered devices (API level 14 or later) that support NFC.'
}
},
{
- tags: ['sample', 'layout', 'ui'],
+ tags: ['sample', 'layout', 'ui', 'updated'],
path: 'samples/ApiDemos/index.html',
title: {
en: 'API Demos'
@@ -608,7 +608,7 @@
}
},
{
- tags: ['sample', 'accountsync'],
+ tags: ['sample', 'accountsync', 'updated'],
path: 'samples/SampleSyncAdapter/index.html',
title: {
en: 'SampleSyncAdapter'
diff --git a/docs/html/resources/samples/images/hcgallery-phone1.png b/docs/html/resources/samples/images/hcgallery-phone1.png
new file mode 100644
index 0000000..9f0c280
--- /dev/null
+++ b/docs/html/resources/samples/images/hcgallery-phone1.png
Binary files differ
diff --git a/docs/html/resources/samples/images/hcgallery-phone2.png b/docs/html/resources/samples/images/hcgallery-phone2.png
new file mode 100644
index 0000000..b049a65
--- /dev/null
+++ b/docs/html/resources/samples/images/hcgallery-phone2.png
Binary files differ
diff --git a/docs/html/sdk/android-3.2.jd b/docs/html/sdk/android-3.2.jd
index ea2b4ed..aeaf9c8 100644
--- a/docs/html/sdk/android-3.2.jd
+++ b/docs/html/sdk/android-3.2.jd
@@ -550,7 +550,11 @@
<p>A typical application that functions properly in both landscape and portrait orientations would not normally need to declare an orientation requirement. Rather, an application designed primarily for one orientation, such as an app designed for a television, could declare one of the constants to ensure that it isn't available to devices that don't provide that orientation.</p>
-<p>If the application is targeting API level 12 or lower, the platform assumes that if app has not specified whether it requires portrait or landscape, both orientations are required.</p>
+<p>If any of activities declared in the manifest request that they run in a specific orientation,
+using the <a href="{@docRoot}guide/topics/manifest/activity-element.html#screen">{@code
+android:screenOrientation}</a> attribute, then this also declares that the application
+requires that orientation.</p>
+
</li>
<li>Other feature constants
diff --git a/docs/html/sdk/android-4.0-highlights.jd b/docs/html/sdk/android-4.0-highlights.jd
new file mode 100644
index 0000000..fe69e12
--- /dev/null
+++ b/docs/html/sdk/android-4.0-highlights.jd
@@ -0,0 +1,995 @@
+page.title=Android 4.0 Platform Highlights
+
+@jd:body
+
+
+<style type="text/css">
+#jd-content {
+ max-width:1024px;
+}
+#jd-content div.screenshot {
+ float:left;
+ clear:left;
+ padding:15px 30px 15px 0;
+}
+#jd-content div.video {
+ float:right;
+ padding:0 60px 40px;
+ margin-top:-15px;
+}
+#jd-content table.columns {
+ margin:0 0 1em 0;
+}
+#jd-content table.columns td {
+ padding:0;
+}
+#jd-content table.columns td+td {
+ padding:0 2em;
+}
+#jd-content table.columns td img {
+ margin:0;
+}
+#jd-content table.columns td+td>*:first-child {
+ margin-top:-2em;
+}
+.green {
+ color:#8db529;
+ font-weight:bold;
+}
+</style>
+<!--
+<div class="video" style="border:1px solid gray;width:250px;height:180px;margin:1.5em">
+<object width="278" height="180">
+<xparam name="movie" value="http://www.youtube.com/v/Jx3pdWBlZ34?hl=en&fs=1"></param>
+<xparam name="allowFullScreen" value="true"></param><param name="allowscriptaccess"
+value="always"></param>
+ICS CONSUMER VIDEO [ziwang]
+<embed xsrc="http://www.youtube.com/v/Jx3pdWBlZ34?hl=en&fs=1" type="application/x-shockwave-flash"
+allowscriptaccess="always" allowfullscreen="true" width="278" height="180"></embed>
+</object>
+</div>
+-->
+<p>Welcome to Android 4.0!</p>
+
+<p>Android 4.0 delivers a refined, unified UI for phones and tablets and introduces innovative features for users and developers. This document provides a glimpse of the many new features and technologies that make Android 4.0 simple, beautiful, and beyond smart. <!--For technical details about
+new developer APIs described below, see the <a
+href="{@docRoot}sdk/android-4.0.html">Android 4.0 API Overview</a> document.--></p>
+
+<ul>
+ <li><a href="#UserFeatures">Android 4.0 for Users</a></li>
+ <li><a href="#DeveloperApis">Android 4.0 for Developers</a></li>
+</ul>
+
+<h2 id="UserFeatures" style="clear:right">Android 4.0 for Users</h2>
+
+<div style="padding-bottom:0em;">
+<a href="{@docRoot}sdk/images/4.0/home-lg.png" target="_android"><img style="float:right;xborder:1px solid #ddd;border-radius: 5px;" src="{@docRoot}sdk/images/4.0/home.png" alt="" height="300" width="180" /></a>
+<a href="{@docRoot}sdk/images/4.0/lock-lg.png" target="_android"><img style="float:right;border:1px solid #ddd;border-radius: 5px;" src="{@docRoot}sdk/images/4.0/lock.png" alt="" height="300" width="180" /></a>
+</div>
+
+
+<h3 id="simple" style="color:#172861">Simple, beautiful, beyond smart</h3>
+
+<p>Android 4.0 builds on the things people love most about Android — easy
+multitasking, rich notifications, customizable home screens, resizable widgets,
+and deep interactivity — and adds powerful new ways of communicating and
+sharing.</p>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Refined, evolved UI</strong></p>
+
+<p>Focused on bringing the power of Android to the surface, Android 4.0 makes
+<strong>common actions more visible</strong> and lets users navigate with
+simple, intuitive gestures. Refined <strong>animations</strong> and feedback
+throughout the system make interactions engaging and interesting. An entirely
+<strong>new typeface</strong> optimized for high-resolution screens improves
+readability and brings a polished, modern feel to the user interface.</p>
+
+<p>Virtual buttons in the System Bar let users navigate instantly to Back, Home,
+and Recent Apps. The <strong>System Bar</strong> and virtual buttons are present
+across all apps, but can be dimmed by applications for full-screen viewing.
+Users can access each application's contextual options in the <strong>Action
+Bar</strong>, displayed at the top (and sometimes also at the bottom) of the
+screen.</p>
+
+<p><strong>Multitasking</strong> is a key strength of Android and it's made even
+easier and more visual on Android 4.0. The Recent Apps button lets users jump
+instantly from one task to another using the list in the System Bar. The list
+pops up to show thumbnail images of apps used recently — tapping a
+thumbnail switches to the app.</p>
+
+<div style="padding-top:0em;">
+<div style="margin-right:.5em;float:left;width:182px;padding-top:.5em;">
+<a href="{@docRoot}sdk/images/4.0/tasks-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/tasks.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<div style="padding-left:1em;padding-bottom:1em;font-size:.9em;padding-right:1em;">The Recent Apps list makes multitasking simple.</div>
+<a href="{@docRoot}sdk/images/4.0/lock-camera-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/lock-camera.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<div style="padding-left:1em;padding-bottom:1em;font-size:.9em;padding-right:1.75em;">Jump to the camera or see notifications without unlocking.</div>
+<a href="{@docRoot}sdk/images/4.0/contact-call-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/contact-call.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;padding:0" /></a>
+<!--<a href="{@docRoot}sdk/images/4.0/quick-response-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/quick-responses-new.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;" /></a>-->
+<div style="padding-left:1em;padding-bottom:.5em;font-size:.9em;padding-right:1.75em;">For incoming calls, you can respond instantly by text.</div>
+</div>
+</div>
+
+<p>Rich and interactive <strong>notifications</strong> let users keep in
+constant touch with incoming messages, play music tracks, see real-time updates
+from apps, and much more. On smaller-screen devices, notifications appear at the
+top of the screen, while on larger-screen devices they appear in the System
+Bar.</p>
+
+<div style="padding-top:0em;">
+<div style="margin-right:1em;float:right;margin-left:1em;margin-top:.5em;margin-bottom:0;padding-bottom:0;width:326px">
+<a href="{@docRoot}sdk/images/4.0/allapps-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/allapps.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<a href="{@docRoot}sdk/images/4.0/calendar-widget-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/calendar-widget.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<div style="padding-left:1em;padding-bottom:1em;margin-top:0;padding-top:0;font-size:.9em"><!--<strong>Figure 3.</strong>-->The All Apps launcher (left) and resizable widgets (right) give you apps and rich content from the home screen.</div>
+</div>
+</div>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Home screen folders and
+favorites tray</strong></p>
+
+<p>New <strong>home screen folders</strong> offer a new way for users to group
+their apps and shortcuts logically, just by dragging one onto another. From the
+All Apps launcher, users can now simply drag an app to get information about it
+or immediately uninstall it, or disable a pre-installed app.</p>
+
+<p>On smaller-screen devices, the home screen now includes a customizable
+<strong>favorites tray</strong> visible from all home screens. Users can drag
+apps, shortcuts, folders, and other priority items in or out of the favorites
+tray for instant access from any home screen.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Resizable
+widgets</strong></p>
+
+<p>Home screens in Android 4.0 are designed to be content-rich and customizable.
+Users can do much more than add shortcuts — they can embed live
+application content directly through interactive <strong>widgets</strong>.
+Widgets let users check email, flip through a calendar, play music, check social
+streams, and more — right from the home screen, without having to launch
+apps. Widgets are resizable, so users can expand them to show more content or
+shrink them to save space.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>New lock screen
+actions</strong></p>
+
+<p>The lock screens now let users do more without unlocking. From the slide lock
+screen, users can <strong>jump directly to the camera</strong> for a picture or
+<strong>pull down the notifications window</strong> to check for messages. When
+listening to music, users can even manage music tracks and see album art. </p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Quick responses for
+incoming calls</strong></p>
+
+<p>When an incoming call arrives, users can now quickly <strong>respond by text
+message</strong>, without needing to pick up the call or unlock the device. On
+the incoming call screen, users simply slide a control to see a list of text
+responses and then tap to send and end the call. Users can add their own
+responses and manage the list from the Settings app.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Swipe to dismiss
+notifications, tasks, and browser tabs</strong></p>
+
+<p>Android 4.0 makes managing notifications, recent apps, and browoser tabs even
+easier. Users can now dismiss individual notifications, apps from the Recent
+Apps list, and browser tabs lists with a simple swipe of a finger. </p>
+
+<div style="padding-top:0em;">
+<div style="margin-right:1em;float:right;margin-left:1em;margin-top:1.5em;margin-bottom:0;padding-bottom:0;width:200px">
+<a href="{@docRoot}sdk/images/4.0/text-replace-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/text-replace.png" alt="" width="190" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<div style="padding-left:1em;padding-bottom:1.25em;margin-top:0;padding-top:0;font-size:.9em"><!--<strong>Figure 3.</strong>-->A spell-checker lets you find errors and fix them faster. </div>
+<a href="{@docRoot}sdk/images/4.0/tts-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/tts.png" alt="" width="190" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<div style="padding-left:1em;padding-bottom:1.25em;margin-top:0;padding-top:0;font-size:.9em">A powerful voice input engine lets you dictate continously.</div>
+</div>
+</div>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Improved text input and
+spell-checking</strong></p>
+
+<p>The soft keyboard in Android 4.0 makes text input even faster and more
+accurate. Error correction and word suggestion are improved through a new set of
+default dictionaries and more accurate heuristics for handling cases such as
+double-typed characters, skipped letters, and omitted spaces. Word suggestion is
+also improved and the suggestion strip is simplified to show only three words at
+a time.</p>
+
+<p>To fix misspelled words more easily, Android 4.0 adds a spell-checker that
+locates and underlines errors and suggests replacement words. With one tap,
+users can choose from multiple spelling suggestions, delete a word, or add it to
+the dictionary. Users can even tap to see replacement suggestions for words that
+are spelled correctly. For specialized features or additional languages, users
+can now download and install third-party dictionaries, spell-checkers, and other
+text services.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Powerful voice input
+engine</strong></p>
+
+<p>Android 4.0 introduces a powerful new voice input engine that offers a
+continuous "open microphone" experience and streaming voice recognition. The new
+voice input engine lets users dictate the text they want, for as long as they
+want, using the language they want. Users can speak continously for a prolonged
+time, even pausing for intervals if needed, and dictate punctuation to create
+correct sentences. As the voice input engine enters text, it underlines possible
+dictation errors in gray. After dictating, users can tap the underlined words to
+quickly replace them from a list of suggestions.</p>
+
+<div style="padding-top:0em;">
+<div style="margsin-right:.8em;float:left;width:350px;padding-top:1em;">
+<a href="{@docRoot}sdk/images/4.0/usage-all-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/usage-all.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<a href="{@docRoot}sdk/images/4.0/usage-maps-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/usage-maps.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<div style="padding-left:1em;padding-bottom:1em;font-size:.9em;padding-right:1.75em;"><!--<strong>Figure 3.</strong>--> Data usage controls let you monitor total usage by network type and application and then set limits if needed.</div>
+</div>
+</div>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Control over network
+data</strong></p>
+
+<p>Mobile devices can make extensive use of network data for streaming content,
+synchronizing data, downloading apps, and more. To meet the needs of users with
+<strong>tiered or metered data plans</strong>, Android 4.0 adds new controls for
+managing network data usage.</p>
+
+<p>In the Settings app, colorful charts show the total data usage on each
+network type (mobile or Wi-Fi), as well as amount of data used by each running
+application. Based on their data plans, users can optionally set warning levels
+or hard limits on data usage or disable mobile data altogether. Users can also
+manage the background data used by individual applications as needed.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Designed for
+accessibility</strong></p>
+
+<p>A variety of new features greatly enhance the accessibility of Android 4.0
+for blind or visually impaired users. Most important is a new
+<strong>explore-by-touch mode</strong> that lets users navigate without having
+to see the screen. Touching the screen once triggers audible feedback that
+identifies the UI component below; a second touch in the same component
+activates it with a full touch event. The new mode is especially important to
+support users on new devices that use virtual buttons in the System Bar, rather
+than dedicated hardware buttons or trackballs. Also, standard apps are updated
+to offer an improved accessibility experience. The <strong>Browser</strong>
+supports a script-based screen reader for reading favorite web content and
+navigating sites. For improved readability, users can also increase the default
+font size used across the system.</p>
+
+<p>The accessibility experience begins at first setup — a simple
+<strong>touch gesture</strong> during setup (clockwise square from upper left)
+activates all accessibility features and loads a setup tutorial. Once
+accessibility features are active, everything visible on the screen can be
+spoken aloud by the standard screen reader.</p>
+
+
+<h3 id="comms" style="color:#172861">Communication and sharing</h3>
+
+<div style="padding-top:0em;">
+<div style="margin-right:1em;float:right;margin-left:.5em;margin-top:1.5em;margin-bottom:0;padding-bottom:0;width:490px">
+<!--<img src="{@docRoot}sdk/images/4.0/contact-call.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;" />-->
+<a href="{@docRoot}sdk/images/4.0/contact-faves-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/contact-faves.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;padding:0" /></a>
+<a href="{@docRoot}sdk/images/4.0/contact-connect-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/contact-connect.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;padding:0" /></a>
+<a href="{@docRoot}sdk/images/4.0/contact-email-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/contact-email.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;padding:0" /></a>
+
+<div style="padding-left:1em;padding-bottom:1.25em;margin-top:0;padding-top:0;font-size:.9em"><!--<strong>Figure 3.</strong>-->Contacts and profiles are integrated across apps and social networks, for a consistent, personal experience everywhere — from incoming calls to emails.</div>
+</div>
+</div>
+
+<p>Designed for the way people live, Android 4.0 integrates rich social
+communication and sharing touchpoints across the system, making it easy to talk,
+email, text, and share.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>People and
+profiles</strong></p>
+
+<p>Throughout the system, a user’s social groups, profiles, and contacts are
+linked together and integrated for easy accessibility. At the center is a new
+<strong>People app</strong> that offers richer profile information, including a
+large profile picture, phone numbers, addresses and accounts, status updates,
+and a new button for connecting on integrated social networks. </p>
+
+<p>The user's own contact information is stored in a new <strong>"Me"
+profile</strong>, allowing easier sharing with apps and people. All of the
+user's integrated contacts are displayed in an easy to manage list, including
+controls over which contacts are shown from any integrated account or social
+network. Wherever the user navigates across the system, tapping a profile photo
+displays Quick Contacts, with shortcuts to phone numbers, text messaging, and
+more. </p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Unified calendar, visual
+voicemail</strong></p>
+
+<p>To help organize appointments and events, an updated <strong>Calendar
+app</strong> brings together personal, work, school, and social agendas. With
+user permission, other applications can contribute events to the calendar and
+manage reminders, for an integrated view across multiple calendar providers. The
+app is redesigned to let users manage events more easily. Calendars are
+color-coded and users can <strong>swipe left or right</strong> to change dates
+and pinch to zoom in or out agendas. </p>
+
+<p>In the phone app, a new <strong>visual voicemail</strong> features integrates
+incoming messages, voice transcriptions, and audio files from one or more
+providers. Third-party applications can integrate with the Phone app to add
+their own voice messages, transcriptions, and more to the visual voicemail
+inbox. </p>
+
+<div style="padding-top:0em;">
+<div style="margsin-right:0em;float:left;width:282px;padding-top:1em;">
+<a href="{@docRoot}sdk/images/4.0/camera-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/camera.png" alt="" width="240" height="144" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<a href="{@docRoot}sdk/images/4.0/gallery-edit-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/gallery-edit.png" alt="" width="240" height="144" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<a href="{@docRoot}sdk/images/4.0/gallery-share-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/gallery-share.png" alt="" width="240" height="144" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<div style="padding-left:1em;padding-bottom:1em;font-size:.9em;padding-right:2.75em;">Capture the picture you want, edit, and share instantly. </div>
+</div>
+</div>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Rich and versatile camera
+capabilities</strong></p>
+
+<p>The Camera app includes many new features let users capture special moments
+with great photos and videos. After capturing images, they can edit and share
+them easily with friemds. </p>
+
+<p>When taking pictures, <strong>continuous focus</strong>, <strong>zero shutter
+lag exposure</strong>, and decreased shot-to-shot speed help capture clear,
+precise images. <strong>Stabilized image zoom</strong> lets users compose photos
+and video in the way they want, including while video is recording. For new
+flexibility and convenience while shooting video, users can now take
+<strong>snapshots at full video resolution</strong> just by tapping the screen
+as video continues to record.</p>
+
+<p>To make it easier to take great pictures of people, built-in <strong>face
+detection</strong> locates faces in the frame and automatically sets focus. For
+more control, users can <strong>tap to focus</strong> anywhere in the preview
+image. </p>
+
+<p>For capturing larger scenes, the Camera introduces a <strong>single-motion
+panorama</strong> mode. In this mode, the user starts an exposure and then
+slowly turns the Camera to encompass as wide a perspective as needed. The Camera
+assembles the full range of continuous imagery into a single panoramic
+photo.</p>
+
+<p>After taking a picture or video, users can quickly share it by email, text
+message, bluetooth, social networks, and more, just by tapping the thumbnail in
+the camera controls. </p>
+
+
+<div style="padding-top:0em;">
+<div style="margin-right:1em;float:right;margin-left:1em;padding-top:1em;margin-bottom:1em;padding-bottom:0;width:160px">
+<img src="{@docRoot}sdk/images/4.0/gallery-widget.png" alt="" width="144" style="border:1px solid #ddd;border-radius: 6px;" />
+<div style="padding-left:1em;padding-bottom:1.25em;margin-top:0;padding-top:0;font-size:.9em">A Photo Gallery widget on the home screen.</div>
+</div>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Redesigned Gallery app
+with photo editor</strong></p>
+
+<p>The Gallery app now makes it easier to manage, show, and share photos and
+videos. For managing collections, a <strong>redesigned album layout</strong>
+shows many more albums and offers larger thumbnails. There are many ways to sort
+albums, including by time, location, people, and tags. To help pictures look
+their best, the Gallery now includes a powerful <strong>photo editor</strong>.
+Users can crop and rotate pictures, set levels, remove red eyes, add effects,
+and much more. After retouching, users can select one or multiple pictures or
+videos to share instantly over email, text messaging, bluetooth, social
+networks, or other apps.</p>
+
+<p>An improved <strong>Picture Gallery widget</strong> lets users look at
+pictures directly on their home screen. The widget can display pictures from a
+selected album, shuffle pictures from all albums, or show a single image. After
+adding the widget to the home screen, users can flick through the photo stacks
+to locate the image they want, then tap to load it in Gallery. </p>
+
+<div style="padding-top:0em;clear:right;">
+<div style="margin-right:1em;float:right;margin-left:1em;padding-top:1em;margin-bottom:1em;padding-bottom:0;width:320px">
+<img src="{@docRoot}sdk/images/4.0/live-effects.png" alt="" width="297" style="border:1px solid #ddd;border-radius: 6px;" />
+<div style="padding-left:1em;padding-bottom:1em;margin-top:0;padding-top:0;font-size:.9em">Live Effects let you change backgrounds and use Silly Faces during video.</div>
+</div>
+</div>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Live Effects for transforming video</strong></p>
+
+<p>Live Effects is a collection of graphical transformations that add interest and fun to videos captured in the Camera app. For example, users can change the background behind them to any stock or custom image, for just the right setting when shooting video or using Google Talk video chat. Also available is Silly Faces, a set of morphing effects that use state-of-the-art face recognition and GPU filters to add great effects facial features during video capture. For example, you can use effects such as small eyes, big mouth, big nose, face squeeze, and more. Outside of the Camera app, Live Effects is available during video chat in the Google Talk app.</p>
+
+<div style="padding-top:0em;">
+<div style="margsin-right:.8em;float:left;width:186px;padding-top:1em;">
+<a href="{@docRoot}sdk/images/4.0/screenshot-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/screenshot.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<div style="padding-left:1em;padding-bottom:1.25em;margin-top:0;padding-top:0;font-size:.9em"> Snapping a screenshot.</div>
+</div>
+</div>
+</div>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Sharing with screenshots</strong></p>
+
+<p>Users can now share what's on their screens more easily by taking screenshots. Hardware buttons let them snap a <strong>screenshot</strong> and store it locally. Afterward, they can view, edit, and share the screen shot in Gallery or a similar app.</p>
+
+
+<h3 id="cloud" style="color:#172861">Cloud-connected experience</h3>
+
+<div style="padding-top:0em;">
+<div style="margin-right:1em;float:right;margin-left:1em;padding-top:1em;margin-bottom:0;padding-bottom:0;width:326px">
+<a href="{@docRoot}sdk/images/4.0/browser-tabs-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/browser-tabs.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<a href="{@docRoot}sdk/images/4.0/browser-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/browser.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<div style="padding-left:1em;padding-bottom:1.25em;margin-top:0;padding-top:0;font-size:.9em"><!--<strong>Figure 3.</strong>-->The Browser tabs menu <em>(left)</em> lets you quickly switch browser tabs. The options menu <em>(right)</em> gives you new ways to manage your browsing experience.</div>
+<img src="{@docRoot}sdk/images/4.0/bbench.png" alt="" width="310" />
+<div style="padding-left:1em;padding-bottom:1em;margin-top:0;padding-top:0;font-size:.9em">Benchmark comparisons of Android Browser.</div>
+</div>
+</div>
+
+<p>Android has always been cloud-connected, letting users browse the web and sync photos, apps, games, email, and contacts — wherever they are and across all of their devices. Android 4.0 adds new browsing and email capabilities to let users take even more with them and keep communication organized.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Powerful web
+browsing</strong></p>
+
+<p>The Android Browser offers an experience that’s as rich and convenient as a
+desktop browser. It lets users instantly and manage <strong>sync Google Chrome
+bookmarks</strong> from all of their accounts, jump to their favorite content
+faster, and even save it for reading later in case there's no network
+available.</p>
+
+<p>To get the most out of web content, users can now request full
+<strong>desktop versions</strong> of web sites, rather than their mobile
+versions. Users can set their preference for web sites separately for each
+<strong>browser tab</strong>. For longer content, users can save a copy for
+<strong>offline reading</strong>. To find and open saved pages, users can browse
+a visual list that’s included with browser bookmarks and history. For better
+readability and accessibility, users can increase the browser’s <strong>zoom
+levels</strong> and override the system default <strong>text sizes</strong>.</p>
+
+<p>Across all types of content, the Android Browser offers dramatically improved
+<strong>page rendering performance</strong> through updated versions of the
+WebKit core and the V8 Crankshaft compilation engine for JavaScript. In
+benchmarks run on a Nexus S device, the Android 4.0 browser showed an
+improvement of nearly 220% over the Android 2.3 browser in the V8 Benchmark
+Suite and more than 35% in the SunSpider 9.1 JavaScript Benchmark. When run on a
+Galaxy Nexus device, the Android 4.0 browser showed improvement of nearly 550%
+in the V8 benchmark and nearly 70% in the SunSpider benchmark.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Improved
+email</strong></p>
+
+<p>In Android 4.0, email is easier to send, read, and manage. For composing
+email, <strong>improved auto-completion</strong> of recipients helps with
+finding and adding frequent contacts more quickly. For easier input of frequent
+text, users can now create <strong>quick responses</strong> and store them in
+the app, then enter them from a convenient menu when composing. When replying to
+a message, users can now toggle the message to Reply All and Forward without
+changing screens.</p>
+
+<p>For easier browsing across accounts and labels, the app adds an
+<strong>integrated menu</strong> of accounts and recent labels. To help users
+locate and organize IMAP and Exchange email, the Email app now supports
+<strong>nested mail subfolders</strong>, each with synchronization rules. Users
+can also search across folders on the server, for faster results. </p>
+
+<p>For <strong>enterprises</strong>, the Email app supports EAS v14. It supports
+EAS certificate authentication, provides ABQ strings for device type and mode,
+and allows automatic sync to be disabled while roaming. Administrators can also
+limit attachment size or disable attachments.</p>
+
+<p>For keeping track of incoming email more easily, a <strong>resizable Email
+widget</strong> lets users flick through recent email right from the home
+screen, then jump into the Email app to compose or reply.</p>
+
+
+<div style="padding-top:0em;">
+<div style="margsin-right:.8em;float:left;width:186px;padding-top:1em;">
+<a href="{@docRoot}sdk/images/4.0/beam-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/beam.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<div style="padding-left:1em;padding-bottom:1em;margin-top:0;padding-top:0;font-size:.9em;padding-right:1.5em;">Android Beam lets users share what they are using with a single tap.</div>
+</div>
+</div>
+
+<h3 id="innovation" style="color:#172861">Innovation</h3>
+
+<p>Android is continously driving innovation forward, pushing the boundaries of
+communication and sharing with new capabilities and interactions.</p>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Android Beam for
+NFC-based sharing</strong></p>
+
+<p>Android Beam is an innovative, convenient feature for sharing across two
+NFC-enabled devices, It lets people instantly exchange favorite apps, contacts,
+music, videos — almost anything. It’s incredibly simple and convenient to
+use — there’s no menu to open, application to launch, or pairing needed.
+Just touch one Android-powered phone to another, then tap to send.</p>
+
+<p>For sharing apps, Android Beam pushes a link to the app's details page in
+Android Market. On the other device, the Market app launches and loads the
+details page, for easy downloading of the app. Individual apps can build on
+Android Beam to add other types of interactions, such as passing game scores,
+initiating a multiplayer game or chat, and more.</p>
+
+<div style="padding-top:0em;">
+<div style="margin-right:1em;float:right;margin-left:1em;margin-top:.5em;margin-bottom:0;padding-bottom:0;width:160px">
+<a href="{@docRoot}sdk/images/4.0/face-unlock-lg.png" target="_android">
+<img src="{@docRoot}sdk/images/4.0/face-unlock.png" alt="" height="240" width="144" style="border:1px solid #ddd;border-radius: 6px;" /></a>
+<div style="padding-left:1em;padding-bottom:1em;margin-top:0;padding-top:0;font-size:.9em">Face recognition lets you unlock your phone with your face.</div>
+</div>
+</div>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Face Unlock</strong></p>
+
+<p>Android 4.0 introduces a completely new approach to securing a device, making
+it even more personal — Face Unlock is a new screen-lock option that lets
+users unlock their devices with their faces. It takes advantage of
+state-of-the-art facial recognition technology to register a face and to
+recognize it later when unlocking the device. Users just hold their devices in
+front of their faces to unlock, or use a backup PIN or pattern. </p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Wi-Fi Direct and Bluetooth HDP</strong></p>
+
+<p>Support for <strong>Wi-Fi Direct</strong> lets users connect directly to
+nearby peer devices over Wi-Fi, for more reliable, higher-speed communication.
+No internet connection or tethering is needed. Through third-party apps, users
+can connect to compatible devices to take advantage of new features such as
+instant sharing of files, photos, or other media; streaming video or audio from
+another device; or connecting to compatible printers or other devices.</p>
+
+<p>Android 4.0 also introduces built-in support for connecting to <strong>Bluetooth Health Device Profile (HDP)</strong> devices. With support from third-party apps, users can connect to wireless medical devices and sensors in hospitals, fitness centers, homes, and elsewhere. In addition, for connecting to higher quality Bluetooth audio devices, Android 4.0 adds support for Bluetooth Hands Free Profile (HFP) 1.6.</p>
+
+
+<h2 id="DeveloperApis" style="clear:right">New Developer Features</h2>
+
+<!-- <ul>
+<li><a href="#ui-dev">Unified UI framework for phones, tablets, and more</a></li>
+<li><a href="#communication-dev">Communication and sharing</a></li>
+<li><a href="#media-dev">New media capabilities</a></li>
+<li><a href="#connectivity-dev">New types of connectivity</a></li>
+<li><a href="#uicomp-dev">New UI components and capabilities</a></li>
+<li><a href="input-dev">New input types and text services</a></li>
+<li><a href="#accessibility-dev">Enhanced accessibility APIs</a></li>
+<li><a href="#data-dev">Efficient network usage</a></li>
+<li><a href="#security-dev">Security for apps and content</a></li>
+<li><a href="#enterprise-dev">Enhancements for Enterprise</a></li>
+</ul>-->
+
+<h3 id="ui-dev">Unified UI framework for phones, tablets, and more</h3>
+
+<p>Android 4.0 brings a unified UI framework that lets developers create
+elegant, innovative apps for phones, tablets, and more. It includes all of the
+familiar Android 3.x interface elements and APIs — fragments, content
+loaders, Action Bar, rich notifications, resizable home screen widgets, and more
+— as well as new elements and APIs.</p>
+
+<p>For developers, the unified UI framework in Android 4.0 means new UI tools,
+consistent design practices, simplified code and resources, and streamlined
+development across the range of Android-powered devices.</p>
+
+<div class="sidebox-wrapper">
+<div class="sidebox" style="border-left:1px solid #22a5ca;background-color:#fff;">
+ <h3>Key Android 3.x developer features, <br>now for phones too</h3>
+
+<p>Core UI</p>
+<ul>
+<li>Fragments and content loaders</li>
+<li>Resizeable home screen widgets</li>
+<li>Rich notifications</li>
+<li>Multi-selection, drag-drop, clipboard</li>
+<li>Improved screen-support API</li>
+<li>Hardware-accelerated 2D graphics</li>
+</ul>
+
+<p>Graphics and animation</p>
+<ul>
+<li>Property-based animation</li>
+<li>Renderscript 3D graphics</li>
+</ul>
+
+<p>Media and connectivity</p>
+<ul>
+<li>HTTP Live streaming</li>
+<li>Bluetooth A2DP and HSP devices</li>
+<li>Support for RTP</li>
+<li>MTP/PTP file transfer</li>
+<li>DRM framework</li>
+<li>Input from keyboard, mouse, gamepad, joystick</li>
+</ul>
+
+<p>Enterprise</p>
+<ul>
+<li>Full device encryption</li>
+<li>DPM policies for encrypted storage and passwords</li>
+</ul>
+</div>
+</div>
+
+<h3 id="communication-dev">Communication and sharing</h3>
+
+<p>Android 4.0 extends social and sharing features to any application on the
+device. Applications can integrate contacts, profile data, and calendar events
+from any of the user’s activities or social networks.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Social API</strong></p>
+
+<p>A shared social provider and API provide a new unified store for contacts,
+profile data, status updates, and photos. Any app or social network with user
+permission can contribute raw contacts and make them accessible to other apps
+and networks. Applications with user permission can also read profile data from
+the provider and display it in their applications.</p>
+
+<p>The social API lets applications store standard contact data as well as new
+types of content for any given contact, including large profile photos and
+recent activity feedback. Recent activity feedback is a standard way for
+applications to “tag” a contact with common activity, such as when the user
+calls the contact or sends an email or SMS message. The social provider uses the
+recent activity feedback as a new signal in ranking, such as for name
+auto-complete, to keep the most relevant contacts ranked closest to the top.</p>
+
+<p>Applications can also let users set up a social connection to a contact from
+the People app. When the user touches Add Connection in a contact, the app
+broadcasts a public intent that other apps can handle, displaying any UI needed
+to create the social connection.</p>
+
+<p>Building on the social API, developers can add powerful new interactions that
+span multiple social networks and contacts sources.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Calendar API</strong></p>
+
+<p>A shared calendar content provider and framework API make it easier for
+developers to add calendar services to their apps.</p>
+
+<p>With user permission, any application can add events to the shared database
+and manage dates, attendees, alerts, and reminders. Applications can also read
+entries from the database, including events contributed by other applications,
+and handle the display of event alerts and reminders. Using the calendar
+provider, applications can take advantage of event data sourced from a variety
+of apps and protocols, to offer innovative ways of viewing and managing a user’s
+events. Apps can also use of calendar data to improve the relevance of their
+other content.</p>
+
+<p>For lighter-weight access to calendar services, the Calendar app defines a
+set of public Intents for creating, viewing, and editing events. Rather than
+needing to implement a calendar UI and integrate directly with the calendar
+provider, applications can simply broadcast calendar Intents. When the Calendar
+app receives the Intents, it launches the appropriate UI and stores any event
+data entered. Using calendar Intents, for example, apps can let users add events
+directly from lists, dialogs, or home screen widgets, such as for making
+restaurant reservations or booking time with friends.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Visual voicemail
+API</strong></p>
+
+<p>A shared Voicemail provider and API allow developers to build applications
+that contribute to a unified voicemail store. Voicemails are displayed and
+played in the call log tab of the platform’s Phone app.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Android Beam</strong></p>
+
+<p>Android Beam is an NFC-based feature that lets users instantly share
+information about the apps they are using, just by touching two NFC-enabled
+phones together. When the devices are in range — within a few centimeters
+— the system sets up an NFC connection and displays a sharing UI. To share
+whatever they are viewing with the other device, users just touch the screen.
+</p>
+
+<p>For developers, Android Beam is a new way of triggering almost any type of
+proximity-based interaction. For example, it can let users instantly exchange
+contacts, set up multiplayer gaming, join a chat or video call, share a photo or
+video, and more. The system provides the low-level NFC support and the sharing
+UI, while the foreground app provides lightweight data to transfer to the other
+device. Developers have complete control over the data that is shared and how it
+is handled, so almost any interaction is possible. For larger payloads,
+developers can even use Android Beam to initiate a connection and transfer the
+data over Bluetooth, without the need for user-visible pairing.</p>
+
+<p>Even if developers do not add custom interactions based on Android Beam they
+can still benefit from it being deeply integrated into Android. By default the
+system shares the app’s Android Market URL, so it’s easy for the user to
+download or purchase the app right away.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Modular sharing
+widget</strong></p>
+
+<p>The UI framework includes a new widget, ShareActionProvider, that lets
+developers quickly embed standard share functionality and UI in the Action Bar
+of their applications. Developers simply add ShareActionProvider to the menu and
+set an intent that describes the desired sharing action. The system handles the
+rest, building up the list of applications that can handle the share intent and
+dispatching the intent when the user chooses from the menu.</p>
+
+
+<h3 id="media-dev">New media capabilities</h3>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Low-level streaming
+multimedia</strong></p>
+
+<p>Android 4.0 provides a direct, efficient path for low-level streaming
+multimedia. The new path is ideal for applications that need to maintain
+complete control over media data before passing it to the platform for
+presentation. For example, media applications can now retrieve data from any
+source, apply proprietary encryption/decryption, and then send the data to the
+platform for display.</p>
+
+<p>Applications can now send processed data to the platform as a multiplexed
+stream of audio/video content in MPEG-2 transport stream format. The platform
+de-muxes, decodes, and renders the content. The audio track is rendered to the
+active audio device, while the video track is rendered to either a Surface or a
+SurfaceTexture. When rendering to a SurfaceTexture, the application can apply
+subsequent graphics effects to each frame using OpenGL.</p>
+
+<p>To support this low-level streaming, the platform introduces a new native API
+based on <a href="http://www.khronos.org/openmax/al/" target="_top">Khronos
+OpenMAX AL 1.0.1</a>. The API is implemented on the same underlying services as
+the platform’s existing OpenSL ES API, so developers can make use of both APIs
+together if needed. Tools support for low-level streaming multimedia will be
+available in an upcoming release of the Android NDK.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>New camera
+capabilities</strong></p>
+
+<p>Developers can take advantage of a variety of new camera features in Android
+4.0. ZSL exposure, continuous focus, and image zoom let apps capture better
+still and video images, including during video capture. Apps can even capture
+full-resolution snapshots while shooting video. Apps can now set custom metering
+regions in a camera preview, then manage white balance and exposure dynamically
+for those regions. For easier focusing and image processing, a face-detection
+service identifies and tracks faces in a preview and returns their screen
+coordinates.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Media effects for
+transforming images and video</strong></p>
+
+<p>A set of high-performance transformation filters let developers apply rich
+effects to any image passed as an OpenGL ES 2.0 texture. Developers can adjust
+color levels and brightness, change backgrounds, sharpen, crop, rotate, add lens
+distortion, and apply other effects. The transformations are processed by the
+GPU, so they are fast enough for processing image frames loaded from disk,
+camera, or video stream.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Audio remote
+controls</strong></p>
+
+<p>Android 4.0 adds a new audio remote control API that lets media applications
+integrate with playback controls that are displayed in a remote view. Media
+applications can integrate with a remote music playback control that’s built
+into in the platform’s lock screen, allowing users to control song selection and
+playback without having to unlock and navigate to the music app.</p>
+
+<p>Using the audio remote control API, any music or media app can register to
+receive media button events from the remote control and then manage play state
+accordingly. The application can also supply metadata to the remote control,
+such as album art or image, play state, track number and description, duration,
+genre, and more.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>New media codecs and
+containers</strong></p>
+
+<p>Android 4.0 adds support for additional media types and containers to give
+developers access to the formats they need. For high-quality compressed images,
+the media framework adds support for WebP content. For video, the framework now
+supports streaming VP8 content. For streaming multimedia, the framework supports
+HTTP Live streaming protocol version 3 and encoding of ADTS-contained AAC
+content. Additionally, developers can now use Matroska containers for Vorbis and
+VP8 content.</p>
+
+
+<h3 id="connectivity-dev">New types of connectivity</h3>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Wi-Fi Direct</strong></p>
+
+<p>Developers can use a framework API to discover and connect directly to nearby
+devices over a high-performance, secure Wi-Fi Direct connection. No internet
+connection or hotspot is needed.</p>
+
+<p>Wi-Fi Direct opens new opportunities for developers to add innovative
+features to their applications. Applications can use Wi-Fi Direct to share
+files, photos, or other media between devices or between a desktop computer and
+an Android-powered device. Applications could also use Wi-Fi Direct to stream
+media content from a peer device such as a digital television or audio player,
+connect a group of users for gaming, print files, and more.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Bluetooth Health Device
+Profile (HDP)</strong></p>
+
+<p>Developers can now build powerful medical applications that use Bluetooth to
+communicate with wireless devices and sensors in hospitals, fitness centers,
+homes, and elsewhere. Applications can collect and manage data from HDP source
+devices and transmit it to backend medical applications such as records systems,
+data analysis services, and others.</p>
+
+<p>Using a framework API, applications can use Bluetooth to discover nearby
+devices, establish reliable or streaming data channels, and manage data
+transmission. Applications can supply any IEEE 11073 Manager to retrieve and
+interpret health data from Continua-certified devices such as heart-rate
+monitors, blood meters, thermometers, and scales. </p>
+
+
+<h3 id="uicomp-dev">New UI components and capabilities</h3>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Layout
+enhancements</strong></p>
+
+<p>A new layout, GridLayout, improves the performance of Android applications by
+supporting flatter view hierarchies that are faster to layout and render.
+Because hierarchies are flatter, developers can also manage alignments between
+components that are visually related to each other even when they are not
+logically related, for precise control over application UI. GridLayout is also
+specifically designed to be configured by drag-and-drop design tools such as the
+ADT Plug-in for Eclipse.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>OpenGL ES texture
+views</strong></p>
+
+<p>A new TextureView object lets developers directly integrate OpenGL ES
+textures as rendering targets in a UI hierarchy. The object lets developers
+display and manipulate OpenGL ES rendering just as they would a normal view
+object in the hierarchy, including moving, transforming, and animating the view
+as needed. The TextureView object makes it easy for developers to embed camera
+preview, decoded video, OpenGL game scenes, and more. TextureView can be viewed
+as a more powerful version of the existing SurfaceView object, since it offers
+the same benefits of access to a GL rendering surface, with the added advantage
+of having that surface participate fully in the normal view hierarchy.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Hardware-accelerated 2D
+drawing</strong></p>
+
+<p>All Android-powered devices running Android 4.0 are required to support
+hardware-accelerated 2D drawing. Developers can take advantage of this to add
+great UI effects while maintaining optimal performance on high-resolution
+screens, even on phones. For example, developers can rely on accelerated
+scaling, rotation, and other 2D operations, as well as accelerated UI components
+such as TextureView and compositing modes such as filtering, blending, and
+opacity.</p>
+
+
+<h3 id="input-dev">New input types and text services</h3>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Stylus input, button
+support, hover events</strong></p>
+
+<p>Android 4.0 includes full support for stylus input events, including tilt and
+distance axes, pressure, and related motion event properties. To help
+applications distinguish motion events from different sources, the platform adds
+distinct tool types for stylus, finger, mouse, and eraser. For improved input
+from multi-button pointing devices, the platform now provides distinct primary,
+secondary, and tertiary buttons, as well as back and forward buttons.
+Hover-enter and hover-exit events are also added, for improved navigation and
+accessibility. Developers can build on these new input features to add powerful
+interactions to their apps, such as precise drawing and gesturing, handwriting
+and shape recognition, improved mouse input, and others.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Text services API for
+integrating spelling checkers</strong></p>
+
+<p>Android 4.0 lets applications query available text services such as
+dictionaries and spell checkers for word suggestions, corrections, and similar
+data. The text services are external to the active IME, so developers can create
+and distribute dictionaries and suggestion engines that plug into the platform.
+When an application receives results from a text service — for example,
+word suggestions — it can display them in a dedicated suggestion popup
+window directly inside the text view, rather than relying on the IME to display
+them. </p>
+
+
+<h3 id="accessibility-dev">Enhanced accessibility APIs</h3>
+
+<p>Android 4.0 adds new accessibility features and an enhanced API to let
+developers improve the user experience in their apps, especially on devices that
+don’t have hardware buttons. For accessibility services such as screen readers
+in particular, the platform offers new APIs to query window content, for easier
+navigation, better feedback, and richer user interfaces.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Accessibility
+API</strong></p>
+
+<p>To let applications manage interactions more effectively when accessibility
+features are enabled, the platform adds accessibility events for
+explore-by-touch mode, scrolling, and text selection. For these and other
+events, the platform can attach a new object called an accessibility record that
+provides extra information about the event context.</p>
+
+<p>Using the accessibility record and related APIs, applications can now access
+the view hierarchy associated with an event. Applications can query for key
+properties such as parent and child nodes, available states, supported actions,
+screen position, and more. Applications can also request changes to certain
+properties to help manage focus and selected state. For example, an
+accessibility service could use these new capabilities to add convenient
+features such as screen-search by text. </p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Text-to-speech
+API</strong></p>
+
+<p>A new framework API lets developers write text-to-speech engines and make
+them available to any app requesting TTS capabilities.</p>
+
+
+<h3 id="data-dev">Efficient network usage</h3>
+
+<p>In Android 4.0, users can see how much network data their running apps are
+using. They can also set limits on data usage by network type and disable
+background data usage for specific applications. In this context, developers
+need to design their apps to run efficiently and follow best practices for
+checking the network connection. Android 4.0 provides network APIs to let
+applications meet those goals.</p>
+
+<p>As users move between networks or set limits on network data, the platform
+lets applications query for connection type and availability. Developers can use
+this information to dynamically manage network requests to ensure the best
+experience for users. Developers can also build custom network and data-usage
+options into their apps, then expose them to users directly from Settings by
+means of a new system Intent.</p>
+
+
+<h3 id="security-dev">Security for apps and content</h3>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Secure management of
+credentials</strong></p>
+
+<p>Android 4.0 makes it easier for applications to manage authentication and
+secure sessions. A new keychain API and underlying encrypted storage let
+applications store and retrieve private keys and their corresponding certificate
+chains. Any application can use the keychain API to install and store user
+certificates and CAs securely.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Address Space Layout
+Randomization</strong></p>
+
+<p>Android 4.0 now provides address space layout randomization (ASLR) to help
+protect system and third party applications from exploitation due to
+memory-management issues.</p>
+
+
+<h3 id="enterprise-dev">Enhancements for Enterprise</h3>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>VPN client
+API</strong></p>
+
+<p>Developers can now build or extend their own VPN solutions on the platform
+using a new VPN API and underlying secure credential storage. With user
+permission, applications can configure addresses and routing rules, process
+outgoing and incoming packets, and establish secure tunnels to a remote server.
+Enterprises can also take advantage of a standard VPN client built into the
+platform that provides access to L2TP and IPSec protocols.</p>
+
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Device policy management
+for camera</strong></p>
+
+<p>The platform adds a new policy control for administrators who manage devices
+using an installed Device Policy Manager. Administrators can now remotely
+disable the camera on a managed device for users working in sensitive
+environments.</p>
+
+
+
+
+
diff --git a/docs/html/sdk/android-4.0.jd b/docs/html/sdk/android-4.0.jd
index 8f7ac55..da40d52 100644
--- a/docs/html/sdk/android-4.0.jd
+++ b/docs/html/sdk/android-4.0.jd
@@ -10,7 +10,7 @@
<ol>
<li><a href="#relnotes">Revisions</a></li>
<li><a href="#api">API Overview</a></li>
- <li><a href="#api-diff">API Differences Report</a></li>
+ <li><a href="#Honeycomb">Previous APIs</a></li>
<li><a href="#api-level">API Level</a></li>
<li><a href="#apps">Built-in Applications</a></li>
<li><a href="#locs">Locales</a></li>
@@ -30,14 +30,19 @@
<p><em>API Level:</em> <strong>{@sdkPlatformApiLevel}</strong></p>
-<p>Android 4.0 (Ice Cream Sandwich) is a major platform release that adds new
-capabilities for users and developers. The sections below provide an overview
-of the new features and developer APIs.</p>
+<p>Android 4.0 is a major platform release that adds a variety of new features for users and app
+developers. Besides all the new features and APIs discussed below, Android 4.0 is an important
+platform release because it brings the extensive set of APIs and Holographic themes from Android 3.x
+to smaller screens. As an app developer, you now have a single platform and unified API framework
+that enables you to develop and publish your application with a single APK that provides an
+optimized user experience for handsets, tablets, and more, when running the same version of
+Android—Android 4.0 (API level 14) or greater. </p>
-<p>For developers, the Android {@sdkPlatformVersion} platform is available as a
-downloadable component for the Android SDK. The downloadable platform includes
+<p>The Android {@sdkPlatformVersion} platform is available as a
+downloadable component for the Android SDK so you can begin developing and testing your
+applications on Android 4.0 with the Android emulator. The downloadable platform includes
an Android library and system image, as well as a set of emulator skins and
-more. The downloadable platform includes no external libraries.</p>
+more. The downloadable platform does not include any external libraries.</p>
<p>To start developing or testing against Android {@sdkPlatformVersion},
use the Android SDK Manager to download the platform into your SDK. For more
@@ -45,14 +50,15 @@
Components</a>. If you are new to Android, <a
href="{@docRoot}sdk/index.html">download the SDK Starter Package</a> first.</p>
-<p>For a high-level introduction to the new user and developer features in Android 4.0, see the
-<a href="http://developer.android.com/sdk/android-4.0-highlights.html">Platform Highlights</a>.</p>
-
<p class="note"><strong>Reminder:</strong> If you've already published an
Android application, please test your application on Android {@sdkPlatformVersion} as
soon as possible to be sure your application provides the best
experience possible on the latest Android-powered devices.</p>
+<p>For a high-level overview of the new user and developer features in Android 4.0, see the
+<a href="http://developer.android.com/sdk/android-4.0-highlights.html">Platform Highlights</a>.</p>
+
+
<h2 id="relnotes">Revisions</h2>
@@ -71,7 +77,12 @@
<div class="toggle-content-toggleme" style="padding-left:2em;">
<dl>
-<dt>Initial release. SDK Tools r14 or higher is recommended.</dt>
+<dt>Initial release. SDK Tools r14 or higher is required.
+ <p class="caution"><strong>Important:</strong> To download the new Android
+ 4.0 system components from the Android SDK Manager, you must first update the
+ SDK tools to revision 14 and restart the Android SDK Manager. If you do not,
+ the Android 4.0 system components will not be available for download.</p>
+</dt>
</dl>
</div>
@@ -92,23 +103,24 @@
<div class="toggle-content-toggleme" style="padding-left:2em;">
<ol class="toc" style="margin-left:-1em">
- <li><a href="#Contacts">Contacts</a></li>
- <li><a href="#Calendar">Calendar</a></li>
- <li><a href="#Camera">Camera</a></li>
+ <li><a href="#Contacts">Social APIs in Contacts Provider</a></li>
+ <li><a href="#Calendar">Calendar Provider</a></li>
+ <li><a href="#Voicemail">Voicemail Provider</a></li>
<li><a href="#Multimedia">Multimedia</a></li>
- <li><a href="#Bluetooth">Bluetooth</a></li>
+ <li><a href="#Camera">Camera</a></li>
<li><a href="#AndroidBeam">Android Beam (NDEF Push with NFC)</a></li>
- <li><a href="#P2pWiFi">Peer-to-peer Wi-Fi</a></li>
- <li><a href="#NetworkData">Network Data</a></li>
- <li><a href="#Sensors">Device Sensors</a></li>
- <li><a href="#Renderscript">Renderscript</a></li>
+ <li><a href="#WiFiDirect">Wi-Fi Direct</a></li>
+ <li><a href="#Bluetooth">Bluetooth Health Devices</a></li>
<li><a href="#A11y">Accessibility</a></li>
- <li><a href="#Enterprise">Enterprise</a></li>
- <li><a href="#Voicemail">Voicemail</a></li>
<li><a href="#SpellChecker">Spell Checker Services</a></li>
<li><a href="#TTS">Text-to-speech Engines</a></li>
+ <li><a href="#NetworkUsage">Network Usage</a></li>
+ <li><a href="#RenderScript">RenderScript</a></li>
+ <li><a href="#Enterprise">Enterprise</a></li>
+ <li><a href="#Sensors">Device Sensors</a></li>
<li><a href="#ActionBar">Action Bar</a></li>
<li><a href="#UI">User Interface and Views</a></li>
+ <li><a href="#Input">Input Framework</a></li>
<li><a href="#Properties">Properties</a></li>
<li><a href="#HwAccel">Hardware Acceleration</a></li>
<li><a href="#Jni">JNI Changes</a></li>
@@ -123,86 +135,95 @@
-<h3 id="Contacts">Contacts</h3>
+<h3 id="Contacts">Social APIs in Contacts Provider</h3>
-<p>The Contact APIs that are defined by the {@link android.provider.ContactsContract} provider have
-been extended to support new features such as a personal profile for the device owner, large contact
-photos, and the ability for users to invite individual contacts to social networks that are
-installed on the device.</p>
+<p>The contact APIs defined by the {@link android.provider.ContactsContract} provider have been
+extended to support new social-oriented features such as a personal profile for the device owner and
+the ability for users to invite individual contacts to social networks that are installed on the
+device.</p>
<h4>User Profile</h4>
<p>Android now includes a personal profile that represents the device owner, as defined by the
-{@link
-android.provider.ContactsContract.Profile} table. Social apps that maintain a user identity can
-contribute to the user's profile data by creating a new {@link
+{@link android.provider.ContactsContract.Profile} table. Social apps that maintain a user identity
+can contribute to the user's profile data by creating a new {@link
android.provider.ContactsContract.RawContacts} entry within the {@link
android.provider.ContactsContract.Profile}. That is, raw contacts that represent the device user do
not belong in the traditional raw contacts table defined by the {@link
android.provider.ContactsContract.RawContacts} Uri; instead, you must add a profile raw contact in
the table at {@link android.provider.ContactsContract.Profile#CONTENT_RAW_CONTACTS_URI}. Raw
-contacts in this table are then aggregated into the single user-visible profile information.</p>
+contacts in this table are then aggregated into the single user-visible profile labeled "Me".</p>
<p>Adding a new raw contact for the profile requires the {@link
android.Manifest.permission#WRITE_PROFILE} permission. Likewise, in order to read from the profile
table, you must request the {@link android.Manifest.permission#READ_PROFILE} permission. However,
-reading the user profile should not be required by most apps, even when contributing data to the
-profile. Reading the user profile is a sensitive permission and users will be very skeptical of apps
-that request reading their profile information.</p>
+most apps should need to read the user profile, even when contributing data to the
+profile. Reading the user profile is a sensitive permission and you should expect users to be
+skeptical of apps that request it.</p>
+
+
+<h4>Invite Intent</h4>
+
+<p>The {@link android.provider.ContactsContract.Intents#INVITE_CONTACT} intent action allows an app
+to invoke an action that indicates the user wants to add a contact to a social network. The app
+receiving the app uses it to invite the specified contact to that
+social network. Most apps will be on the receiving-end of this operation. For example, the
+built-in People app invokes the invite intent when the user selects "Add connection" for a specific
+social app that's listed in a person's contact details.</p>
+
+<p>To make your app visible as in the "Add connection" list, your app must provide a sync adapter to
+sync contact information from your social network. You must then indicate to the system that your
+app responds to the {@link android.provider.ContactsContract.Intents#INVITE_CONTACT} intent by
+adding the {@code inviteContactActivity} attribute to your app’s sync configuration file, with a
+fully-qualified name of the activity that the system should start when sending the invite intent.
+The activity that starts can then retrieve the URI for the contact in question from the intent’s
+data and perform the necessary work to invite that contact to the network or add the person to the
+user’s connections.</p>
+
+<p>See the <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">Sample Sync
+Adapter</a> app for an example (specifically, see the <a
+href="{@docRoot}resources/samples/SampleSyncAdapter/res/xml-v14/contacts.html">contacts.xml</a>
+file).</p>
+
<h4>Large photos</h4>
<p>Android now supports high resolution photos for contacts. Now, when you push a photo into a
-contact
-record, the system processes it into both a 96x96 thumbnail (as it has previously) and a 256x256
-"display photo" stored in a new file-based photo store (the exact dimensions that the system chooses
-may vary in the future). You can add a large photo to a contact by putting a large photo in the
-usual {@link android.provider.ContactsContract.CommonDataKinds.Photo#PHOTO} column of a data row,
-which the system will then process into the appropriate thumbnail and display photo records.</p>
+contact record, the system processes it into both a 96x96 thumbnail (as it has previously) and a
+256x256 "display photo" that's stored in a new file-based photo store (the exact dimensions that the
+system chooses may vary in the future). You can add a large photo to a contact by putting a large
+photo in the usual {@link android.provider.ContactsContract.CommonDataKinds.Photo#PHOTO} column of a
+data row, which the system will then process into the appropriate thumbnail and display photo
+records.</p>
-<h4>Invite Intent</h4>
-
-<p>The {@link android.provider.ContactsContract.Intents#INVITE_CONTACT} intent action allows you to
-invoke an action that indicates the user wants to add a contact to a social network that understand
-this intent and use it to invite the contact specified in the contact to that social network.</p>
-
-<p>Apps that use a sync adapter to provide information about contacts can register with the system
-to
-receive the invite intent when there’s an opportunity for the user to “invite” a contact to the
-app’s social network (such as from a contact card in the People app). To receive the invite intent,
-you simply need to add the {@code inviteContactActivity} attribute to your app’s XML sync
-configuration file, providing a fully-qualified name of the activity that the system should start
-when the user wants to “invite” a contact in your social network. The activity that starts can then
-retrieve the URI for the contact in question from the intent’s data and perform the necessary work
-to
-invite that contact to the network or add the person to the user’s connections.</p>
<h4>Contact Usage Feedback</h4>
<p>The new {@link android.provider.ContactsContract.DataUsageFeedback} APIs allow you to help track
how often the user uses particular methods of contacting people, such as how often the user uses
each phone number or e-mail address. This information helps improve the ranking for each contact
-method associated with each person and provide such contact methods as suggestions.</p>
+method associated with each person and provide better suggestions for contacting each person.</p>
-<h3 id="Calendar">Calendar</h3>
+<h3 id="Calendar">Calendar Provider</h3>
-<p>The new calendar API allows you to access and modify the user’s calendars and events. The
-calendar
-APIs are provided with the {@link android.provider.CalendarContract} provider. Using the calendar
-provider, you can:</p>
-<ul>
-<li>Read, write, and modify calendars.</li>
-<li>Add and modify events, attendees, reminders, and alarms.</li>
-</ul>
+<p>The new calendar APIs allow you to read, add, modify and delete calendars, events, attendees,
+reminders and alerts, which are stored in the Calendar Provider.</p>
-<p>{@link android.provider.CalendarContract} defines the data model of calendar and event-related
-information. All of the user’s calendar data is stored in a number of tables defined by subclasses
-of {@link android.provider.CalendarContract}:</p>
+<p>A variety of apps and widgets can use these APIs to read and modify calendar events. However,
+some of the most compelling use cases are sync adapters that synchronize the user's calendar from
+other calendar services with the Calendar Provider, in order to offer a unified location for all the
+user's events. Google Calendar events, for example, are synchronized with the Calendar Provider by
+the Google Calendar Sync Adapter, allowing these events to be viewed with Android's built-in
+Calendar app.</p>
+
+<p>The data model for calendars and event-related information in the Calendar Provider is
+defined by {@link android.provider.CalendarContract}. All the user’s calendar data is stored in a
+number of tables defined by various subclasses of {@link android.provider.CalendarContract}:</p>
<ul>
<li>The {@link android.provider.CalendarContract.Calendars} table holds the calendar-specific
@@ -210,11 +231,10 @@
color, sync information, and so on.</li>
<li>The {@link android.provider.CalendarContract.Events} table holds event-specific information.
-Each
-row in this table has the information for a single event. It contains information such as event
-title, location, start time, end time, and so on. The event can occur one-time or can recur multiple
-times. Attendees, reminders, and extended properties are stored in separate tables and reference the
-event’s _ID to link them with the event.</li>
+Each row in this table contains the information for a single event, such as the
+event title, location, start time, end time, and so on. The event can occur one time or recur
+multiple times. Attendees, reminders, and extended properties are stored in separate tables and
+use the event’s {@code _ID} to link them with the event.</li>
<li>The {@link android.provider.CalendarContract.Instances} table holds the start and end time for
occurrences of an event. Each row in this table represents a single occurrence. For one-time events
@@ -223,175 +243,155 @@
<li>The {@link android.provider.CalendarContract.Attendees} table holds the event attendee or guest
information. Each row represents a single guest of an event. It specifies the type of guest the
-person is and the person’s attendance response for the event.</li>
+person is and the person’s response for the event.</li>
<li>The {@link android.provider.CalendarContract.Reminders} table holds the alert/notification data.
Each row represents a single alert for an event. An event can have multiple reminders. The number of
-reminders per event is specified in MAX_REMINDERS, which is set by the Sync Adapter that owns the
-given calendar. Reminders are specified in minutes before the event and have a type.</li>
+reminders per event is specified in {@code MAX_REMINDERS}, which is set by the sync adapter that
+owns the given calendar. Reminders are specified in number-of-minutes before the event is
+scheduled and specify an alarm method such as to use an alert, email, or SMS to remind
+the user.</li>
<li>The {@link android.provider.CalendarContract.ExtendedProperties} table hold opaque data fields
-used
-by the sync adapter. The provider takes no action with items in this table except to delete them
-when their related events are deleted.</li>
+used by the sync adapter. The provider takes no action with items in this table except to delete
+them when their related events are deleted.</li>
</ul>
-<p>To access a user’s calendar data with the calendar provider, your application must request
-permission from the user by declaring <uses-permission
-android:name="android.permission.READ_CALENDAR" /> (for read access) and <uses-permission
-android:name="android.permission.WRITE_CALENDAR" /> (for write access) in their manifest files.</p>
-
-<p>However, if all you want to do is add an event to the user’s calendar, you can instead use an
-INSERT
-{@link android.content.Intent} to start an activity in the Calendar app that creates new events.
-Using the intent does not require the WRITE_CALENDAR permission and you can specify the {@link
-android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME} and {@link
-android.provider.CalendarContract#EXTRA_EVENT_END_TIME} extra fields to pre-populate the form with
-the time of the event. The values for these times must be in milliseconds from the epoch. You must
-also specify {@code “vnd.android.cursor.item/event”} as the intent type.</p>
+<p>To access a user’s calendar data with the Calendar Provider, your application must request
+the {@link android.Manifest.permission#READ_CALENDAR} permission (for read access) and
+{@link android.Manifest.permission#WRITE_CALENDAR} (for write access).</p>
+<h4>Event intent</h4>
-
-
-<h3 id="Camera">Camera</h3>
-
-<p>The {@link android.hardware.Camera} APIs now support face detection and control for metering and
-focus areas.</p>
-
-<h4>Face Detection</h4>
-
-<p>Camera apps can now enhance their abilities with Android’s face detection software, which not
-only
-detects the face of a subject, but also specific facial features, such as the eyes and mouth. </p>
-
-<p>To detect faces in your camera application, you must register a {@link
-android.hardware.Camera.FaceDetectionListener} by calling {@link
-android.hardware.Camera#setFaceDetectionListener setFaceDetectionListener()}. You can then start
-your camera surface and start detecting faces by calling {@link
-android.hardware.Camera#startFaceDetection}.</p>
-
-<p>When the system detects a face, it calls the {@link
-android.hardware.Camera.FaceDetectionListener#onFaceDetection onFaceDetection()} callback in your
-implementation of {@link android.hardware.Camera.FaceDetectionListener}, including an array of
-{@link android.hardware.Camera.Face} objects.</p>
-
-<p>An instance of the {@link android.hardware.Camera.Face} class provides various information about
-the
-face detected by the camera, including:</p>
-<ul>
-<li>A {@link android.graphics.Rect} that specifies the bounds of the face, relative to the camera's
-current field of view</li>
-<li>An integer betwen 0 and 100 that indicates how confident the system is that the object is a
-human
-face</li>
-<li>A unique ID so you can track multiple faces</li>
-<li>Several {@link android.graphics.Point} objects that indicate where the eyes and mouth are
-located</li>
-</ul>
-
-
-<h4>Focus and Metering Areas</h4>
-
-<p>Camera apps can now control the areas that the camera uses for focus and when metering white
-balance
-and auto-exposure (when supported by the hardware). Both features use the new {@link
-android.hardware.Camera.Area} class to specify the region of the camera’s current view that should
-be focused or metered. An instance of the {@link android.hardware.Camera.Area} class defines the
-bounds of the area with a {@link android.graphics.Rect} and the weight of the
-area—representing the level of importance of that area, relative to other areas in
-consideration—with an integer.</p>
-
-<p>Before setting either a focus area or metering area, you should first call {@link
-android.hardware.Camera.Parameters#getMaxNumFocusAreas} or {@link
-android.hardware.Camera.Parameters#getMaxNumMeteringAreas}, respectively. If these return zero, then
-the device does not support the respective feature. </p>
-
-<p>To specify the focus or metering areas to use, simply call {@link
-android.hardware.Camera.Parameters#setFocusAreas setFocusAreas()} or {@link
-android.hardware.Camera.Parameters#setFocusAreas setMeteringAreas()}. Each take a {@link
-java.util.List} of {@link android.hardware.Camera.Area} objects that indicate the areas to consider
-for focus or metering. For example, you might implement a feature that allows the user to set the
-focus area by touching an area of the preview, which you then translate to an {@link
-android.hardware.Camera.Area} object and set the focus to that spot. The focus or exposure in that
-area will continually update as the scene in the area changes.</p>
-
-
-<h4>Other Camera Features</h4>
-<ul>
-<li>Capture photos during video recording
-While recording video, you can now call {@link android.hardware.Camera#takePicture takePicture()} to
-save a photo without interrupting the video session. Before doing so, you should call {@link
-android.hardware.Camera.Parameters#isVideoSnapshotSupported} to be sure the hardware supports
-it.</li>
-
-<li>Lock auto exposure and white balance with {@link
-android.hardware.Camera.Parameters#setAutoExposureLock setAutoExposureLock()} and {@link
-android.hardware.Camera.Parameters#setAutoWhiteBalanceLock setAutoWhiteBalanceLock()}, to prevent
-these properties from changing.</li>
-</ul>
-
-<h4>Camera Broadcast Intents</h4>
+<p>If all you want to do is add an event to the user’s calendar, you can use an
+{@link android.content.Intent#ACTION_INSERT} intent with a {@code "vnd.android.cursor.item/event"}
+MIME type to start an activity in the Calendar app that creates new events. Using the intent does
+not require any permission and you can specify event details with the following extras:</p>
<ul>
-<li>{@link android.hardware.Camera#ACTION_NEW_PICTURE Camera.ACTION_NEW_PICTURE}
-This indicates that the user has captured a new photo. The built-in camera app invokes this
-broadcast after a photo is captured and third-party camera apps should also broadcast this intent
-after capturing a photo.</li>
-<li>{@link android.hardware.Camera#ACTION_NEW_VIDEO Camera.ACTION_NEW_VIDEO}
-This indicates that the user has captured a new video. The built-in camera app invokes this
-broadcast after a video is recorded and third-party camera apps should also broadcast this intent
-after capturing a video.</li>
+ <li>{@link android.provider.CalendarContract.EventsColumns#TITLE Events.TITLE}: Name for the
+event</li>
+ <li>{@link
+android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}:
+Event begin time in milliseconds from the
+epoch</li>
+ <li>{@link
+android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}: Event
+end time in milliseconds from the epoch</li>
+ <li>{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION Events.EVENT_LOCATION}:
+Location of the event</li>
+ <li>{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION Events.DESCRIPTION}: Event
+description</li>
+ <li>{@link android.content.Intent#EXTRA_EMAIL Intent.EXTRA_EMAIL}: Email addresses of those to
+invite</li>
+ <li>{@link android.provider.CalendarContract.EventsColumns#RRULE Events.RRULE}: The recurrence
+rule for the event</li>
+ <li>{@link android.provider.CalendarContract.EventsColumns#ACCESS_LEVEL Events.ACCESS_LEVEL}:
+Whether the event is private or public</li>
+ <li>{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY Events.AVAILABILITY}:
+Whether the time period of this event allows for other events to be scheduled at the same time</li>
</ul>
-
-
-
+
+
+<h3 id="Voicemail">Voicemail Provider</h3>
+
+<p>The new Voicemail Provider allows applications to add voicemails to the
+device, in order to present all the user's voicemails in a single visual presentation. For instance,
+it’s possible that a user has multiple voicemail sources, such as
+one from the phone’s service provider and others from VoIP or other alternative voice
+services. These apps can use the Voicemail Provider APIs to add their voicemails to the device. The
+built-in Phone application then presents all voicemails to the user in a unified presentation.
+Although the system’s Phone application is the only application that can read all the voicemails,
+each application that provides voicemails can read those that it has added to the system (but cannot
+read voicemails from other services).</p>
+
+<p>Because the APIs currently do not allow third-party apps to read all the voicemails from the
+system, the only third-party apps that should use the voicemail APIs are those that have voicemail
+to deliver to the user.</p>
+
+<p>The {@link android.provider.VoicemailContract} class defines the content provider for the
+Voicemail Provder. The subclasses {@link android.provider.VoicemailContract.Voicemails} and {@link
+android.provider.VoicemailContract.Status} provide tables in which apps can
+insert voicemail data for storage on the device. For an example of a voicemail provider app, see the
+<a href="{@docRoot}resources/samples/VoicemailProviderDemo/index.html">Voicemail Provider
+Demo</a>.</p>
+
+
+
+
+
<h3 id="Multimedia">Multimedia</h3>
<p>Android 4.0 adds several new APIs for applications that interact with media such as photos,
-videos,
-and music.</p>
+videos, and music.</p>
-<h4>Media Player</h4>
+<h4>Media Effects</h4>
-<ul>
-<li>Streaming online media from {@link android.media.MediaPlayer} now requires {@link
-android.Manifest.permission#INTERNET} permission. If you use {@link android.media.MediaPlayer} to
-play content from the internet, be sure to add the {@link android.Manifest.permission#INTERNET}
-permission or else your media playback will not work beginning with Android 4.0.</li>
-<li>{@link android.media.MediaPlayer#setSurface(Surface) setSurface()} allows you define a {@link
-android.view.Surface} to behave as the video sink.</li>
-<li>{@link android.media.MediaPlayer#setDataSource(Context,Uri,Map) setDataSource()} allows you to
-send additional HTTP headers with your request, which can be useful for HTTP(S) live streaming</li>
-<li>HTTP(S) live streaming now respects HTTP cookies across requests</li>
-</ul>
+<p>A new media effects framework allows you to apply a variety of visual effects to images and
+videos. For example, image effects allow you to easily fix red-eye, convert an image to grayscale,
+adjust brightness, adjust saturation, rotate an image, apply a fisheye effect, and much more. The
+system performs all effects processing on the GPU to obtain maximum performance.</p>
-<h4>Media Type Support</h4>
+<p>For maximum performance, effects are applied directly to OpenGL textures, so your application
+must have a valid OpenGL context before it can use the effects APIs. The textures to which you apply
+effects may be from bitmaps, videos or even the camera. However, there are certain restrictions that
+textures must meet:</p>
+<ol>
+<li>They must be bound to a {@link android.opengl.GLES20#GL_TEXTURE_2D} texture image</li>
+<li>They must contain at least one mipmap level</li>
+</ol>
-<p>Android 4.0 adds support for:</p>
-<ul>
-<li>HTTP/HTTPS live streaming protocol version 3 </li>
-<li>ADTS raw AAC audio encoding</li>
-<li>WEBP images</li>
-<li>Matroska video</li>
-</ul>
-<p>For more info, see <a href=”{@docRoot}guide/appendix/media-formats.html”>Supported Media
-Formats</a>.</p>
+<p>An {@link android.media.effect.Effect} object defines a single media effect that you can apply to
+an image frame. The basic workflow to create an {@link android.media.effect.Effect} is:</p>
+
+<ol>
+<li>Call {@link android.media.effect.EffectContext#createWithCurrentGlContext
+EffectContext.createWithCurrentGlContext()} from your OpenGL ES 2.0 context.</li>
+<li>Use the returned {@link android.media.effect.EffectContext} to call {@link
+android.media.effect.EffectContext#getFactory EffectContext.getFactory()}, which returns an instance
+of {@link android.media.effect.EffectFactory}.</li>
+<li>Call {@link android.media.effect.EffectFactory#createEffect createEffect()}, passing it an
+effect name from @link android.media.effect.EffectFactory}, such as {@link
+android.media.effect.EffectFactory#EFFECT_FISHEYE} or {@link
+android.media.effect.EffectFactory#EFFECT_VIGNETTE}.</li>
+</ol>
+
+<p>You can adjust an effect’s parameters by calling {@link android.media.effect.Effect#setParameter
+setParameter()} and passing a parameter name and parameter value. Each type of effect accepts
+different parameters, which are documented with the effect name. For example, {@link
+android.media.effect.EffectFactory#EFFECT_FISHEYE} has one parameter for the {@code scale} of the
+distortion.</p>
+
+<p>To apply an effect on a texture, call {@link android.media.effect.Effect#apply apply()} on the
+{@link
+android.media.effect.Effect} and pass in the input texture, it’s width and height, and the output
+texture. The input texture must be bound to a {@link android.opengl.GLES20#GL_TEXTURE_2D} texture
+image (usually done by calling the {@link android.opengl.GLES20#glTexImage2D glTexImage2D()}
+function). You may provide multiple mipmap levels. If the output texture has not been bound to a
+texture image, it will be automatically bound by the effect as a {@link
+android.opengl.GLES20#GL_TEXTURE_2D} and with one mipmap level (0), which will have the same
+size as the input.</p>
+
+<p>All effects listed in {@link android.media.effect.EffectFactory} are guaranteed to be supported.
+However, some additional effects available from external libraries are not supported by all devices,
+so you must first check if the desired effect from the external library is supported by calling
+{@link android.media.effect.EffectFactory#isEffectSupported isEffectSupported()}.</p>
-<h4>Remote Control Client</h4>
+<h4>Remote control client</h4>
<p>The new {@link android.media.RemoteControlClient} allows media players to enable playback
-controls
-from remote control clients such as the device lock screen. Media players can also expose
+controls from remote control clients such as the device lock screen. Media players can also expose
information about the media currently playing for display on the remote control, such as track
information and album art.</p>
<p>To enable remote control clients for your media player, instantiate a {@link
-android.media.RemoteControlClient} with a {@link android.app.PendingIntent} that broadcasts {@link
+android.media.RemoteControlClient} with its constructor, passing it a {@link
+android.app.PendingIntent} that broadcasts {@link
android.content.Intent#ACTION_MEDIA_BUTTON}. The intent must also declare the explicit {@link
android.content.BroadcastReceiver} component in your app that handles the {@link
android.content.Intent#ACTION_MEDIA_BUTTON} event.</p>
@@ -418,107 +418,168 @@
android.media.MediaMetadataRetriever}.</p>
<p>For a sample implementation, see the <a
-href=”{@docRoot}resources/samples/RandomMusicPlayer/index.html”>Random Music Player</a>, which
-provides compatibility logic such that it enables the remote control client while continuing to
-support Android 2.1 devices.</p>
+href="{@docRoot}resources/samples/RandomMusicPlayer/index.html">Random Music Player</a>, which
+provides compatibility logic such that it enables the remote control client on Android 4.0
+devices while continuing to support devices back to Android 2.1.</p>
-<h4>Media Effects</h4>
+<h4>Media player</h4>
-<p>A new media effects framework allows you to apply a variety of visual effects to images and
-videos.
-The system performs all effects processing on the GPU to obtain maximum performance. Applications in
-Android 4.0 such as Google Talk or the Gallery editor make use of the effects API to apply real-time
-effects to video and photos.</p>
-
-<p>For maximum performance, effects are applied directly to OpenGL textures, so your application
-must
-have a valid OpenGL context before it can use the effects APIs. The textures to which you apply
-effects may be from bitmaps, videos or even the camera. However, there are certain restrictions that
-textures must meet:</p>
-<ol>
-<li>They must be bound to a {@link android.opengl.GLES20#GL_TEXTURE_2D} texture image</li>
-<li>They must contain at least one mipmap level</li>
-</ol>
-
-<p>An {@link android.media.effect.Effect} object defines a single media effect that you can apply to
-an
-image frame. The basic workflow to create an {@link android.media.effect.Effect} is:</p>
-
-<ol>
-<li>Call {@link android.media.effect.EffectContext#createWithCurrentGlContext
-EffectContext.createWithCurrentGlContext()} from your OpenGL ES 2.0 context.</li>
-<li>Use the returned {@link android.media.effect.EffectContext} to call {@link
-android.media.effect.EffectContext#getFactory EffectContext.getFactory()}, which returns an instance
-of {@link android.media.effect.EffectFactory}.</li>
-<li>Call {@link android.media.effect.EffectFactory#createEffect createEffect()}, passing it an
-effect
-name from @link android.media.effect.EffectFactory}, such as {@link
-android.media.effect.EffectFactory#EFFECT_FISHEYE} or {@link
-android.media.effect.EffectFactory#EFFECT_VIGNETTE}.</li>
-</ol>
-
-<p>Not all devices support all effects, so you must first check if the desired effect is supported
-by
-calling {@link android.media.effect.EffectFactory#isEffectSupported isEffectSupported()}.</p>
-
-<p>You can adjust the effect’s parameters by calling {@link android.media.effect.Effect#setParameter
-setParameter()} and passing a parameter name and parameter value. Each type of effect accepts
-different parameters, which are documented with the effect name. For example, {@link
-android.media.effect.EffectFactory#EFFECT_FISHEYE} has one parameter for the {@code scale} of the
-distortion.</p>
-
-<p>To apply an effect on a texture, call {@link android.media.effect.Effect#apply apply()} on the
-{@link
-android.media.effect.Effect} and pass in the input texture, it’s width and height, and the output
-texture. The input texture must be bound to a {@link android.opengl.GLES20#GL_TEXTURE_2D} texture
-image (usually done by calling the {@link android.opengl.GLES20#glTexImage2D glTexImage2D()}
-function). You may provide multiple mipmap levels. If the output texture has not been bound to a
-texture image, it will be automatically bound by the effect as a {@link
-android.opengl.GLES20#GL_TEXTURE_2D}. It will contain one mipmap level (0), which will have the same
-size as the input.</p>
-
-
-
-
-
-
-
-<h3 id="Bluetooth">Bluetooth</h3>
-
-<p>Android now supports Bluetooth Health Profile devices, so you can create applications that use
-Bluetooth to communicate with health devices that support Bluetooth, such as heart-rate monitors,
-blood meters, thermometers, and scales.</p>
-
-<p>Similar to regular headset and A2DP profile devices, you must call {@link
-android.bluetooth.BluetoothAdapter#getProfileProxy getProfileProxy()} with a {@link
-android.bluetooth.BluetoothProfile.ServiceListener} and the {@link
-android.bluetooth.BluetoothProfile#HEALTH} profile type to establish a connection with the profile
-proxy object.</p>
-
-<p>Once you’ve acquired the Health profile proxy (the {@link android.bluetooth.BluetoothHealth}
-object), connecting to and communicating with paired health devices involves the following new
-Bluetooth classes:</p>
<ul>
-<li>{@link android.bluetooth.BluetoothHealthCallback}: You must extend this class and implement the
-callback methods to receive updates about changes in the application’s registration state and
-Bluetooth channel state.</li>
-<li>{@link android.bluetooth.BluetoothHealthAppConfiguration}: During callbacks to your {@link
-android.bluetooth.BluetoothHealthCallback}, you’ll receive an instance of this object, which
-provides configuration information about the available Bluetooth health device, which you must use
-to perform various operations such as initiate and terminate connections with the {@link
-android.bluetooth.BluetoothHealth} APIs.</li>
+<li>Streaming online media from {@link android.media.MediaPlayer} now requires the {@link
+android.Manifest.permission#INTERNET} permission. If you use {@link android.media.MediaPlayer} to
+play content from the Internet, be sure to add the {@link android.Manifest.permission#INTERNET}
+permission to your manifest or else your media playback will not work beginning with Android
+4.0.</li>
+
+<li>{@link android.media.MediaPlayer#setSurface(Surface) setSurface()} allows you define a {@link
+android.view.Surface} to behave as the video sink.</li>
+
+<li>{@link android.media.MediaPlayer#setDataSource(Context,Uri,Map) setDataSource()} allows you to
+send additional HTTP headers with your request, which can be useful for HTTP(S) live streaming</li>
+
+<li>HTTP(S) live streaming now respects HTTP cookies across requests</li>
</ul>
-<p>For more information about using the Bluetooth Health profile, see the documentation for {@link
-android.bluetooth.BluetoothHealth}.</p>
+
+<h4>Media types</h4>
+
+<p>Android 4.0 adds support for:</p>
+<ul>
+<li>HTTP/HTTPS live streaming protocol version 3 </li>
+<li>ADTS raw AAC audio encoding</li>
+<li>WEBP images</li>
+<li>Matroska video</li>
+</ul>
+<p>For more info, see <a href="{@docRoot}guide/appendix/media-formats.html">Supported Media
+Formats</a>.</p>
+
+
+
+
+
+<h3 id="Camera">Camera</h3>
+
+<p>The {@link android.hardware.Camera} class now includes APIs for detecting faces and controlling
+focus and metering areas.</p>
+
+
+<h4>Face detection</h4>
+
+<p>Camera apps can now enhance their abilities with Android’s face detection APIs, which not
+only detect the face of a subject, but also specific facial features, such as the eyes and mouth.
+</p>
+
+<p>To detect faces in your camera application, you must register a {@link
+android.hardware.Camera.FaceDetectionListener} by calling {@link
+android.hardware.Camera#setFaceDetectionListener setFaceDetectionListener()}. You can then start
+your camera surface and start detecting faces by calling {@link
+android.hardware.Camera#startFaceDetection}.</p>
+
+<p>When the system detects one or more faces in the camera scene, it calls the {@link
+android.hardware.Camera.FaceDetectionListener#onFaceDetection onFaceDetection()} callback in your
+implementation of {@link android.hardware.Camera.FaceDetectionListener}, including an array of
+{@link android.hardware.Camera.Face} objects.</p>
+
+<p>An instance of the {@link android.hardware.Camera.Face} class provides various information about
+the face detected, including:</p>
+<ul>
+<li>A {@link android.graphics.Rect} that specifies the bounds of the face, relative to the camera's
+current field of view</li>
+<li>An integer betwen 1 and 100 that indicates how confident the system is that the object is a
+human face</li>
+<li>A unique ID so you can track multiple faces</li>
+<li>Several {@link android.graphics.Point} objects that indicate where the eyes and mouth are
+located</li>
+</ul>
+
+<p class="note"><strong>Note:</strong> Face detection may not be supported on some
+devices, so you should check by calling {@link
+android.hardware.Camera.Parameters#getMaxNumDetectedFaces()} and ensure the return
+value is greater than zero. Also, some devices may not support identification of eyes and mouth,
+in which case, those fields in the {@link android.hardware.Camera.Face} object will be null.</p>
+
+
+<h4>Focus and metering areas</h4>
+
+<p>Camera apps can now control the areas that the camera uses for focus and for metering white
+balance
+and auto-exposure. Both features use the new {@link android.hardware.Camera.Area} class to specify
+the region of the camera’s current view that should be focused or metered. An instance of the {@link
+android.hardware.Camera.Area} class defines the bounds of the area with a {@link
+android.graphics.Rect} and the area's weight—representing the level of importance of that
+area, relative to other areas in consideration—with an integer.</p>
+
+<p>Before setting either a focus area or metering area, you should first call {@link
+android.hardware.Camera.Parameters#getMaxNumFocusAreas} or {@link
+android.hardware.Camera.Parameters#getMaxNumMeteringAreas}, respectively. If these return zero, then
+the device does not support the corresponding feature.</p>
+
+<p>To specify the focus or metering areas to use, simply call {@link
+android.hardware.Camera.Parameters#setFocusAreas setFocusAreas()} or {@link
+android.hardware.Camera.Parameters#setFocusAreas setMeteringAreas()}. Each take a {@link
+java.util.List} of {@link android.hardware.Camera.Area} objects that indicate the areas to consider
+for focus or metering. For example, you might implement a feature that allows the user to set the
+focus area by touching an area of the preview, which you then translate to an {@link
+android.hardware.Camera.Area} object and request that the camera focus on that area of the scene.
+The focus or exposure in that area will continually update as the scene in the area changes.</p>
+
+
+<h4>Continuous auto focus for photos</h4>
+
+<p>You can now enable continuous auto focusing (CAF) when taking photos. To enable CAF in your
+camera app, pass {@link android.hardware.Camera.Parameters#FOCUS_MODE_CONTINUOUS_PICTURE}
+to {@link android.hardware.Camera.Parameters#setFocusMode setFocusMode()}. When ready to capture
+a photo, call {@link android.hardware.Camera#autoFocus autoFocus()}. Your {@link
+android.hardware.Camera.AutoFocusCallback} immediately receives a callback to indicate whether
+focus was achieved. To resume CAF after receiving the callback, you must call {@link
+android.hardware.Camera#cancelAutoFocus()}.</p>
+
+<p class="note"><strong>Note:</strong> Continuous auto focus is also supported when capturing
+video, using {@link android.hardware.Camera.Parameters#FOCUS_MODE_CONTINUOUS_VIDEO}, which was
+added in API level 9.</p>
+
+
+<h4>Other camera features</h4>
+
+<ul>
+<li>While recording video, you can now call {@link android.hardware.Camera#takePicture
+takePicture()} to save a photo without interrupting the video session. Before doing so, you should
+call {@link android.hardware.Camera.Parameters#isVideoSnapshotSupported} to be sure the hardware
+supports it.</li>
+
+<li>You can now lock auto exposure and white balance with {@link
+android.hardware.Camera.Parameters#setAutoExposureLock setAutoExposureLock()} and {@link
+android.hardware.Camera.Parameters#setAutoWhiteBalanceLock setAutoWhiteBalanceLock()} to prevent
+these properties from changing.</li>
+
+<li>You can now call {@link android.hardware.Camera#setDisplayOrientation
+setDisplayOrientation()} while the camera preview is running. Previously, you could call this
+only before beginning the preview, but you can now change the orientation at any time.</li>
+</ul>
+
+
+<h4>Camera broadcast intents</h4>
+
+<ul>
+<li>{@link android.hardware.Camera#ACTION_NEW_PICTURE Camera.ACTION_NEW_PICTURE}:
+This indicates that the user has captured a new photo. The built-in Camera app invokes this
+broadcast after a photo is captured and third-party camera apps should also broadcast this intent
+after capturing a photo.</li>
+<li>{@link android.hardware.Camera#ACTION_NEW_VIDEO Camera.ACTION_NEW_VIDEO}:
+This indicates that the user has captured a new video. The built-in Camera app invokes this
+broadcast after a video is recorded and third-party camera apps should also broadcast this intent
+after capturing a video.</li>
+</ul>
+
+
+
<h3 id="AndroidBeam">Android Beam (NDEF Push with NFC)</h3>
-<p>Android Beam allows you to send NDEF messages (an NFC standard for data stored on NFC tags) from
-one
-device to another (a process also known as “NDEF Push”). The data transfer is initiated when two
+<p>Android Beam is a new NFC feature that allows you to send NDEF messages from one device to
+another (a process also known as “NDEF Push"). The data transfer is initiated when two
Android-powered devices that support Android Beam are in close proximity (about 4 cm), usually with
their backs touching. The data inside the NDEF message can contain any data that you wish to share
between devices. For example, the People app shares contacts, YouTube shares videos, and Browser
@@ -526,29 +587,30 @@
<p>To transmit data between devices using Android Beam, you need to create an {@link
android.nfc.NdefMessage} that contains the information you want to share while your activity is in
-the foreground. You must then pass the
-{@link android.nfc.NdefMessage} to the system in one of two ways:</p>
+the foreground. You must then pass the {@link android.nfc.NdefMessage} to the system in one of two
+ways:</p>
<ul>
-<li>Define a single {@link android.nfc.NdefMessage} to use from the activity:
+<li>Define a single {@link android.nfc.NdefMessage} to push while in the activity:
<p>Call {@link android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()} at any time to set
-the
-message you want to send. For instance, you might call this method and pass it your {@link
+the message you want to send. For instance, you might call this method and pass it your {@link
android.nfc.NdefMessage} during your activity’s {@link android.app.Activity#onCreate onCreate()}
-method. Then, whenever Android Beam is activated with another device while your activity is in the
-foreground, the system sends that {@link android.nfc.NdefMessage} to the other device.</p></li>
+method. Then, whenever Android Beam is activated with another device while the activity is in the
+foreground, the system sends the {@link android.nfc.NdefMessage} to the other device.</p></li>
-<li>Define the {@link android.nfc.NdefMessage} depending on the current context:
-<p>Implement {@link android.nfc.NfcAdapter.CreateNdefMessageCallback}, in which the {@link
-android.nfc.NfcAdapter.CreateNdefMessageCallback#createNdefMessage createNdefMessage()} callback
+<li>Define the {@link android.nfc.NdefMessage} to push at the time that Android Beam is initiated:
+<p>Implement {@link android.nfc.NfcAdapter.CreateNdefMessageCallback}, in which your
+implementation of the {@link
+android.nfc.NfcAdapter.CreateNdefMessageCallback#createNdefMessage createNdefMessage()}
method returns the {@link android.nfc.NdefMessage} you want to send. Then pass the {@link
-android.nfc.NfcAdapter.CreateNdefMessageCallback} to {@link
-android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()}. In this case, when
-Android Beam is activated with another device while your activity is in the foreground, the system
-calls {@link android.nfc.NfcAdapter.CreateNdefMessageCallback#createNdefMessage createNdefMessage()}
-to retrieve the {@link android.nfc.NdefMessage} you want to send. This allows you to create a
-different {@link android.nfc.NdefMessage} for each occurrence, depending on the user context (such
-as which contact in the People app is currently visible).</p></li>
+android.nfc.NfcAdapter.CreateNdefMessageCallback} implementation to {@link
+android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()}.</p>
+<p>In this case, when Android Beam is activated with another device while your activity is in the
+foreground, the system calls {@link
+android.nfc.NfcAdapter.CreateNdefMessageCallback#createNdefMessage createNdefMessage()} to retrieve
+the {@link android.nfc.NdefMessage} you want to send. This allows you to define the {@link
+android.nfc.NdefMessage} to deliver only once Android Beam is initiated, in case the contents
+of the message might vary throughout the life of the activity.</p></li>
</ul>
<p>In case you want to run some specific code once the system has successfully delivered your NDEF
@@ -562,9 +624,9 @@
tags. The system invokes an intent with the {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED}
action to start an activity, with either a URL or a MIME type set according to the first {@link
android.nfc.NdefRecord} in the {@link android.nfc.NdefMessage}. For the activity you want to
-respond, you can set intent filters for the URLs or MIME types your app cares about. For more
+respond, you can declare intent filters for the URLs or MIME types your app cares about. For more
information about Tag Dispatch see the <a
-href=”{@docRoot}guide/topics/nfc/index.html#dispatch”>NFC</a> developer guide.</p>
+href="{@docRoot}guide/topics/nfc/index.html#dispatch">NFC</a> developer guide.</p>
<p>If you want your {@link android.nfc.NdefMessage} to carry a URI, you can now use the convenience
method {@link android.nfc.NdefRecord#createUri createUri} to construct a new {@link
@@ -573,46 +635,54 @@
should create an intent filter for your activity using the same URI scheme in order to receive the
incoming NDEF message.</p>
-<p>You may also want to pass an “Android application record” with your {@link
-android.nfc.NdefMessage}
-in order to guarantee a specific application handles an NDEF message, regardless of whether other
-applications filter for the same intent. You can create an Android application record by calling
-{@link android.nfc.NdefRecord#createApplicationRecord createApplicationRecord()}, passing it the
-application’s package name. When the other device receives the NDEF message with this record, the
-system automatically starts the application matching the package name. If the target device does not
-currently have the application installed, the system uses the Android application record to launch
-Android Market and take the user to the application to install it.</p>
+<p>You should also pass an “Android application record" with your {@link android.nfc.NdefMessage} in
+order to guarantee that your application handles the incoming NDEF message, even if other
+applications filter for the same intent action. You can create an Android application record by
+calling {@link android.nfc.NdefRecord#createApplicationRecord createApplicationRecord()}, passing it
+your application’s package name. When the other device receives the NDEF message with the
+application record and multiple applications contain activities that handle the specified intent,
+the system always delivers the message to the activity in your application (based on the matching
+application record). If the target device does not currently have your application installed, the
+system uses the Android application record to launch Android Market and take the user to the
+application in order to install it.</p>
<p>If your application doesn’t use NFC APIs to perform NDEF Push messaging, then Android provides a
default behavior: When your application is in the foreground on one device and Android Beam is
invoked with another Android-powered device, then the other device receives an NDEF message with an
Android application record that identifies your application. If the receiving device has the
application installed, the system launches it; if it’s not installed, Android Market opens and takes
-the user to your application so they can install it.</p>
+the user to your application in order to install it.</p>
+
+<p>You can read more about Android Beam and other NFC features in the <a
+href="{@docRoot}guide/topics/nfc/nfc.html">NFC Basics</a> developer guide. For some example code
+using Android Beam, see the <a
+href="{@docRoot}resources/samples/AndroidBeamDemo/src/com/example/android/beam/Beam.html">Android
+Beam Demo</a>.</p>
-<h3 id="P2pWiFi">Peer-to-peer Wi-Fi</h3>
+<h3 id="WiFiDirect">Wi-Fi Direct</h3>
-<p>Android now supports Wi-Fi Direct™ for peer-to-peer (P2P) connections between
-Android-powered
+<p>Android now supports Wi-Fi Direct for peer-to-peer (P2P) connections between Android-powered
devices and other device types without a hotspot or Internet connection. The Android framework
provides a set of Wi-Fi P2P APIs that allow you to discover and connect to other devices when each
-device supports Wi-Fi Direct™, then communicate over a speedy connection across distances much
-longer than a Bluetooth connection.</p>
+device supports Wi-Fi Direct, then communicate over a speedy connection across distances much longer
+than a Bluetooth connection.</p>
<p>A new package, {@link android.net.wifi.p2p}, contains all the APIs for performing peer-to-peer
connections with Wi-Fi. The primary class you need to work with is {@link
-android.net.wifi.p2p.WifiP2pManager}, for which you can get an instance by calling {@link
+android.net.wifi.p2p.WifiP2pManager}, which you can acquire by calling {@link
android.app.Activity#getSystemService getSystemService(WIFI_P2P_SERVICE)}. The {@link
-android.net.wifi.p2p.WifiP2pManager} provides methods that allow you to:</p>
+android.net.wifi.p2p.WifiP2pManager} includes APIs that allow you to:</p>
<ul>
<li>Initialize your application for P2P connections by calling {@link
android.net.wifi.p2p.WifiP2pManager#initialize initialize()}</li>
+
<li>Discover nearby devices by calling {@link android.net.wifi.p2p.WifiP2pManager#discoverPeers
discoverPeers()}</li>
+
<li>Start a P2P connection by calling {@link android.net.wifi.p2p.WifiP2pManager#connect
connect()}</li>
<li>And more</li>
@@ -622,18 +692,20 @@
<ul>
<li>The {@link android.net.wifi.p2p.WifiP2pManager.ActionListener} interface allows you to receive
callbacks when an operation such as discovering peers or connecting to them succeeds or fails.</li>
+
<li>{@link android.net.wifi.p2p.WifiP2pManager.PeerListListener} interface allows you to receive
information about discovered peers. The callback provides a {@link
android.net.wifi.p2p.WifiP2pDeviceList}, from which you can retrieve a {@link
android.net.wifi.p2p.WifiP2pDevice} object for each device within range and get information such as
the device name, address, device type, the WPS configurations the device supports, and more.</li>
+
<li>The {@link android.net.wifi.p2p.WifiP2pManager.GroupInfoListener} interface allows you to
-receive
-information about a P2P group. The callback provides a {@link android.net.wifi.p2p.WifiP2pGroup}
-object, which provides group information such as the owner, the network name, and passphrase.</li>
+receive information about a P2P group. The callback provides a {@link
+android.net.wifi.p2p.WifiP2pGroup} object, which provides group information such as the owner, the
+network name, and passphrase.</li>
+
<li>{@link android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener} interface allows you to
-receive
-information about the current connection. The callback provides a {@link
+receive information about the current connection. The callback provides a {@link
android.net.wifi.p2p.WifiP2pInfo} object, which has information such as whether a group has been
formed and who is the group owner.</li>
</ul>
@@ -642,58 +714,328 @@
<ul>
<li>{@link android.Manifest.permission#ACCESS_WIFI_STATE}</li>
<li>{@link android.Manifest.permission#CHANGE_WIFI_STATE}</li>
-<li>{@link android.Manifest.permission#INTERNET} (even though your app doesn’t technically connect
-to
-the Internet, the WiFi Direct implementation uses traditional sockets that do require Internet
-permission to work).</li>
+<li>{@link android.Manifest.permission#INTERNET} (although your app doesn’t technically connect
+to the Internet, communicating to Wi-Fi Direct peers with standard java sockets requires Internet
+permission).</li>
</ul>
<p>The Android system also broadcasts several different actions during certain Wi-Fi P2P events:</p>
<ul>
<li>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_CONNECTION_CHANGED_ACTION}: The P2P
-connection
-state has changed. This carries {@link android.net.wifi.p2p.WifiP2pManager#EXTRA_WIFI_P2P_INFO} with
-a {@link android.net.wifi.p2p.WifiP2pInfo} object and {@link
+connection state has changed. This carries {@link
+android.net.wifi.p2p.WifiP2pManager#EXTRA_WIFI_P2P_INFO} with a {@link
+android.net.wifi.p2p.WifiP2pInfo} object and {@link
android.net.wifi.p2p.WifiP2pManager#EXTRA_NETWORK_INFO} with a {@link android.net.NetworkInfo}
object.</li>
+
<li>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_CHANGED_ACTION}: The P2P state has
-changed
-between enabled and disabled. It carries {@link
+changed between enabled and disabled. It carries {@link
android.net.wifi.p2p.WifiP2pManager#EXTRA_WIFI_STATE} with either {@link
android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_DISABLED} or {@link
android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_ENABLED}</li>
+
<li>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION}: The list of peer
-devices
-has changed.</li>
+devices has changed.</li>
+
<li>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_THIS_DEVICE_CHANGED_ACTION}: The details for
this device have changed.</li>
</ul>
<p>See the {@link android.net.wifi.p2p.WifiP2pManager} documentation for more information. Also
-look
-at the <a href=”{@docRoot}resources/samples/WiFiDirectDemo/index.html”>Wi-Fi Direct</a> sample
-application for example code.</p>
+look at the <a href="{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi Direct Demo</a>
+sample application.</p>
-<h3 id="NetworkData">Network Data</h3>
+<h3 id="Bluetooth">Bluetooth Health Devices</h3>
-<p>Android 4.0 gives users precise visibility of how much network data applications are using. The
-Settings app provides controls that allow users to manage set limits for network data usage and even
-disable the use of background data for individual apps. In order to avoid users disabling your app’s
-access to data from the background, you should develop strategies to use use the data connection
-efficiently and vary your usage depending on the type of connection available.</p>
+<p>Android now supports Bluetooth Health Profile devices, so you can create applications that use
+Bluetooth to communicate with health devices that support Bluetooth, such as heart-rate monitors,
+blood meters, thermometers, and scales.</p>
+
+<p>Similar to regular headset and A2DP profile devices, you must call {@link
+android.bluetooth.BluetoothAdapter#getProfileProxy getProfileProxy()} with a {@link
+android.bluetooth.BluetoothProfile.ServiceListener} and the {@link
+android.bluetooth.BluetoothProfile#HEALTH} profile type to establish a connection with the profile
+proxy object.</p>
+
+<p>Once you’ve acquired the Health Profile proxy (the {@link android.bluetooth.BluetoothHealth}
+object), connecting to and communicating with paired health devices involves the following new
+Bluetooth classes:</p>
+<ul>
+<li>{@link android.bluetooth.BluetoothHealthCallback}: You must extend this class and implement the
+callback methods to receive updates about changes in the application’s registration state and
+Bluetooth channel state.</li>
+<li>{@link android.bluetooth.BluetoothHealthAppConfiguration}: During callbacks to your {@link
+android.bluetooth.BluetoothHealthCallback}, you’ll receive an instance of this object, which
+provides configuration information about the available Bluetooth health device, which you must use
+to perform various operations such as initiate and terminate connections with the {@link
+android.bluetooth.BluetoothHealth} APIs.</li>
+</ul>
+
+<p>For more information about using the Bluetooth Health Profile, see the documentation for {@link
+android.bluetooth.BluetoothHealth}.</p>
+
+
+
+
+
+<h3 id="A11y">Accessibility</h3>
+
+<p>Android 4.0 improves accessibility for sight-impaired users with new explore-by-touch mode
+and extended APIs that allow you to provide more information about view content or
+develop advanced accessibility services.</p>
+
+
+<h4>Explore-by-touch mode</h4>
+
+<p>Users with vision loss can now explore the screen by touching and dragging a finger across the
+screen to hear voice descriptions of the content. Because the explore-by-touch mode works like a
+virtual cursor, it allows screen readers to identify the descriptive text the same way that screen
+readers can when the user navigates with a d-pad or trackball—by reading information provided
+by {@link android.R.attr#contentDescription android:contentDescription} and {@link
+android.view.View#setContentDescription setContentDescription()} upon a simulated "hover" event. So,
+consider this is a reminder that you should provide descriptive text for the views in your
+application, especially for {@link android.widget.ImageButton}, {@link android.widget.EditText},
+{@link android.widget.ImageView} and other widgets that might not naturally contain descriptive
+text.</p>
+
+
+<h4>Accessibility for views</h4>
+
+<p>To enhance the information available to accessibility services such as screen readers, you can
+implement new callback methods for accessibility events in your custom {@link
+android.view.View} components.</p>
+
+<p>It's important to first note that the behavior of the {@link
+android.view.View#sendAccessibilityEvent sendAccessibilityEvent()} method has changed in Android
+4.0. As with previous version of Android, when the user enables accessibility services on the device
+and an input event such as a click or hover occurs, the respective view is notified with a call to
+{@link android.view.View#sendAccessibilityEvent sendAccessibilityEvent()}. Previously, the
+implementation of {@link android.view.View#sendAccessibilityEvent sendAccessibilityEvent()} would
+initialize an {@link android.view.accessibility.AccessibilityEvent} and send it to {@link
+android.view.accessibility.AccessibilityManager}. The new behavior involves some additional callback
+methods that allow the view and its parents to add more contextual information to the event:
+<ol>
+ <li>When invoked, the {@link
+android.view.View#sendAccessibilityEvent sendAccessibilityEvent()} and {@link
+android.view.View#sendAccessibilityEventUnchecked sendAccessibilityEventUnchecked()} methods defer
+to {@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}.
+ <p>Custom implementations of {@link android.view.View} might want to implement {@link
+android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()} to
+attach additional accessibility information to the {@link
+android.view.accessibility.AccessibilityEvent}, but should also call the super implementation to
+provide default information such as the standard content description, item index, and more.
+However, you should not add additional text content in this callback—that happens
+next.</p></li>
+ <li>Once initialized, if the event is one of several types that should be populated with text
+information, the view then receives a call to {@link
+android.view.View#dispatchPopulateAccessibilityEvent dispatchPopulateAccessibilityEvent()}, which
+defers to the {@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()}
+callback.
+ <p>Custom implementations of {@link android.view.View} should usually implement {@link
+android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} to add additional
+text content to the {@link android.view.accessibility.AccessibilityEvent} if the {@link
+android.R.attr#contentDescription android:contentDescription} text is missing or
+insufficient. To add more text description to the
+{@link android.view.accessibility.AccessibilityEvent}, call {@link
+android.view.accessibility.AccessibilityEvent#getText()}.{@link java.util.List#add add()}.</p>
+</li>
+ <li>At this point, the {@link android.view.View} passes the event up the view hierarchy by calling
+{@link android.view.ViewGroup#requestSendAccessibilityEvent requestSendAccessibilityEvent()} on the
+parent view. Each parent view then has the chance to augment the accessibility information by
+adding an {@link android.view.accessibility.AccessibilityRecord}, until it
+ultimately reaches the root view, which sends the event to the {@link
+android.view.accessibility.AccessibilityManager} with {@link
+android.view.accessibility.AccessibilityManager#sendAccessibilityEvent
+sendAccessibilityEvent()}.</li>
+</ol>
+
+<p>In addition to the new methods above, which are useful when extending the {@link
+android.view.View} class, you can also intercept these event callbacks on any {@link
+android.view.View} by extending {@link
+android.view.View.AccessibilityDelegate AccessibilityDelegate} and setting it on the view with
+{@link android.view.View#setAccessibilityDelegate setAccessibilityDelegate()}.
+When you do, each accessibility method in the view defers the call to the corresponding method in
+the delegate. For example, when the view receives a call to {@link
+android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()}, it passes it to the
+same method in the {@link android.view.View.AccessibilityDelegate}. Any methods not handled by
+the delegate are given right back to the view for default behavior. This allows you to override only
+the methods necessary for any given view without extending the {@link android.view.View} class.</p>
+
+
+<p>If you want to maintain compatibility with Android versions prior to 4.0, while also supporting
+the new the accessibility APIs, you can do so with the latest version of the <em>v4 support
+library</em> (in <a href="{@docRoot}sdk/compatibility-library.html">Compatibility Package, r4</a>)
+using a set of utility classes that provide the new accessibility APIs in a backward-compatible
+design.</p>
+
+
+
+
+<h4>Accessibility services</h4>
+
+<p>If you're developing an accessibility service, the information about various accessibility events
+has been significantly expanded to enable more advanced accessibility feedback for users. In
+particular, events are generated based on view composition, providing better context information and
+allowing accessibility services to traverse view hierarchies to get additional view information and
+deal with special cases.</p>
+
+<p>If you're developing an accessibility service (such as a screen reader), you can access
+additional content information and traverse view hierarchies with the following procedure:</p>
+<ol>
+<li>Upon receiving an {@link android.view.accessibility.AccessibilityEvent} from an application,
+call the {@link android.view.accessibility.AccessibilityEvent#getRecord(int)
+AccessibilityEvent.getRecord()} to retrieve a specific {@link
+android.view.accessibility.AccessibilityRecord} (there may be several records attached to the
+event).</li>
+
+<li>From either {@link android.view.accessibility.AccessibilityEvent} or an individual {@link
+android.view.accessibility.AccessibilityRecord}, you can call {@link
+android.view.accessibility.AccessibilityRecord#getSource() getSource()} to retrieve a {@link
+android.view.accessibility.AccessibilityNodeInfo} object.
+ <p>An {@link android.view.accessibility.AccessibilityNodeInfo} represents a single node
+of the window content in a format that allows you to query accessibility information about that
+node. The {@link android.view.accessibility.AccessibilityNodeInfo} object returned from {@link
+android.view.accessibility.AccessibilityEvent} describes the event source, whereas the source from
+an {@link android.view.accessibility.AccessibilityRecord} describes the predecessor of the event
+source.</p></li>
+
+<li>With the {@link android.view.accessibility.AccessibilityNodeInfo}, you can query information
+about it, call {@link
+android.view.accessibility.AccessibilityNodeInfo#getParent getParent()} or {@link
+android.view.accessibility.AccessibilityNodeInfo#getChild getChild()} to traverse the view
+hierarchy, and even add child views to the node.</li>
+</ol>
+
+<p>In order for your application to publish itself to the system as an accessibility service, it
+must declare an XML configuration file that corresponds to {@link
+android.accessibilityservice.AccessibilityServiceInfo}. For more information about creating an
+accessibility service, see {@link
+android.accessibilityservice.AccessibilityService} and {@link
+android.accessibilityservice.AccessibilityService#SERVICE_META_DATA
+SERVICE_META_DATA} for information about the XML configuration.</p>
+
+
+<h4>Other accessibility APIs</h4>
+
+<p>If you're interested in the device's accessibility state, the {@link
+android.view.accessibility.AccessibilityManager} has some new APIs such as:</p>
+<ul>
+ <li>{@link android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener}
+is an interface that allows you to receive a callback whenever accessibility is enabled or
+disabled.</li>
+ <li>{@link android.view.accessibility.AccessibilityManager#getEnabledAccessibilityServiceList
+ getEnabledAccessibilityServiceList()} provides information about which accessibility services
+ are currently enabled.</li>
+ <li>{@link android.view.accessibility.AccessibilityManager#isTouchExplorationEnabled()} tells
+ you whether the explore-by-touch mode is enabled.</li>
+</ul>
+
+
+
+
+
+
+<h3 id="SpellChecker">Spell Checker Services</h3>
+
+<p>A new spell checker framework allows apps to create spell checkers in a manner similar to the
+input method framework (for IMEs). To create a new spell checker, you must implement a service that
+extends
+{@link android.service.textservice.SpellCheckerService} and extend the {@link
+android.service.textservice.SpellCheckerService.Session} class to provide spelling suggestions based
+on text provided by the interface's callback methods. In the {@link
+android.service.textservice.SpellCheckerService.Session} callback methods, you must return the
+spelling suggestions as {@link android.view.textservice.SuggestionsInfo} objects. </p>
+
+<p>Applications with a spell checker service must declare the {@link
+android.Manifest.permission#BIND_TEXT_SERVICE} permission as required by the service.
+The service must also declare an intent filter with {@code <action
+android:name="android.service.textservice.SpellCheckerService" />} as the intent’s action and should
+include a {@code <meta-data>} element that declares configuration information for the spell
+checker. </p>
+
+<p>See the <a href="{@docRoot}resources/samples/SampleSpellCheckerService/index.html">Spell
+Checker</a> sample app for example code.</p>
+
+
+
+
+<h3 id="TTS">Text-to-speech Engines</h3>
+
+<p>Android’s text-to-speech (TTS) APIs have been significantly extended to allow applications to
+more easily implement custom TTS engines, while applications that want to use a TTS engine have a
+couple new APIs for selecting an engine.</p>
+
+
+<h4>Using text-to-speech engines</h4>
+
+<p>In previous versions of Android, you could use the {@link android.speech.tts.TextToSpeech} class
+to perform text-to-speech (TTS) operations using the TTS engine provided by the system or set a
+custom engine using {@link android.speech.tts.TextToSpeech#setEngineByPackageName
+setEngineByPackageName()}. In Android 4.0, the {@link
+android.speech.tts.TextToSpeech#setEngineByPackageName setEngineByPackageName()} method has been
+deprecated and you can now specify the engine to use with a new {@link
+android.speech.tts.TextToSpeech} constructor that accepts the package name of a TTS engine.</p>
+
+<p>You can also query the available TTS engines with {@link
+android.speech.tts.TextToSpeech#getEngines()}. This method returns a list of {@link
+android.speech.tts.TextToSpeech.EngineInfo} objects, which include meta data such as the engine’s
+icon, label, and package name.</p>
+
+
+<h4>Building text-to-speech engines</h4>
+
+<p>Previously, custom engines required that the engine be built using an undocumented native header
+file. In Android 4.0, there is a complete set of framework APIs for building TTS engines. </p>
+
+<p>The basic setup requires an implementation of {@link android.speech.tts.TextToSpeechService} that
+responds to the {@link android.speech.tts.TextToSpeech.Engine#INTENT_ACTION_TTS_SERVICE} intent. The
+primary work for a TTS engine happens during the {@link
+android.speech.tts.TextToSpeechService#onSynthesizeText onSynthesizeText()} callback in a service
+that extends {@link android.speech.tts.TextToSpeechService}. The system delivers this method two
+objects:</p>
+<ul>
+<li>{@link android.speech.tts.SynthesisRequest}: This contains various data including the text to
+synthesize, the locale, the speech rate, and voice pitch.</li>
+<li>{@link android.speech.tts.SynthesisCallback}: This is the interface by which your TTS engine
+delivers the resulting speech data as streaming audio. First the engine must call {@link
+android.speech.tts.SynthesisCallback#start start()} to indicate that the engine is ready to deliver
+the audio, then call {@link android.speech.tts.SynthesisCallback#audioAvailable audioAvailable()},
+passing it the audio data in a byte buffer. Once your engine has passed all audio through the
+buffer, call {@link android.speech.tts.SynthesisCallback#done()}.</li>
+</ul>
+
+<p>Now that the framework supports a true API for creating TTS engines, support for the native code
+implementation has been removed. Look for a blog post about a compatibility layer
+that you can use to convert your old TTS engines to the new framework.</p>
+
+<p>For an example TTS engine using the new APIs, see the <a
+href="{@docRoot}resources/samples/TtsEngine/index.html">Text To Speech Engine</a> sample app.</p>
+
+
+
+
+
+
+<h3 id="NetworkUsage">Network Usage</h3>
+
+<p>Android 4.0 gives users precise visibility of how much network data their applications are using.
+The Settings app provides controls that allow users to manage set limits for network data usage and
+even disable the use of background data for individual apps. In order to avoid users disabling your
+app’s access to data from the background, you should develop strategies to use use the data
+connection efficiently and adjust your usage depending on the type of connection available.</p>
<p>If your application performs a lot of network transactions, you should provide user settings that
allow users to control your app’s data habits, such as how often your app syncs data, whether to
perform uploads/downloads only when on Wi-Fi, whether to use data while roaming, etc. With these
controls available to them, users are much less likely to disable your app’s access to data when
they approach their limits, because they can instead precisely control how much data your app uses.
-When you provide an activity with these settings, you should include in its manifest declaration an
-intent filter for the {@link android.content.Intent#ACTION_MANAGE_NETWORK_USAGE} action. For
-example:</p>
+If you provide a preference activity with these settings, you should include in its manifest
+declaration an intent filter for the {@link android.content.Intent#ACTION_MANAGE_NETWORK_USAGE}
+action. For example:</p>
<pre>
<activity android:name="DataPreferences" android:label="@string/title_preferences">
@@ -704,10 +1046,10 @@
</activity>
</pre>
-<p>This intent filter indicates to the system that this is the application that controls your
+<p>This intent filter indicates to the system that this is the activity that controls your
application’s data usage. Thus, when the user inspects how much data your app is using from the
-Settings app, a “View application settings” button is available that launches your activity so the
-user can refine how much data your app uses.</p>
+Settings app, a “View application settings" button is available that launches your
+preference activity so the user can refine how much data your app uses.</p>
<p>Also beware that {@link android.net.ConnectivityManager#getBackgroundDataSetting()} is now
deprecated and always returns true—use {@link
@@ -715,7 +1057,7 @@
transactions, you should always call {@link android.net.ConnectivityManager#getActiveNetworkInfo()}
to get the {@link android.net.NetworkInfo} that represents the current network and query {@link
android.net.NetworkInfo#isConnected()} to check whether the device has a
-connection. You can then check various other connection properties, such as whether the device is
+connection. You can then check other connection properties, such as whether the device is
roaming or connected to Wi-Fi.</p>
@@ -724,43 +1066,10 @@
-<h3 id="Sensors">Device Sensors</h3>
-<p>Two new sensor types have been added in Android 4.0: {@link
-android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} and {@link
-android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY}. </p>
+<h3 id="RenderScript">RenderScript</h3>
-<p>{@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} is a temperature sensor that provides
-the ambient (room) temperature near a device. This sensor reports data in degrees Celsius. {@link
-android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY} is a humidity sensor that provides the relative
-ambient (room) humidity. The sensor reports data as a percentage. If a device has both {@link
-android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} and {@link
-android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY} sensors, you can use them to calculate the dew point
-and the absolute humidity.</p>
-
-<p>The existing temperature sensor ({@link android.hardware.Sensor#TYPE_TEMPERATURE}) has been
-deprecated. You should use the {@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} sensor
-instead.</p>
-
-<p>Additionally, Android’s three synthetic sensors have been improved so they now have lower latency
-and smoother output. These sensors include the gravity sensor ({@link
-android.hardware.Sensor#TYPE_GRAVITY}), rotation vector sensor ({@link
-android.hardware.Sensor#TYPE_ROTATION_VECTOR}), and linear acceleration sensor ({@link
-android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}). The improved sensors rely on the gyroscope
-sensor to improve their output so the sensors appear only on devices that have a gyroscope. If a
-device already provides one of the sensors, then that sensor appears as a second sensor on the
-device. The three improved sensors have a version number of 2.</p>
-
-
-
-
-
-
-
-
-<h3 id="Renderscript">Renderscript</h3>
-
-<p>Three major features have been added to Renderscript:</p>
+<p>Three major features have been added to RenderScript:</p>
<ul>
<li>Off-screen rendering to a framebuffer object</li>
@@ -771,144 +1080,30 @@
<p>The {@link android.renderscript.Allocation} class now supports a {@link
android.renderscript.Allocation#USAGE_GRAPHICS_RENDER_TARGET} memory space, which allows you to
render things directly into the {@link android.renderscript.Allocation} and use it as a framebuffer
-object. </p>
+object.</p>
-<p>{@link android.renderscript.RSTextureView} provides a means to display Renderscript graphics
-inside
-of a normal View, unlike {@link android.renderscript.RSSurfaceView}, which creates a separate
-window. This key difference allows you to do things such as move, transform, or animate an {@link
-android.renderscript.RSTextureView} as well as draw Renderscript graphics inside the View alongside
-other traditional View widgets.</p>
+<p>{@link android.renderscript.RSTextureView} provides a means to display RenderScript graphics
+inside of a {@link android.view.View}, unlike {@link android.renderscript.RSSurfaceView}, which
+creates a separate window. This key difference allows you to do things such as move, transform, or
+animate an {@link android.renderscript.RSTextureView} as well as draw RenderScript graphics inside
+a view that lies within an activity layout.</p>
-<p>The {@link android.renderscript.Script#forEach forEach()} method allows you to call Renderscript
-compute scripts from the VM level and have them automatically delegated to available cores on the
-device. You do not use this method directly, but any compute Renderscript that you write will have a
-{@link android.renderscript.Script#forEach forEach()} method that you can call in the reflected
-Renderscript class. You can call the reflected {@link android.renderscript.Script#forEach forEach()}
-method by passing in an input {@link android.renderscript.Allocation} to process, an output {@link
-android.renderscript.Allocation} to write the result to, and a data structure if the Renderscript
-needs more information in addition to the {@link android.renderscript.Allocation}s to. Only one of
-the {@link android.renderscript.Allocation}s is necessary and the data structure is optional.</p>
+<p>The {@link android.renderscript.Script#forEach Script.forEach()} method allows you to call
+RenderScript compute scripts from the VM level and have them automatically delegated to available
+cores on the device. You do not use this method directly, but any compute RenderScript that you
+write will have a {@link android.renderscript.Script#forEach forEach()} method that you can call in
+the reflected RenderScript class. You can call the reflected {@link
+android.renderscript.Script#forEach forEach()} method by passing in an input {@link
+android.renderscript.Allocation} to process, an output {@link android.renderscript.Allocation} to
+write the result to, and a {@link android.renderscript.FieldPacker} data structure in case the
+RenderScript needs more information. Only one of the {@link android.renderscript.Allocation}s is
+necessary and the data structure is optional.</p>
-<h3 id="A11y">Accessibility</h3>
-
-<p>Android 4.0 improves accessibility for users with disabilities with the Touch Exploration service
-and provides extended APIs for developers of new accessibility services.</p>
-
-<h4>Touch Exploration</h4>
-
-<p>Users with vision loss can now explore applications by touching areas of the screen and hearing
-voice descriptions of the content. The “Explore by Touch” feature works like a virtual cursor as the
-user drags a finger across the screen.</p>
-
-<p>You don’t have to use any new APIs to enhance touch exploration in your application, because the
-existing {@link android.R.attr#contentDescription android:contentDescription}
-attribute and {@link android.view.View#setContentDescription setContentDescription()} method is all
-you need. Because touch exploration works like a virtual cursor, it allows screen readers to
-identify the descriptive the same way that screen readers can when navigating with a d-pad or
-trackball. So this is a reminder to provide descriptive text for the views in your application,
-especially for {@link android.widget.ImageButton}, {@link android.widget.EditText}, {@link
-android.widget.CheckBox} and other interactive widgets that might not contain text information by
-default.</p>
-
-<h4>Accessibility for Custom Views</h4>
-
-<p>Developers of custom Views, ViewGroups and widgets can make their components compatible with
-accessibility services like Touch Exploration. For custom views and widgets targeted for Android 4.0
-and later, developers should implement the following accessibility API methods in their classes:</p>
-<ul>
-<li>These two methods initiate the accessibility event generation process and must be implemented by
-your custom view class.
- <ul>
- <li>{@link android.view.View#sendAccessibilityEvent(int) sendAccessibilityEvent()} If
-accessibility
- is
- not enabled, this call has no effect.</li>
- <li>{@link
- android.view.View#sendAccessibilityEventUnchecked(android.view.accessibility.AccessibilityEvent)
- sendAccessibilityEventUnchecked()} - This method executes regardless of whether accessibility is
- enabled or not.</li>
- </ul>
-</li>
-
-<li>These methods are called in order by the sendAccessibilityEvent methods listed above to collect
-accessibility information about the view, and its child views.
- <ul>
- <li>{@link
- android.view.View#onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent)
- onInitializeAccessibilityEvent()} - This method collects information about the view. If your
- application has specific requirements for accessibility, you should extend this method to add that
- information to the {@link android.view.accessibility.AccessibilityEvent}.</li>
-
- <li>{@link
-
-android.view.View#dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent)
- dispatchPopulateAccessibilityEvent()} is called by the framework to request text information for
- this view and its children. This method calls {@link
- android.view.View#onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent)
- onPopulateAccessibilityEvent()} first on the current view and then on its children.</li>
- </ul>
-</li>
-
-<li>The {@link
-android.view.View#onInitializeAccessibilityNodeInfo onInitializeAccessibilityNodeInfo()} method
-provides additional context information for
-accessibility services. You should implement or override this method to provide improved information
-for accessibility services investigating your custom view.</li>
-
-<li>Custom {@link android.view.ViewGroup} classes should also implement {@link
-android.view.ViewGroup#onRequestSendAccessibilityEvent(android.view.View,
-android.view.accessibility.AccessibilityEvent) onRequestSendAccessibilityEvent()} </li>
-</ul>
-
-<p>Developers who want to maintain compatibility with Android versions prior to 4.0, while still
-providing support for new the accessibility APIs, can use the {@link
-android.view.View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)
-setAccessibilityDelegate()} method to provide an {@link android.view.View.AccessibilityDelegate}
-containing implementations of the new accessibility API methods while maintaining compatibility with
-prior releases.</p>
-
-
-
-<h4>Accessibility Service APIs</h4>
-
-<p>Accessibility events have been significantly improved to provide better information for
-accessibility services. In particular, events are generated based on view composition, providing
-better context information and allowing accessibility service developers to traverse view
-hierarchies to get additional view information and deal with special cases.</p>
-
-<p>To access additional content information and traverse view hierarchies, accessibility service
-application developers should use the following procedure.</p>
-<ol>
-<li>Upon receiving an {@link android.view.accessibility.AccessibilityEvent} from an application,
-call
-the {@link android.view.accessibility.AccessibilityEvent#getRecord(int)
-AccessibilityEvent.getRecord()} to retrieve new accessibility information about the state of the
-view.</li>
-<li>From the {@link android.view.accessibility.AccessibilityRecord}, call {@link
-android.view.accessibility.AccessibilityRecord#getSource() getSource()} to retrieve a {@link
-android.view.accessibility.AccessibilityNodeInfo} object.</li>
-<li>With the {@link android.view.accessibility.AccessibilityNodeInfo}, call {@link
-android.view.accessibility.AccessibilityNodeInfo#getParent getParent()} or {@link
-android.view.accessibility.AccessibilityNodeInfo#getChild getChild()} to traverse the view
-hierarchy and get additional context information.</li>
-</ol>
-
-<p>In order to retrieve {@link android.view.accessibility.AccessibilityNodeInfo} information, your
-application must request permission to retrieve application window content through a manifest
-declaration that includes a new, separate xml configuration file, which supercedes {@link
-android.accessibilityservice.AccessibilityServiceInfo}. For more information, see {@link
-android.accessibilityservice.AccessibilityService} and {@link
-android.accessibilityservice.AccessibilityService#SERVICE_META_DATA
-AccessibilityService.SERVICE_META_DATA}.</p>
-
-
-
@@ -916,13 +1111,12 @@
<p>Android 4.0 expands the capabilities for enterprise application with the following features.</p>
-<h4>VPN Services</h4>
+<h4>VPN services</h4>
<p>The new {@link android.net.VpnService} allows applications to build their own VPN (Virtual
-Private
-Network), running as a {@link android.app.Service}. A VPN service creates an interface for a virtual
-network with its own address and routing rules and performs all reading and writing with a file
-descriptor.</p>
+Private Network), running as a {@link android.app.Service}. A VPN service creates an interface for a
+virtual network with its own address and routing rules and performs all reading and writing with a
+file descriptor.</p>
<p>To create a VPN service, use {@link android.net.VpnService.Builder}, which allows you to specify
the network address, DNS server, network route, and more. When complete, you can establish the
@@ -936,7 +1130,7 @@
users must manually enable it in the system settings.</p>
-<h4>Device Restrictions</h4>
+<h4>Device policies</h4>
<p>Applications that manage the device restrictions can now disable the camera using {@link
android.app.admin.DevicePolicyManager#setCameraDisabled setCameraDisabled()} and the {@link
@@ -944,119 +1138,46 @@
<disable-camera />} element in the policy configuration file).</p>
-<h4>Certificate Management</h4>
+<h4>Certificate management</h4>
<p>The new {@link android.security.KeyChain} class provides APIs that allow you to import and access
-certificates and key stores in credential storage. See the {@link android.security.KeyChain}
+certificates in the system key store. Certificates streamline the installation of both client
+certificates (to validate the identity of the user) and certificate authority certificates (to
+verify server identity). Applications such as web browsers or email clients can access the installed
+certificates to authenticate users to servers. See the {@link android.security.KeyChain}
documentation for more information.</p>
-<h3 id="Voicemail">Voicemail</h3>
-
-<p>A new voicemail APIs allows applications to add voicemails to the system. Because the APIs
-currently
-do not allow third party apps to read all the voicemails from the system, the only third-party apps
-that should use the voicemail APIs are those that have voicemail to deliver to the user. For
-instance, it’s possible that a users have multiple voicemail sources, such as one provided by their
-phone’s service provider and others from VoIP or other alternative services. These kinds of apps can
-use the APIs to add voicemail to the system. The built-in Phone application can then present all
-voicemails to the user with a single list. Although the system’s Phone application is the only
-application that can read all the voicemails, each application that provides voicemails can read
-those that it has added to the system.</p>
-
-<p>The {@link android.provider.VoicemailContract} class defines the content provider for the
-voicemail
-APIs. The subclasses {@link android.provider.VoicemailContract.Voicemails} and {@link
-android.provider.VoicemailContract.Status} provide tables in which the voicemail providers can
-insert voicemail data for storage on the device. For an example of a voicemail provider app, see the
-<a href=”{@docRoot}resources/samples/VoicemailProviderDemo/index.html”>Voicemail Provider
-Demo</a>.</p>
+<h3 id="Sensors">Device Sensors</h3>
-<h3 id="SpellChecker">Spell Checker Services</h3>
+<p>Two new sensor types have been added in Android 4.0:</p>
-<p>The new spell checker framework allows apps to create spell checkers in a manner similar to the
-input method framework. To create a new spell checker, you must override the {@link
-android.service.textservice.SpellCheckerService.Session} class to provide spelling suggestions based
-on text provided by the interface callback methods, returning suggestions as a {@link
-android.view.textservice.SuggestionsInfo} object. </p>
-
-<p>Applications with a spell checker service must declare the {@link
-android.Manifest.permission#BIND_TEXT_SERVICE} permission as required by the service, such that
-other services must have this permission in order for them to bind with the spell checker service.
-The service must also declare an intent filter with <action
-android:name="android.service.textservice.SpellCheckerService" /> as the intent’s action and should
-include a {@code <meta-data>} element that declares configuration information for the spell
-checker. </p>
-
-
-
-
-
-<h3 id="TTS">Text-to-speech Engines</h3>
-
-<p>Android’s text-to-speech (TTS) APIs have been greatly extended to allow applications to more
-easily
-implement custom TTS engines, while applications that want to use a TTS engine have a couple new
-APIs for selecting the engine.</p>
-
-
-<h4>Using text-to-speech engines</h4>
-
-<p>In previous versions of Android, you could use the {@link android.speech.tts.TextToSpeech} class
-to
-perform text-to-speech (TTS) operations using the TTS engine provided by the system or set a custom
-engine using {@link android.speech.tts.TextToSpeech#setEngineByPackageName
-setEngineByPackageName()}.
-In Android 4.0, the {@link android.speech.tts.TextToSpeech#setEngineByPackageName
-setEngineByPackageName()} method has been deprecated and you can now specify the engine to use with
-a new {@link android.speech.tts.TextToSpeech} that accepts the package name of a TTS engine.</p>
-
-<p>You can also query the available TTS engines with {@link
-android.speech.tts.TextToSpeech#getEngines()}. This method returns a list of {@link
-android.speech.tts.TextToSpeech.EngineInfo} objects, which include meta data such as the engine’s
-icon, label, and package name.</p>
-
-
-<h4>Building text-to-speech engines</h4>
-
-<p>Previously, custom engines required that the engine be built using native code, based on a TTS
-engine header file. In Android 4.0, there is a framework API for building TTS engines. </p>
-
-<p>The basic setup requires an implementation of {@link android.speech.tts.TextToSpeechService} that
-responds to the {@link android.speech.tts.TextToSpeech.Engine#INTENT_ACTION_TTS_SERVICE} intent. The
-primary work for a TTS engine happens during the {@link
-android.speech.tts.TextToSpeechService#onSynthesizeText onSynthesizeText()} callback in the {@link
-android.speech.tts.TextToSpeechService}. The system delivers this method two objects:</p>
<ul>
-<li>{@link android.speech.tts.SynthesisRequest}: This contains various data including the text to
-synthesize, the locale, the speech rate, and voice pitch.</li>
-<li>{@link android.speech.tts.SynthesisCallback}: This is the interface by which your TTS engine
-delivers the resulting speech data as streaming audio, by calling {@link
-android.speech.tts.SynthesisCallback#start start()} to indicate that the engine is ready to deliver
-the
-audio, then call {@link android.speech.tts.SynthesisCallback#audioAvailable audioAvailable()},
-passing it the audio
-data in a byte buffer. Once your engine has passed all audio through the buffer, call {@link
-android.speech.tts.SynthesisCallback#done()}.</li>
+ <li>{@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE}: A temperature sensor that provides
+the ambient (room) temperature in degrees Celsius.</li>
+ <li>{@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY}: A humidity sensor that provides the
+relative ambient (room) humidity as a percentage.</li>
</ul>
-<p>Now that the framework supports a true API for creating TTS engines, support for the previous
-technique using native code has been removed. Watch for a blog post about the compatibility layer
-that you can use to convert TTS engines built using the previous technique to the new framework.</p>
+<p>If a device has both {@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} and {@link
+android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY} sensors, you can use them to calculate the dew point
+and the absolute humidity.</p>
-<p>For an example TTS engine using the new APIs, see the <a
-href=”{@docRoot}resources/samples/TtsEngine/index.html”>Text To Speech Engine</a> sample app.</p>
+<p>The previous temperature sensor, {@link android.hardware.Sensor#TYPE_TEMPERATURE}, has been
+deprecated. You should use the {@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} sensor
+instead.</p>
-
-
-
-
-
+<p>Additionally, Android’s three synthetic sensors have been greatly improved so they now have lower
+latency and smoother output. These sensors include the gravity sensor ({@link
+android.hardware.Sensor#TYPE_GRAVITY}), rotation vector sensor ({@link
+android.hardware.Sensor#TYPE_ROTATION_VECTOR}), and linear acceleration sensor ({@link
+android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}). The improved sensors rely on the gyroscope
+sensor to improve their output, so the sensors appear only on devices that have a gyroscope.</p>
@@ -1066,34 +1187,38 @@
<p>The {@link android.app.ActionBar} has been updated to support several new behaviors. Most
importantly, the system gracefully manages the action bar’s size and configuration when running on
-smaller screens in order to provide an optimal user experience. For example, when the screen is
-narrow (such as when a handset is in portrait orientation), the action bar’s navigation tabs appear
-in a “stacked bar,” which appears directly below the main action bar. You can also opt-in to a
-“split action bar,” which will place all action items in a separate bar at the bottom of the screen
-when the screen is narrow.</p>
+smaller screens in order to provide an optimal user experience on all screen sizes. For example,
+when the screen is narrow (such as when a handset is in portrait orientation), the action bar’s
+navigation tabs appear in a “stacked bar," which appears directly below the main action bar. You can
+also opt-in to a “split action bar," which places all action items in a separate bar at the bottom
+of the screen when the screen is narrow.</p>
-<h4>Split Action Bar</h4>
+<h4>Split action bar</h4>
-<p>If your action bar includes several action items, not all of them will fit into the action bar
-when on a narrow screen, so the system will place them into the overflow menu. However, Android 4.0
-allows you to enable “split action bar” so that more action items can appear on the screen in a
+<p>If your action bar includes several action items, not all of them will fit into the action bar on
+a narrow screen, so the system will place more of them into the overflow menu. However, Android 4.0
+allows you to enable “split action bar" so that more action items can appear on the screen in a
separate bar at the bottom of the screen. To enable split action bar, add {@link
-android.R.attr#uiOptions android:uiOptions} with {@code ”splitActionBarWhenNarrow”} to either your
-{@code <application>} tag or individual {@code <activity>} tags in your manifest file.
-When enabled, the system will enable the additional bar for action items when the screen is narrow
-and add all action items to the new bar (no action items will appear in the primary action bar).</p>
+android.R.attr#uiOptions android:uiOptions} with {@code "splitActionBarWhenNarrow"} to either your
+<a href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a>
+tag or
+individual <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+<activity>}</a> tags
+in your manifest file. When enabled, the system will add an additional bar at the bottom of the
+screen for all action items when the screen is narrow (no action items will appear in the primary
+action bar).</p>
<p>If you want to use the navigation tabs provided by the {@link android.app.ActionBar.Tab} APIs,
-but
-don’t want the stacked bar—you want only the tabs to appear, then enable the split action bar
-as described above and also call {@link android.app.ActionBar#setDisplayShowHomeEnabled
-setDisplayShowHomeEnabled(false)} to disable the application icon in the action bar. With nothing
-left in the main action bar, it disappears—all that’s left are the navigation tabs at the top
-and the action items at the bottom of the screen.</p>
+but don’t need the main action bar on top (you want only the tabs to appear at the top), then enable
+the split action bar as described above and also call {@link
+android.app.ActionBar#setDisplayShowHomeEnabled setDisplayShowHomeEnabled(false)} to disable the
+application icon in the action bar. With nothing left in the main action bar, it
+disappears—all that’s left are the navigation tabs at the top and the action items at the
+bottom of the screen.</p>
-<h4>Action Bar Styles</h4>
+<h4>Action bar styles</h4>
<p>If you want to apply custom styling to the action bar, you can use new style properties {@link
android.R.attr#backgroundStacked} and {@link android.R.attr#backgroundSplit} to apply a background
@@ -1103,31 +1228,38 @@
setSplitBackgroundDrawable()}.</p>
-<h4>Action Provider</h4>
+<h4>Action provider</h4>
-<p>The new {@link android.view.ActionProvider} class facilitates user actions to which several
-different applications may respond. For example, a “share” action in your application might invoke
-several different apps that can handle the {@link android.content.Intent#ACTION_SEND} intent and the
-associated data. In this case, you can use the {@link android.widget.ShareActionProvider} (an
-extension of {@link android.view.ActionProvider}) in your action bar, instead of a traditional menu
-item that invokes the intent. The {@link android.widget.ShareActionProvider} populates a drop-down
-menu with all the available apps that can handle the intent.</p>
+<p>The new {@link android.view.ActionProvider} class allows you to create a specialized handler for
+action items. An action provider can define an action view, a default action behavior, and a submenu
+for each action item to which it is associated. When you want to create an action item that has
+dynamic behaviors (such as a variable action view, default action, or submenu), extending {@link
+android.view.ActionProvider} is a good solution in order to create a reusable component, rather than
+handling the various action item transformations in your fragment or activity.</p>
+
+<p>For example, the {@link android.widget.ShareActionProvider} is an extension of {@link
+android.view.ActionProvider} that facilitates a “share" action from the action bar. Instead of using
+traditional action item that invokes the {@link android.content.Intent#ACTION_SEND} intent, you can
+use this action provider to present an action view with a drop-down list of applications that handle
+the {@link android.content.Intent#ACTION_SEND} intent. When the user selects an application to use
+for the action, {@link android.widget.ShareActionProvider} remembers that selection and provides it
+in the action view for faster access to sharing with that app.</p>
<p>To declare an action provider for an action item, include the {@code android:actionProviderClass}
-attribute in the {@code <item>} element for your activity’s options menu, with the class name
-of the action provider as the attribute value. For example:</p>
+attribute in the <a href="{@docRoot}guide/topics/resources/menu-resource.html#item-element">{@code
+<item>}</a> element for your activity’s options menu, with the class name of the action
+provider as the value. For example:</p>
<pre>
<item android:id="@+id/menu_share"
android:title="Share"
- android:icon="@drawable/ic_share"
android:showAsAction="ifRoom"
android:actionProviderClass="android.widget.ShareActionProvider" />
</pre>
<p>In your activity’s {@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()}
-callback
-method, retrieve an instance of the action provider from the menu item and set the intent:</p>
+callback method, retrieve an instance of the action provider from the menu item and set the
+intent:</p>
<pre>
public boolean onCreateOptionsMenu(Menu menu) {
@@ -1142,21 +1274,22 @@
</pre>
<p>For an example using the {@link android.widget.ShareActionProvider}, see the <a
-href=”{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ActionBarActionProviderActivity.html”>ActionBarActionProviderActivity</a>
-class in ApiDemos.</p>
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ActionBarActionProviderActivity.html"
+>ActionBarActionProviderActivity</a> class in ApiDemos.</p>
-<h4>Collapsible Action Views</h4>
+<h4>Collapsible action views</h4>
-<p>Menu items that appear as action items can now toggle between their action view state and
+<p>Action items that provide an action view can now toggle between their action view state and
traditional action item state. Previously only the {@link android.widget.SearchView} supported
collapsing when used as an action view, but now you can add an action view for any action item and
switch between the expanded state (action view is visible) and collapsed state (action item is
visible).</p>
<p>To declare that an action item that contains an action view be collapsible, include the {@code
-“collapseActionView”} flag in the {@code android:showAsAction} attribute for the {@code
-<item>} element in the menu’s XML file.</p>
+“collapseActionView"} flag in the {@code android:showAsAction} attribute for the <a
+href="{@docRoot}guide/topics/resources/menu-resource.html#item-element">{@code
+<item>}</a> element in the menu’s XML file.</p>
<p>To receive callbacks when an action view switches between expanded and collapsed, register an
instance of {@link android.view.MenuItem.OnActionExpandListener} with the respective {@link
@@ -1173,20 +1306,20 @@
collapsed.</p>
-<h4>Other APIs for Action Bar</h4>
+<h4>Other APIs for action bar</h4>
<ul>
-<li>{@link android.app.ActionBar#setHomeButtonEnabled setHomeButtonEnabled()} allows you to disable
-the
-default behavior in which the application icon/logo behaves as a button (pass “false” to disable it
-as a button).</li>
+<li>{@link android.app.ActionBar#setHomeButtonEnabled setHomeButtonEnabled()} allows you to specify
+whether the icon/logo behaves as a button to navigate home or “up" (pass “true" to make it behave as
+a button).</li>
+
<li>{@link android.app.ActionBar#setIcon setIcon()} and {@link android.app.ActionBar#setLogo
-setLogo()}
-to define the action bar icon or logo at runtime.</li>
+setLogo()} allow you to define the action bar icon or logo at runtime.</li>
+
<li>{@link android.app.Fragment#setMenuVisibility Fragment.setMenuVisibility()} allows you to enable
-or
-disable the visibility of the options menu items declared by the fragment. This is useful if the
+or disable the visibility of the options menu items declared by the fragment. This is useful if the
fragment has been added to the activity, but is not visible, so the menu items should be
hidden.</li>
+
<li>{@link android.app.FragmentManager#invalidateOptionsMenu
FragmentManager.invalidateOptionsMenu()}
allows you to invalidate the activity options menu during various states of the fragment lifecycle
@@ -1204,62 +1337,11 @@
<p>Android 4.0 introduces a variety of new views and other UI components.</p>
-<h4>System UI</h4>
-
-<p>Since the early days of Android, the system has managed a UI component known as the <em>status
-bar</em>, which resides at the top of handset devices to deliver information such as the carrier
-signal, time, notifications, and so on. Android 3.0 added the <em>system bar</em> for tablet
-devices, which resides at the bottom of the screen to provide system navigation controls (Home,
-Back, and so forth) and also an interface for elements traditionally provided by the status bar. In
-Android 4.0, the system provides a new type of system UI called the <em>navigation bar</em>. The
-navigation bar shares some qualities with the system bar, because it provides navigation controls
-for devices that don’t have hardware counterparts for navigating the system, but the navigation
-controls is all that it provides (a device with the navigation bar, thus, also includes the status
-bar at the top of the screen).</p>
-
-<p>To this day, you can hide the status bar on handsets using the {@link
-android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN} flag. In Android 4.0, the APIs that control
-the system bar’s visibility have been updated to better reflect the behavior of both the system bar
-and navigation bar:</p>
-<ul>
-<li>The {@link android.view.View#SYSTEM_UI_FLAG_LOW_PROFILE} flag replaces View.STATUS_BAR_HIDDEN
-flag
-(now deprecated). When set, this flag enables “low profile” mode for the system bar or navigation
-bar. Navigation buttons dim and other elements in the system bar also hide.</li>
-<li>The {@link android.view.View#SYSTEM_UI_FLAG_VISIBLE} flag replaces the {@code
-STATUS_BAR_VISIBLE}
-flag to request the system bar or navigation bar be visible.</li>
-<li>The {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} is a new flag that requests that
-the
-navigation bar hide completely. Take note that this works only for the <em>navigation bar</em> used
-by some handsets (it does <strong>not</strong> hide the system bar on tablets). The navigation bar
-returns as soon as the system receives user input. As such, this mode is generally used for video
-playback or other cases in which user input is not required.</li>
-</ul>
-
-<p>You can set each of these flags for the system bar by calling {@link
-android.view.View#setSystemUiVisibility setSystemUiVisibility()} on any view in your activity
-window. The window manager will combine (OR-together) all flags from all views in your window and
-apply them to the system UI as long as your window has input focus. When your window loses input
-focus (the user navigates away from your app, or a dialog appears), your flags cease to have effect.
-Similarly, if you remove those views from the view hierarchy their flags no longer apply.</p>
-
-<p>To synchronize other events in your activity with visibility changes to the system UI (for
-example,
-hide the action bar or other UI controls when the system UI hides), you can register a {@link
-android.view.View.OnSystemUiVisibilityChangeListener} to get a callback when the visibility
-changes.</p>
-
-<p>See the <a
-href=”{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/OverscanActivity.html”>
-OverscanActivity</a> class for a demonstration of different system UI options.</p>
-
<h4>GridLayout</h4>
<p>{@link android.widget.GridLayout} is a new view group that places child views in a rectangular
-grid.
-Unlike {@link android.widget.TableLayout}, {@link android.widget.GridLayout} relies on a flat
+grid. Unlike {@link android.widget.TableLayout}, {@link android.widget.GridLayout} relies on a flat
hierarchy and does not make use of intermediate views such as table rows for providing structure.
Instead, children specify which row(s) and column(s) they should occupy (cells can span multiple
rows and/or columns), and by default are laid out sequentially across the grid’s rows and columns.
@@ -1269,7 +1351,8 @@
on children.</p>
<p>See <a
-href=”{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/index.html”>ApiDemos</a>
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/index.html">ApiDemos</a
+>
for samples using {@link android.widget.GridLayout}.</p>
@@ -1277,11 +1360,10 @@
<h4>TextureView</h4>
<p>{@link android.view.TextureView} is a new view that allows you to display a content stream, such
-as
-a video or an OpenGL scene. Although similar to {@link android.view.SurfaceView}, {@link
+as a video or an OpenGL scene. Although similar to {@link android.view.SurfaceView}, {@link
android.view.TextureView} is unique in that it behaves like a regular view, rather than creating a
separate window, so you can treat it like any other {@link android.view.View} object. For example,
-you can apply transforms, animate it using {@link android.view.ViewPropertyAnimator}, or easily
+you can apply transforms, animate it using {@link android.view.ViewPropertyAnimator}, or
adjust its opacity with {@link android.view.View#setAlpha setAlpha()}.</p>
<p>Beware that {@link android.view.TextureView} works only within a hardware accelerated window.</p>
@@ -1289,38 +1371,36 @@
<p>For more information, see the {@link android.view.TextureView} documentation.</p>
-<h4>Switch Widget</h4>
+<h4>Switch widget</h4>
<p>The new {@link android.widget.Switch} widget is a two-state toggle that users can drag to one
-side
-or the other (or simply tap) to toggle an option between two states.</p>
+side or the other (or simply tap) to toggle an option between two states.</p>
-<p>You can declare a switch in your layout with the {@code <Switch>} element. You can use the
-{@code android:textOn} and {@code android:textOff} attributes to specify the text to appear on the
-switch when in the on and off setting. The {@code android:text} attribute also allows you to place a
-label alongside the switch.</p>
+<p>You can use the {@code android:textOn} and {@code android:textOff} attributes to specify the text
+to appear on the switch when in the on and off setting. The {@code android:text} attribute also
+allows you to place a label alongside the switch.</p>
<p>For a sample using switches, see the <a
-href=”{@docRoot}resources/samples/ApiDemos/res/layout/switches.html”>switches.xml</a> layout file
+href="{@docRoot}resources/samples/ApiDemos/res/layout/switches.html">switches.xml</a> layout file
and respective <a
-href=”{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/Switches.html”>Switches
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/Switches.html">Switches
</a> activity.</p>
-<h4>Popup Menus</h4>
+<h4>Popup menus</h4>
<p>Android 3.0 introduced {@link android.widget.PopupMenu} to create short contextual menus that pop
-up
-at an anchor point you specify (usually at the point of the item selected). Android 4.0 extends the
-{@link android.widget.PopupMenu} with a couple useful features:</p>
+up at an anchor point you specify (usually at the point of the item selected). Android 4.0 extends
+the {@link android.widget.PopupMenu} with a couple useful features:</p>
<ul>
<li>You can now easily inflate the contents of a popup menu from an XML <a
-href=”{@docRoot}guide/topics/resources/menu-resource.html”>menu resource</a> with {@link
+href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a> with {@link
android.widget.PopupMenu#inflate inflate()}, passing it the menu resource ID.</li>
<li>You can also now create a {@link android.widget.PopupMenu.OnDismissListener} that receives a
callback when the menu is dismissed.</li>
</ul>
+
<h4>Preferences</h4>
<p>A new {@link android.preference.TwoStatePreference} abstract class serves as the basis for
@@ -1332,10 +1412,106 @@
android.preference.SwitchPreference} for the Wi-Fi and Bluetooth settings.</p>
-<h4>Hover Events</h4>
-<p>The {@link android.view.View} class now supports “hover” events to enable richer interactions
-through the use of pointer devices (such as a mouse or other device that drives an on-screen
+<h4>System themes</h4>
+
+<p>The default theme for all applications that target Android 4.0 (by setting either <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> or
+<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> to
+{@code “14"} or higher) is now the
+"device default" theme: {@link android.R.style#Theme_DeviceDefault Theme.DeviceDefault}. This may be
+the dark Holo theme or a different dark theme defined by the specific device.</p>
+
+<p>The {@link android.R.style#Theme_Holo Theme.Holo} family of themes are guaranteed to not change
+from one device to another when running the same version of Android. If you explicitly
+apply any of the {@link android.R.style#Theme_Holo Theme.Holo} themes to your activities, you can
+rest assured that these themes will not change character on different devices within the same
+platform version.</p>
+
+<p>If you wish for your app to blend in with the overall device theme (such as when different OEMs
+provide different default themes for the system), you should explicitly apply themes from the {@link
+android.R.style#Theme_DeviceDefault Theme.DeviceDefault} family.</p>
+
+
+<h4>Options menu button</h4>
+
+<p>Beginning with Android 4.0, you'll notice that handsets no longer require a Menu hardware button.
+However, there's no need for you to worry about this if your existing application provides an <a
+href="{@docRoot}guide/topics/ui/menus.html#options-menu">options menu</a> and expects there to be a
+Menu button. To ensure that existing apps continue to work as they expect, the system provides an
+on-screen Menu button for apps that were designed for older versions of Android.</p>
+
+<p>For the best user experience, new and updated apps should instead use the {@link
+android.app.ActionBar} to provide access to menu items and set <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> to
+{@code "14"} to take advantage of the latest framework default behaviors.</p>
+
+
+
+<h4>Controls for system UI visibility</h4>
+
+<p>Since the early days of Android, the system has managed a UI component known as the <em>status
+bar</em>, which resides at the top of handset devices to deliver information such as the carrier
+signal, time, notifications, and so on. Android 3.0 added the <em>system bar</em> for tablet
+devices, which resides at the bottom of the screen to provide system navigation controls (Home,
+Back, and so forth) and also an interface for elements traditionally provided by the status bar. In
+Android 4.0, the system provides a new type of system UI called the <em>navigation bar</em>. You
+might consider the navigation bar a re-tuned version of the system bar designed for
+handsets—it provides navigation controls
+for devices that don’t have hardware counterparts for navigating the system, but it leaves out the
+system bar's notification UI and setting controls. As such, a device that provides the navigation
+bar also has the status bar at the top.</p>
+
+<p>To this day, you can hide the status bar on handsets using the {@link
+android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN} flag. In Android 4.0, the APIs that control
+the system bar’s visibility have been updated to better reflect the behavior of both the system bar
+and navigation bar:</p>
+<ul>
+<li>The {@link android.view.View#SYSTEM_UI_FLAG_LOW_PROFILE} flag replaces the {@code
+STATUS_BAR_HIDDEN} flag. When set, this flag enables “low profile" mode for the system bar or
+navigation bar. Navigation buttons dim and other elements in the system bar also hide. Enabling
+this is useful for creating more immersive games without distraction for the system navigation
+buttons.</li>
+
+<li>The {@link android.view.View#SYSTEM_UI_FLAG_VISIBLE} flag replaces the {@code
+STATUS_BAR_VISIBLE} flag to request the system bar or navigation bar be visible.</li>
+
+<li>The {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} is a new flag that requests
+the navigation bar hide completely. Be aware that this works only for the <em>navigation bar</em>
+used by some handsets (it does <strong>not</strong> hide the system bar on tablets). The navigation
+bar returns to view as soon as the system receives user input. As such, this mode is useful
+primarily for video playback or other cases in which the whole screen is needed but user input is
+not required.</li>
+</ul>
+
+<p>You can set each of these flags for the system bar and navigation bar by calling {@link
+android.view.View#setSystemUiVisibility setSystemUiVisibility()} on any view in your activity. The
+window manager combines (OR-together) all flags from all views in your window and
+apply them to the system UI as long as your window has input focus. When your window loses input
+focus (the user navigates away from your app, or a dialog appears), your flags cease to have effect.
+Similarly, if you remove those views from the view hierarchy their flags no longer apply.</p>
+
+<p>To synchronize other events in your activity with visibility changes to the system UI (for
+example, hide the action bar or other UI controls when the system UI hides), you should register a
+{@link android.view.View.OnSystemUiVisibilityChangeListener} to be notified when the visibility
+of the system bar or navigation bar changes.</p>
+
+<p>See the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/OverscanActivity.html">
+OverscanActivity</a> class for a demonstration of different system UI options.</p>
+
+
+
+
+
+<h3 id="Input">Input Framework</h3>
+
+<p>Android 4.0 adds support for cursor hover events and new stylus and mouse button events.</p>
+
+<h4>Hover events</h4>
+
+<p>The {@link android.view.View} class now supports “hover" events to enable richer interactions
+through the use of pointer devices (such as a mouse or other devices that drive an on-screen
cursor).</p>
<p>To receive hover events on a view, implement the {@link android.view.View.OnHoverListener} and
@@ -1355,21 +1531,19 @@
listener returns false, then the hover event will be dispatched to the parent view as usual.</p>
<p>If your application uses buttons or other widgets that change their appearance based on the
-current
-state, you can now use the {@code android:state_hovered} attribute in a <a
-href=”{@docRoot}guide/topics/resources/drawable-resource.html#StateList”>state list drawable</a> to
+current state, you can now use the {@code android:state_hovered} attribute in a <a
+href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">state list drawable</a> to
provide a different background drawable when a cursor hovers over the view.</p>
<p>For a demonstration of the new hover events, see the <a
-href=”{@docRoot}samples/ApiDemos/src/com/example/android/apis/view/Hover.html”>Hover</a> class in
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/Hover.html">Hover</a> class in
ApiDemos.</p>
-<h4>Stylus and Mouse Button Input Events</h4>
+<h4>Stylus and mouse button events</h4>
<p>Android now provides APIs for receiving input from a stylus input device such as a digitizer
-tablet
-peripheral or a stylus-enabled touch screen.</p>
+tablet peripheral or a stylus-enabled touch screen.</p>
<p>Stylus input operates in a similar manner to touch or mouse input. When the stylus is in contact
with the digitizer, applications receive touch events just like they would when a finger is used to
@@ -1378,7 +1552,7 @@
are pressed.</p>
<p>Your application can distinguish between finger, mouse, stylus and eraser input by querying the
-“tool type” associated with each pointer in a {@link android.view.MotionEvent} using {@link
+“tool type" associated with each pointer in a {@link android.view.MotionEvent} using {@link
android.view.MotionEvent#getToolType getToolType()}. The currently defined tool types are: {@link
android.view.MotionEvent#TOOL_TYPE_UNKNOWN}, {@link android.view.MotionEvent#TOOL_TYPE_FINGER},
{@link android.view.MotionEvent#TOOL_TYPE_MOUSE}, {@link android.view.MotionEvent#TOOL_TYPE_STYLUS},
@@ -1386,26 +1560,24 @@
can choose to handle stylus input in different ways from finger or mouse input.</p>
<p>Your application can also query which mouse or stylus buttons are pressed by querying the “button
-state” of a {@link android.view.MotionEvent} using {@link android.view.MotionEvent#getButtonState
+state" of a {@link android.view.MotionEvent} using {@link android.view.MotionEvent#getButtonState
getButtonState()}. The currently defined button states are: {@link
-android.view.MotionEvent#BUTTON_PRIMARY}, {@link
-android.view.MotionEvent#BUTTON_SECONDARY}, {@link
-android.view.MotionEvent#BUTTON_TERTIARY}, {@link android.view.MotionEvent#BUTTON_BACK},
-and {@link android.view.MotionEvent#BUTTON_FORWARD}.
-For convenience, the back and forward mouse buttons are automatically mapped to the {@link
-android.view.KeyEvent#KEYCODE_BACK} and {@link android.view.KeyEvent#KEYCODE_FORWARD} keys. Your
-application can handle these keys to support mouse button based back and forward navigation.</p>
+android.view.MotionEvent#BUTTON_PRIMARY}, {@link android.view.MotionEvent#BUTTON_SECONDARY}, {@link
+android.view.MotionEvent#BUTTON_TERTIARY}, {@link android.view.MotionEvent#BUTTON_BACK}, and {@link
+android.view.MotionEvent#BUTTON_FORWARD}. For convenience, the back and forward mouse buttons are
+automatically mapped to the {@link android.view.KeyEvent#KEYCODE_BACK} and {@link
+android.view.KeyEvent#KEYCODE_FORWARD} keys. Your application can handle these keys to support
+mouse button based back and forward navigation.</p>
<p>In addition to precisely measuring the position and pressure of a contact, some stylus input
-devices
-also report the distance between the stylus tip and the digitizer, the stylus tilt angle, and the
-stylus orientation angle. Your application can query this information using {@link
+devices also report the distance between the stylus tip and the digitizer, the stylus tilt angle,
+and the stylus orientation angle. Your application can query this information using {@link
android.view.MotionEvent#getAxisValue getAxisValue()} with the axis codes {@link
android.view.MotionEvent#AXIS_DISTANCE}, {@link android.view.MotionEvent#AXIS_TILT}, and {@link
android.view.MotionEvent#AXIS_ORIENTATION}.</p>
<p>For a demonstration of tool types, button states and the new axis codes, see the <a
-href=”{@docRoot}samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.html”>TouchPaint
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.html">TouchPaint
</a> class in ApiDemos.</p>
@@ -1463,40 +1635,42 @@
application has set either <a
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> or
<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> to
-{@code “14”} or higher. Hardware acceleration generally results in smoother animations, smoother
+{@code “14"} or higher. Hardware acceleration generally results in smoother animations, smoother
scrolling, and overall better performance and response to user interaction.</p>
<p>If necessary, you can manually disable hardware acceleration with the <a
-href=”{@docRoot}guide/topics/manifest/activity-element.html#hwaccel”>{@code hardwareAccelerated}</a>
+href="{@docRoot}guide/topics/manifest/activity-element.html#hwaccel">{@code hardwareAccelerated}</a>
attribute for individual <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
<activity>}</a> elements or the <a
href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a>
element. You can alternatively disable hardware acceleration for individual views by calling {@link
android.view.View#setLayerType setLayerType(LAYER_TYPE_SOFTWARE)}.</p>
+<p>For more information about hardware acceleration, including a list of unsupported drawing
+operations, see the <a href="{@docRoot}guide/topics/graphics/hardware-accel.html">Hardware
+Acceleration</a> document.</p>
+
+
<h3 id="Jni">JNI Changes</h3>
-<p>In previous versions of Android, JNI local references weren’t indirect handles; we used direct
-pointers. This didn’t seem like a problem as long as we didn’t have a garbage collector that moves
-objects, but it was because it meant that it was possible to write buggy code that still seemed to
-work. In Android 4.0, we’ve moved to using indirect references so we can detect these bugs before we
-need third-party native code to be correct.</p>
+<p>In previous versions of Android, JNI local references weren’t indirect handles; Android used
+direct pointers. This wasn't a problem as long as the garbage collector didn't move objects, but it
+seemed to work because it made it possible to write buggy code. In Android 4.0, the system now uses
+indirect references in order to detect these bugs.</p>
-<p>The ins and outs of JNI local references are described in “Local and Global References” in
-<a href="{@docRoot}guide/practices/design/jni.html">JNI Tips</a>. In Android 4.0, <a
-href="http://android-developers.blogspot.com/2011/07/debugging-android-jni-with-checkjni.html">CheckJNI</a>
-has been
-enhanced to detect these errors. Watch the <a href=”http://android-developers.blogspot.com/”>Android
-Developers Blog</a> for an upcoming post about common errors with JNI references and how you can fix
-them.</p>
+<p>The ins and outs of JNI local references are described in “Local and Global References" in <a
+href="{@docRoot}guide/practices/design/jni.html">JNI Tips</a>. In Android 4.0, <a
+href="http://android-developers.blogspot.com/2011/07/debugging-android-jni-with-checkjni.html">
+CheckJNI</a> has been enhanced to detect these errors. Watch the <a
+href="http://android-developers.blogspot.com/">Android Developers Blog</a> for an upcoming post
+about common errors with JNI references and how you can fix them.</p>
<p>This change in the JNI implementation only affects apps that target Android 4.0 by setting either
-the <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> or
-<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> to
-{@code “14”} or higher. If you’ve set these attributes to any lower
-value, then JNI local references will behave the same as in previous versions.</p>
+the <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+targetSdkVersion}</a> or <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+minSdkVersion}</a> to {@code “14"} or higher. If you’ve set these attributes to any lower value,
+then JNI local references behave the same as in previous versions.</p>
@@ -1521,7 +1695,7 @@
<ul>
<li>Updated V8 JavaScript compiler for faster performance</li>
<li>Plus other notable enhancements carried over from <a
-href=”{@docRoot}sdk/android-3.0.html”>Android
+href="{@docRoot}sdk/android-3.0.html">Android
3.0</a> are now available for handsets:
<ul>
<li>Support for fixed position elements on all pages</li>
@@ -1563,43 +1737,142 @@
</ul>
-
-
-
-
-
-
-
-
-
-<h2 id="api-diff">API Differences Report</h2>
-
-<p>For a detailed view of all API changes in Android {@sdkPlatformVersion} (API
-Level
+<div class="special" style="margin-top:3em">
+<p>For a detailed view of all API changes in Android {@sdkPlatformVersion} (API Level
{@sdkPlatformApiLevel}), see the <a
-href="{@docRoot}sdk/api_diff/{@sdkPlatformApiLevel}/changes.html">API
-Differences Report</a>.</p>
+href="{@docRoot}sdk/api_diff/{@sdkPlatformApiLevel}/changes.html">API Differences Report</a>.</p>
+</div>
+<h2 id="Honeycomb">Previous APIs</h2>
+
+<p>In addition to everything above, Android 4.0 naturally supports all APIs from previous releases.
+Because the Android 3.x platform is available only for large-screen devices, if you've
+been developing primarily for handsets, then you might not be aware of all the APIs added to Android
+in these recent releases.</p>
+
+<p>Here's a look at some of the most notable APIs you might have missed that are now available
+on handsets as well:</p>
+
+<dl>
+ <dt><a href="android-3.0.html">Android 3.0</a></dt>
+ <dd>
+ <ul>
+ <li>{@link android.app.Fragment}: A framework component that allows you to separate distinct
+elements of an activity into self-contained modules that define their own UI and lifecycle. See the
+<a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</li>
+ <li>{@link android.app.ActionBar}: A replacement for the traditional title bar at the top of
+the activity window. It includes the application logo in the left corner and provides a new
+interface for menu items. See the
+<a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> developer guide.</li>
+ <li>{@link android.content.Loader}: A framework component that facilitates asynchronous
+loading of data in combination with UI components to dynamically load data without blocking the
+main thread. See the
+<a href="{@docRoot}guide/topics/fundamentals/loaders.html">Loaders</a> developer guide.</li>
+ <li>System clipboard: Applications can copy and paste data (beyond mere text) to and from
+the system-wide clipboard. Clipped data can be plain text, a URI, or an intent. See the
+<a href="{@docRoot}guide/topics/clipboard/copy-paste.html">Copy and Paste</a> developer guide.</li>
+ <li>Drag and drop: A set of APIs built into the view framework that facilitates drag and drop
+operations. See the
+<a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</li>
+ <li>An all new flexible animation framework allows you to animate arbitrary properties of any
+object (View, Drawable, Fragment, Object, or anything else) and define animation aspects such
+as duration, interpolation, repeat and more. The new framework makes Animations in Android
+simpler than ever. See the
+<a href="{@docRoot}guide/topics/graphics/prop-animation.html">Property Animation</a> developer
+guide.</li>
+ <li>RenderScript graphics and compute engine: RenderScript offers a high performance 3D
+graphics rendering and compute API at the native level, which you write in the C (C99 standard),
+providing the type of performance you expect from a native environment while remaining portable
+across various CPUs and GPUs. See the
+<a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer
+guide.</li>
+ <li>Hardware accelerated 2D graphics: You can now enable the OpenGL renderer for your
+application by setting {android:hardwareAccelerated="true"} in your manifest element's <a
+href="{@docRoot}guide/topics/manifest/application-element.html"><code><application></code></a>
+element or for individual <a
+href="{@docRoot}guide/topics/manifest/activity-element.html"><code><activity></code></a>
+elements. This results
+in smoother animations, smoother scrolling, and overall better performance and response to user
+interaction.
+ <p class="note"><strong>Note:</strong> If you set your application's <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> or <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> to
+{@code "14"} or higher, hardware acceleration is enabled by default.</p></li>
+ <li>And much, much more. See the <a href="android-3.0.html">Android 3.0 Platform</a>
+notes for more information.</li>
+ </ul>
+ </dd>
+
+ <dt><a href="android-3.1.html">Android 3.1</a></dt>
+ <dd>
+ <ul>
+ <li>USB APIs: Powerful new APIs for integrating connected peripherals with
+Android applications. The APIs are based on a USB stack and services that are
+built into the platform, including support for both USB host and device interactions. See the <a
+href="{@docRoot}guide/topics/usb/index.html">USB Host and Accessory</a> developer guide.</li>
+ <li>MTP/PTP APIs: Applications can interact directly with connected cameras and other PTP
+devices to receive notifications when devices are attached and removed, manage files and storage on
+those devices, and transfer files and metadata to and from them. The MTP API implements the PTP
+(Picture Transfer Protocol) subset of the MTP (Media Transfer Protocol) specification. See the
+{@link android.mtp} documentation.</li>
+ <li>RTP APIs: Android exposes an API to its built-in RTP (Real-time Transport Protocol) stack,
+which applications can use to manage on-demand or interactive data streaming. In particular, apps
+that provide VOIP, push-to-talk, conferencing, and audio streaming can use the API to initiate
+sessions and transmit or receive data streams over any available network. See the {@link
+android.net.rtp} documentation.</li>
+ <li>Support for joysticks and other generic motion inputs.</li>
+ <li>See the <a href="android-3.1.html">Android 3.1 Platform</a>
+notes for many more new APIs.</li>
+ </ul>
+ </dd>
+
+ <dt><a href="android-3.2.html">Android 3.2</a></dt>
+ <dd>
+ <ul>
+ <li>New screens support APIs that give you more control over how your applications are
+displayed across different screen sizes. The API extends the existing screen support model with the
+ability to precisely target specific screen size ranges by dimensions, measured in
+density-independent pixel units (such as 600dp or 720dp wide), rather than by their generalized
+screen sizes (such as large or xlarge). For example, this is important in order to help you
+distinguish between a 5" device and a 7" device, which would both traditionally be bucketed as
+"large" screens. See the blog post, <a
+href="http://android-developers.blogspot.com/2011/07/new-tools-for-managing-screen-sizes.html">
+New Tools for Managing Screen Sizes</a>.</li>
+ <li>New constants for <a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code <uses-feature>}</a> to
+declare landscape or portrait screen orientation requirements.</li>
+ <li>The device "screen size" configuration now changes during a screen orientation
+change. If your app targets API level 13 or higher, you must handle the {@code "screenSize"}
+configuration change if you also want to handle the {@code "orientation"} configuration change. See
+<a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
+android:configChanges}</a> for more information.</li>
+ <li>See the <a href="android-3.2.html">Android 3.2 Platform</a>
+notes for other new APIs.</li>
+ </ul>
+ </dd>
+
+</dl>
+
<h2 id="api-level">API Level</h2>
-<p>The Android {@sdkPlatformVersion} platform delivers an updated version of the framework API. The
-Android {@sdkPlatformVersion} API is assigned an integer identifier —
-<strong>{@sdkPlatformApiLevel}</strong> — that is stored in the system itself. This
-identifier, called the "API Level", allows the system to correctly determine whether an application
-is compatible with the system, prior to installing the application. </p>
+<p>The Android {@sdkPlatformVersion} API is assigned an integer
+identifier—<strong>{@sdkPlatformApiLevel}</strong>—that is stored in the system itself.
+This identifier, called the "API level", allows the system to correctly determine whether an
+application is compatible with the system, prior to installing the application. </p>
<p>To use APIs introduced in Android {@sdkPlatformVersion} in your application, you need compile the
-application against the Android library that is provided in the Android {@sdkPlatformVersion} SDK
-platform. Depending on your needs, you might also need to add an
+application against an Android platform that supports API level {@sdkPlatformApiLevel} or
+higher. Depending on your needs, you might also need to add an
<code>android:minSdkVersion="{@sdkPlatformApiLevel}"</code> attribute to the
-<code><uses-sdk></code> element in the application's manifest.</p>
+<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a>
+element.</p>
-<p>For more information about how to use API Level, see the <a
-href="{@docRoot}guide/appendix/api-levels.html">API Levels</a> document. </p>
+<p>For more information, see the <a href="{@docRoot}guide/appendix/api-levels.html">API Levels</a>
+document. </p>
<h2 id="apps">Built-in Applications</h2>
@@ -1614,6 +1887,7 @@
<li>API Demos</li>
<li>Browser</li>
<li>Calculator</li>
+<li>Calendar</li>
<li>Camera</li>
<li>Clock</li>
<li>Custom Locale</li>
@@ -1632,7 +1906,7 @@
<li>Phone</li>
<li>Search</li>
<li>Settings</li>
-<li>Spare Parts</li>
+<li>Speech Recorder</li>
<li>Speech Recorder</li>
<li>Widget Preview</li>
</ul>
@@ -1643,13 +1917,10 @@
<h2 id="locs" style="margin-top:.75em;">Locales</h2>
-<p>The system image included in the downloadable SDK platform provides a variety
-of
-built-in locales. In some cases, region-specific strings are available for the
-locales. In other cases, a default version of the language is used. The
-languages that are available in the Android 3.0 system
-image are listed below (with <em>language</em>_<em>country/region</em> locale
-descriptor).</p>
+<p>The system image included in the downloadable SDK platform provides a variety of built-in
+locales. In some cases, region-specific strings are available for the locales. In other cases, a
+default version of the language is used. The languages that are available in the Android 3.0 system
+image are listed below (with <em>language</em>_<em>country/region</em> locale descriptor).</p>
<table style="border:0;padding-bottom:0;margin-bottom:0;">
<tr>
@@ -1726,15 +1997,45 @@
<h2 id="skins">Emulator Skins</h2>
-<p>The downloadable platform includes the following emulator skin:</p>
+<p>The downloadable platform includes the following emulator skins:</p>
<ul>
<li>
- WVGA800 (1280x800, extra high density, normal screen)
+ QVGA (240x320, low density, small screen)
+ </li>
+ <li>
+ WQVGA400 (240x400, low density, normal screen)
+ </li>
+ <li>
+ WQVGA432 (240x432, low density, normal screen)
+ </li>
+ <li>
+ HVGA (320x480, medium density, normal screen)
+ </li>
+ <li>
+ WVGA800 (480x800, high density, normal screen)
+ </li>
+ <li>
+ WVGA854 (480x854 high density, normal screen)
+ </li>
+ <li>
+ WXGA720 (1280x720, extra-high density, normal screen) <span class="new">new</span>
+ </li>
+ <li>
+ WSVGA (1024x600, medium density, large screen) <span class="new">new</span>
+ </li>
+ <li>
+ WXGA (1280x800, medium density, xlarge screen)
</li>
</ul>
-<p>For more information about how to develop an application that displays
-and functions properly on all Android-powered devices, see <a
-href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
-Screens</a>.</p>
+<p>To test your application on an emulator that represents the latest Android device, you can create
+an AVD with the new WXGA720 skin (it's an xhdpi, normal screen device). Note that the emulator
+currently doesn't support the new on-screen navigation bar for devices without hardware navigation
+buttons, so when using this skin, you must use keyboard keys <em>Home</em> for the Home button,
+<em>ESC</em> for the Back button, and <em>F2</em> or <em>Page-up</em> for the Menu button.</p>
+
+<p>However, due to performance issues in the emulator when running high-resolution screens such as
+the one for the WXGA720 skin, we recommend that you primarily use the traditional WVGA800 skin
+(hdpi, normal screen) to test your application.</p>
+
diff --git a/docs/html/sdk/compatibility-library.jd b/docs/html/sdk/compatibility-library.jd
index c8cd5b2..8b19fb47 100644
--- a/docs/html/sdk/compatibility-library.jd
+++ b/docs/html/sdk/compatibility-library.jd
@@ -1,4 +1,4 @@
-page.title=Compatibility Package
+page.title=Support Package
@jd:body
@@ -8,7 +8,7 @@
<h2>In this document</h2>
<ol>
<li><a href="#Notes">Revisions</a></li>
- <li><a href="#Downloading">Downloading the Compatibility Package</a></li>
+ <li><a href="#Downloading">Downloading the Support Package</a></li>
<li><a href="#SettingUp">Setting Up a Project to Use a Library</a></li>
<li><a href="#Using">Using the v4 Library APIs</a></li>
<li><a href="#Docs">Reference Docs</a></li>
@@ -27,28 +27,118 @@
<p><em>Minimum API level supported:</em> <b>4</b></p>
-<p>The Compatibility Package includes static "support libraries" that you can add to your Android
+<p>The Support Package includes static "support libraries" that you can add to your Android
application in order to use APIs that are either not available for older platform versions or that
offer "utility" APIs that aren't a part of the framework APIs. The goal is to simplify your
development by offering more APIs that you can bundle with your application so you can
worry less about platform versions.</p>
-<p class="note"><strong>Note:</strong> The Compatibility Package includes more than one support
+<p class="note"><strong>Note:</strong> The Support Package includes more than one support
library. Each one has a different <em>minimum API level</em>. For example, one library requires API
-level 4 or higher, while another requires API level 13 or higher. The minimum version is indicated
+level 4 or higher, while another requires API level 13 or higher (v13 is a superset of v4 and includes additional
+support classes to work with v13 APIs). The minimum version is indicated
by the directory name, such as {@code v4/} and {@code v13/}.</p>
<h2 id="Notes">Revisions</h2>
<p>The sections below provide notes about successive releases of
-the Compatibility Package, as denoted by revision number.</p>
+the Support Package, as denoted by revision number.</p>
+
<div class="toggle-content open">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img" />
+ Support Package, revision 4 (October 2011)
+ </a></p>
+
+ <div class="toggle-content-toggleme" style="padding-left:2em">
+ <dl>
+ <dt>Changes for v4 support library:</dt>
+ <dd>
+ <ul>
+ <li>Support for Accessiblity APIs:
+ <ul>
+ <li>Added <code>AccessibilityDelegateCompat</code> to support
+ {@link android.view.View.AccessibilityDelegate}.</li>
+
+ <li>Added <code>AccessibilityEventCompat</code> to support
+ {@link android.view.accessibility.AccessibilityEvent}.</li>
+
+ <li>Added <code>AccessibilityManagerCompat</code> to support
+ {@link android.view.accessibility.AccessibilityManager}.</li>
+
+ <li>Added <code>AccessibilityNodeInfoCompat</code> to support
+ {@link android.view.accessibility.AccessibilityNodeInfo}.</li>
+
+ <li>Added <code>AccessibilityRecordCompat</code> to support
+ {@link android.view.accessibility.AccessibilityRecord}.</li>
+
+ <li>Added <code>AccessibilityServiceInfoCompat</code> to support
+ {@link android.accessibilityservice.AccessibilityServiceInfo}.</li>
+
+ <li>Added <code>ViewGroupCompat</code>
+ to support accessibility features in {@link android.view.ViewGroup}.
+ </li>
+
+ <li>Modified <code>ViewCompat</code>
+ to support accessibility features in {@link android.view.View}.</li>
+ </ul>
+ </li>
+
+ <li>Added <code>EdgeEffectCompat</code> to
+ support {@link android.widget.EdgeEffect}.</li>
+
+ <li>Added <code>LocalBroadcastManager</code> to allow applications to easily
+ register for and receive intents within a single application without
+ broadcasting them globally.</li>
+
+ <li>Added support in <code>ViewCompat</code> to check for and set overscroll
+ modes for {@link android.view.View}s on Android 2.3 and later.</li>
+ <li>Changes to Fragment APIs:
+ <ul>
+ <li>Added new APIs to control the visibility of new menus.</li>
+ <li>Added custom animation APIs.</li>
+ <li>Added APIs in <code>FragmentActivity</code> to retain custom,
+ non-configuration instance data.</li>
+ <li>Various bug fixes.</li>
+ </ul>
+ </li>
+ <li>Changes to <code>ViewPager</code>:
+ <ul>
+ <li>Added support for margins between pages.
+ An optional {@link android.graphics.drawable.Drawable} can be provided
+ to fill the margins.</li>
+ <li>Added support for {@link android.widget.EdgeEffect}.</li>
+ <li>Added support for keyboard navigation</li>
+ <li>Added support to control how many pages are kept to either side
+ of the current page.</li>
+ <li>Improved touch physics.</li>
+ </ul>
+ </li>
+
+ <li>Fixed a {@link android.content.Loader} bug that caused issues in
+ canceling {@link android.os.AsyncTask}s when running on Froyo and older
+ versions of the platform. The support
+ code now uses its own version of {@link android.os.AsyncTask} to keep the same
+ behavior on all platform versions.</li>
+
+ </ul>
+ </dd>
+ </dl>
+ </div>
+
+
+
+</div>
+
+
+<div class="toggle-content closed">
+
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" />
Compatibility Package, revision 3 (July 2011)
</a></p>
@@ -136,9 +226,9 @@
-<h2 id="Downloading">Downloading the Compatibility Package</h2>
+<h2 id="Downloading">Downloading the Support Package</h2>
-<p>The Compatibility Package is provided as a downloadable package from the Android SDK and AVD
+<p>The Support Package is provided as a downloadable package from the Android SDK and AVD
Manager. To install:</p>
<ol>
@@ -147,13 +237,13 @@
> <strong>Android SDK and AVD Manager</strong>. Or, launch {@code SDK Manager.exe} from
the {@code <sdk>/} directory (on Windows only) or {@code android} from the {@code
<sdk>/tools/} directory.</p></li>
- <li>Expand the Android Repository, check <strong>Android Compatibility package</strong>
+ <li>Expand the Android Repository, check <strong>Android Support package</strong>
and click <strong>Install selected</strong>.</li>
<li>Proceed to install the package.</li>
</ol>
<p>When done, all files (including source code, samples, and the {@code .jar} files) are saved
-into the <code><sdk>/extras/android/compatibility/</code> directory. This directory contains
+into the <code><sdk>/extras/android/support/</code> directory. This directory contains
each of the different support libraries, such as the library for API level 4 and up and the library
for API level 13 and up, each named with the respective version (such as {@code v4/}).</p>
@@ -167,7 +257,7 @@
<li>Locate the JAR file for the library you want to use and copy it into the {@code
libs/} directory.
<p>For example, the library that supports API level 4 and up is located at {@code
-<sdk>/extras/android/compatibility/v4/android-support-v4.jar}.</p>
+<sdk>/extras/android/support/v4/android-support-v4.jar}.</p>
</li>
<li>Add the JAR to your project build path.
<p>In Eclipse, right-click the JAR file in the Package Explorer, select <strong>Build
@@ -181,7 +271,7 @@
example, {@code android.support.v4}).</p>
<p class="note"><strong>Tip:</strong> To see the library APIs in action, take a look at the sample
-apps in {@code extras/android/compatibility/<version>/samples/}.</p>
+apps in {@code extras/android/support/<version>/samples/}.</p>
<p class="warning"><strong>Warning:</strong> Be certain that you not confuse the standard
{@code android} packages with those in {@code android.support} library. Some code completion tools
@@ -265,7 +355,7 @@
library:</p>
<pre class="no-pretty-print">
-cd <sdk>/extras/android/compatibility/v4/
+cd <sdk>/extras/android/support/v4/
mkdir docs
javadoc -sourcepath src/java/ -subpackages android.support.v4 -d docs
</pre>
@@ -275,8 +365,8 @@
<h2 id="Samples">Samples</h2>
<p>If you want to see some code that uses the support libraries, samples are included with the
-Compatibility Package, inside each support library directory. For example, at {@code
-extras/android/compatibility/v4/samples/}.</p>
+Support Package, inside each support library directory. For example, at {@code
+extras/android/support/v4/samples/}.</p>
<p>Additionally, the <a href="http://code.google.com/p/iosched/">Google I/O App</a> is a complete
application that uses the v4 support library to provide a single APK for both handsets and tablets
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index 333efa2..59675a8 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -1,8 +1,8 @@
page.title=ADT Plugin for Eclipse
adt.zip.version=14.0.0
adt.zip.download=ADT-14.0.0.zip
-adt.zip.bytes=6745584
-adt.zip.checksum=a645330d90fd9dae6187662bb1c3c644
+adt.zip.bytes=6747816
+adt.zip.checksum=3883973cd229dc4336911117af949509
@jd:body
@@ -66,6 +66,9 @@
<p>The sections below provide notes about successive releases of
the ADT Plugin, as denoted by revision number. </p>
+<p>For a summary of all known issues in ADT, see <a
+href="http://tools.android.com/release/knownissues">http://tools.android.com/release/knownissues</a>.</p>
+
<script type="text/javascript">
function toggleDiv(link) {
var toggleable = $(link).parent();
diff --git a/docs/html/sdk/images/4.0/allapps-lg.png b/docs/html/sdk/images/4.0/allapps-lg.png
new file mode 100644
index 0000000..f5eba3c
--- /dev/null
+++ b/docs/html/sdk/images/4.0/allapps-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/allapps.png b/docs/html/sdk/images/4.0/allapps.png
new file mode 100644
index 0000000..317a49a
--- /dev/null
+++ b/docs/html/sdk/images/4.0/allapps.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/bbench.png b/docs/html/sdk/images/4.0/bbench.png
new file mode 100644
index 0000000..f113092
--- /dev/null
+++ b/docs/html/sdk/images/4.0/bbench.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/beam-lg.png b/docs/html/sdk/images/4.0/beam-lg.png
new file mode 100644
index 0000000..608fc94
--- /dev/null
+++ b/docs/html/sdk/images/4.0/beam-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/beam-maps-lg.png b/docs/html/sdk/images/4.0/beam-maps-lg.png
new file mode 100644
index 0000000..96ac235
--- /dev/null
+++ b/docs/html/sdk/images/4.0/beam-maps-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/beam-maps.png b/docs/html/sdk/images/4.0/beam-maps.png
new file mode 100644
index 0000000..63b6756
--- /dev/null
+++ b/docs/html/sdk/images/4.0/beam-maps.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/beam.png b/docs/html/sdk/images/4.0/beam.png
new file mode 100644
index 0000000..0eb7d26
--- /dev/null
+++ b/docs/html/sdk/images/4.0/beam.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/browser-lg.png b/docs/html/sdk/images/4.0/browser-lg.png
new file mode 100644
index 0000000..fe3fe81
--- /dev/null
+++ b/docs/html/sdk/images/4.0/browser-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/browser-tabs-lg.png b/docs/html/sdk/images/4.0/browser-tabs-lg.png
new file mode 100644
index 0000000..0ea8f10
--- /dev/null
+++ b/docs/html/sdk/images/4.0/browser-tabs-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/browser-tabs.png b/docs/html/sdk/images/4.0/browser-tabs.png
new file mode 100644
index 0000000..413b0c6
--- /dev/null
+++ b/docs/html/sdk/images/4.0/browser-tabs.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/browser.png b/docs/html/sdk/images/4.0/browser.png
new file mode 100644
index 0000000..4bc8179
--- /dev/null
+++ b/docs/html/sdk/images/4.0/browser.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/calendar-widget-lg.png b/docs/html/sdk/images/4.0/calendar-widget-lg.png
new file mode 100644
index 0000000..39fc986
--- /dev/null
+++ b/docs/html/sdk/images/4.0/calendar-widget-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/calendar-widget.png b/docs/html/sdk/images/4.0/calendar-widget.png
new file mode 100644
index 0000000..80a57f7
--- /dev/null
+++ b/docs/html/sdk/images/4.0/calendar-widget.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/camera-lg.png b/docs/html/sdk/images/4.0/camera-lg.png
new file mode 100644
index 0000000..7d96a4f
--- /dev/null
+++ b/docs/html/sdk/images/4.0/camera-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/camera.png b/docs/html/sdk/images/4.0/camera.png
new file mode 100644
index 0000000..7454549
--- /dev/null
+++ b/docs/html/sdk/images/4.0/camera.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/contact-call-lg.png b/docs/html/sdk/images/4.0/contact-call-lg.png
new file mode 100644
index 0000000..40b1f40
--- /dev/null
+++ b/docs/html/sdk/images/4.0/contact-call-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/contact-call.png b/docs/html/sdk/images/4.0/contact-call.png
new file mode 100644
index 0000000..5550b57
--- /dev/null
+++ b/docs/html/sdk/images/4.0/contact-call.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/contact-call.xcf b/docs/html/sdk/images/4.0/contact-call.xcf
new file mode 100644
index 0000000..3046e92
--- /dev/null
+++ b/docs/html/sdk/images/4.0/contact-call.xcf
Binary files differ
diff --git a/docs/html/sdk/images/4.0/contact-connect-lg.png b/docs/html/sdk/images/4.0/contact-connect-lg.png
new file mode 100644
index 0000000..ad0d04c
--- /dev/null
+++ b/docs/html/sdk/images/4.0/contact-connect-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/contact-connect.png b/docs/html/sdk/images/4.0/contact-connect.png
new file mode 100644
index 0000000..d958206
--- /dev/null
+++ b/docs/html/sdk/images/4.0/contact-connect.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/contact-email-lg.png b/docs/html/sdk/images/4.0/contact-email-lg.png
new file mode 100644
index 0000000..db75a46
--- /dev/null
+++ b/docs/html/sdk/images/4.0/contact-email-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/contact-email.png b/docs/html/sdk/images/4.0/contact-email.png
new file mode 100644
index 0000000..9e5460d
--- /dev/null
+++ b/docs/html/sdk/images/4.0/contact-email.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/contact-faves-lg.png b/docs/html/sdk/images/4.0/contact-faves-lg.png
new file mode 100644
index 0000000..1ec3fd0
--- /dev/null
+++ b/docs/html/sdk/images/4.0/contact-faves-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/contact-faves.png b/docs/html/sdk/images/4.0/contact-faves.png
new file mode 100644
index 0000000..57e4ca6
--- /dev/null
+++ b/docs/html/sdk/images/4.0/contact-faves.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/face-unlock-lg.png b/docs/html/sdk/images/4.0/face-unlock-lg.png
new file mode 100644
index 0000000..3fd1695
--- /dev/null
+++ b/docs/html/sdk/images/4.0/face-unlock-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/face-unlock.png b/docs/html/sdk/images/4.0/face-unlock.png
new file mode 100644
index 0000000..00afb83
--- /dev/null
+++ b/docs/html/sdk/images/4.0/face-unlock.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/folders.xcf b/docs/html/sdk/images/4.0/folders.xcf
new file mode 100644
index 0000000..66cc02c
--- /dev/null
+++ b/docs/html/sdk/images/4.0/folders.xcf
Binary files differ
diff --git a/docs/html/sdk/images/4.0/gallery-edit-lg.png b/docs/html/sdk/images/4.0/gallery-edit-lg.png
new file mode 100644
index 0000000..3d6688f
--- /dev/null
+++ b/docs/html/sdk/images/4.0/gallery-edit-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/gallery-edit.png b/docs/html/sdk/images/4.0/gallery-edit.png
new file mode 100644
index 0000000..69744ec
--- /dev/null
+++ b/docs/html/sdk/images/4.0/gallery-edit.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/gallery-share-lg.png b/docs/html/sdk/images/4.0/gallery-share-lg.png
new file mode 100644
index 0000000..749f51e
--- /dev/null
+++ b/docs/html/sdk/images/4.0/gallery-share-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/gallery-share.png b/docs/html/sdk/images/4.0/gallery-share.png
new file mode 100644
index 0000000..443a70c
--- /dev/null
+++ b/docs/html/sdk/images/4.0/gallery-share.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/gallery-widget.png b/docs/html/sdk/images/4.0/gallery-widget.png
new file mode 100644
index 0000000..e72fd0d
--- /dev/null
+++ b/docs/html/sdk/images/4.0/gallery-widget.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/home-lg.png b/docs/html/sdk/images/4.0/home-lg.png
new file mode 100644
index 0000000..5b9021d
--- /dev/null
+++ b/docs/html/sdk/images/4.0/home-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/home.png b/docs/html/sdk/images/4.0/home.png
new file mode 100644
index 0000000..cd24732
--- /dev/null
+++ b/docs/html/sdk/images/4.0/home.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/live-effects.png b/docs/html/sdk/images/4.0/live-effects.png
new file mode 100644
index 0000000..11a0122
--- /dev/null
+++ b/docs/html/sdk/images/4.0/live-effects.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/lock-camera-lg.png b/docs/html/sdk/images/4.0/lock-camera-lg.png
new file mode 100644
index 0000000..2a169b3
--- /dev/null
+++ b/docs/html/sdk/images/4.0/lock-camera-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/lock-camera.png b/docs/html/sdk/images/4.0/lock-camera.png
new file mode 100644
index 0000000..a5c63c3
--- /dev/null
+++ b/docs/html/sdk/images/4.0/lock-camera.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/lock-lg.png b/docs/html/sdk/images/4.0/lock-lg.png
new file mode 100644
index 0000000..b859e11
--- /dev/null
+++ b/docs/html/sdk/images/4.0/lock-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/lock.png b/docs/html/sdk/images/4.0/lock.png
new file mode 100644
index 0000000..d168826
--- /dev/null
+++ b/docs/html/sdk/images/4.0/lock.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/quick-responses-lg.png b/docs/html/sdk/images/4.0/quick-responses-lg.png
new file mode 100644
index 0000000..39cea9a
--- /dev/null
+++ b/docs/html/sdk/images/4.0/quick-responses-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/quick-responses.png b/docs/html/sdk/images/4.0/quick-responses.png
new file mode 100644
index 0000000..d43f348
--- /dev/null
+++ b/docs/html/sdk/images/4.0/quick-responses.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/screenshot-lg.png b/docs/html/sdk/images/4.0/screenshot-lg.png
new file mode 100644
index 0000000..30ac339
--- /dev/null
+++ b/docs/html/sdk/images/4.0/screenshot-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/screenshot.png b/docs/html/sdk/images/4.0/screenshot.png
new file mode 100644
index 0000000..b23c913
--- /dev/null
+++ b/docs/html/sdk/images/4.0/screenshot.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/tasks-lg.png b/docs/html/sdk/images/4.0/tasks-lg.png
new file mode 100644
index 0000000..58b5c5d
--- /dev/null
+++ b/docs/html/sdk/images/4.0/tasks-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/tasks.png b/docs/html/sdk/images/4.0/tasks.png
new file mode 100644
index 0000000..34a9d4a
--- /dev/null
+++ b/docs/html/sdk/images/4.0/tasks.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/text-replace-lg.png b/docs/html/sdk/images/4.0/text-replace-lg.png
new file mode 100644
index 0000000..047d802
--- /dev/null
+++ b/docs/html/sdk/images/4.0/text-replace-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/text-replace.png b/docs/html/sdk/images/4.0/text-replace.png
new file mode 100644
index 0000000..d2bda3e
--- /dev/null
+++ b/docs/html/sdk/images/4.0/text-replace.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/tts-lg.png b/docs/html/sdk/images/4.0/tts-lg.png
new file mode 100644
index 0000000..2f49051
--- /dev/null
+++ b/docs/html/sdk/images/4.0/tts-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/tts.png b/docs/html/sdk/images/4.0/tts.png
new file mode 100644
index 0000000..3eae634
--- /dev/null
+++ b/docs/html/sdk/images/4.0/tts.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/usage-all-lg.png b/docs/html/sdk/images/4.0/usage-all-lg.png
new file mode 100644
index 0000000..fd7eeba
--- /dev/null
+++ b/docs/html/sdk/images/4.0/usage-all-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/usage-all.png b/docs/html/sdk/images/4.0/usage-all.png
new file mode 100644
index 0000000..048db83
--- /dev/null
+++ b/docs/html/sdk/images/4.0/usage-all.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/usage-maps-lg.png b/docs/html/sdk/images/4.0/usage-maps-lg.png
new file mode 100644
index 0000000..b144370
--- /dev/null
+++ b/docs/html/sdk/images/4.0/usage-maps-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/usage-maps.png b/docs/html/sdk/images/4.0/usage-maps.png
new file mode 100644
index 0000000..a6dcd21
--- /dev/null
+++ b/docs/html/sdk/images/4.0/usage-maps.png
Binary files differ
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 065f41b..82db803 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -2,20 +2,20 @@
sdk.redirect=0
sdk.win_installer=installer_r14-windows.exe
-sdk.win_installer_bytes=33860145
-sdk.win_installer_checksum=7a563491bf4671d09b9da0dcde85f212
+sdk.win_installer_bytes=33853391
+sdk.win_installer_checksum=4f1cb329a41328c2cee2908b31ae6f6b
sdk.win_download=android-sdk_r14-windows.zip
-sdk.win_bytes=33852972
-sdk.win_checksum=d1381a0cc8e6f9358174aa6d051ba379
+sdk.win_bytes=33846273
+sdk.win_checksum=48d44ae4cfcadede68621acb53caee80
sdk.mac_download=android-sdk_r14-macosx.zip
-sdk.mac_bytes=30426052
-sdk.mac_checksum=df0a5c5b5327ffcaf256ce735998e12a
+sdk.mac_bytes=30428734
+sdk.mac_checksum=812887018435382de8486f3bb26a5db4
sdk.linux_download=android-sdk_r14-linux.tgz
-sdk.linux_bytes=26083315
-sdk.linux_checksum=2049d5c1a164fcae47a5e93c52200752
+sdk.linux_bytes=26075938
+sdk.linux_checksum=35c989ff67184766dc4960813ede8ab5
@jd:body
diff --git a/docs/html/sdk/oem-usb.jd b/docs/html/sdk/oem-usb.jd
index ad3be4a..88bf008 100644
--- a/docs/html/sdk/oem-usb.jd
+++ b/docs/html/sdk/oem-usb.jd
@@ -55,6 +55,14 @@
</tr>
<tr>
<td>
+ Fujitsu
+ </td>
+ <td><a
+href="http://www.fmworld.net/product/phone/sp/android/develop/">http://www.fmworld.net/product/phone/sp/android/develop/</a>
+ </td>
+ </tr>
+ <tr>
+ <td>
Fujitsu Toshiba
</td>
<td><a
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index 9bc9b9a..a33bbca 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -79,7 +79,7 @@
<div><a href="<?cs var:toroot ?>sdk/android-4.0.html">
<span class="en">Android 4.0 Platform</span></a> <span class="new">new!</span></div>
<ul>
- <!-- <li><a href="<?cs var:toroot ?>sdk/android-4.0-highlights.html">Platform Highlights</a></li> -->
+ <li><a href="<?cs var:toroot ?>sdk/android-4.0-highlights.html">Platform Highlights</a></li>
<li><a href="<?cs var:toroot ?>sdk/api_diff/14/changes.html">API Differences Report »</a></li>
</ul>
</li>
@@ -150,11 +150,11 @@
</li>
</ul>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r14</a> <span
-class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r14</a>
+ <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>sdk/win-usb.html">Google USB Driver, r4</a></li>
- <li><a href="<?cs var:toroot ?>sdk/compatibility-library.html">Compatibility Package,
-r3</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/compatibility-library.html">Support Package, r4</a>
+ <span class="new">new!</span></li>
</ul>
</li>
<li>
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index 2d044ed..f5b61ee 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -23,6 +23,9 @@
Tools you are using, refer to the "Installed Packages" listing in the Android SDK
and AVD Manager. </p>
+<p>For a summary of all known issues in SDK Tools, see <a
+href="http://tools.android.com/release/knownissues">http://tools.android.com/release/knownissues</a>.</p>
+
<script type="text/javascript">
function toggleDiv(link) {
var toggleable = $(link).parent();
@@ -66,7 +69,12 @@
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
width="9px" />SDK Tools, Revision 14</a> <em>(October 2011)</em>
+
<div class="toggleme">
+ <p class="note"><strong>Important:</strong> To download the new Android
+ 4.0 system components from the Android SDK Manager, you must first update the
+ SDK tools to revision 14 and restart the Android SDK Manager. If you do not,
+ the Android 4.0 system components will not be available for download.</p>
<dl>
<dt>Dependencies:</dt>
<dd>
@@ -81,6 +89,9 @@
<dt>General notes:</dt>
<dd>
<ul>
+ <li>Added webcam support to Android 4.0 or later platforms to emulate rear-facing cameras when one webcam is present,
+ and to emulate both rear-facing and front-facing cameras when two webcams are present. Webcam suport is for Windows and Linux only.
+ Mac support will come in a later release.</li>
<li>Changed <code>default.properties</code> to <code>project.properties</code> and
<code>build.properties</code> to <code>ant.properties</code>. Any existing
projects that you build with Ant must be updated with the <code>android update project</code>
@@ -90,7 +101,6 @@
commands, see the
<a href="{@docRoot}guide/developing/building/building-cmdline.html#AntReference">Ant Command
Reference</a>.</li>
-
<li>Changed how library projects are built.</a></li>
<li>Improved incremental builds, so that resource compilation runs less frequently. Builds no
longer run when you edit strings or layouts (unless you add a new <code>id</code>) and no longer
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index de0fabc..50964d5 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -285,7 +285,7 @@
of the fill (if any) without worrying about blending artifacts.
*/
final boolean useLayer = haveStroke && haveFill && st.mShape != LINE &&
- currStrokeAlpha < 255;
+ currStrokeAlpha < 255 && (mAlpha < 255 || mColorFilter != null);
/* Drawing with a layer is slower than direct drawing, but it
allows us to apply paint effects like alpha and colorfilter to
diff --git a/include/binder/CursorWindow.h b/include/binder/CursorWindow.h
index d227244..f0284de 100644
--- a/include/binder/CursorWindow.h
+++ b/include/binder/CursorWindow.h
@@ -21,18 +21,8 @@
#include <stddef.h>
#include <stdint.h>
-#include <binder/IMemory.h>
-#include <utils/RefBase.h>
-
-#define DEFAULT_WINDOW_SIZE 4096
-#define WINDOW_ALLOCATION_SIZE 4096
-
-#define ROW_SLOT_CHUNK_NUM_ROWS 16
-
-// Row slots are allocated in chunks of ROW_SLOT_CHUNK_NUM_ROWS,
-// with an offset after the rows that points to the next chunk
-#define ROW_SLOT_CHUNK_SIZE ((ROW_SLOT_CHUNK_NUM_ROWS * sizeof(row_slot_t)) + sizeof(uint32_t))
-
+#include <binder/Parcel.h>
+#include <utils/String8.h>
#if LOG_NDEBUG
@@ -46,176 +36,156 @@
#endif
-
-// When defined to true strings are stored as UTF8, otherwise they're UTF16
-#define WINDOW_STORAGE_UTF8 1
-
-// When defined to true numberic values are stored inline in the field_slot_t, otherwise they're allocated in the window
-#define WINDOW_STORAGE_INLINE_NUMERICS 1
-
namespace android {
-typedef struct
-{
- uint32_t numRows;
- uint32_t numColumns;
-} window_header_t;
-
-typedef struct
-{
- uint32_t offset;
-} row_slot_t;
-
-typedef struct
-{
- uint8_t type;
- union {
- double d;
- int64_t l;
- struct {
- uint32_t offset;
- uint32_t size;
- } buffer;
- } data;
-} __attribute__((packed)) field_slot_t;
-
-#define FIELD_TYPE_NULL 0
-#define FIELD_TYPE_INTEGER 1
-#define FIELD_TYPE_FLOAT 2
-#define FIELD_TYPE_STRING 3
-#define FIELD_TYPE_BLOB 4
-
/**
* This class stores a set of rows from a database in a buffer. The begining of the
- * window has first chunk of row_slot_ts, which are offsets to the row directory, followed by
- * an offset to the next chunk in a linked-list of additional chunk of row_slot_ts in case
+ * window has first chunk of RowSlots, which are offsets to the row directory, followed by
+ * an offset to the next chunk in a linked-list of additional chunk of RowSlots in case
* the pre-allocated chunk isn't big enough to refer to all rows. Each row directory has a
- * field_slot_t per column, which has the size, offset, and type of the data for that field.
+ * FieldSlot per column, which has the size, offset, and type of the data for that field.
* Note that the data types come from sqlite3.h.
+ *
+ * Strings are stored in UTF-8.
*/
-class CursorWindow
-{
+class CursorWindow {
+ CursorWindow(const String8& name, int ashmemFd,
+ void* data, size_t size, bool readOnly);
+
public:
- CursorWindow(size_t maxSize);
- CursorWindow(){}
- bool setMemory(const sp<IMemory>&);
- ~CursorWindow();
+ /* Field types. */
+ enum {
+ FIELD_TYPE_NULL = 0,
+ FIELD_TYPE_INTEGER = 1,
+ FIELD_TYPE_FLOAT = 2,
+ FIELD_TYPE_STRING = 3,
+ FIELD_TYPE_BLOB = 4,
+ };
- bool initBuffer(bool localOnly);
- sp<IMemory> getMemory() {return mMemory;}
+ /* Opaque type that describes a field slot. */
+ struct FieldSlot {
+ private:
+ int32_t type;
+ union {
+ double d;
+ int64_t l;
+ struct {
+ uint32_t offset;
+ uint32_t size;
+ } buffer;
+ } data;
- size_t size() {return mSize;}
- uint8_t * data() {return mData;}
- uint32_t getNumRows() {return mHeader->numRows;}
- uint32_t getNumColumns() {return mHeader->numColumns;}
- void freeLastRow() {
- if (mHeader->numRows > 0) {
- mHeader->numRows--;
- }
- }
- bool setNumColumns(uint32_t numColumns)
- {
- uint32_t cur = mHeader->numColumns;
- if (cur > 0 && cur != numColumns) {
- LOGE("Trying to go from %d columns to %d", cur, numColumns);
- return false;
- }
- mHeader->numColumns = numColumns;
- return true;
- }
+ friend class CursorWindow;
+ } __attribute((packed));
- int32_t freeSpace();
+ ~CursorWindow();
- void clear();
+ static status_t create(const String8& name, size_t size, CursorWindow** outCursorWindow);
+ static status_t createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow);
- /**
- * Allocate a row slot and its directory. The returned
- * pointer points to the begining of the row's directory
- * or NULL if there wasn't room. The directory is
- * initialied with NULL entries for each field.
- */
- field_slot_t * allocRow();
+ status_t writeToParcel(Parcel* parcel);
- /**
- * Allocate a portion of the window. Returns the offset
- * of the allocation, or 0 if there isn't enough space.
- * If aligned is true, the allocation gets 4 byte alignment.
- */
- uint32_t alloc(size_t size, bool aligned = false);
+ inline String8 name() { return mName; }
+ inline size_t size() { return mSize; }
+ inline size_t freeSpace() { return mSize - mHeader->freeOffset; }
+ inline uint32_t getNumRows() { return mHeader->numRows; }
+ inline uint32_t getNumColumns() { return mHeader->numColumns; }
- /**
- * Copy data into the window at the given offset.
- */
- void copyIn(uint32_t offset, uint8_t const * data, size_t size);
- void copyIn(uint32_t offset, int64_t data);
- void copyIn(uint32_t offset, double data);
-
- void copyOut(uint32_t offset, uint8_t * data, size_t size);
- int64_t copyOutLong(uint32_t offset);
- double copyOutDouble(uint32_t offset);
-
- bool putLong(unsigned int row, unsigned int col, int64_t value);
- bool putDouble(unsigned int row, unsigned int col, double value);
- bool putNull(unsigned int row, unsigned int col);
-
- bool getLong(unsigned int row, unsigned int col, int64_t * valueOut);
- bool getDouble(unsigned int row, unsigned int col, double * valueOut);
- bool getNull(unsigned int row, unsigned int col, bool * valueOut);
-
- uint8_t * offsetToPtr(uint32_t offset) {return mData + offset;}
-
- row_slot_t * allocRowSlot();
-
- row_slot_t * getRowSlot(int row);
-
- /**
- * return NULL if Failed to find rowSlot or
- * Invalid rowSlot
- */
- field_slot_t * getFieldSlotWithCheck(int row, int column);
- field_slot_t * getFieldSlot(int row, int column)
- {
- int fieldDirOffset = getRowSlot(row)->offset;
- return ((field_slot_t *)offsetToPtr(fieldDirOffset)) + column;
- }
-
- int64_t getFieldSlotValueLong(field_slot_t* fieldSlot) {
-#if WINDOW_STORAGE_INLINE_NUMERICS
- return fieldSlot->data.l;
-#else
- return copyOutLong(fieldSlot->data.buffer.offset);
-#endif
- }
-
- double getFieldSlotValueDouble(field_slot_t* fieldSlot) {
-#if WINDOW_STORAGE_INLINE_NUMERICS
- return fieldSlot->data.d;
-#else
- return copyOutDouble(fieldSlot->data.buffer.offset);
-#endif
- }
-
-#if WINDOW_STORAGE_UTF8
- char* getFieldSlotValueString(field_slot_t* fieldSlot) {
- return reinterpret_cast<char*>(offsetToPtr(fieldSlot->data.buffer.offset));
- }
-#else
- char16_t* getFieldSlotValueString(field_slot_t* fieldSlot) {
- return reinterpret_cast<char16_t*>(offsetToPtr(fieldSlot->data.buffer.offset));
- }
-#endif
-
-private:
- uint8_t * mData;
- size_t mSize;
- size_t mMaxSize;
- window_header_t * mHeader;
- sp<IMemory> mMemory;
+ status_t clear();
+ status_t setNumColumns(uint32_t numColumns);
/**
- * Offset of the lowest unused data byte in the array.
+ * Allocate a row slot and its directory.
+ * The row is initialized will null entries for each field.
*/
- uint32_t mFreeOffset;
+ status_t allocRow();
+ status_t freeLastRow();
+
+ status_t putBlob(uint32_t row, uint32_t column, const void* value, size_t size);
+ status_t putString(uint32_t row, uint32_t column, const char* value, size_t sizeIncludingNull);
+ status_t putLong(uint32_t row, uint32_t column, int64_t value);
+ status_t putDouble(uint32_t row, uint32_t column, double value);
+ status_t putNull(uint32_t row, uint32_t column);
+
+ /**
+ * Gets the field slot at the specified row and column.
+ * Returns null if the requested row or column is not in the window.
+ */
+ FieldSlot* getFieldSlot(uint32_t row, uint32_t column);
+
+ inline int32_t getFieldSlotType(FieldSlot* fieldSlot) {
+ return fieldSlot->type;
+ }
+
+ inline int64_t getFieldSlotValueLong(FieldSlot* fieldSlot) {
+ return fieldSlot->data.l;
+ }
+
+ inline double getFieldSlotValueDouble(FieldSlot* fieldSlot) {
+ return fieldSlot->data.d;
+ }
+
+ inline const char* getFieldSlotValueString(FieldSlot* fieldSlot,
+ size_t* outSizeIncludingNull) {
+ *outSizeIncludingNull = fieldSlot->data.buffer.size;
+ return static_cast<char*>(offsetToPtr(fieldSlot->data.buffer.offset));
+ }
+
+ inline const void* getFieldSlotValueBlob(FieldSlot* fieldSlot, size_t* outSize) {
+ *outSize = fieldSlot->data.buffer.size;
+ return offsetToPtr(fieldSlot->data.buffer.offset);
+ }
+
+private:
+ static const size_t ROW_SLOT_CHUNK_NUM_ROWS = 100;
+
+ struct Header {
+ // Offset of the lowest unused byte in the window.
+ uint32_t freeOffset;
+
+ // Offset of the first row slot chunk.
+ uint32_t firstChunkOffset;
+
+ uint32_t numRows;
+ uint32_t numColumns;
+ };
+
+ struct RowSlot {
+ uint32_t offset;
+ };
+
+ struct RowSlotChunk {
+ RowSlot slots[ROW_SLOT_CHUNK_NUM_ROWS];
+ uint32_t nextChunkOffset;
+ };
+
+ String8 mName;
+ int mAshmemFd;
+ void* mData;
+ size_t mSize;
+ bool mReadOnly;
+ Header* mHeader;
+
+ inline void* offsetToPtr(uint32_t offset) {
+ return static_cast<uint8_t*>(mData) + offset;
+ }
+
+ inline uint32_t offsetFromPtr(void* ptr) {
+ return static_cast<uint8_t*>(ptr) - static_cast<uint8_t*>(mData);
+ }
+
+ /**
+ * Allocate a portion of the window. Returns the offset
+ * of the allocation, or 0 if there isn't enough space.
+ * If aligned is true, the allocation gets 4 byte alignment.
+ */
+ uint32_t alloc(size_t size, bool aligned = false);
+
+ RowSlot* getRowSlot(uint32_t row);
+ RowSlot* allocRowSlot();
+
+ status_t putBlobOrString(uint32_t row, uint32_t column,
+ const void* value, size_t size, int32_t type);
};
}; // namespace android
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index a520a6a..ef4cf5c 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -283,7 +283,8 @@
// outside the current field of view, even when using zoom.
//
// Focus area only has effect if the current focus mode is FOCUS_MODE_AUTO,
- // FOCUS_MODE_MACRO, or FOCUS_MODE_CONTINOUS_VIDEO.
+ // FOCUS_MODE_MACRO, FOCUS_MODE_CONTINUOUS_VIDEO, or
+ // FOCUS_MODE_CONTINUOUS_PICTURE.
// Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write.
static const char KEY_FOCUS_AREAS[];
// Focal length in millimeter.
@@ -504,6 +505,25 @@
// Example value: "true" or "false". Read only.
static const char KEY_VIDEO_SNAPSHOT_SUPPORTED[];
+ // The state of the video stabilization. If set to true, both the
+ // preview stream and the recorded video stream are stabilized by
+ // the camera. Only valid to set if KEY_VIDEO_STABILIZATION_SUPPORTED is
+ // set to true.
+ //
+ // The value of this key can be changed any time the camera is
+ // open. If preview or recording is active, it is acceptable for
+ // there to be a slight video glitch when video stabilization is
+ // toggled on and off.
+ //
+ // This only stabilizes video streams (between-frames stabilization), and
+ // has no effect on still image capture.
+ static const char KEY_VIDEO_STABILIZATION[];
+
+ // Returns true if video stabilization is supported. That is, applications
+ // can set KEY_VIDEO_STABILIZATION to true and have a stabilized preview
+ // stream and record stabilized videos.
+ static const char KEY_VIDEO_STABILIZATION_SUPPORTED[];
+
// Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED.
static const char TRUE[];
static const char FALSE[];
@@ -610,19 +630,29 @@
// recording because the focus changes smoothly . Applications still can
// call CameraHardwareInterface.takePicture in this mode but the subject may
// not be in focus. Auto focus starts when the parameter is set.
- // Applications should not call CameraHardwareInterface.autoFocus in this
- // mode. To stop continuous focus, applications should change the focus mode
- // to other modes.
+ //
+ // Applications can call CameraHardwareInterface.autoFocus in this mode. The
+ // focus callback will immediately return with a boolean that indicates
+ // whether the focus is sharp or not. The focus position is locked after
+ // autoFocus call. If applications want to resume the continuous focus,
+ // cancelAutoFocus must be called. Restarting the preview will not resume
+ // the continuous autofocus. To stop continuous focus, applications should
+ // change the focus mode to other modes.
static const char FOCUS_MODE_CONTINUOUS_VIDEO[];
// Continuous auto focus mode intended for taking pictures. The camera
// continuously tries to focus. The speed of focus change is more aggressive
// than FOCUS_MODE_CONTINUOUS_VIDEO. Auto focus starts when the parameter is
- // set. If applications call autoFocus in this mode, the focus callback will
- // immediately return with a boolean that indicates the focus is sharp or
- // not. The apps can then decide if they want to take a picture immediately
- // or to change the focus mode to auto, and run a full autofocus cycle. To
- // stop continuous focus, applications should change the focus mode to other
- // modes.
+ // set.
+ //
+ // If applications call CameraHardwareInterface.autoFocus in this mode, the
+ // focus callback will immediately return with a boolean that indicates
+ // whether the focus is sharp or not. The apps can then decide if they want
+ // to take a picture immediately or to change the focus mode to auto, and
+ // run a full autofocus cycle. The focus position is locked after autoFocus
+ // call. If applications want to resume the continuous focus,
+ // cancelAutoFocus must be called. Restarting the preview will not resume
+ // the continuous autofocus. To stop continuous focus, applications should
+ // change the focus mode to other modes.
static const char FOCUS_MODE_CONTINUOUS_PICTURE[];
private:
diff --git a/include/gui/SensorManager.h b/include/gui/SensorManager.h
index e1b1a7be..3176462 100644
--- a/include/gui/SensorManager.h
+++ b/include/gui/SensorManager.h
@@ -20,6 +20,8 @@
#include <stdint.h>
#include <sys/types.h>
+#include <binder/IBinder.h>
+
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/Singleton.h>
@@ -41,7 +43,9 @@
// ----------------------------------------------------------------------------
-class SensorManager : public ASensorManager, public Singleton<SensorManager>
+class SensorManager :
+ public ASensorManager,
+ public Singleton<SensorManager>
{
public:
SensorManager();
@@ -52,9 +56,17 @@
sp<SensorEventQueue> createEventQueue();
private:
- sp<ISensorServer> mSensorServer;
- Sensor const** mSensorList;
- Vector<Sensor> mSensors;
+ // DeathRecipient interface
+ void sensorManagerDied();
+
+ status_t assertStateLocked() const;
+
+private:
+ mutable Mutex mLock;
+ mutable sp<ISensorServer> mSensorServer;
+ mutable Sensor const** mSensorList;
+ mutable Vector<Sensor> mSensors;
+ mutable sp<IBinder::DeathRecipient> mDeathObserver;
};
// ----------------------------------------------------------------------------
diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h
index 3e48459..2eb259e 100644
--- a/include/media/stagefright/MediaDefs.h
+++ b/include/media/stagefright/MediaDefs.h
@@ -31,7 +31,9 @@
extern const char *MEDIA_MIMETYPE_AUDIO_AMR_NB;
extern const char *MEDIA_MIMETYPE_AUDIO_AMR_WB;
-extern const char *MEDIA_MIMETYPE_AUDIO_MPEG;
+extern const char *MEDIA_MIMETYPE_AUDIO_MPEG; // layer III
+extern const char *MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I;
+extern const char *MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II;
extern const char *MEDIA_MIMETYPE_AUDIO_AAC;
extern const char *MEDIA_MIMETYPE_AUDIO_QCELP;
extern const char *MEDIA_MIMETYPE_AUDIO_VORBIS;
@@ -47,6 +49,7 @@
extern const char *MEDIA_MIMETYPE_CONTAINER_MATROSKA;
extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG2TS;
extern const char *MEDIA_MIMETYPE_CONTAINER_AVI;
+extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG2PS;
extern const char *MEDIA_MIMETYPE_CONTAINER_WVM;
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index e0f4cf9..5eb09c7 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -53,6 +53,7 @@
eFXSurfaceNormal = 0x00000000,
eFXSurfaceBlur = 0x00010000,
eFXSurfaceDim = 0x00020000,
+ eFXSurfaceScreenshot= 0x00030000,
eFXSurfaceMask = 0x000F0000,
};
@@ -80,9 +81,14 @@
eOrientation90 = 1,
eOrientation180 = 2,
eOrientation270 = 3,
+ eOrientationUnchanged = 4,
eOrientationSwapMask = 0x01
};
-
+
+ enum {
+ eSynchronous = 0x01,
+ };
+
enum {
eElectronBeamAnimationOn = 0x01,
eElectronBeamAnimationOff = 0x10
@@ -101,15 +107,8 @@
virtual sp<IMemoryHeap> getCblk() const = 0;
/* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
- virtual void setTransactionState(const Vector<ComposerState>& state) = 0;
-
- /* [un]freeze display. requires ACCESS_SURFACE_FLINGER permission */
- virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags) = 0;
- virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags) = 0;
-
- /* Set display orientation. requires ACCESS_SURFACE_FLINGER permission
- * No flags are currently defined. Set flags to 0. */
- virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags) = 0;
+ virtual void setTransactionState(const Vector<ComposerState>& state,
+ int orientation, uint32_t flags) = 0;
/* signal that we're done booting.
* Requires ACCESS_SURFACE_FLINGER permission
@@ -148,8 +147,6 @@
GET_CBLK,
SET_TRANSACTION_STATE,
SET_ORIENTATION,
- FREEZE_DISPLAY,
- UNFREEZE_DISPLAY,
CAPTURE_SCREEN,
TURN_ELECTRON_BEAM_OFF,
TURN_ELECTRON_BEAM_ON,
diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h
index ace0735..8226abe 100644
--- a/include/surfaceflinger/SurfaceComposerClient.h
+++ b/include/surfaceflinger/SurfaceComposerClient.h
@@ -112,7 +112,7 @@
static void openGlobalTransaction();
//! Close a composer transaction on all active SurfaceComposerClients.
- static void closeGlobalTransaction();
+ static void closeGlobalTransaction(bool synchronous = false);
//! Freeze the specified display but not transactions.
static status_t freezeDisplay(DisplayID dpy, uint32_t flags = 0);
@@ -195,4 +195,3 @@
}; // namespace android
#endif // ANDROID_SF_SURFACE_COMPOSER_CLIENT_H
-
diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h
index e1ee8eb..a42ce21 100644
--- a/include/utils/Singleton.h
+++ b/include/utils/Singleton.h
@@ -20,12 +20,13 @@
#include <stdint.h>
#include <sys/types.h>
#include <utils/threads.h>
+#include <cutils/compiler.h>
namespace android {
// ---------------------------------------------------------------------------
template <typename TYPE>
-class Singleton
+class ANDROID_API Singleton
{
public:
static TYPE& getInstance() {
diff --git a/libs/binder/CursorWindow.cpp b/libs/binder/CursorWindow.cpp
index b02374f..bf8d7a6 100644
--- a/libs/binder/CursorWindow.cpp
+++ b/libs/binder/CursorWindow.cpp
@@ -19,8 +19,9 @@
#include <utils/Log.h>
#include <binder/CursorWindow.h>
-#include <binder/MemoryHeapBase.h>
-#include <binder/MemoryBase.h>
+
+#include <cutils/ashmem.h>
+#include <sys/mman.h>
#include <assert.h>
#include <string.h>
@@ -28,350 +29,323 @@
namespace android {
-CursorWindow::CursorWindow(size_t maxSize) :
- mMaxSize(maxSize)
-{
+CursorWindow::CursorWindow(const String8& name, int ashmemFd,
+ void* data, size_t size, bool readOnly) :
+ mName(name), mAshmemFd(ashmemFd), mData(data), mSize(size), mReadOnly(readOnly) {
+ mHeader = static_cast<Header*>(mData);
}
-bool CursorWindow::setMemory(const sp<IMemory>& memory)
-{
- mMemory = memory;
- mData = (uint8_t *) memory->pointer();
- if (mData == NULL) {
- return false;
- }
- mHeader = (window_header_t *) mData;
-
- // Make the window read-only
- ssize_t size = memory->size();
- mSize = size;
- mMaxSize = size;
- mFreeOffset = size;
-LOG_WINDOW("Created CursorWindow from existing IMemory: mFreeOffset = %d, numRows = %d, numColumns = %d, mSize = %d, mMaxSize = %d, mData = %p", mFreeOffset, mHeader->numRows, mHeader->numColumns, mSize, mMaxSize, mData);
- return true;
+CursorWindow::~CursorWindow() {
+ ::munmap(mData, mSize);
+ ::close(mAshmemFd);
}
-bool CursorWindow::initBuffer(bool localOnly)
-{
- //TODO Use a non-memory dealer mmap region for localOnly
+status_t CursorWindow::create(const String8& name, size_t size, CursorWindow** outCursorWindow) {
+ String8 ashmemName("CursorWindow: ");
+ ashmemName.append(name);
- sp<MemoryHeapBase> heap;
- heap = new MemoryHeapBase(mMaxSize, 0, "CursorWindow");
- if (heap != NULL) {
- mMemory = new MemoryBase(heap, 0, mMaxSize);
- if (mMemory != NULL) {
- mData = (uint8_t *) mMemory->pointer();
- if (mData) {
- mHeader = (window_header_t *) mData;
- mSize = mMaxSize;
-
- // Put the window into a clean state
- clear();
- LOG_WINDOW("Created CursorWindow with new MemoryDealer: mFreeOffset = %d, mSize = %d, mMaxSize = %d, mData = %p", mFreeOffset, mSize, mMaxSize, mData);
- return true;
- }
- }
- LOGE("CursorWindow heap allocation failed");
- return false;
+ status_t result;
+ int ashmemFd = ashmem_create_region(ashmemName.string(), size);
+ if (ashmemFd < 0) {
+ result = -errno;
} else {
- LOGE("failed to create the CursorWindow heap");
- return false;
+ result = ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);
+ if (result >= 0) {
+ void* data = ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0);
+ if (data == MAP_FAILED) {
+ result = -errno;
+ } else {
+ result = ashmem_set_prot_region(ashmemFd, PROT_READ);
+ if (result >= 0) {
+ CursorWindow* window = new CursorWindow(name, ashmemFd,
+ data, size, false /*readOnly*/);
+ result = window->clear();
+ if (!result) {
+ LOG_WINDOW("Created new CursorWindow: freeOffset=%d, "
+ "numRows=%d, numColumns=%d, mSize=%d, mData=%p",
+ window->mHeader->freeOffset,
+ window->mHeader->numRows,
+ window->mHeader->numColumns,
+ window->mSize, window->mData);
+ *outCursorWindow = window;
+ return OK;
+ }
+ delete window;
+ }
+ }
+ ::munmap(data, size);
+ }
+ ::close(ashmemFd);
}
+ *outCursorWindow = NULL;
+ return result;
}
-CursorWindow::~CursorWindow()
-{
- // Everything that matters is a smart pointer
+status_t CursorWindow::createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow) {
+ String8 name = parcel->readString8();
+
+ status_t result;
+ int ashmemFd = parcel->readFileDescriptor();
+ if (ashmemFd == int(BAD_TYPE)) {
+ result = BAD_TYPE;
+ } else {
+ ssize_t size = ashmem_get_size_region(ashmemFd);
+ if (size < 0) {
+ result = UNKNOWN_ERROR;
+ } else {
+ int dupAshmemFd = ::dup(ashmemFd);
+ if (dupAshmemFd < 0) {
+ result = -errno;
+ } else {
+ void* data = ::mmap(NULL, size, PROT_READ, MAP_SHARED, dupAshmemFd, 0);
+ if (data == MAP_FAILED) {
+ result = -errno;
+ } else {
+ CursorWindow* window = new CursorWindow(name, dupAshmemFd,
+ data, size, true /*readOnly*/);
+ LOG_WINDOW("Created CursorWindow from parcel: freeOffset=%d, "
+ "numRows=%d, numColumns=%d, mSize=%d, mData=%p",
+ window->mHeader->freeOffset,
+ window->mHeader->numRows,
+ window->mHeader->numColumns,
+ window->mSize, window->mData);
+ *outCursorWindow = window;
+ return OK;
+ }
+ ::close(dupAshmemFd);
+ }
+ }
+ }
+ *outCursorWindow = NULL;
+ return result;
}
-void CursorWindow::clear()
-{
+status_t CursorWindow::writeToParcel(Parcel* parcel) {
+ status_t status = parcel->writeString8(mName);
+ if (!status) {
+ status = parcel->writeDupFileDescriptor(mAshmemFd);
+ }
+ return status;
+}
+
+status_t CursorWindow::clear() {
+ if (mReadOnly) {
+ return INVALID_OPERATION;
+ }
+
+ mHeader->freeOffset = sizeof(Header) + sizeof(RowSlotChunk);
+ mHeader->firstChunkOffset = sizeof(Header);
mHeader->numRows = 0;
mHeader->numColumns = 0;
- mFreeOffset = sizeof(window_header_t) + ROW_SLOT_CHUNK_SIZE;
- // Mark the first chunk's next 'pointer' as null
- *((uint32_t *)(mData + mFreeOffset - sizeof(uint32_t))) = 0;
+
+ RowSlotChunk* firstChunk = static_cast<RowSlotChunk*>(offsetToPtr(mHeader->firstChunkOffset));
+ firstChunk->nextChunkOffset = 0;
+ return OK;
}
-int32_t CursorWindow::freeSpace()
-{
- int32_t freeSpace = mSize - mFreeOffset;
- if (freeSpace < 0) {
- freeSpace = 0;
+status_t CursorWindow::setNumColumns(uint32_t numColumns) {
+ if (mReadOnly) {
+ return INVALID_OPERATION;
}
- return freeSpace;
+
+ uint32_t cur = mHeader->numColumns;
+ if ((cur > 0 || mHeader->numRows > 0) && cur != numColumns) {
+ LOGE("Trying to go from %d columns to %d", cur, numColumns);
+ return INVALID_OPERATION;
+ }
+ mHeader->numColumns = numColumns;
+ return OK;
}
-field_slot_t * CursorWindow::allocRow()
-{
+status_t CursorWindow::allocRow() {
+ if (mReadOnly) {
+ return INVALID_OPERATION;
+ }
+
// Fill in the row slot
- row_slot_t * rowSlot = allocRowSlot();
+ RowSlot* rowSlot = allocRowSlot();
if (rowSlot == NULL) {
- return NULL;
+ return NO_MEMORY;
}
// Allocate the slots for the field directory
- size_t fieldDirSize = mHeader->numColumns * sizeof(field_slot_t);
- uint32_t fieldDirOffset = alloc(fieldDirSize);
+ size_t fieldDirSize = mHeader->numColumns * sizeof(FieldSlot);
+ uint32_t fieldDirOffset = alloc(fieldDirSize, true /*aligned*/);
if (!fieldDirOffset) {
mHeader->numRows--;
- LOG_WINDOW("The row failed, so back out the new row accounting from allocRowSlot %d", mHeader->numRows);
- return NULL;
+ LOG_WINDOW("The row failed, so back out the new row accounting "
+ "from allocRowSlot %d", mHeader->numRows);
+ return NO_MEMORY;
}
- field_slot_t * fieldDir = (field_slot_t *)offsetToPtr(fieldDirOffset);
- memset(fieldDir, 0x0, fieldDirSize);
+ FieldSlot* fieldDir = static_cast<FieldSlot*>(offsetToPtr(fieldDirOffset));
+ memset(fieldDir, 0, fieldDirSize);
-LOG_WINDOW("Allocated row %u, rowSlot is at offset %u, fieldDir is %d bytes at offset %u\n", (mHeader->numRows - 1), ((uint8_t *)rowSlot) - mData, fieldDirSize, fieldDirOffset);
+ LOG_WINDOW("Allocated row %u, rowSlot is at offset %u, fieldDir is %d bytes at offset %u\n",
+ mHeader->numRows - 1, offsetFromPtr(rowSlot), fieldDirSize, fieldDirOffset);
rowSlot->offset = fieldDirOffset;
-
- return fieldDir;
+ return OK;
}
-uint32_t CursorWindow::alloc(size_t requestedSize, bool aligned)
-{
- int32_t size;
+status_t CursorWindow::freeLastRow() {
+ if (mReadOnly) {
+ return INVALID_OPERATION;
+ }
+
+ if (mHeader->numRows > 0) {
+ mHeader->numRows--;
+ }
+ return OK;
+}
+
+uint32_t CursorWindow::alloc(size_t size, bool aligned) {
uint32_t padding;
if (aligned) {
// 4 byte alignment
- padding = 4 - (mFreeOffset & 0x3);
+ padding = (~mHeader->freeOffset + 1) & 3;
} else {
padding = 0;
}
- size = requestedSize + padding;
-
- if (size > freeSpace()) {
- LOGV("need to grow: mSize = %d, size = %d, freeSpace() = %d, numRows = %d", mSize, size,
- freeSpace(), mHeader->numRows);
- // Only grow the window if the first row doesn't fit
- if (mHeader->numRows > 1) {
- LOGV("not growing since there are already %d row(s), max size %d", mHeader->numRows,
- mMaxSize);
- return 0;
- }
-
- // Find a new size that will fit the allocation
- int allocated = mSize - freeSpace();
- int newSize = mSize + WINDOW_ALLOCATION_SIZE;
- while (size > (newSize - allocated)) {
- newSize += WINDOW_ALLOCATION_SIZE;
- if (newSize > mMaxSize) {
- LOGE("Attempting to grow window beyond max size (%d)", mMaxSize);
- return 0;
- }
- }
-LOG_WINDOW("found size %d", newSize);
- mSize = newSize;
+ uint32_t offset = mHeader->freeOffset + padding;
+ uint32_t nextFreeOffset = offset + size;
+ if (nextFreeOffset > mSize) {
+ LOGE("Window is full: requested allocation %d bytes, "
+ "free space %d bytes, window size %d bytes",
+ size, freeSpace(), mSize);
+ return 0;
}
- uint32_t offset = mFreeOffset + padding;
- mFreeOffset += size;
+ mHeader->freeOffset = nextFreeOffset;
return offset;
}
-row_slot_t * CursorWindow::getRowSlot(int row)
-{
- LOG_WINDOW("enter getRowSlot current row num %d, this row %d", mHeader->numRows, row);
- int chunkNum = row / ROW_SLOT_CHUNK_NUM_ROWS;
- int chunkPos = row % ROW_SLOT_CHUNK_NUM_ROWS;
- int chunkPtrOffset = sizeof(window_header_t) + ROW_SLOT_CHUNK_SIZE - sizeof(uint32_t);
- uint8_t * rowChunk = mData + sizeof(window_header_t);
- for (int i = 0; i < chunkNum; i++) {
- rowChunk = offsetToPtr(*((uint32_t *)(mData + chunkPtrOffset)));
- chunkPtrOffset = rowChunk - mData + (ROW_SLOT_CHUNK_NUM_ROWS * sizeof(row_slot_t));
+CursorWindow::RowSlot* CursorWindow::getRowSlot(uint32_t row) {
+ uint32_t chunkPos = row;
+ RowSlotChunk* chunk = static_cast<RowSlotChunk*>(
+ offsetToPtr(mHeader->firstChunkOffset));
+ while (chunkPos >= ROW_SLOT_CHUNK_NUM_ROWS) {
+ chunk = static_cast<RowSlotChunk*>(offsetToPtr(chunk->nextChunkOffset));
+ chunkPos -= ROW_SLOT_CHUNK_NUM_ROWS;
}
- return (row_slot_t *)(rowChunk + (chunkPos * sizeof(row_slot_t)));
- LOG_WINDOW("exit getRowSlot current row num %d, this row %d", mHeader->numRows, row);
+ return &chunk->slots[chunkPos];
}
-row_slot_t * CursorWindow::allocRowSlot()
-{
- int chunkNum = mHeader->numRows / ROW_SLOT_CHUNK_NUM_ROWS;
- int chunkPos = mHeader->numRows % ROW_SLOT_CHUNK_NUM_ROWS;
- int chunkPtrOffset = sizeof(window_header_t) + ROW_SLOT_CHUNK_SIZE - sizeof(uint32_t);
- uint8_t * rowChunk = mData + sizeof(window_header_t);
-LOG_WINDOW("Allocating row slot, mHeader->numRows is %d, chunkNum is %d, chunkPos is %d", mHeader->numRows, chunkNum, chunkPos);
- for (int i = 0; i < chunkNum; i++) {
- uint32_t nextChunkOffset = *((uint32_t *)(mData + chunkPtrOffset));
-LOG_WINDOW("nextChunkOffset is %d", nextChunkOffset);
- if (nextChunkOffset == 0) {
- // Allocate a new row chunk
- nextChunkOffset = alloc(ROW_SLOT_CHUNK_SIZE, true);
- if (nextChunkOffset == 0) {
+CursorWindow::RowSlot* CursorWindow::allocRowSlot() {
+ uint32_t chunkPos = mHeader->numRows;
+ RowSlotChunk* chunk = static_cast<RowSlotChunk*>(
+ offsetToPtr(mHeader->firstChunkOffset));
+ while (chunkPos > ROW_SLOT_CHUNK_NUM_ROWS) {
+ chunk = static_cast<RowSlotChunk*>(offsetToPtr(chunk->nextChunkOffset));
+ chunkPos -= ROW_SLOT_CHUNK_NUM_ROWS;
+ }
+ if (chunkPos == ROW_SLOT_CHUNK_NUM_ROWS) {
+ if (!chunk->nextChunkOffset) {
+ chunk->nextChunkOffset = alloc(sizeof(RowSlotChunk), true /*aligned*/);
+ if (!chunk->nextChunkOffset) {
return NULL;
}
- rowChunk = offsetToPtr(nextChunkOffset);
-LOG_WINDOW("allocated new chunk at %d, rowChunk = %p", nextChunkOffset, rowChunk);
- *((uint32_t *)(mData + chunkPtrOffset)) = rowChunk - mData;
- // Mark the new chunk's next 'pointer' as null
- *((uint32_t *)(rowChunk + ROW_SLOT_CHUNK_SIZE - sizeof(uint32_t))) = 0;
- } else {
-LOG_WINDOW("follwing 'pointer' to next chunk, offset of next pointer is %d", chunkPtrOffset);
- rowChunk = offsetToPtr(nextChunkOffset);
- chunkPtrOffset = rowChunk - mData + (ROW_SLOT_CHUNK_NUM_ROWS * sizeof(row_slot_t));
}
+ chunk = static_cast<RowSlotChunk*>(offsetToPtr(chunk->nextChunkOffset));
+ chunk->nextChunkOffset = 0;
+ chunkPos = 0;
}
- mHeader->numRows++;
-
- return (row_slot_t *)(rowChunk + (chunkPos * sizeof(row_slot_t)));
+ mHeader->numRows += 1;
+ return &chunk->slots[chunkPos];
}
-field_slot_t * CursorWindow::getFieldSlotWithCheck(int row, int column)
-{
- if (row < 0 || row >= mHeader->numRows || column < 0 || column >= mHeader->numColumns) {
- LOGE("Failed to read row# %d, column# from a CursorWindow which has %d rows, %d columns.",
- row, column, mHeader->numRows, mHeader->numColumns);
- return NULL;
- }
- row_slot_t * rowSlot = getRowSlot(row);
- if (!rowSlot) {
- LOGE("Failed to find rowSlot for row %d", row);
- return NULL;
- }
- if (rowSlot->offset == 0 || rowSlot->offset >= mSize) {
- LOGE("Invalid rowSlot, offset = %d", rowSlot->offset);
- return NULL;
- }
- int fieldDirOffset = rowSlot->offset;
- return ((field_slot_t *)offsetToPtr(fieldDirOffset)) + column;
+CursorWindow::FieldSlot* CursorWindow::getFieldSlot(uint32_t row, uint32_t column) {
+ if (row >= mHeader->numRows || column >= mHeader->numColumns) {
+ LOGE("Failed to read row %d, column %d from a CursorWindow which "
+ "has %d rows, %d columns.",
+ row, column, mHeader->numRows, mHeader->numColumns);
+ return NULL;
+ }
+ RowSlot* rowSlot = getRowSlot(row);
+ if (!rowSlot) {
+ LOGE("Failed to find rowSlot for row %d.", row);
+ return NULL;
+ }
+ FieldSlot* fieldDir = static_cast<FieldSlot*>(offsetToPtr(rowSlot->offset));
+ return &fieldDir[column];
}
-void CursorWindow::copyIn(uint32_t offset, uint8_t const * data, size_t size)
-{
- assert(offset + size <= mSize);
- memcpy(mData + offset, data, size);
+status_t CursorWindow::putBlob(uint32_t row, uint32_t column, const void* value, size_t size) {
+ return putBlobOrString(row, column, value, size, FIELD_TYPE_BLOB);
}
-void CursorWindow::copyIn(uint32_t offset, int64_t data)
-{
- assert(offset + sizeof(int64_t) <= mSize);
- memcpy(mData + offset, (uint8_t *)&data, sizeof(int64_t));
+status_t CursorWindow::putString(uint32_t row, uint32_t column, const char* value,
+ size_t sizeIncludingNull) {
+ return putBlobOrString(row, column, value, sizeIncludingNull, FIELD_TYPE_STRING);
}
-void CursorWindow::copyIn(uint32_t offset, double data)
-{
- assert(offset + sizeof(double) <= mSize);
- memcpy(mData + offset, (uint8_t *)&data, sizeof(double));
-}
+status_t CursorWindow::putBlobOrString(uint32_t row, uint32_t column,
+ const void* value, size_t size, int32_t type) {
+ if (mReadOnly) {
+ return INVALID_OPERATION;
+ }
-void CursorWindow::copyOut(uint32_t offset, uint8_t * data, size_t size)
-{
- assert(offset + size <= mSize);
- memcpy(data, mData + offset, size);
-}
-
-int64_t CursorWindow::copyOutLong(uint32_t offset)
-{
- int64_t value;
- assert(offset + sizeof(int64_t) <= mSize);
- memcpy(&value, mData + offset, sizeof(int64_t));
- return value;
-}
-
-double CursorWindow::copyOutDouble(uint32_t offset)
-{
- double value;
- assert(offset + sizeof(double) <= mSize);
- memcpy(&value, mData + offset, sizeof(double));
- return value;
-}
-
-bool CursorWindow::putLong(unsigned int row, unsigned int col, int64_t value)
-{
- field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
+ FieldSlot* fieldSlot = getFieldSlot(row, column);
if (!fieldSlot) {
- return false;
+ return BAD_VALUE;
}
-#if WINDOW_STORAGE_INLINE_NUMERICS
- fieldSlot->data.l = value;
-#else
- int offset = alloc(sizeof(int64_t));
+ uint32_t offset = alloc(size);
if (!offset) {
- return false;
+ return NO_MEMORY;
}
- copyIn(offset, value);
+ memcpy(offsetToPtr(offset), value, size);
+ fieldSlot->type = type;
fieldSlot->data.buffer.offset = offset;
- fieldSlot->data.buffer.size = sizeof(int64_t);
-#endif
+ fieldSlot->data.buffer.size = size;
+ return OK;
+}
+
+status_t CursorWindow::putLong(uint32_t row, uint32_t column, int64_t value) {
+ if (mReadOnly) {
+ return INVALID_OPERATION;
+ }
+
+ FieldSlot* fieldSlot = getFieldSlot(row, column);
+ if (!fieldSlot) {
+ return BAD_VALUE;
+ }
+
fieldSlot->type = FIELD_TYPE_INTEGER;
- return true;
+ fieldSlot->data.l = value;
+ return OK;
}
-bool CursorWindow::putDouble(unsigned int row, unsigned int col, double value)
-{
- field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
+status_t CursorWindow::putDouble(uint32_t row, uint32_t column, double value) {
+ if (mReadOnly) {
+ return INVALID_OPERATION;
+ }
+
+ FieldSlot* fieldSlot = getFieldSlot(row, column);
if (!fieldSlot) {
- return false;
+ return BAD_VALUE;
}
-#if WINDOW_STORAGE_INLINE_NUMERICS
- fieldSlot->data.d = value;
-#else
- int offset = alloc(sizeof(int64_t));
- if (!offset) {
- return false;
- }
-
- copyIn(offset, value);
-
- fieldSlot->data.buffer.offset = offset;
- fieldSlot->data.buffer.size = sizeof(double);
-#endif
fieldSlot->type = FIELD_TYPE_FLOAT;
- return true;
+ fieldSlot->data.d = value;
+ return OK;
}
-bool CursorWindow::putNull(unsigned int row, unsigned int col)
-{
- field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
+status_t CursorWindow::putNull(uint32_t row, uint32_t column) {
+ if (mReadOnly) {
+ return INVALID_OPERATION;
+ }
+
+ FieldSlot* fieldSlot = getFieldSlot(row, column);
if (!fieldSlot) {
- return false;
+ return BAD_VALUE;
}
fieldSlot->type = FIELD_TYPE_NULL;
fieldSlot->data.buffer.offset = 0;
fieldSlot->data.buffer.size = 0;
- return true;
-}
-
-bool CursorWindow::getLong(unsigned int row, unsigned int col, int64_t * valueOut)
-{
- field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
- if (!fieldSlot || fieldSlot->type != FIELD_TYPE_INTEGER) {
- return false;
- }
-
- *valueOut = getFieldSlotValueLong(fieldSlot);
- return true;
-}
-
-bool CursorWindow::getDouble(unsigned int row, unsigned int col, double * valueOut)
-{
- field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
- if (!fieldSlot || fieldSlot->type != FIELD_TYPE_FLOAT) {
- return false;
- }
-
- *valueOut = getFieldSlotValueDouble(fieldSlot);
- return true;
-}
-
-bool CursorWindow::getNull(unsigned int row, unsigned int col, bool * valueOut)
-{
- field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
- if (!fieldSlot) {
- return false;
- }
-
- if (fieldSlot->type != FIELD_TYPE_NULL) {
- *valueOut = false;
- } else {
- *valueOut = true;
- }
- return true;
+ return OK;
}
}; // namespace android
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 608877e..c7180ce 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -752,7 +752,7 @@
int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
if (result < 0) {
- status = -result;
+ status = result;
} else {
void* ptr = ::mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED) {
@@ -760,7 +760,7 @@
} else {
result = ashmem_set_prot_region(fd, PROT_READ);
if (result < 0) {
- status = -result;
+ status = result;
} else {
status = writeInt32(1);
if (!status) {
diff --git a/libs/camera/CameraParameters.cpp b/libs/camera/CameraParameters.cpp
index 0dcab6b..c6087b4 100644
--- a/libs/camera/CameraParameters.cpp
+++ b/libs/camera/CameraParameters.cpp
@@ -88,6 +88,8 @@
const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW[] = "max-num-detected-faces-sw";
const char CameraParameters::KEY_RECORDING_HINT[] = "recording-hint";
const char CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED[] = "video-snapshot-supported";
+const char CameraParameters::KEY_VIDEO_STABILIZATION[] = "video-stabilization";
+const char CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED[] = "video-stabilization-supported";
const char CameraParameters::TRUE[] = "true";
const char CameraParameters::FALSE[] = "false";
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 030a83e..86bc62a 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -78,7 +78,8 @@
return interface_cast<IMemoryHeap>(reply.readStrongBinder());
}
- virtual void setTransactionState(const Vector<ComposerState>& state)
+ virtual void setTransactionState(const Vector<ComposerState>& state,
+ int orientation, uint32_t flags)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -88,38 +89,9 @@
for ( ; b != e ; ++b ) {
b->write(data);
}
- remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply);
- }
-
- virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeInt32(dpy);
- data.writeInt32(flags);
- remote()->transact(BnSurfaceComposer::FREEZE_DISPLAY, data, &reply);
- return reply.readInt32();
- }
-
- virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeInt32(dpy);
- data.writeInt32(flags);
- remote()->transact(BnSurfaceComposer::UNFREEZE_DISPLAY, data, &reply);
- return reply.readInt32();
- }
-
- virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeInt32(dpy);
data.writeInt32(orientation);
data.writeInt32(flags);
- remote()->transact(BnSurfaceComposer::SET_ORIENTATION, data, &reply);
- return reply.readInt32();
+ remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply);
}
virtual void bootFinished()
@@ -232,26 +204,9 @@
s.read(data);
state.add(s);
}
- setTransactionState(state);
- } break;
- case SET_ORIENTATION: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- DisplayID dpy = data.readInt32();
int orientation = data.readInt32();
uint32_t flags = data.readInt32();
- reply->writeInt32( setOrientation(dpy, orientation, flags) );
- } break;
- case FREEZE_DISPLAY: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- DisplayID dpy = data.readInt32();
- uint32_t flags = data.readInt32();
- reply->writeInt32( freezeDisplay(dpy, flags) );
- } break;
- case UNFREEZE_DISPLAY: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- DisplayID dpy = data.readInt32();
- uint32_t flags = data.readInt32();
- reply->writeInt32( unfreezeDisplay(dpy, flags) );
+ setTransactionState(state, orientation, flags);
} break;
case BOOT_FINISHED: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
diff --git a/libs/gui/ISurfaceTexture.cpp b/libs/gui/ISurfaceTexture.cpp
index babd2c0..d2e5627 100644
--- a/libs/gui/ISurfaceTexture.cpp
+++ b/libs/gui/ISurfaceTexture.cpp
@@ -58,13 +58,16 @@
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(bufferIdx);
- remote()->transact(REQUEST_BUFFER, data, &reply);
+ status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
bool nonNull = reply.readInt32();
if (nonNull) {
*buf = new GraphicBuffer();
reply.read(**buf);
}
- status_t result = reply.readInt32();
+ result = reply.readInt32();
return result;
}
@@ -73,9 +76,12 @@
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(bufferCount);
- remote()->transact(SET_BUFFER_COUNT, data, &reply);
- status_t err = reply.readInt32();
- return err;
+ status_t result =remote()->transact(SET_BUFFER_COUNT, data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply.readInt32();
+ return result;
}
virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
@@ -86,9 +92,12 @@
data.writeInt32(h);
data.writeInt32(format);
data.writeInt32(usage);
- remote()->transact(DEQUEUE_BUFFER, data, &reply);
+ status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
*buf = reply.readInt32();
- int result = reply.readInt32();
+ result = reply.readInt32();
return result;
}
@@ -98,11 +107,14 @@
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(buf);
data.writeInt64(timestamp);
- remote()->transact(QUEUE_BUFFER, data, &reply);
+ status_t result = remote()->transact(QUEUE_BUFFER, data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
*outWidth = reply.readInt32();
*outHeight = reply.readInt32();
*outTransform = reply.readInt32();
- status_t result = reply.readInt32();
+ result = reply.readInt32();
return result;
}
@@ -120,8 +132,11 @@
data.writeFloat(reg.top);
data.writeFloat(reg.right);
data.writeFloat(reg.bottom);
- remote()->transact(SET_CROP, data, &reply);
- status_t result = reply.readInt32();
+ status_t result = remote()->transact(SET_CROP, data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply.readInt32();
return result;
}
@@ -129,8 +144,11 @@
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(transform);
- remote()->transact(SET_TRANSFORM, data, &reply);
- status_t result = reply.readInt32();
+ status_t result = remote()->transact(SET_TRANSFORM, data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply.readInt32();
return result;
}
@@ -138,8 +156,11 @@
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(mode);
- remote()->transact(SET_SCALING_MODE, data, &reply);
- status_t result = reply.readInt32();
+ status_t result = remote()->transact(SET_SCALING_MODE, data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply.readInt32();
return result;
}
@@ -147,9 +168,12 @@
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(what);
- remote()->transact(QUERY, data, &reply);
+ status_t result = remote()->transact(QUERY, data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
value[0] = reply.readInt32();
- status_t result = reply.readInt32();
+ result = reply.readInt32();
return result;
}
@@ -157,8 +181,11 @@
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(enabled);
- remote()->transact(SET_SYNCHRONOUS_MODE, data, &reply);
- status_t result = reply.readInt32();
+ status_t result = remote()->transact(SET_SYNCHRONOUS_MODE, data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply.readInt32();
return result;
}
@@ -167,11 +194,14 @@
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(api);
- remote()->transact(CONNECT, data, &reply);
+ status_t result = remote()->transact(CONNECT, data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
*outWidth = reply.readInt32();
*outHeight = reply.readInt32();
*outTransform = reply.readInt32();
- status_t result = reply.readInt32();
+ result = reply.readInt32();
return result;
}
@@ -179,8 +209,11 @@
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(api);
- remote()->transact(DISCONNECT, data, &reply);
- status_t result = reply.readInt32();
+ status_t result =remote()->transact(DISCONNECT, data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply.readInt32();
return result;
}
};
diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp
index d719efb..dafcdea 100644
--- a/libs/gui/SensorManager.cpp
+++ b/libs/gui/SensorManager.cpp
@@ -23,6 +23,7 @@
#include <utils/RefBase.h>
#include <utils/Singleton.h>
+#include <binder/IBinder.h>
#include <binder/IServiceManager.h>
#include <gui/ISensorServer.h>
@@ -40,17 +41,8 @@
SensorManager::SensorManager()
: mSensorList(0)
{
- const String16 name("sensorservice");
- while (getService(name, &mSensorServer) != NO_ERROR) {
- usleep(250000);
- }
-
- mSensors = mSensorServer->getSensorList();
- size_t count = mSensors.size();
- mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*));
- for (size_t i=0 ; i<count ; i++) {
- mSensorList[i] = mSensors.array() + i;
- }
+ // okay we're not locked here, but it's not needed during construction
+ assertStateLocked();
}
SensorManager::~SensorManager()
@@ -58,29 +50,100 @@
free(mSensorList);
}
+void SensorManager::sensorManagerDied()
+{
+ Mutex::Autolock _l(mLock);
+ mSensorServer.clear();
+ free(mSensorList);
+ mSensorList = NULL;
+ mSensors.clear();
+}
+
+status_t SensorManager::assertStateLocked() const {
+ if (mSensorServer == NULL) {
+ // try for one second
+ const String16 name("sensorservice");
+ for (int i=0 ; i<4 ; i++) {
+ status_t err = getService(name, &mSensorServer);
+ if (err == NAME_NOT_FOUND) {
+ usleep(250000);
+ continue;
+ }
+ if (err != NO_ERROR) {
+ return err;
+ }
+ break;
+ }
+
+ class DeathObserver : public IBinder::DeathRecipient {
+ SensorManager& mSensorManger;
+ virtual void binderDied(const wp<IBinder>& who) {
+ LOGW("sensorservice died [%p]", who.unsafe_get());
+ mSensorManger.sensorManagerDied();
+ }
+ public:
+ DeathObserver(SensorManager& mgr) : mSensorManger(mgr) { }
+ };
+
+ mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
+ mSensorServer->asBinder()->linkToDeath(mDeathObserver);
+
+ mSensors = mSensorServer->getSensorList();
+ size_t count = mSensors.size();
+ mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*));
+ for (size_t i=0 ; i<count ; i++) {
+ mSensorList[i] = mSensors.array() + i;
+ }
+ }
+
+ return NO_ERROR;
+}
+
+
+
ssize_t SensorManager::getSensorList(Sensor const* const** list) const
{
+ Mutex::Autolock _l(mLock);
+ status_t err = assertStateLocked();
+ if (err < 0) {
+ return ssize_t(err);
+ }
*list = mSensorList;
return mSensors.size();
}
Sensor const* SensorManager::getDefaultSensor(int type)
{
- // For now we just return the first sensor of that type we find.
- // in the future it will make sense to let the SensorService make
- // that decision.
- for (size_t i=0 ; i<mSensors.size() ; i++) {
- if (mSensorList[i]->getType() == type)
- return mSensorList[i];
+ Mutex::Autolock _l(mLock);
+ if (assertStateLocked() == NO_ERROR) {
+ // For now we just return the first sensor of that type we find.
+ // in the future it will make sense to let the SensorService make
+ // that decision.
+ for (size_t i=0 ; i<mSensors.size() ; i++) {
+ if (mSensorList[i]->getType() == type)
+ return mSensorList[i];
+ }
}
return NULL;
}
sp<SensorEventQueue> SensorManager::createEventQueue()
{
- sp<SensorEventQueue> result = new SensorEventQueue(
- mSensorServer->createSensorEventConnection());
- return result;
+ sp<SensorEventQueue> queue;
+
+ Mutex::Autolock _l(mLock);
+ while (assertStateLocked() == NO_ERROR) {
+ sp<ISensorEventConnection> connection =
+ mSensorServer->createSensorEventConnection();
+ if (connection == NULL) {
+ // SensorService just died.
+ LOGE("createEventQueue: connection is NULL. SensorService died.");
+ continue;
+ }
+ queue = new SensorEventQueue(connection);
+ break;
+ }
+ return queue;
}
// ----------------------------------------------------------------------------
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 00a4bf6..4ad6c22 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -91,10 +91,15 @@
mutable Mutex mLock;
SortedVector<ComposerState> mStates;
+ int mOrientation;
+ uint32_t mForceSynchronous;
- Composer() : Singleton<Composer>() { }
+ Composer() : Singleton<Composer>(),
+ mOrientation(ISurfaceComposer::eOrientationUnchanged),
+ mForceSynchronous(0)
+ { }
- void closeGlobalTransactionImpl();
+ void closeGlobalTransactionImpl(bool synchronous);
layer_state_t* getLayerStateLocked(
const sp<SurfaceComposerClient>& client, SurfaceID id);
@@ -119,9 +124,10 @@
status_t setFreezeTint(
const sp<SurfaceComposerClient>& client, SurfaceID id,
uint32_t tint);
+ status_t setOrientation(int orientation);
- static void closeGlobalTransaction() {
- Composer::getInstance().closeGlobalTransactionImpl();
+ static void closeGlobalTransaction(bool synchronous) {
+ Composer::getInstance().closeGlobalTransactionImpl(synchronous);
}
};
@@ -129,18 +135,28 @@
// ---------------------------------------------------------------------------
-void Composer::closeGlobalTransactionImpl() {
+void Composer::closeGlobalTransactionImpl(bool synchronous) {
sp<ISurfaceComposer> sm(getComposerService());
Vector<ComposerState> transaction;
+ int orientation;
+ uint32_t flags = 0;
{ // scope for the lock
Mutex::Autolock _l(mLock);
transaction = mStates;
mStates.clear();
+
+ orientation = mOrientation;
+ mOrientation = ISurfaceComposer::eOrientationUnchanged;
+
+ if (synchronous || mForceSynchronous) {
+ flags |= ISurfaceComposer::eSynchronous;
+ }
+ mForceSynchronous = false;
}
- sm->setTransactionState(transaction);
+ sm->setTransactionState(transaction, orientation, flags);
}
layer_state_t* Composer::getLayerStateLocked(
@@ -181,6 +197,10 @@
s->what |= ISurfaceComposer::eSizeChanged;
s->w = w;
s->h = h;
+
+ // Resizing a surface makes the transaction synchronous.
+ mForceSynchronous = true;
+
return NO_ERROR;
}
@@ -260,6 +280,16 @@
return NO_ERROR;
}
+status_t Composer::setOrientation(int orientation) {
+ Mutex::Autolock _l(mLock);
+ mOrientation = orientation;
+
+ // Changing the orientation makes the transaction synchronous.
+ mForceSynchronous = true;
+
+ return NO_ERROR;
+}
+
// ---------------------------------------------------------------------------
SurfaceComposerClient::SurfaceComposerClient()
@@ -362,8 +392,8 @@
// Currently a no-op
}
-void SurfaceComposerClient::closeGlobalTransaction() {
- Composer::closeGlobalTransaction();
+void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) {
+ Composer::closeGlobalTransaction(synchronous);
}
// ----------------------------------------------------------------------------
@@ -427,6 +457,12 @@
return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy);
}
+status_t SurfaceComposerClient::setOrientation(DisplayID dpy,
+ int orientation, uint32_t flags)
+{
+ return Composer::getInstance().setOrientation(orientation);
+}
+
// ----------------------------------------------------------------------------
status_t SurfaceComposerClient::getDisplayInfo(
@@ -491,21 +527,14 @@
status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
{
- sp<ISurfaceComposer> sm(getComposerService());
- return sm->freezeDisplay(dpy, flags);
+ // This has been made a no-op because it can cause Gralloc buffer deadlocks.
+ return NO_ERROR;
}
status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
{
- sp<ISurfaceComposer> sm(getComposerService());
- return sm->unfreezeDisplay(dpy, flags);
-}
-
-int SurfaceComposerClient::setOrientation(DisplayID dpy,
- int orientation, uint32_t flags)
-{
- sp<ISurfaceComposer> sm(getComposerService());
- return sm->setOrientation(dpy, orientation, flags);
+ // This has been made a no-op because it can cause Gralloc buffer deadlocks.
+ return NO_ERROR;
}
// ----------------------------------------------------------------------------
@@ -572,4 +601,3 @@
// ----------------------------------------------------------------------------
}; // namespace android
-
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index ce587b3..693b7b8 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -75,7 +75,7 @@
}
// This test probably doesn't belong here.
-TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersFail) {
+TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) {
sp<ANativeWindow> anw(mSurface);
// Verify the screenshot works with no protected buffers.
@@ -114,31 +114,8 @@
}
heap = 0;
w = h = fmt = 0;
- ASSERT_EQ(INVALID_OPERATION, sf->captureScreen(0, &heap, &w, &h, &fmt,
+ ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt,
64, 64, 0, 0x7fffffff));
- ASSERT_TRUE(heap == NULL);
-
- // XXX: This should not be needed, but it seems that the new buffers don't
- // correctly show up after the upcoming dequeue/lock/queue loop without it.
- // We should look into this at some point.
- ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3));
-
- // Un-set the PROTECTED usage bit and verify that the screenshot works
- // again. Note that we have to change the buffers geometry to ensure that
- // the buffers get reallocated, as the new usage bits are a subset of the
- // old.
- ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), 0));
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(anw.get(), 32, 32, 0));
- for (int i = 0; i < 4; i++) {
- // Loop to make sure SurfaceFlinger has retired a protected buffer.
- ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf));
- ASSERT_EQ(NO_ERROR, anw->lockBuffer(anw.get(), buf));
- ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf));
- }
- heap = 0;
- w = h = fmt = 0;
- ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0,
- 0x7fffffff));
ASSERT_TRUE(heap != NULL);
}
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index a98e4cd..9bfc94c 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -39,6 +39,7 @@
external/skia/include/utils
LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER
+ LOCAL_CFLAGS += -fvisibility=hidden
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_SHARED_LIBRARIES := libcutils libutils libGLESv2 libskia libui
LOCAL_MODULE := libhwui
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index cdcbf21..9b0d7c6e 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -23,6 +23,8 @@
#include <utils/Singleton.h>
+#include <cutils/compiler.h>
+
#include "Extensions.h"
#include "FontRenderer.h"
#include "GammaFontRenderer.h"
@@ -82,7 +84,7 @@
// Caches
///////////////////////////////////////////////////////////////////////////////
-class Caches: public Singleton<Caches> {
+class ANDROID_API Caches: public Singleton<Caches> {
Caches();
~Caches();
diff --git a/libs/hwui/DisplayListLogBuffer.h b/libs/hwui/DisplayListLogBuffer.h
index bf16f29..5d689bb 100644
--- a/libs/hwui/DisplayListLogBuffer.h
+++ b/libs/hwui/DisplayListLogBuffer.h
@@ -18,6 +18,7 @@
#define ANDROID_HWUI_DISPLAY_LIST_LOG_BUFFER_H
#include <utils/Singleton.h>
+
#include <stdio.h>
namespace android {
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 8cd7fea..ab475bf 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -26,6 +26,8 @@
#include <SkTDArray.h>
#include <SkTSearch.h>
+#include <cutils/compiler.h>
+
#include "DisplayListLogBuffer.h"
#include "OpenGLRenderer.h"
#include "utils/Functor.h"
@@ -58,7 +60,7 @@
class DisplayList {
public:
DisplayList(const DisplayListRenderer& recorder);
- ~DisplayList();
+ ANDROID_API ~DisplayList();
// IMPORTANT: Update the intialization of OP_NAMES in the .cpp file
// when modifying this file
@@ -107,13 +109,13 @@
void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
- size_t getSize();
+ ANDROID_API size_t getSize();
bool replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level = 0);
void output(OpenGLRenderer& renderer, uint32_t level = 0);
- static void outputLogBuffer(int fd);
+ ANDROID_API static void outputLogBuffer(int fd);
void setRenderable(bool renderable) {
mIsRenderable = renderable;
@@ -230,75 +232,76 @@
*/
class DisplayListRenderer: public OpenGLRenderer {
public:
- DisplayListRenderer();
- ~DisplayListRenderer();
+ ANDROID_API DisplayListRenderer();
+ virtual ~DisplayListRenderer();
- DisplayList* getDisplayList(DisplayList* displayList);
+ ANDROID_API DisplayList* getDisplayList(DisplayList* displayList);
- void setViewport(int width, int height);
- void prepareDirty(float left, float top, float right, float bottom, bool opaque);
- void finish();
+ virtual void setViewport(int width, int height);
+ virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
+ virtual void finish();
- bool callDrawGLFunction(Functor *functor, Rect& dirty);
+ virtual bool callDrawGLFunction(Functor *functor, Rect& dirty);
- void interrupt();
- void resume();
+ virtual void interrupt();
+ virtual void resume();
- int save(int flags);
- void restore();
- void restoreToCount(int saveCount);
+ virtual int save(int flags);
+ virtual void restore();
+ virtual void restoreToCount(int saveCount);
- int saveLayer(float left, float top, float right, float bottom,
+ virtual int saveLayer(float left, float top, float right, float bottom,
SkPaint* p, int flags);
- int saveLayerAlpha(float left, float top, float right, float bottom,
+ virtual int saveLayerAlpha(float left, float top, float right, float bottom,
int alpha, int flags);
- void translate(float dx, float dy);
- void rotate(float degrees);
- void scale(float sx, float sy);
- void skew(float sx, float sy);
+ virtual void translate(float dx, float dy);
+ virtual void rotate(float degrees);
+ virtual void scale(float sx, float sy);
+ virtual void skew(float sx, float sy);
- void setMatrix(SkMatrix* matrix);
- void concatMatrix(SkMatrix* matrix);
+ virtual void setMatrix(SkMatrix* matrix);
+ virtual void concatMatrix(SkMatrix* matrix);
- bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
+ virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
- bool drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
+ virtual bool drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
Rect& dirty, uint32_t level = 0);
- void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
- void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
- void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
- void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
+ virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
+ virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
+ virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
+ virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, SkPaint* paint);
- void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
+ virtual void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
float* vertices, int* colors, SkPaint* paint);
- void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
+ virtual void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
float left, float top, float right, float bottom, SkPaint* paint);
- void drawColor(int color, SkXfermode::Mode mode);
- void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
- void drawRoundRect(float left, float top, float right, float bottom,
+ virtual void drawColor(int color, SkXfermode::Mode mode);
+ virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
+ virtual void drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, SkPaint* paint);
- void drawCircle(float x, float y, float radius, SkPaint* paint);
- void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
- void drawArc(float left, float top, float right, float bottom,
+ virtual void drawCircle(float x, float y, float radius, SkPaint* paint);
+ virtual void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
+ virtual void drawArc(float left, float top, float right, float bottom,
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
- void drawPath(SkPath* path, SkPaint* paint);
- void drawLines(float* points, int count, SkPaint* paint);
- void drawPoints(float* points, int count, SkPaint* paint);
- void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
+ virtual void drawPath(SkPath* path, SkPaint* paint);
+ virtual void drawLines(float* points, int count, SkPaint* paint);
+ virtual void drawPoints(float* points, int count, SkPaint* paint);
+ virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
+ SkPaint* paint);
- void resetShader();
- void setupShader(SkiaShader* shader);
+ virtual void resetShader();
+ virtual void setupShader(SkiaShader* shader);
- void resetColorFilter();
- void setupColorFilter(SkiaColorFilter* filter);
+ virtual void resetColorFilter();
+ virtual void setupColorFilter(SkiaColorFilter* filter);
- void resetShadow();
- void setupShadow(float radius, float dx, float dy, int color);
+ virtual void resetShadow();
+ virtual void setupShadow(float radius, float dx, float dy, int color);
- void reset();
+ ANDROID_API void reset();
const SkWriter32& writeStream() const {
return mWriter;
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 349b9e3..e38b479 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -31,6 +31,12 @@
// Rendering
///////////////////////////////////////////////////////////////////////////////
+LayerRenderer::LayerRenderer(Layer* layer): mLayer(layer) {
+}
+
+LayerRenderer::~LayerRenderer() {
+}
+
void LayerRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->getFbo());
@@ -210,7 +216,8 @@
layer->allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE);
if (glGetError() != GL_NO_ERROR) {
- LOGD("Could not allocate texture");
+ LOGD("Could not allocate texture for layer (fbo=%d %dx%d)",
+ fbo, width, height);
glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
Caches::getInstance().fboCache.put(fbo);
@@ -264,7 +271,7 @@
layer->setFbo(0);
layer->setAlpha(255, SkXfermode::kSrcOver_Mode);
layer->layer.set(0.0f, 0.0f, 0.0f, 0.0f);
- layer->texCoords.set(0.0f, 1.0f, 0.0f, 1.0f);
+ layer->texCoords.set(0.0f, 1.0f, 1.0f, 0.0f);
layer->region.clear();
layer->setRenderTarget(GL_NONE); // see ::updateTextureLayer()
@@ -400,6 +407,18 @@
renderer.setViewport(bitmap->width(), bitmap->height());
renderer.OpenGLRenderer::prepareDirty(0.0f, 0.0f,
bitmap->width(), bitmap->height(), !layer->isBlend());
+
+ glDisable(GL_SCISSOR_TEST);
+ renderer.translate(0.0f, bitmap->height());
+ renderer.scale(1.0f, -1.0f);
+
+ mat4 texTransform(layer->getTexTransform());
+
+ mat4 invert;
+ invert.translate(0.0f, 1.0f, 0.0f);
+ invert.scale(1.0f, -1.0f, 1.0f);
+ layer->getTexTransform().multiply(invert);
+
if ((error = glGetError()) != GL_NO_ERROR) goto error;
{
@@ -413,6 +432,7 @@
if ((error = glGetError()) != GL_NO_ERROR) goto error;
}
+ layer->getTexTransform().load(texTransform);
status = true;
}
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index 2246573..6104301 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_HWUI_LAYER_RENDERER_H
#define ANDROID_HWUI_LAYER_RENDERER_H
+#include <cutils/compiler.h>
+
#include "OpenGLRenderer.h"
#include "Layer.h"
@@ -42,27 +44,24 @@
class LayerRenderer: public OpenGLRenderer {
public:
- LayerRenderer(Layer* layer): mLayer(layer) {
- }
+ ANDROID_API LayerRenderer(Layer* layer);
+ virtual ~LayerRenderer();
- ~LayerRenderer() {
- }
+ virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
+ virtual void finish();
- void prepareDirty(float left, float top, float right, float bottom, bool opaque);
- void finish();
+ virtual bool hasLayer();
+ virtual Region* getRegion();
+ virtual GLint getTargetFbo();
- bool hasLayer();
- Region* getRegion();
- GLint getTargetFbo();
-
- static Layer* createTextureLayer(bool isOpaque);
- static Layer* createLayer(uint32_t width, uint32_t height, bool isOpaque = false);
- static bool resizeLayer(Layer* layer, uint32_t width, uint32_t height);
- static void updateTextureLayer(Layer* layer, uint32_t width, uint32_t height,
+ ANDROID_API static Layer* createTextureLayer(bool isOpaque);
+ ANDROID_API static Layer* createLayer(uint32_t width, uint32_t height, bool isOpaque = false);
+ ANDROID_API static bool resizeLayer(Layer* layer, uint32_t width, uint32_t height);
+ ANDROID_API static void updateTextureLayer(Layer* layer, uint32_t width, uint32_t height,
bool isOpaque, GLenum renderTarget, float* transform);
- static void destroyLayer(Layer* layer);
- static void destroyLayerDeferred(Layer* layer);
- static bool copyLayer(Layer* layer, SkBitmap* bitmap);
+ ANDROID_API static void destroyLayer(Layer* layer);
+ ANDROID_API static void destroyLayerDeferred(Layer* layer);
+ ANDROID_API static bool copyLayer(Layer* layer, SkBitmap* bitmap);
private:
void generateMesh();
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index 56fd37d..22220a9 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -19,6 +19,8 @@
#include <SkMatrix.h>
+#include <cutils/compiler.h>
+
#include "Rect.h"
namespace android {
@@ -28,7 +30,7 @@
// Classes
///////////////////////////////////////////////////////////////////////////////
-class Matrix4 {
+class ANDROID_API Matrix4 {
public:
float data[16];
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 14b22b3..2fc88e1 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -31,6 +31,8 @@
#include <utils/RefBase.h>
#include <utils/Vector.h>
+#include <cutils/compiler.h>
+
#include "Debug.h"
#include "Extensions.h"
#include "Matrix.h"
@@ -57,12 +59,12 @@
*/
class OpenGLRenderer {
public:
- OpenGLRenderer();
+ ANDROID_API OpenGLRenderer();
virtual ~OpenGLRenderer();
virtual void setViewport(int width, int height);
- void prepare(bool opaque);
+ ANDROID_API void prepare(bool opaque);
virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
virtual void finish();
@@ -72,7 +74,7 @@
virtual bool callDrawGLFunction(Functor *functor, Rect& dirty);
- int getSaveCount() const;
+ ANDROID_API int getSaveCount() const;
virtual int save(int flags);
virtual void restore();
virtual void restoreToCount(int saveCount);
@@ -87,12 +89,12 @@
virtual void scale(float sx, float sy);
virtual void skew(float sx, float sy);
- void getMatrix(SkMatrix* matrix);
+ ANDROID_API void getMatrix(SkMatrix* matrix);
virtual void setMatrix(SkMatrix* matrix);
virtual void concatMatrix(SkMatrix* matrix);
- const Rect& getClipBounds();
- bool quickReject(float left, float top, float right, float bottom);
+ ANDROID_API const Rect& getClipBounds();
+ ANDROID_API bool quickReject(float left, float top, float right, float bottom);
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
virtual bool drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
index 2a38910..8cf466b 100644
--- a/libs/hwui/ResourceCache.h
+++ b/libs/hwui/ResourceCache.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_HWUI_RESOURCE_CACHE_H
#define ANDROID_HWUI_RESOURCE_CACHE_H
+#include <cutils/compiler.h>
+
#include <SkBitmap.h>
#include <SkiaColorFilter.h>
#include <SkiaShader.h>
@@ -49,7 +51,7 @@
ResourceType resourceType;
};
-class ResourceCache {
+class ANDROID_API ResourceCache {
KeyedVector<void *, ResourceReference *>* mCache;
public:
ResourceCache();
diff --git a/libs/hwui/SkiaColorFilter.h b/libs/hwui/SkiaColorFilter.h
index 1bf475c..2feb834 100644
--- a/libs/hwui/SkiaColorFilter.h
+++ b/libs/hwui/SkiaColorFilter.h
@@ -20,6 +20,8 @@
#include <GLES2/gl2.h>
#include <SkColorFilter.h>
+#include <cutils/compiler.h>
+
#include "ProgramCache.h"
#include "Extensions.h"
@@ -45,7 +47,7 @@
kBlend,
};
- SkiaColorFilter(SkColorFilter *skFilter, Type type, bool blend);
+ ANDROID_API SkiaColorFilter(SkColorFilter *skFilter, Type type, bool blend);
virtual ~SkiaColorFilter();
virtual void describe(ProgramDescription& description, const Extensions& extensions) = 0;
@@ -79,7 +81,7 @@
* A color filter that multiplies the source color with a matrix and adds a vector.
*/
struct SkiaColorMatrixFilter: public SkiaColorFilter {
- SkiaColorMatrixFilter(SkColorFilter *skFilter, float* matrix, float* vector);
+ ANDROID_API SkiaColorMatrixFilter(SkColorFilter *skFilter, float* matrix, float* vector);
~SkiaColorMatrixFilter();
void describe(ProgramDescription& description, const Extensions& extensions);
@@ -95,7 +97,7 @@
* another fixed value. Ignores the alpha channel of both arguments.
*/
struct SkiaLightingFilter: public SkiaColorFilter {
- SkiaLightingFilter(SkColorFilter *skFilter, int multiply, int add);
+ ANDROID_API SkiaLightingFilter(SkColorFilter *skFilter, int multiply, int add);
void describe(ProgramDescription& description, const Extensions& extensions);
void setupProgram(Program* program);
@@ -110,7 +112,7 @@
* and PorterDuff blending mode.
*/
struct SkiaBlendFilter: public SkiaColorFilter {
- SkiaBlendFilter(SkColorFilter *skFilter, int color, SkXfermode::Mode mode);
+ ANDROID_API SkiaBlendFilter(SkColorFilter *skFilter, int color, SkXfermode::Mode mode);
void describe(ProgramDescription& description, const Extensions& extensions);
void setupProgram(Program* program);
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index 89dd131..2de9a93 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -22,6 +22,8 @@
#include <GLES2/gl2.h>
+#include <cutils/compiler.h>
+
#include "Extensions.h"
#include "ProgramCache.h"
#include "TextureCache.h"
@@ -52,8 +54,8 @@
kCompose
};
- SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX, SkShader::TileMode tileY,
- SkMatrix* matrix, bool blend);
+ ANDROID_API SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX,
+ SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
virtual ~SkiaShader();
virtual SkiaShader* copy() = 0;
@@ -139,7 +141,7 @@
* A shader that draws a bitmap.
*/
struct SkiaBitmapShader: public SkiaShader {
- SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX,
+ ANDROID_API SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX,
SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
SkiaShader* copy();
@@ -169,8 +171,8 @@
* A shader that draws a linear gradient.
*/
struct SkiaLinearGradientShader: public SkiaShader {
- SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions, int count,
- SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
+ ANDROID_API SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions,
+ int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
~SkiaLinearGradientShader();
SkiaShader* copy();
@@ -193,8 +195,8 @@
* A shader that draws a sweep gradient.
*/
struct SkiaSweepGradientShader: public SkiaShader {
- SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions, int count,
- SkShader* key, SkMatrix* matrix, bool blend);
+ ANDROID_API SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions,
+ int count, SkShader* key, SkMatrix* matrix, bool blend);
~SkiaSweepGradientShader();
SkiaShader* copy();
@@ -218,8 +220,9 @@
* A shader that draws a circular gradient.
*/
struct SkiaCircularGradientShader: public SkiaSweepGradientShader {
- SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors, float* positions,
- int count, SkShader* key,SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
+ ANDROID_API SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors,
+ float* positions, int count, SkShader* key,SkShader::TileMode tileMode,
+ SkMatrix* matrix, bool blend);
SkiaShader* copy();
void describe(ProgramDescription& description, const Extensions& extensions);
@@ -233,7 +236,8 @@
* A shader that draws two shaders, composited with an xfermode.
*/
struct SkiaComposeShader: public SkiaShader {
- SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode, SkShader* key);
+ ANDROID_API SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode,
+ SkShader* key);
~SkiaComposeShader();
SkiaShader* copy();
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index 5fd5c35..4ecf8e8 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -226,6 +226,7 @@
RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
uint32_t sig = mtls->sig;
+ outer_foreach_t fn = dc->mForEachLaunch[sig];
while (1) {
uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
uint32_t yStart = mtls->yStart + slice * mtls->mSliceSize;
@@ -239,16 +240,10 @@
//LOGE("usr ptr in %p, out %p", mtls->ptrIn, mtls->ptrOut);
for (p.y = yStart; p.y < yEnd; p.y++) {
uint32_t offset = mtls->dimX * p.y;
- uint8_t *xPtrOut = mtls->ptrOut + (mtls->eStrideOut * offset);
- const uint8_t *xPtrIn = mtls->ptrIn + (mtls->eStrideIn * offset);
-
- for (p.x = mtls->xStart; p.x < mtls->xEnd; p.x++) {
- p.in = xPtrIn;
- p.out = xPtrOut;
- dc->mForEachLaunch[sig](&mtls->script->mHal.info.root, &p);
- xPtrIn += mtls->eStrideIn;
- xPtrOut += mtls->eStrideOut;
- }
+ p.out = mtls->ptrOut + (mtls->eStrideOut * offset);
+ p.in = mtls->ptrIn + (mtls->eStrideIn * offset);
+ fn(&mtls->script->mHal.info.root, &p, mtls->xStart, mtls->xEnd,
+ mtls->eStrideIn, mtls->eStrideOut);
}
}
}
@@ -262,6 +257,7 @@
RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
uint32_t sig = mtls->sig;
+ outer_foreach_t fn = dc->mForEachLaunch[sig];
while (1) {
uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
uint32_t xStart = mtls->xStart + slice * mtls->mSliceSize;
@@ -271,17 +267,12 @@
return;
}
- //LOGE("usr idx %i, x %i,%i y %i,%i", idx, mtls->xStart, mtls->xEnd, yStart, yEnd);
+ //LOGE("usr slice %i idx %i, x %i,%i", slice, idx, xStart, xEnd);
//LOGE("usr ptr in %p, out %p", mtls->ptrIn, mtls->ptrOut);
- uint8_t *xPtrOut = mtls->ptrOut + (mtls->eStrideOut * xStart);
- const uint8_t *xPtrIn = mtls->ptrIn + (mtls->eStrideIn * xStart);
- for (p.x = xStart; p.x < xEnd; p.x++) {
- p.in = xPtrIn;
- p.out = xPtrOut;
- dc->mForEachLaunch[sig](&mtls->script->mHal.info.root, &p);
- xPtrIn += mtls->eStrideIn;
- xPtrOut += mtls->eStrideOut;
- }
+
+ p.out = mtls->ptrOut + (mtls->eStrideOut * xStart);
+ p.in = mtls->ptrIn + (mtls->eStrideIn * xStart);
+ fn(&mtls->script->mHal.info.root, &p, xStart, xEnd, mtls->eStrideIn, mtls->eStrideOut);
}
}
@@ -392,22 +383,17 @@
uint32_t sig = mtls.sig;
//LOGE("launch 3");
+ outer_foreach_t fn = dc->mForEachLaunch[sig];
for (p.ar[0] = mtls.arrayStart; p.ar[0] < mtls.arrayEnd; p.ar[0]++) {
for (p.z = mtls.zStart; p.z < mtls.zEnd; p.z++) {
for (p.y = mtls.yStart; p.y < mtls.yEnd; p.y++) {
uint32_t offset = mtls.dimX * mtls.dimY * mtls.dimZ * p.ar[0] +
mtls.dimX * mtls.dimY * p.z +
mtls.dimX * p.y;
- uint8_t *xPtrOut = mtls.ptrOut + (mtls.eStrideOut * offset);
- const uint8_t *xPtrIn = mtls.ptrIn + (mtls.eStrideIn * offset);
-
- for (p.x = mtls.xStart; p.x < mtls.xEnd; p.x++) {
- p.in = xPtrIn;
- p.out = xPtrOut;
- dc->mForEachLaunch[sig](&s->mHal.info.root, &p);
- xPtrIn += mtls.eStrideIn;
- xPtrOut += mtls.eStrideOut;
- }
+ p.out = mtls.ptrOut + (mtls.eStrideOut * offset);
+ p.in = mtls.ptrIn + (mtls.eStrideIn * offset);
+ fn(&mtls.script->mHal.info.root, &p, mtls.xStart, mtls.xEnd,
+ mtls.eStrideIn, mtls.eStrideOut);
}
}
}
diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp
index f8107d9..247f4dc 100644
--- a/libs/rs/driver/rsdCore.cpp
+++ b/libs/rs/driver/rsdCore.cpp
@@ -292,75 +292,136 @@
}
static void rsdForEach17(const void *vRoot,
- const android::renderscript::RsForEachStubParamStruct *p) {
+ const android::renderscript::RsForEachStubParamStruct *p,
+ uint32_t x1, uint32_t x2,
+ uint32_t instep, uint32_t outstep) {
typedef void (*fe)(const void *, uint32_t);
(*(fe*)vRoot)(p->in, p->y);
}
static void rsdForEach18(const void *vRoot,
- const android::renderscript::RsForEachStubParamStruct *p) {
+ const android::renderscript::RsForEachStubParamStruct *p,
+ uint32_t x1, uint32_t x2,
+ uint32_t instep, uint32_t outstep) {
typedef void (*fe)(void *, uint32_t);
(*(fe*)vRoot)(p->out, p->y);
}
static void rsdForEach19(const void *vRoot,
- const android::renderscript::RsForEachStubParamStruct *p) {
+ const android::renderscript::RsForEachStubParamStruct *p,
+ uint32_t x1, uint32_t x2,
+ uint32_t instep, uint32_t outstep) {
typedef void (*fe)(const void *, void *, uint32_t);
(*(fe*)vRoot)(p->in, p->out, p->y);
}
static void rsdForEach21(const void *vRoot,
- const android::renderscript::RsForEachStubParamStruct *p) {
+ const android::renderscript::RsForEachStubParamStruct *p,
+ uint32_t x1, uint32_t x2,
+ uint32_t instep, uint32_t outstep) {
typedef void (*fe)(const void *, const void *, uint32_t);
(*(fe*)vRoot)(p->in, p->usr, p->y);
}
static void rsdForEach22(const void *vRoot,
- const android::renderscript::RsForEachStubParamStruct *p) {
+ const android::renderscript::RsForEachStubParamStruct *p,
+ uint32_t x1, uint32_t x2,
+ uint32_t instep, uint32_t outstep) {
typedef void (*fe)(void *, const void *, uint32_t);
(*(fe*)vRoot)(p->out, p->usr, p->y);
}
static void rsdForEach23(const void *vRoot,
- const android::renderscript::RsForEachStubParamStruct *p) {
+ const android::renderscript::RsForEachStubParamStruct *p,
+ uint32_t x1, uint32_t x2,
+ uint32_t instep, uint32_t outstep) {
typedef void (*fe)(const void *, void *, const void *, uint32_t);
(*(fe*)vRoot)(p->in, p->out, p->usr, p->y);
}
static void rsdForEach25(const void *vRoot,
- const android::renderscript::RsForEachStubParamStruct *p) {
+ const android::renderscript::RsForEachStubParamStruct *p,
+ uint32_t x1, uint32_t x2,
+ uint32_t instep, uint32_t outstep) {
typedef void (*fe)(const void *, uint32_t, uint32_t);
- (*(fe*)vRoot)(p->in, p->x, p->y);
+ const uint8_t *pin = (const uint8_t *)p->in;
+ uint32_t y = p->y;
+ for (uint32_t x = x1; x < x2; x++) {
+ (*(fe*)vRoot)(pin, x, y);
+ pin += instep;
+ }
}
static void rsdForEach26(const void *vRoot,
- const android::renderscript::RsForEachStubParamStruct *p) {
+ const android::renderscript::RsForEachStubParamStruct *p,
+ uint32_t x1, uint32_t x2,
+ uint32_t instep, uint32_t outstep) {
typedef void (*fe)(void *, uint32_t, uint32_t);
- (*(fe*)vRoot)(p->out, p->x, p->y);
+ uint8_t *pout = (uint8_t *)p->out;
+ uint32_t y = p->y;
+ for (uint32_t x = x1; x < x2; x++) {
+ (*(fe*)vRoot)(pout, x, y);
+ pout += outstep;
+ }
}
static void rsdForEach27(const void *vRoot,
- const android::renderscript::RsForEachStubParamStruct *p) {
+ const android::renderscript::RsForEachStubParamStruct *p,
+ uint32_t x1, uint32_t x2,
+ uint32_t instep, uint32_t outstep) {
typedef void (*fe)(const void *, void *, uint32_t, uint32_t);
- (*(fe*)vRoot)(p->in, p->out, p->x, p->y);
+ uint8_t *pout = (uint8_t *)p->out;
+ const uint8_t *pin = (const uint8_t *)p->in;
+ uint32_t y = p->y;
+ for (uint32_t x = x1; x < x2; x++) {
+ (*(fe*)vRoot)(pin, pout, x, y);
+ pin += instep;
+ pout += outstep;
+ }
}
static void rsdForEach29(const void *vRoot,
- const android::renderscript::RsForEachStubParamStruct *p) {
+ const android::renderscript::RsForEachStubParamStruct *p,
+ uint32_t x1, uint32_t x2,
+ uint32_t instep, uint32_t outstep) {
typedef void (*fe)(const void *, const void *, uint32_t, uint32_t);
- (*(fe*)vRoot)(p->in, p->usr, p->x, p->y);
+ const uint8_t *pin = (const uint8_t *)p->in;
+ const void *usr = p->usr;
+ const uint32_t y = p->y;
+ for (uint32_t x = x1; x < x2; x++) {
+ (*(fe*)vRoot)(pin, usr, x, y);
+ pin += instep;
+ }
}
static void rsdForEach30(const void *vRoot,
- const android::renderscript::RsForEachStubParamStruct *p) {
+ const android::renderscript::RsForEachStubParamStruct *p,
+ uint32_t x1, uint32_t x2,
+ uint32_t instep, uint32_t outstep) {
typedef void (*fe)(void *, const void *, uint32_t, uint32_t);
- (*(fe*)vRoot)(p->out, p->usr, p->x, p->y);
+ uint8_t *pout = (uint8_t *)p->out;
+ const void *usr = p->usr;
+ const uint32_t y = p->y;
+ for (uint32_t x = x1; x < x2; x++) {
+ (*(fe*)vRoot)(pout, usr, x, y);
+ pout += outstep;
+ }
}
static void rsdForEach31(const void *vRoot,
- const android::renderscript::RsForEachStubParamStruct *p) {
+ const android::renderscript::RsForEachStubParamStruct *p,
+ uint32_t x1, uint32_t x2,
+ uint32_t instep, uint32_t outstep) {
typedef void (*fe)(const void *, void *, const void *, uint32_t, uint32_t);
- (*(fe*)vRoot)(p->in, p->out, p->usr, p->x, p->y);
+ uint8_t *pout = (uint8_t *)p->out;
+ const uint8_t *pin = (const uint8_t *)p->in;
+ const void *usr = p->usr;
+ const uint32_t y = p->y;
+ for (uint32_t x = x1; x < x2; x++) {
+ (*(fe*)vRoot)(pin, pout, usr, x, y);
+ pin += instep;
+ pout += outstep;
+ }
}
diff --git a/libs/rs/driver/rsdCore.h b/libs/rs/driver/rsdCore.h
index 159b72a..ce86d11 100644
--- a/libs/rs/driver/rsdCore.h
+++ b/libs/rs/driver/rsdCore.h
@@ -28,7 +28,9 @@
typedef void (*WorkerCallback_t)(void *usr, uint32_t idx);
typedef void (*outer_foreach_t)(const void *,
- const android::renderscript::RsForEachStubParamStruct *);
+ const android::renderscript::RsForEachStubParamStruct *,
+ uint32_t x1, uint32_t x2,
+ uint32_t instep, uint32_t outstep);
typedef struct RsdSymbolTableRec {
const char * mName;
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 53d4970..2d51208 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -319,8 +319,12 @@
void Context::printWatchdogInfo(void *ctx) {
Context *rsc = (Context *)ctx;
- LOGE("RS watchdog timeout: %i %s line %i %s", rsc->watchdog.inRoot,
- rsc->watchdog.command, rsc->watchdog.line, rsc->watchdog.file);
+ if (rsc->watchdog.command && rsc->watchdog.file) {
+ LOGE("RS watchdog timeout: %i %s line %i %s", rsc->watchdog.inRoot,
+ rsc->watchdog.command, rsc->watchdog.line, rsc->watchdog.file);
+ } else {
+ LOGE("RS watchdog timeout: %i", rsc->watchdog.inRoot);
+ }
}
diff --git a/libs/rs/rsProgramRaster.h b/libs/rs/rsProgramRaster.h
index 20af30a..c552ea3 100644
--- a/libs/rs/rsProgramRaster.h
+++ b/libs/rs/rsProgramRaster.h
@@ -24,17 +24,16 @@
namespace renderscript {
class ProgramRasterState;
-
+/*****************************************************************************
+ * CAUTION
+ *
+ * Any layout changes for this class may require a corresponding change to be
+ * made to frameworks/compile/libbcc/lib/ScriptCRT/rs_core.c, which contains
+ * a partial copy of the information below.
+ *
+ *****************************************************************************/
class ProgramRaster : public ProgramBase {
public:
- virtual void setup(const Context *, ProgramRasterState *);
- virtual void serialize(OStream *stream) const;
- virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_RASTER; }
- static ProgramRaster *createFromStream(Context *rsc, IStream *stream);
-
- static ObjectBaseRef<ProgramRaster> getProgramRaster(Context *rsc,
- bool pointSprite,
- RsCullMode cull);
struct Hal {
mutable void *drv;
@@ -46,6 +45,14 @@
};
Hal mHal;
+ virtual void setup(const Context *, ProgramRasterState *);
+ virtual void serialize(OStream *stream) const;
+ virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_RASTER; }
+ static ProgramRaster *createFromStream(Context *rsc, IStream *stream);
+
+ static ObjectBaseRef<ProgramRaster> getProgramRaster(Context *rsc,
+ bool pointSprite,
+ RsCullMode cull);
protected:
virtual void preDestroy() const;
virtual ~ProgramRaster();
diff --git a/libs/rs/rsProgramStore.h b/libs/rs/rsProgramStore.h
index e21f039..9bb2795 100644
--- a/libs/rs/rsProgramStore.h
+++ b/libs/rs/rsProgramStore.h
@@ -25,23 +25,16 @@
namespace renderscript {
class ProgramStoreState;
-
+/*****************************************************************************
+ * CAUTION
+ *
+ * Any layout changes for this class may require a corresponding change to be
+ * made to frameworks/compile/libbcc/lib/ScriptCRT/rs_core.c, which contains
+ * a partial copy of the information below.
+ *
+ *****************************************************************************/
class ProgramStore : public ProgramBase {
public:
- virtual void setup(const Context *, ProgramStoreState *);
-
- virtual void serialize(OStream *stream) const;
- virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_STORE; }
- static ProgramStore *createFromStream(Context *rsc, IStream *stream);
- static ObjectBaseRef<ProgramStore> getProgramStore(Context *,
- bool colorMaskR, bool colorMaskG,
- bool colorMaskB, bool colorMaskA,
- bool depthMask, bool ditherEnable,
- RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
- RsDepthFunc depthFunc);
-
- void init();
-
struct Hal {
mutable void *drv;
@@ -64,6 +57,18 @@
};
Hal mHal;
+ virtual void setup(const Context *, ProgramStoreState *);
+
+ virtual void serialize(OStream *stream) const;
+ virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_STORE; }
+ static ProgramStore *createFromStream(Context *rsc, IStream *stream);
+ static ObjectBaseRef<ProgramStore> getProgramStore(Context *,
+ bool colorMaskR, bool colorMaskG,
+ bool colorMaskB, bool colorMaskA,
+ bool depthMask, bool ditherEnable,
+ RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
+ RsDepthFunc depthFunc);
+ void init();
protected:
virtual void preDestroy() const;
virtual ~ProgramStore();
diff --git a/libs/rs/rsSampler.h b/libs/rs/rsSampler.h
index e698132..654cd9c 100644
--- a/libs/rs/rsSampler.h
+++ b/libs/rs/rsSampler.h
@@ -27,23 +27,16 @@
const static uint32_t RS_MAX_SAMPLER_SLOT = 16;
class SamplerState;
-
+/*****************************************************************************
+ * CAUTION
+ *
+ * Any layout changes for this class may require a corresponding change to be
+ * made to frameworks/compile/libbcc/lib/ScriptCRT/rs_core.c, which contains
+ * a partial copy of the information below.
+ *
+ *****************************************************************************/
class Sampler : public ObjectBase {
public:
- static ObjectBaseRef<Sampler> getSampler(Context *,
- RsSamplerValue magFilter,
- RsSamplerValue minFilter,
- RsSamplerValue wrapS,
- RsSamplerValue wrapT,
- RsSamplerValue wrapR,
- float aniso = 1.0f);
- void bindToContext(SamplerState *, uint32_t slot);
- void unbindFromContext(SamplerState *);
-
- virtual void serialize(OStream *stream) const;
- virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_SAMPLER; }
- static Sampler *createFromStream(Context *rsc, IStream *stream);
-
struct Hal {
mutable void *drv;
@@ -59,6 +52,20 @@
};
Hal mHal;
+ static ObjectBaseRef<Sampler> getSampler(Context *,
+ RsSamplerValue magFilter,
+ RsSamplerValue minFilter,
+ RsSamplerValue wrapS,
+ RsSamplerValue wrapT,
+ RsSamplerValue wrapR,
+ float aniso = 1.0f);
+ void bindToContext(SamplerState *, uint32_t slot);
+ void unbindFromContext(SamplerState *);
+
+ virtual void serialize(OStream *stream) const;
+ virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_SAMPLER; }
+ static Sampler *createFromStream(Context *rsc, IStream *stream);
+
protected:
int32_t mBoundSlot;
diff --git a/libs/rs/scriptc/rs_graphics.rsh b/libs/rs/scriptc/rs_graphics.rsh
index 3e9339e..80267c7 100644
--- a/libs/rs/scriptc/rs_graphics.rsh
+++ b/libs/rs/scriptc/rs_graphics.rsh
@@ -23,6 +23,55 @@
#ifndef __RS_GRAPHICS_RSH__
#define __RS_GRAPHICS_RSH__
+// These are API 15 once it get official
+typedef enum {
+ RS_DEPTH_FUNC_ALWAYS,
+ RS_DEPTH_FUNC_LESS,
+ RS_DEPTH_FUNC_LEQUAL,
+ RS_DEPTH_FUNC_GREATER,
+ RS_DEPTH_FUNC_GEQUAL,
+ RS_DEPTH_FUNC_EQUAL,
+ RS_DEPTH_FUNC_NOTEQUAL
+} rs_depth_func;
+
+typedef enum {
+ RS_BLEND_SRC_ZERO, // 0
+ RS_BLEND_SRC_ONE, // 1
+ RS_BLEND_SRC_DST_COLOR, // 2
+ RS_BLEND_SRC_ONE_MINUS_DST_COLOR, // 3
+ RS_BLEND_SRC_SRC_ALPHA, // 4
+ RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA, // 5
+ RS_BLEND_SRC_DST_ALPHA, // 6
+ RS_BLEND_SRC_ONE_MINUS_DST_ALPHA, // 7
+ RS_BLEND_SRC_SRC_ALPHA_SATURATE // 8
+} rs_blend_src_func;
+
+typedef enum {
+ RS_BLEND_DST_ZERO, // 0
+ RS_BLEND_DST_ONE, // 1
+ RS_BLEND_DST_SRC_COLOR, // 2
+ RS_BLEND_DST_ONE_MINUS_SRC_COLOR, // 3
+ RS_BLEND_DST_SRC_ALPHA, // 4
+ RS_BLEND_DST_ONE_MINUS_SRC_ALPHA, // 5
+ RS_BLEND_DST_DST_ALPHA, // 6
+ RS_BLEND_DST_ONE_MINUS_DST_ALPHA // 7
+} rs_blend_dst_func;
+
+typedef enum {
+ RS_CULL_BACK,
+ RS_CULL_FRONT,
+ RS_CULL_NONE
+} rs_cull_mode;
+
+typedef enum {
+ RS_SAMPLER_NEAREST,
+ RS_SAMPLER_LINEAR,
+ RS_SAMPLER_LINEAR_MIP_LINEAR,
+ RS_SAMPLER_WRAP,
+ RS_SAMPLER_CLAMP,
+ RS_SAMPLER_LINEAR_MIP_NEAREST,
+} rs_sampler_value;
+
#if (defined(RS_VERSION) && (RS_VERSION >= 14))
/**
* Set the color target used for all subsequent rendering calls
@@ -83,6 +132,88 @@
extern void __attribute__((overloadable))
rsgBindProgramStore(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store depth function
+ *
+ * @param ps
+ */
+extern rs_depth_func __attribute__((overloadable))
+ rsgProgramStoreGetDepthFunc(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store depth mask
+ *
+ * @param ps
+ */
+extern bool __attribute__((overloadable))
+ rsgProgramStoreGetDepthMask(rs_program_store ps);
+/**
+ * @hide
+ * Get program store red component color mask
+ *
+ * @param ps
+ */
+extern bool __attribute__((overloadable))
+ rsgProgramStoreGetColorMaskR(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store green component color mask
+ *
+ * @param ps
+ */
+extern bool __attribute__((overloadable))
+ rsgProgramStoreGetColorMaskG(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store blur component color mask
+ *
+ * @param ps
+ */
+extern bool __attribute__((overloadable))
+ rsgProgramStoreGetColorMaskB(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store alpha component color mask
+ *
+ * @param ps
+ */
+extern bool __attribute__((overloadable))
+ rsgProgramStoreGetColorMaskA(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store blend source function
+ *
+ * @param ps
+ */
+extern rs_blend_src_func __attribute__((overloadable))
+ rsgProgramStoreGetBlendSrcFunc(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store blend destination function
+ *
+ * @param ps
+ */
+extern rs_blend_dst_func __attribute__((overloadable))
+ rsgProgramStoreGetBlendDstFunc(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store dither state
+ *
+ * @param ps
+ */
+extern bool __attribute__((overloadable))
+ rsgProgramStoreGetDitherEnabled(rs_program_store ps);
+
+
/**
* Bind a new ProgramVertex to the rendering context.
*
@@ -100,6 +231,24 @@
rsgBindProgramRaster(rs_program_raster pr);
/**
+ * @hide
+ * Get program raster point sprite state
+ *
+ * @param pr
+ */
+extern bool __attribute__((overloadable))
+ rsgProgramRasterGetPointSpriteEnabled(rs_program_raster pr);
+
+/**
+ * @hide
+ * Get program raster cull mode
+ *
+ * @param pr
+ */
+extern rs_cull_mode __attribute__((overloadable))
+ rsgProgramRasterGetCullMode(rs_program_raster pr);
+
+/**
* Bind a new Sampler object to a ProgramFragment. The sampler will
* operate on the texture bound at the matching slot.
*
@@ -109,6 +258,51 @@
rsgBindSampler(rs_program_fragment, uint slot, rs_sampler);
/**
+ * @hide
+ * Get sampler minification value
+ *
+ * @param pr
+ */
+extern rs_sampler_value __attribute__((overloadable))
+ rsgSamplerGetMinification(rs_sampler s);
+
+/**
+ * @hide
+ * Get sampler magnification value
+ *
+ * @param pr
+ */
+extern rs_sampler_value __attribute__((overloadable))
+ rsgSamplerGetMagnification(rs_sampler s);
+
+/**
+ * @hide
+ * Get sampler wrap S value
+ *
+ * @param pr
+ */
+extern rs_sampler_value __attribute__((overloadable))
+ rsgSamplerGetWrapS(rs_sampler s);
+
+/**
+ * @hide
+ * Get sampler wrap T value
+ *
+ * @param pr
+ */
+extern rs_sampler_value __attribute__((overloadable))
+ rsgSamplerGetWrapT(rs_sampler s);
+
+/**
+ * @hide
+ * Get sampler anisotropy
+ *
+ * @param pr
+ */
+extern float __attribute__((overloadable))
+ rsgSamplerGetAnisotropy(rs_sampler s);
+
+/**
* Bind a new Allocation object to a ProgramFragment. The
* Allocation must be a valid texture for the Program. The sampling
* of the texture will be controled by the Sampler bound at the
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 4f4f929..1d20e248 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -85,8 +85,7 @@
private static final String TAG = "AudioService";
/** Debug remote control client/display feature */
- // TODO set to false before release
- protected static final boolean DEBUG_RC = true;
+ protected static final boolean DEBUG_RC = false;
/** How long to delay before persisting a change in volume/ringer mode. */
private static final int PERSIST_DELAY = 3000;
@@ -369,6 +368,8 @@
intentFilter.addAction(Intent.ACTION_USB_DGTL_HEADSET_PLUG);
intentFilter.addAction(Intent.ACTION_HDMI_AUDIO_PLUG);
intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
+ intentFilter.addAction(Intent.ACTION_SCREEN_ON);
+ intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
context.registerReceiver(mReceiver, intentFilter);
// Register for package removal intent broadcasts for media button receiver persistence
@@ -516,8 +517,8 @@
ensureValidDirection(direction);
ensureValidStreamType(streamType);
-
- VolumeStreamState streamState = mStreamStates[STREAM_VOLUME_ALIAS[streamType]];
+ int streamTypeAlias = STREAM_VOLUME_ALIAS[streamType];
+ VolumeStreamState streamState = mStreamStates[streamTypeAlias];
final int oldIndex = (streamState.muteCount() != 0) ? streamState.mLastAudibleIndex : streamState.mIndex;
boolean adjustVolume = true;
@@ -526,14 +527,14 @@
if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
(!mVoiceCapable && streamType != AudioSystem.STREAM_VOICE_CALL &&
streamType != AudioSystem.STREAM_BLUETOOTH_SCO) ||
- (mVoiceCapable && streamType == AudioSystem.STREAM_RING)) {
+ (mVoiceCapable && streamTypeAlias == AudioSystem.STREAM_RING)) {
// do not vibrate if already in silent mode
if (mRingerMode != AudioManager.RINGER_MODE_NORMAL) {
flags &= ~AudioManager.FLAG_VIBRATE;
}
// Check if the ringer mode changes with this volume adjustment. If
// it does, it will handle adjusting the volume, so we won't below
- adjustVolume = checkForRingerModeChange(oldIndex, direction);
+ adjustVolume = checkForRingerModeChange(oldIndex, direction, streamTypeAlias);
}
// If stream is muted, adjust last audible index only
@@ -550,7 +551,7 @@
if (adjustVolume && streamState.adjustIndex(direction)) {
// Post message to set system volume (it in turn will post a message
// to persist). Do not change volume if stream is muted.
- sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME, STREAM_VOLUME_ALIAS[streamType], SENDMSG_NOOP, 0, 0,
+ sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME, streamTypeAlias, SENDMSG_NOOP, 0, 0,
streamState, 0);
}
index = streamState.mIndex;
@@ -566,6 +567,23 @@
final int oldIndex = (streamState.muteCount() != 0) ? streamState.mLastAudibleIndex : streamState.mIndex;
+ // setting ring or notifications volume to 0 on voice capable devices enters silent mode
+ if (mVoiceCapable && (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
+ (STREAM_VOLUME_ALIAS[streamType] == AudioSystem.STREAM_RING))) {
+ int newRingerMode = mRingerMode;
+ if (index == 0) {
+ newRingerMode = System.getInt(mContentResolver, System.VIBRATE_IN_SILENT, 1) == 1
+ ? AudioManager.RINGER_MODE_VIBRATE
+ : AudioManager.RINGER_MODE_SILENT;
+ setStreamVolumeInt(STREAM_VOLUME_ALIAS[streamType], index, false, true);
+ } else {
+ newRingerMode = AudioManager.RINGER_MODE_NORMAL;
+ }
+ if (newRingerMode != mRingerMode) {
+ setRingerMode(newRingerMode);
+ }
+ }
+
index = rescaleIndex(index * 10, streamType, STREAM_VOLUME_ALIAS[streamType]);
setStreamVolumeInt(STREAM_VOLUME_ALIAS[streamType], index, false, true);
@@ -691,6 +709,13 @@
if (isStreamMutedByRingerMode(streamType)) {
if (!isStreamAffectedByRingerMode(streamType) ||
mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
+ // ring and notifications volume should never be 0 when not silenced
+ // on voice capable devices
+ if (mVoiceCapable &&
+ STREAM_VOLUME_ALIAS[streamType] == AudioSystem.STREAM_RING &&
+ mStreamStates[streamType].mLastAudibleIndex == 0) {
+ mStreamStates[streamType].mLastAudibleIndex = 10;
+ }
mStreamStates[streamType].mute(null, false);
mRingerModeMutedStreams &= ~(1 << streamType);
}
@@ -1592,7 +1617,7 @@
* adjusting volume. If so, this will set the proper ringer mode and volume
* indices on the stream states.
*/
- private boolean checkForRingerModeChange(int oldIndex, int direction) {
+ private boolean checkForRingerModeChange(int oldIndex, int direction, int streamType) {
boolean adjustVolumeIndex = true;
int newRingerMode = mRingerMode;
int uiIndex = (oldIndex + 5) / 10;
@@ -1607,7 +1632,8 @@
? AudioManager.RINGER_MODE_VIBRATE
: AudioManager.RINGER_MODE_SILENT;
}
- if (uiIndex == 0) {
+ if (uiIndex == 0 || (mPrevVolDirection == AudioManager.ADJUST_LOWER &&
+ mVoiceCapable && streamType == AudioSystem.STREAM_RING)) {
adjustVolumeIndex = false;
}
}
@@ -1615,13 +1641,8 @@
if (direction == AudioManager.ADJUST_RAISE) {
// exiting silent mode
newRingerMode = AudioManager.RINGER_MODE_NORMAL;
- if (uiIndex != 0) {
- adjustVolumeIndex = false;
- }
- } else {
- // prevent last audible index to reach 0
- adjustVolumeIndex = false;
}
+ adjustVolumeIndex = false;
}
if (newRingerMode != mRingerMode) {
@@ -2566,6 +2587,10 @@
removeMediaButtonReceiverForPackage(packageName);
}
}
+ } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
+ AudioSystem.setParameters("screen_state=on");
+ } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+ AudioSystem.setParameters("screen_state=off");
}
}
}
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 8793841..e275aa6 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -71,6 +71,11 @@
private static final int FIRST_VIDEO_FILE_TYPE = FILE_TYPE_MP4;
private static final int LAST_VIDEO_FILE_TYPE = FILE_TYPE_WEBM;
+ // More video file types
+ public static final int FILE_TYPE_MP2PS = 200;
+ private static final int FIRST_VIDEO_FILE_TYPE2 = FILE_TYPE_MP2PS;
+ private static final int LAST_VIDEO_FILE_TYPE2 = FILE_TYPE_MP2PS;
+
// Image file types
public static final int FILE_TYPE_JPEG = 31;
public static final int FILE_TYPE_GIF = 32;
@@ -235,6 +240,8 @@
addFileType("PPT", FILE_TYPE_MS_POWERPOINT, "application/mspowerpoint", MtpConstants.FORMAT_MS_POWERPOINT_PRESENTATION);
addFileType("FLAC", FILE_TYPE_FLAC, "audio/flac", MtpConstants.FORMAT_FLAC);
addFileType("ZIP", FILE_TYPE_ZIP, "application/zip");
+ addFileType("MPG", FILE_TYPE_MP2PS, "video/mp2p");
+ addFileType("MPEG", FILE_TYPE_MP2PS, "video/mp2p");
}
public static boolean isAudioFileType(int fileType) {
@@ -246,7 +253,9 @@
public static boolean isVideoFileType(int fileType) {
return (fileType >= FIRST_VIDEO_FILE_TYPE &&
- fileType <= LAST_VIDEO_FILE_TYPE);
+ fileType <= LAST_VIDEO_FILE_TYPE)
+ || (fileType >= FIRST_VIDEO_FILE_TYPE2 &&
+ fileType <= LAST_VIDEO_FILE_TYPE2);
}
public static boolean isImageFileType(int fileType) {
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index 198ae4c..77acfe6 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -35,14 +35,27 @@
import java.lang.IllegalArgumentException;
/**
- * TODO javadoc update for ComponentName - PendingIntent change
* RemoteControlClient enables exposing information meant to be consumed by remote controls
* capable of displaying metadata, artwork and media transport control buttons.
- * A remote control client object is associated with a media button event receiver. This
+ *
+ * <p>A remote control client object is associated with a media button event receiver. This
* event receiver must have been previously registered with
* {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)} before the
* RemoteControlClient can be registered through
* {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.
+ *
+ * <p>Here is an example of creating a RemoteControlClient instance after registering a media
+ * button event receiver:
+ * <pre>ComponentName myEventReceiver = new ComponentName(getPackageName(), MyRemoteControlEventReceiver.class.getName());
+ * AudioManager myAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+ * myAudioManager.registerMediaButtonEventReceiver(myEventReceiver);
+ * // build the PendingIntent for the remote control client
+ * Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+ * mediaButtonIntent.setComponent(myEventReceiver);
+ * PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0);
+ * // create and register the remote control client
+ * RemoteControlClient myRemoteControlClient = new RemoteControlClient(mediaPendingIntent);
+ * myAudioManager.registerRemoteControlClient(myRemoteControlClient);</pre>
*/
public class RemoteControlClient
{
diff --git a/media/java/android/media/videoeditor/AudioTrack.java b/media/java/android/media/videoeditor/AudioTrack.java
index 2de82f2..c5cc2ca 100755
--- a/media/java/android/media/videoeditor/AudioTrack.java
+++ b/media/java/android/media/videoeditor/AudioTrack.java
@@ -147,14 +147,16 @@
} catch (Exception e) {
throw new IllegalArgumentException(e.getMessage() + " : " + filename);
}
- switch (mMANativeHelper.getFileType(properties.fileType)) {
+ int fileType = mMANativeHelper.getFileType(properties.fileType);
+ switch (fileType) {
case MediaProperties.FILE_3GP:
case MediaProperties.FILE_MP4:
case MediaProperties.FILE_MP3:
+ case MediaProperties.FILE_AMR:
break;
default: {
- throw new IllegalArgumentException("Unsupported input file type");
+ throw new IllegalArgumentException("Unsupported input file type: " + fileType);
}
}
switch (mMANativeHelper.getAudioCodecType(properties.audioFormat)) {
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index d7b8eaa..03ae62a 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -3239,6 +3239,9 @@
case FileType.M4V:
retValue = MediaProperties.FILE_M4V;
break;
+ case FileType.AMR:
+ retValue = MediaProperties.FILE_AMR;
+ break;
default:
retValue = -1;
diff --git a/media/java/android/media/videoeditor/MediaProperties.java b/media/java/android/media/videoeditor/MediaProperties.java
index fd034ab..cf518a5 100755
--- a/media/java/android/media/videoeditor/MediaProperties.java
+++ b/media/java/android/media/videoeditor/MediaProperties.java
@@ -286,7 +286,7 @@
*/
public static final int FILE_3GP = 0;
public static final int FILE_MP4 = 1;
- // 2 is for AMRNB
+ public static final int FILE_AMR = 2;
public static final int FILE_MP3 = 3;
// 4 is for PCM
public static final int FILE_JPEG = 5;
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index f3174fe..63cbf5e 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -274,8 +274,14 @@
sp<ISurfaceTexture> new_st;
if (jsurface) {
sp<Surface> surface(Surface_getSurface(env, jsurface));
- new_st = surface->getSurfaceTexture();
- new_st->incStrong(thiz);
+ if (surface != NULL) {
+ new_st = surface->getSurfaceTexture();
+ new_st->incStrong(thiz);
+ } else {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "The surface has been released");
+ return;
+ }
}
env->SetIntField(thiz, fields.surface_texture, (int)new_st.get());
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index ec7d8a0..a3e2517 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -32,8 +32,8 @@
libdl
LOCAL_STATIC_LIBRARIES := \
- libstagefright_rtsp \
libstagefright_nuplayer \
+ libstagefright_rtsp \
LOCAL_C_INCLUDES := \
$(JNI_H_INCLUDE) \
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index b5eef94..24e1bfb 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -584,6 +584,10 @@
}
}
+ if (!strncasecmp("rtsp://", url, 7)) {
+ return NU_PLAYER;
+ }
+
// use MidiFile for MIDI extensions
int lenURL = strlen(url);
for (int i = 0; i < NELEM(FILE_EXTS); ++i) {
diff --git a/media/libmediaplayerservice/nuplayer/Android.mk b/media/libmediaplayerservice/nuplayer/Android.mk
index e761509..33e2f93 100644
--- a/media/libmediaplayerservice/nuplayer/Android.mk
+++ b/media/libmediaplayerservice/nuplayer/Android.mk
@@ -8,6 +8,7 @@
NuPlayerDriver.cpp \
NuPlayerRenderer.cpp \
NuPlayerStreamListener.cpp \
+ RTSPSource.cpp \
StreamingSource.cpp \
LOCAL_C_INCLUDES := \
@@ -15,6 +16,7 @@
$(TOP)/frameworks/base/media/libstagefright/include \
$(TOP)/frameworks/base/media/libstagefright/mpeg2ts \
$(TOP)/frameworks/base/media/libstagefright/httplive \
+ $(TOP)/frameworks/base/media/libstagefright/rtsp \
LOCAL_MODULE:= libstagefright_nuplayer
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 6b40528..4c710b4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -25,6 +25,7 @@
#include "NuPlayerDriver.h"
#include "NuPlayerRenderer.h"
#include "NuPlayerSource.h"
+#include "RTSPSource.h"
#include "StreamingSource.h"
#include "ATSParser.h"
@@ -87,7 +88,14 @@
const char *url, const KeyedVector<String8, String8> *headers) {
sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
- msg->setObject("source", new HTTPLiveSource(url, headers, mUIDValid, mUID));
+ if (!strncasecmp(url, "rtsp://", 7)) {
+ msg->setObject(
+ "source", new RTSPSource(url, headers, mUIDValid, mUID));
+ } else {
+ msg->setObject(
+ "source", new HTTPLiveSource(url, headers, mUIDValid, mUID));
+ }
+
msg->post();
}
@@ -568,8 +576,15 @@
CHECK(mAudioDecoder == NULL);
CHECK(mVideoDecoder == NULL);
+ ++mScanSourcesGeneration;
+ mScanSourcesPending = false;
+
mRenderer.clear();
- mSource.clear();
+
+ if (mSource != NULL) {
+ mSource->stop();
+ mSource.clear();
+ }
if (mDriver != NULL) {
sp<NuPlayerDriver> driver = mDriver.promote();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index a5382b4..f90759d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -68,6 +68,7 @@
struct Renderer;
struct Source;
struct StreamingSource;
+ struct RTSPSource;
enum {
kWhatSetDataSource = '=DaS',
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 07e347e..bf19040 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -219,7 +219,9 @@
bool NuPlayer::Renderer::onDrainAudioQueue() {
uint32_t numFramesPlayed;
- CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
+ if (mAudioSink->getPosition(&numFramesPlayed) != OK) {
+ return false;
+ }
ssize_t numFramesAvailableToWrite =
mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index 8a7eece..531b29f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -28,6 +28,7 @@
Source() {}
virtual void start() = 0;
+ virtual void stop() {}
// Returns OK iff more data was available,
// an error or ERROR_END_OF_STREAM if not.
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
new file mode 100644
index 0000000..e72adc4
--- /dev/null
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -0,0 +1,354 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "RTSPSource"
+#include <utils/Log.h>
+
+#include "RTSPSource.h"
+
+#include "AnotherPacketSource.h"
+#include "MyHandler.h"
+
+#include <media/stagefright/MetaData.h>
+
+namespace android {
+
+NuPlayer::RTSPSource::RTSPSource(
+ const char *url,
+ const KeyedVector<String8, String8> *headers,
+ bool uidValid,
+ uid_t uid)
+ : mURL(url),
+ mUIDValid(uidValid),
+ mUID(uid),
+ mFlags(0),
+ mState(DISCONNECTED),
+ mFinalResult(OK),
+ mDisconnectReplyID(0) {
+ if (headers) {
+ mExtraHeaders = *headers;
+
+ ssize_t index =
+ mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log"));
+
+ if (index >= 0) {
+ mFlags |= kFlagIncognito;
+
+ mExtraHeaders.removeItemsAt(index);
+ }
+ }
+}
+
+NuPlayer::RTSPSource::~RTSPSource() {
+ if (mLooper != NULL) {
+ mLooper->stop();
+ }
+}
+
+void NuPlayer::RTSPSource::start() {
+ if (mLooper == NULL) {
+ mLooper = new ALooper;
+ mLooper->setName("rtsp");
+ mLooper->start();
+
+ mReflector = new AHandlerReflector<RTSPSource>(this);
+ mLooper->registerHandler(mReflector);
+ }
+
+ CHECK(mHandler == NULL);
+
+ sp<AMessage> notify = new AMessage(kWhatNotify, mReflector->id());
+
+ mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID);
+ mLooper->registerHandler(mHandler);
+
+ CHECK_EQ(mState, (int)DISCONNECTED);
+ mState = CONNECTING;
+
+ mHandler->connect();
+}
+
+void NuPlayer::RTSPSource::stop() {
+ sp<AMessage> msg = new AMessage(kWhatDisconnect, mReflector->id());
+
+ sp<AMessage> dummy;
+ msg->postAndAwaitResponse(&dummy);
+}
+
+status_t NuPlayer::RTSPSource::feedMoreTSData() {
+ return mFinalResult;
+}
+
+sp<MetaData> NuPlayer::RTSPSource::getFormat(bool audio) {
+ sp<AnotherPacketSource> source = getSource(audio);
+
+ if (source == NULL) {
+ return NULL;
+ }
+
+ return source->getFormat();
+}
+
+status_t NuPlayer::RTSPSource::dequeueAccessUnit(
+ bool audio, sp<ABuffer> *accessUnit) {
+ sp<AnotherPacketSource> source = getSource(audio);
+
+ if (source == NULL) {
+ return -EWOULDBLOCK;
+ }
+
+ status_t finalResult;
+ if (!source->hasBufferAvailable(&finalResult)) {
+ return finalResult == OK ? -EWOULDBLOCK : finalResult;
+ }
+
+ return source->dequeueAccessUnit(accessUnit);
+}
+
+sp<AnotherPacketSource> NuPlayer::RTSPSource::getSource(bool audio) {
+ return audio ? mAudioTrack : mVideoTrack;
+}
+
+status_t NuPlayer::RTSPSource::getDuration(int64_t *durationUs) {
+ *durationUs = 0ll;
+
+ int64_t audioDurationUs;
+ if (mAudioTrack != NULL
+ && mAudioTrack->getFormat()->findInt64(
+ kKeyDuration, &audioDurationUs)
+ && audioDurationUs > *durationUs) {
+ *durationUs = audioDurationUs;
+ }
+
+ int64_t videoDurationUs;
+ if (mVideoTrack != NULL
+ && mVideoTrack->getFormat()->findInt64(
+ kKeyDuration, &videoDurationUs)
+ && videoDurationUs > *durationUs) {
+ *durationUs = videoDurationUs;
+ }
+
+ return OK;
+}
+
+status_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs) {
+ if (mState != CONNECTED) {
+ return UNKNOWN_ERROR;
+ }
+
+ mState = SEEKING;
+ mHandler->seek(seekTimeUs);
+
+ return OK;
+}
+
+bool NuPlayer::RTSPSource::isSeekable() {
+ return true;
+}
+
+void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
+ if (msg->what() == kWhatDisconnect) {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ mDisconnectReplyID = replyID;
+ finishDisconnectIfPossible();
+ return;
+ }
+
+ CHECK_EQ(msg->what(), (int)kWhatNotify);
+
+ int32_t what;
+ CHECK(msg->findInt32("what", &what));
+
+ switch (what) {
+ case MyHandler::kWhatConnected:
+ onConnected();
+ break;
+
+ case MyHandler::kWhatDisconnected:
+ onDisconnected(msg);
+ break;
+
+ case MyHandler::kWhatSeekDone:
+ {
+ mState = CONNECTED;
+ break;
+ }
+
+ case MyHandler::kWhatAccessUnit:
+ {
+ size_t trackIndex;
+ CHECK(msg->findSize("trackIndex", &trackIndex));
+ CHECK_LT(trackIndex, mTracks.size());
+
+ sp<RefBase> obj;
+ CHECK(msg->findObject("accessUnit", &obj));
+
+ sp<ABuffer> accessUnit = static_cast<ABuffer *>(obj.get());
+
+ int32_t damaged;
+ if (accessUnit->meta()->findInt32("damaged", &damaged)
+ && damaged) {
+ LOGI("dropping damaged access unit.");
+ break;
+ }
+
+ const TrackInfo &info = mTracks.editItemAt(trackIndex);
+ sp<AnotherPacketSource> source = info.mSource;
+ if (source != NULL) {
+#if 1
+ uint32_t rtpTime;
+ CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
+
+ int64_t nptUs =
+ ((double)rtpTime - (double)info.mRTPTime)
+ / info.mTimeScale
+ * 1000000ll
+ + info.mNormalPlaytimeUs;
+
+ accessUnit->meta()->setInt64("timeUs", nptUs);
+#endif
+
+ source->queueAccessUnit(accessUnit);
+ }
+ break;
+ }
+
+ case MyHandler::kWhatEOS:
+ {
+ size_t trackIndex;
+ CHECK(msg->findSize("trackIndex", &trackIndex));
+ CHECK_LT(trackIndex, mTracks.size());
+
+ int32_t finalResult;
+ CHECK(msg->findInt32("finalResult", &finalResult));
+ CHECK_NE(finalResult, (status_t)OK);
+
+ TrackInfo *info = &mTracks.editItemAt(trackIndex);
+ sp<AnotherPacketSource> source = info->mSource;
+ if (source != NULL) {
+ source->signalEOS(finalResult);
+ }
+
+ break;
+ }
+
+ case MyHandler::kWhatSeekDiscontinuity:
+ {
+ size_t trackIndex;
+ CHECK(msg->findSize("trackIndex", &trackIndex));
+ CHECK_LT(trackIndex, mTracks.size());
+
+ TrackInfo *info = &mTracks.editItemAt(trackIndex);
+ sp<AnotherPacketSource> source = info->mSource;
+ if (source != NULL) {
+ source->queueDiscontinuity(ATSParser::DISCONTINUITY_SEEK, NULL);
+ }
+
+ break;
+ }
+
+ case MyHandler::kWhatNormalPlayTimeMapping:
+ {
+ size_t trackIndex;
+ CHECK(msg->findSize("trackIndex", &trackIndex));
+ CHECK_LT(trackIndex, mTracks.size());
+
+ uint32_t rtpTime;
+ CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime));
+
+ int64_t nptUs;
+ CHECK(msg->findInt64("nptUs", &nptUs));
+
+ TrackInfo *info = &mTracks.editItemAt(trackIndex);
+ info->mRTPTime = rtpTime;
+ info->mNormalPlaytimeUs = nptUs;
+ break;
+ }
+
+ default:
+ TRESPASS();
+ }
+}
+
+void NuPlayer::RTSPSource::onConnected() {
+ CHECK(mAudioTrack == NULL);
+ CHECK(mVideoTrack == NULL);
+
+ size_t numTracks = mHandler->countTracks();
+ for (size_t i = 0; i < numTracks; ++i) {
+ int32_t timeScale;
+ sp<MetaData> format = mHandler->getTrackFormat(i, &timeScale);
+
+ const char *mime;
+ CHECK(format->findCString(kKeyMIMEType, &mime));
+
+ bool isAudio = !strncasecmp(mime, "audio/", 6);
+ bool isVideo = !strncasecmp(mime, "video/", 6);
+
+ TrackInfo info;
+ info.mTimeScale = timeScale;
+ info.mRTPTime = 0;
+ info.mNormalPlaytimeUs = 0ll;
+
+ if ((isAudio && mAudioTrack == NULL)
+ || (isVideo && mVideoTrack == NULL)) {
+ sp<AnotherPacketSource> source = new AnotherPacketSource(format);
+
+ if (isAudio) {
+ mAudioTrack = source;
+ } else {
+ mVideoTrack = source;
+ }
+
+ info.mSource = source;
+ }
+
+ mTracks.push(info);
+ }
+
+ mState = CONNECTED;
+}
+
+void NuPlayer::RTSPSource::onDisconnected(const sp<AMessage> &msg) {
+ status_t err;
+ CHECK(msg->findInt32("result", &err));
+ CHECK_NE(err, (status_t)OK);
+
+ mLooper->unregisterHandler(mHandler->id());
+ mHandler.clear();
+
+ mState = DISCONNECTED;
+ mFinalResult = err;
+
+ if (mDisconnectReplyID != 0) {
+ finishDisconnectIfPossible();
+ }
+}
+
+void NuPlayer::RTSPSource::finishDisconnectIfPossible() {
+ if (mState != DISCONNECTED) {
+ mHandler->disconnect();
+ return;
+ }
+
+ (new AMessage)->postReply(mDisconnectReplyID);
+ mDisconnectReplyID = 0;
+}
+
+} // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h
new file mode 100644
index 0000000..66eab72
--- /dev/null
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+#ifndef RTSP_SOURCE_H_
+
+#define RTSP_SOURCE_H_
+
+#include "NuPlayerSource.h"
+
+#include <media/stagefright/foundation/AHandlerReflector.h>
+
+namespace android {
+
+struct ALooper;
+struct AnotherPacketSource;
+struct MyHandler;
+
+struct NuPlayer::RTSPSource : public NuPlayer::Source {
+ RTSPSource(
+ const char *url,
+ const KeyedVector<String8, String8> *headers,
+ bool uidValid = false,
+ uid_t uid = 0);
+
+ virtual void start();
+ virtual void stop();
+
+ virtual status_t feedMoreTSData();
+
+ virtual sp<MetaData> getFormat(bool audio);
+ virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
+
+ virtual status_t getDuration(int64_t *durationUs);
+ virtual status_t seekTo(int64_t seekTimeUs);
+ virtual bool isSeekable();
+
+ void onMessageReceived(const sp<AMessage> &msg);
+
+protected:
+ virtual ~RTSPSource();
+
+private:
+ enum {
+ kWhatNotify = 'noti',
+ kWhatDisconnect = 'disc',
+ };
+
+ enum State {
+ DISCONNECTED,
+ CONNECTING,
+ CONNECTED,
+ SEEKING,
+ };
+
+ enum Flags {
+ // Don't log any URLs.
+ kFlagIncognito = 1,
+ };
+
+ struct TrackInfo {
+ sp<AnotherPacketSource> mSource;
+
+ int32_t mTimeScale;
+ uint32_t mRTPTime;
+ int64_t mNormalPlaytimeUs;
+ };
+
+ AString mURL;
+ KeyedVector<String8, String8> mExtraHeaders;
+ bool mUIDValid;
+ uid_t mUID;
+ uint32_t mFlags;
+ State mState;
+ status_t mFinalResult;
+ uint32_t mDisconnectReplyID;
+
+ sp<ALooper> mLooper;
+ sp<AHandlerReflector<RTSPSource> > mReflector;
+ sp<MyHandler> mHandler;
+
+ Vector<TrackInfo> mTracks;
+ sp<AnotherPacketSource> mAudioTrack;
+ sp<AnotherPacketSource> mVideoTrack;
+
+ sp<AnotherPacketSource> getSource(bool audio);
+
+ void onConnected();
+ void onDisconnected(const sp<AMessage> &msg);
+ void finishDisconnectIfPossible();
+
+ DISALLOW_EVIL_CONSTRUCTORS(RTSPSource);
+};
+
+} // namespace android
+
+#endif // RTSP_SOURCE_H_
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 9cb18de..d947760 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -681,6 +681,10 @@
static const MimeToRole kMimeToRole[] = {
{ MEDIA_MIMETYPE_AUDIO_MPEG,
"audio_decoder.mp3", "audio_encoder.mp3" },
+ { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
+ "audio_decoder.mp1", "audio_encoder.mp1" },
+ { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
+ "audio_decoder.mp2", "audio_encoder.mp2" },
{ MEDIA_MIMETYPE_AUDIO_AMR_NB,
"audio_decoder.amrnb", "audio_encoder.amrnb" },
{ MEDIA_MIMETYPE_AUDIO_AMR_WB,
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 0b1a2af..0aeb515 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -58,7 +58,6 @@
$(TOP)/frameworks/base/include/media/stagefright/openmax \
$(TOP)/external/flac/include \
$(TOP)/external/tremolo \
- $(TOP)/frameworks/base/media/libstagefright/rtsp \
$(TOP)/external/openssl/include \
LOCAL_SHARED_LIBRARIES := \
@@ -88,7 +87,6 @@
libvpx \
libstagefright_mpeg2ts \
libstagefright_httplive \
- libstagefright_rtsp \
libstagefright_id3 \
libFLAC \
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index fa9417a50..1c7e58d 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -22,7 +22,6 @@
#include <dlfcn.h>
-#include "include/ARTSPController.h"
#include "include/AwesomePlayer.h"
#include "include/DRMExtractor.h"
#include "include/SoftwareRenderer.h"
@@ -53,7 +52,6 @@
#include <gui/SurfaceTextureClient.h>
#include <surfaceflinger/ISurfaceComposer.h>
-#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/AMessage.h>
#include <cutils/properties.h>
@@ -65,7 +63,6 @@
static int64_t kLowWaterMarkUs = 2000000ll; // 2secs
static int64_t kHighWaterMarkUs = 5000000ll; // 5secs
-static int64_t kHighWaterMarkRTSPUs = 4000000ll; // 4secs
static const size_t kLowWaterMarkBytes = 40000;
static const size_t kHighWaterMarkBytes = 200000;
@@ -485,9 +482,6 @@
if (mConnectingDataSource != NULL) {
LOGI("interrupting the connection process");
mConnectingDataSource->disconnect();
- } else if (mConnectingRTSPController != NULL) {
- LOGI("interrupting the connection process");
- mConnectingRTSPController->disconnect();
}
if (mFlags & PREPARING_CONNECTED) {
@@ -534,11 +528,6 @@
mVideoRenderer.clear();
- if (mRTSPController != NULL) {
- mRTSPController->disconnect();
- mRTSPController.clear();
- }
-
if (mVideoSource != NULL) {
shutdownVideoDecoder_l();
}
@@ -612,10 +601,7 @@
bool AwesomePlayer::getCachedDuration_l(int64_t *durationUs, bool *eos) {
int64_t bitrate;
- if (mRTSPController != NULL) {
- *durationUs = mRTSPController->getQueueDurationUs(eos);
- return true;
- } else if (mCachedSource != NULL && getBitrate(&bitrate)) {
+ if (mCachedSource != NULL && getBitrate(&bitrate)) {
status_t finalStatus;
size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
*durationUs = cachedDataRemaining * 8000000ll / bitrate;
@@ -751,9 +737,6 @@
LOGV("cachedDurationUs = %.2f secs, eos=%d",
cachedDurationUs / 1E6, eos);
- int64_t highWaterMarkUs =
- (mRTSPController != NULL) ? kHighWaterMarkRTSPUs : kHighWaterMarkUs;
-
if ((mFlags & PLAYING) && !eos
&& (cachedDurationUs < kLowWaterMarkUs)) {
LOGI("cache is running low (%.2f secs) , pausing.",
@@ -763,7 +746,7 @@
ensureCacheIsFetching_l();
sendCacheStats();
notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
- } else if (eos || cachedDurationUs > highWaterMarkUs) {
+ } else if (eos || cachedDurationUs > kHighWaterMarkUs) {
if (mFlags & CACHE_UNDERRUN) {
LOGI("cache has filled up (%.2f secs), resuming.",
cachedDurationUs / 1E6);
@@ -1081,7 +1064,8 @@
if (USE_SURFACE_ALLOC
&& !strncmp(component, "OMX.", 4)
- && strncmp(component, "OMX.google.", 11)) {
+ && strncmp(component, "OMX.google.", 11)
+ && strcmp(component, "OMX.Nvidia.mpeg2v.decode")) {
// Hardware decoders avoid the CPU color conversion by decoding
// directly to ANativeBuffers, so we must use a renderer that
// just pushes those buffers to the ANativeWindow.
@@ -1263,10 +1247,7 @@
}
status_t AwesomePlayer::getPosition(int64_t *positionUs) {
- if (mRTSPController != NULL) {
- *positionUs = mRTSPController->getNormalPlayTimeUs();
- }
- else if (mSeeking != NO_SEEK) {
+ if (mSeeking != NO_SEEK) {
*positionUs = mSeekTimeUs;
} else if (mVideoSource != NULL
&& (mAudioPlayer == NULL || !(mFlags & VIDEO_AT_EOS))) {
@@ -1316,25 +1297,7 @@
}
}
-// static
-void AwesomePlayer::OnRTSPSeekDoneWrapper(void *cookie) {
- static_cast<AwesomePlayer *>(cookie)->onRTSPSeekDone();
-}
-
-void AwesomePlayer::onRTSPSeekDone() {
- if (!mSeekNotificationSent) {
- notifyListener_l(MEDIA_SEEK_COMPLETE);
- mSeekNotificationSent = true;
- }
-}
-
status_t AwesomePlayer::seekTo_l(int64_t timeUs) {
- if (mRTSPController != NULL) {
- mSeekNotificationSent = false;
- mRTSPController->seekAsync(timeUs, OnRTSPSeekDoneWrapper, this);
- return OK;
- }
-
if (mFlags & CACHE_UNDERRUN) {
modifyFlags(CACHE_UNDERRUN, CLEAR);
play_l();
@@ -1770,7 +1733,6 @@
int64_t latenessUs = nowUs - timeUs;
if (latenessUs > 500000ll
- && mRTSPController == NULL
&& mAudioPlayer != NULL
&& mAudioPlayer->getMediaTimeMapping(
&realTimeUs, &mediaTimeUs)) {
@@ -2005,6 +1967,11 @@
mConnectingDataSource->setUID(mUID);
}
+ String8 cacheConfig;
+ bool disconnectAtHighwatermark;
+ NuCachedSource2::RemoveCacheSpecificHeaders(
+ &mUriHeaders, &cacheConfig, &disconnectAtHighwatermark);
+
mLock.unlock();
status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
mLock.lock();
@@ -2024,7 +1991,10 @@
new ThrottledSource(
mConnectingDataSource, 50 * 1024 /* bytes/sec */));
#else
- mCachedSource = new NuCachedSource2(mConnectingDataSource);
+ mCachedSource = new NuCachedSource2(
+ mConnectingDataSource,
+ cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
+ disconnectAtHighwatermark);
#endif
dataSource = mCachedSource;
@@ -2077,34 +2047,6 @@
return UNKNOWN_ERROR;
}
}
- } else if (!strncasecmp("rtsp://", mUri.string(), 7)) {
- if (mLooper == NULL) {
- mLooper = new ALooper;
- mLooper->setName("rtsp");
- mLooper->start();
- }
- mRTSPController = new ARTSPController(mLooper);
- mConnectingRTSPController = mRTSPController;
-
- if (mUIDValid) {
- mConnectingRTSPController->setUID(mUID);
- }
-
- mLock.unlock();
- status_t err = mRTSPController->connect(mUri.string());
- mLock.lock();
-
- mConnectingRTSPController.clear();
-
- LOGI("ARTSPController::connect returned %d", err);
-
- if (err != OK) {
- mRTSPController.clear();
- return err;
- }
-
- sp<MediaExtractor> extractor = mRTSPController.get();
- return setDataSource_l(extractor);
} else {
dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders);
}
@@ -2216,7 +2158,7 @@
modifyFlags(PREPARING_CONNECTED, SET);
- if (isStreamingHTTP() || mRTSPController != NULL) {
+ if (isStreamingHTTP()) {
postBufferingEvent_l();
} else {
finishAsyncPrepare_l();
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index c16b3b5..70523c1 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -20,6 +20,7 @@
#include "include/MPEG4Extractor.h"
#include "include/WAVExtractor.h"
#include "include/OggExtractor.h"
+#include "include/MPEG2PSExtractor.h"
#include "include/MPEG2TSExtractor.h"
#include "include/NuCachedSource2.h"
#include "include/HTTPBase.h"
@@ -113,6 +114,7 @@
RegisterSniffer(SniffMP3);
RegisterSniffer(SniffAAC);
RegisterSniffer(SniffAVI);
+ RegisterSniffer(SniffMPEG2PS);
char value[PROPERTY_VALUE_MAX];
if (property_get("drm.service.enabled", value, NULL)
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 92e84c2..34e9cd7 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -25,11 +25,11 @@
#include "include/VBRISeeker.h"
#include "include/XINGSeeker.h"
+#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaSource.h>
@@ -289,9 +289,24 @@
GetMPEGAudioFrameSize(
header, &frame_size, &sample_rate, &num_channels, &bitrate);
+ unsigned layer = 4 - ((header >> 17) & 3);
+
mMeta = new MetaData;
- mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
+ switch (layer) {
+ case 1:
+ mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I);
+ break;
+ case 2:
+ mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
+ break;
+ case 3:
+ mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
+ break;
+ default:
+ TRESPASS();
+ }
+
mMeta->setInt32(kKeySampleRate, sample_rate);
mMeta->setInt32(kKeyBitRate, bitrate * 1000);
mMeta->setInt32(kKeyChannelCount, num_channels);
diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp
index 01f1fba..444e823 100644
--- a/media/libstagefright/MediaDefs.cpp
+++ b/media/libstagefright/MediaDefs.cpp
@@ -30,6 +30,8 @@
const char *MEDIA_MIMETYPE_AUDIO_AMR_NB = "audio/3gpp";
const char *MEDIA_MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb";
const char *MEDIA_MIMETYPE_AUDIO_MPEG = "audio/mpeg";
+const char *MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I = "audio/mpeg-L1";
+const char *MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II = "audio/mpeg-L2";
const char *MEDIA_MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
const char *MEDIA_MIMETYPE_AUDIO_QCELP = "audio/qcelp";
const char *MEDIA_MIMETYPE_AUDIO_VORBIS = "audio/vorbis";
@@ -45,6 +47,7 @@
const char *MEDIA_MIMETYPE_CONTAINER_MATROSKA = "video/x-matroska";
const char *MEDIA_MIMETYPE_CONTAINER_MPEG2TS = "video/mp2ts";
const char *MEDIA_MIMETYPE_CONTAINER_AVI = "video/avi";
+const char *MEDIA_MIMETYPE_CONTAINER_MPEG2PS = "video/mp2p";
const char *MEDIA_MIMETYPE_CONTAINER_WVM = "video/wvm";
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index a8023df..2221268 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -24,6 +24,7 @@
#include "include/MPEG4Extractor.h"
#include "include/WAVExtractor.h"
#include "include/OggExtractor.h"
+#include "include/MPEG2PSExtractor.h"
#include "include/MPEG2TSExtractor.h"
#include "include/DRMExtractor.h"
#include "include/WVMExtractor.h"
@@ -115,6 +116,8 @@
ret = new WVMExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS)) {
ret = new AACExtractor(source);
+ } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2PS)) {
+ ret = new MPEG2PSExtractor(source);
}
if (ret != NULL) {
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 9adb841..1e1de04 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -177,7 +177,10 @@
////////////////////////////////////////////////////////////////////////////////
-NuCachedSource2::NuCachedSource2(const sp<DataSource> &source)
+NuCachedSource2::NuCachedSource2(
+ const sp<DataSource> &source,
+ const char *cacheConfig,
+ bool disconnectAtHighwatermark)
: mSource(source),
mReflector(new AHandlerReflector<NuCachedSource2>(this)),
mLooper(new ALooper),
@@ -190,9 +193,24 @@
mNumRetriesLeft(kMaxNumRetries),
mHighwaterThresholdBytes(kDefaultHighWaterThreshold),
mLowwaterThresholdBytes(kDefaultLowWaterThreshold),
- mKeepAliveIntervalUs(kDefaultKeepAliveIntervalUs) {
+ mKeepAliveIntervalUs(kDefaultKeepAliveIntervalUs),
+ mDisconnectAtHighwatermark(disconnectAtHighwatermark) {
+ // We are NOT going to support disconnect-at-highwatermark indefinitely
+ // and we are not guaranteeing support for client-specified cache
+ // parameters. Both of these are temporary measures to solve a specific
+ // problem that will be solved in a better way going forward.
+
updateCacheParamsFromSystemProperty();
+ if (cacheConfig != NULL) {
+ updateCacheParamsFromString(cacheConfig);
+ }
+
+ if (mDisconnectAtHighwatermark) {
+ // Makes no sense to disconnect and do keep-alives...
+ mKeepAliveIntervalUs = 0;
+ }
+
mLooper->setName("NuCachedSource2");
mLooper->registerHandler(mReflector);
mLooper->start();
@@ -261,6 +279,8 @@
void NuCachedSource2::fetchInternal() {
LOGV("fetchInternal");
+ bool reconnect = false;
+
{
Mutex::Autolock autoLock(mLock);
CHECK(mFinalStatus == OK || mNumRetriesLeft > 0);
@@ -268,18 +288,24 @@
if (mFinalStatus != OK) {
--mNumRetriesLeft;
- status_t err =
- mSource->reconnectAtOffset(mCacheOffset + mCache->totalSize());
+ reconnect = true;
+ }
+ }
- if (err == ERROR_UNSUPPORTED) {
- mNumRetriesLeft = 0;
- return;
- } else if (err != OK) {
- LOGI("The attempt to reconnect failed, %d retries remaining",
- mNumRetriesLeft);
+ if (reconnect) {
+ status_t err =
+ mSource->reconnectAtOffset(mCacheOffset + mCache->totalSize());
- return;
- }
+ Mutex::Autolock autoLock(mLock);
+
+ if (err == ERROR_UNSUPPORTED) {
+ mNumRetriesLeft = 0;
+ return;
+ } else if (err != OK) {
+ LOGI("The attempt to reconnect failed, %d retries remaining",
+ mNumRetriesLeft);
+
+ return;
}
}
@@ -339,6 +365,12 @@
if (mFetching && mCache->totalSize() >= mHighwaterThresholdBytes) {
LOGI("Cache full, done prefetching for now");
mFetching = false;
+
+ if (mDisconnectAtHighwatermark
+ && (mSource->flags() & DataSource::kIsHTTPBasedSource)) {
+ LOGV("Disconnecting at high watermark");
+ static_cast<HTTPBase *>(mSource.get())->disconnect();
+ }
}
} else {
Mutex::Autolock autoLock(mLock);
@@ -637,4 +669,34 @@
mKeepAliveIntervalUs);
}
+// static
+void NuCachedSource2::RemoveCacheSpecificHeaders(
+ KeyedVector<String8, String8> *headers,
+ String8 *cacheConfig,
+ bool *disconnectAtHighwatermark) {
+ *cacheConfig = String8();
+ *disconnectAtHighwatermark = false;
+
+ if (headers == NULL) {
+ return;
+ }
+
+ ssize_t index;
+ if ((index = headers->indexOfKey(String8("x-cache-config"))) >= 0) {
+ *cacheConfig = headers->valueAt(index);
+
+ headers->removeItemsAt(index);
+
+ LOGV("Using special cache config '%s'", cacheConfig->string());
+ }
+
+ if ((index = headers->indexOfKey(
+ String8("x-disconnect-at-highwatermark"))) >= 0) {
+ *disconnectAtHighwatermark = true;
+ headers->removeItemsAt(index);
+
+ LOGV("Client requested disconnection at highwater mark");
+ }
+}
+
} // namespace android
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 7c34257..f9cb882 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -52,6 +52,13 @@
// buffers after 3 seconds.
const static int64_t kBufferFilledEventTimeOutNs = 3000000000LL;
+// OMX Spec defines less than 50 color formats. If the query for
+// color format is executed for more than kMaxColorFormatSupported,
+// the query will fail to avoid looping forever.
+// 1000 is more than enough for us to tell whether the omx
+// component in question is buggy or not.
+const static uint32_t kMaxColorFormatSupported = 1000;
+
struct CodecInfo {
const char *mime;
const char *codec;
@@ -102,6 +109,7 @@
{ MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
// { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
{ MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.google.mp3.decoder" },
+ { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II, "OMX.Nvidia.mp2.decoder" },
// { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
// { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.Nvidia.amr.decoder" },
{ MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.google.amrnb.decoder" },
@@ -818,6 +826,11 @@
}
++index;
+ if (index >= kMaxColorFormatSupported) {
+ CODEC_LOGE("color format %d or compression format %d is not supported",
+ colorFormat, compressionFormat);
+ return UNKNOWN_ERROR;
+ }
}
if (!found) {
@@ -901,22 +914,19 @@
// the incremented index (bug 2897413).
CHECK_EQ(index, portFormat.nIndex);
if (portFormat.eColorFormat == colorFormat) {
- LOGV("Found supported color format: %d", portFormat.eColorFormat);
+ CODEC_LOGV("Found supported color format: %d", portFormat.eColorFormat);
return OK; // colorFormat is supported!
}
++index;
portFormat.nIndex = index;
- // OMX Spec defines less than 50 color formats
- // 1000 is more than enough for us to tell whether the omx
- // component in question is buggy or not.
- if (index >= 1000) {
- LOGE("More than %ld color formats are supported???", index);
+ if (index >= kMaxColorFormatSupported) {
+ CODEC_LOGE("More than %ld color formats are supported???", index);
break;
}
}
- LOGE("color format %d is not supported", colorFormat);
+ CODEC_LOGE("color format %d is not supported", colorFormat);
return UNKNOWN_ERROR;
}
@@ -1462,7 +1472,9 @@
mOutputPortSettingsChangedPending(false),
mLeftOverBuffer(NULL),
mPaused(false),
- mNativeWindow(!strncmp(componentName, "OMX.google.", 11)
+ mNativeWindow(
+ (!strncmp(componentName, "OMX.google.", 11)
+ || !strcmp(componentName, "OMX.Nvidia.mpeg2v.decode"))
? NULL : nativeWindow) {
mPortStatus[kPortIndexInput] = ENABLED;
mPortStatus[kPortIndexOutput] = ENABLED;
@@ -1483,6 +1495,12 @@
static const MimeToRole kMimeToRole[] = {
{ MEDIA_MIMETYPE_AUDIO_MPEG,
"audio_decoder.mp3", "audio_encoder.mp3" },
+ { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
+ "audio_decoder.mp1", "audio_encoder.mp1" },
+ { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
+ "audio_decoder.mp2", "audio_encoder.mp2" },
+ { MEDIA_MIMETYPE_AUDIO_MPEG,
+ "audio_decoder.mp3", "audio_encoder.mp3" },
{ MEDIA_MIMETYPE_AUDIO_AMR_NB,
"audio_decoder.amrnb", "audio_encoder.amrnb" },
{ MEDIA_MIMETYPE_AUDIO_AMR_WB,
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index 571e8be27..bb6e4cd 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -38,7 +38,7 @@
".mpeg", ".ogg", ".mid", ".smf", ".imy", ".wma", ".aac",
".wav", ".amr", ".midi", ".xmf", ".rtttl", ".rtx", ".ota",
".mkv", ".mka", ".webm", ".ts", ".fl", ".flac", ".mxmf",
- ".avi",
+ ".avi", ".mpeg", ".mpg"
};
static const size_t kNumValidExtensions =
sizeof(kValidExtensions) / sizeof(kValidExtensions[0]);
diff --git a/media/libstagefright/include/ARTSPController.h b/media/libstagefright/include/ARTSPController.h
deleted file mode 100644
index 2bd5be6..0000000
--- a/media/libstagefright/include/ARTSPController.h
+++ /dev/null
@@ -1,97 +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.
- */
-
-#ifndef A_RTSP_CONTROLLER_H_
-
-#define A_RTSP_CONTROLLER_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <media/stagefright/foundation/AHandlerReflector.h>
-#include <media/stagefright/MediaExtractor.h>
-
-namespace android {
-
-struct ALooper;
-struct MyHandler;
-
-struct ARTSPController : public MediaExtractor {
- ARTSPController(const sp<ALooper> &looper);
-
- void setUID(uid_t uid);
-
- status_t connect(const char *url);
- void disconnect();
-
- void seekAsync(int64_t timeUs, void (*seekDoneCb)(void *), void *cookie);
-
- virtual size_t countTracks();
- virtual sp<MediaSource> getTrack(size_t index);
-
- virtual sp<MetaData> getTrackMetaData(
- size_t index, uint32_t flags);
-
- int64_t getNormalPlayTimeUs();
- int64_t getQueueDurationUs(bool *eos);
-
- void onMessageReceived(const sp<AMessage> &msg);
-
- virtual uint32_t flags() const {
- // Seeking 10secs forward or backward is a very expensive operation
- // for rtsp, so let's not enable that.
- // The user can always use the seek bar.
-
- return CAN_PAUSE | CAN_SEEK;
- }
-
-protected:
- virtual ~ARTSPController();
-
-private:
- enum {
- kWhatConnectDone = 'cdon',
- kWhatDisconnectDone = 'ddon',
- kWhatSeekDone = 'sdon',
- };
-
- enum State {
- DISCONNECTED,
- CONNECTED,
- CONNECTING,
- };
-
- Mutex mLock;
- Condition mCondition;
-
- State mState;
- status_t mConnectionResult;
-
- sp<ALooper> mLooper;
- sp<MyHandler> mHandler;
- sp<AHandlerReflector<ARTSPController> > mReflector;
-
- bool mUIDValid;
- uid_t mUID;
-
- void (*mSeekDoneCb)(void *);
- void *mSeekDoneCookie;
- int64_t mLastSeekCompletedTimeUs;
-
- DISALLOW_EVIL_CONSTRUCTORS(ARTSPController);
-};
-
-} // namespace android
-
-#endif // A_RTSP_CONTROLLER_H_
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 8e73121..7d6bcad 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -38,9 +38,6 @@
struct NuCachedSource2;
struct ISurfaceTexture;
-struct ALooper;
-struct ARTSPController;
-
class DrmManagerClinet;
class DecryptHandle;
@@ -233,10 +230,6 @@
sp<HTTPBase> mConnectingDataSource;
sp<NuCachedSource2> mCachedSource;
- sp<ALooper> mLooper;
- sp<ARTSPController> mRTSPController;
- sp<ARTSPController> mConnectingRTSPController;
-
DrmManagerClient *mDrmManagerClient;
sp<DecryptHandle> mDecryptHandle;
@@ -287,9 +280,6 @@
static bool ContinuePreparation(void *cookie);
- static void OnRTSPSeekDoneWrapper(void *cookie);
- void onRTSPSeekDone();
-
bool getBitrate(int64_t *bitrate);
void finishSeekIfNecessary(int64_t videoTimeUs);
diff --git a/media/libstagefright/include/MPEG2PSExtractor.h b/media/libstagefright/include/MPEG2PSExtractor.h
new file mode 100644
index 0000000..fb76564
--- /dev/null
+++ b/media/libstagefright/include/MPEG2PSExtractor.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MPEG2_PS_EXTRACTOR_H_
+
+#define MPEG2_PS_EXTRACTOR_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <utils/threads.h>
+#include <utils/KeyedVector.h>
+
+namespace android {
+
+struct ABuffer;
+struct AMessage;
+struct Track;
+struct String8;
+
+struct MPEG2PSExtractor : public MediaExtractor {
+ MPEG2PSExtractor(const sp<DataSource> &source);
+
+ virtual size_t countTracks();
+ virtual sp<MediaSource> getTrack(size_t index);
+ virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
+
+ virtual sp<MetaData> getMetaData();
+
+ virtual uint32_t flags() const;
+
+protected:
+ virtual ~MPEG2PSExtractor();
+
+private:
+ struct Track;
+ struct WrappedTrack;
+
+ mutable Mutex mLock;
+ sp<DataSource> mDataSource;
+
+ off64_t mOffset;
+ status_t mFinalResult;
+ sp<ABuffer> mBuffer;
+ KeyedVector<unsigned, sp<Track> > mTracks;
+ bool mScanning;
+
+ bool mProgramStreamMapValid;
+ KeyedVector<unsigned, unsigned> mStreamTypeByESID;
+
+ status_t feedMore();
+
+ status_t dequeueChunk();
+ ssize_t dequeuePack();
+ ssize_t dequeueSystemHeader();
+ ssize_t dequeuePES();
+
+ DISALLOW_EVIL_CONSTRUCTORS(MPEG2PSExtractor);
+};
+
+bool SniffMPEG2PS(
+ const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ sp<AMessage> *);
+
+} // namespace android
+
+#endif // MPEG2_PS_EXTRACTOR_H_
+
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index f04c566..7a03e7e 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -28,7 +28,10 @@
struct PageCache;
struct NuCachedSource2 : public DataSource {
- NuCachedSource2(const sp<DataSource> &source);
+ NuCachedSource2(
+ const sp<DataSource> &source,
+ const char *cacheConfig = NULL,
+ bool disconnectAtHighwatermark = false);
virtual status_t initCheck() const;
@@ -56,6 +59,11 @@
status_t getEstimatedBandwidthKbps(int32_t *kbps);
status_t setCacheStatCollectFreq(int32_t freqMs);
+ static void RemoveCacheSpecificHeaders(
+ KeyedVector<String8, String8> *headers,
+ String8 *cacheConfig,
+ bool *disconnectAtHighwatermark);
+
protected:
virtual ~NuCachedSource2();
@@ -105,6 +113,8 @@
// If the keep-alive interval is 0, keep-alives are disabled.
int64_t mKeepAliveIntervalUs;
+ bool mDisconnectAtHighwatermark;
+
void onMessageReceived(const sp<AMessage> &msg);
void onFetch();
void onRead(const sp<AMessage> &msg);
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index e13464e..72f1282 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -724,8 +724,10 @@
const uint8_t *data, size_t size) {
LOGV("onPayloadData mStreamType=0x%02x", mStreamType);
- CHECK(PTS_DTS_flags == 2 || PTS_DTS_flags == 3);
- int64_t timeUs = mProgram->convertPTSToTimestamp(PTS);
+ int64_t timeUs = 0ll; // no presentation timestamp available.
+ if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
+ timeUs = mProgram->convertPTSToTimestamp(PTS);
+ }
status_t err = mQueue->appendData(data, size, timeUs);
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index 388cb54..878e534 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -64,12 +64,9 @@
bool PTSTimeDeltaEstablished();
-protected:
- virtual ~ATSParser();
-
-private:
enum {
// From ISO/IEC 13818-1: 2000 (E), Table 2-29
+ STREAMTYPE_RESERVED = 0x00,
STREAMTYPE_MPEG1_VIDEO = 0x01,
STREAMTYPE_MPEG2_VIDEO = 0x02,
STREAMTYPE_MPEG1_AUDIO = 0x03,
@@ -79,6 +76,10 @@
STREAMTYPE_H264 = 0x1b,
};
+protected:
+ virtual ~ATSParser();
+
+private:
struct Program;
struct Stream;
diff --git a/media/libstagefright/mpeg2ts/Android.mk b/media/libstagefright/mpeg2ts/Android.mk
index 4a30416..578c669 100644
--- a/media/libstagefright/mpeg2ts/Android.mk
+++ b/media/libstagefright/mpeg2ts/Android.mk
@@ -6,6 +6,7 @@
AnotherPacketSource.cpp \
ATSParser.cpp \
ESQueue.cpp \
+ MPEG2PSExtractor.cpp \
MPEG2TSExtractor.cpp \
LOCAL_C_INCLUDES:= \
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index f8a1d84..b9a4826 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -444,6 +444,10 @@
}
}
+ if (timeUs == 0ll) {
+ LOGV("Returning 0 timestamp");
+ }
+
return timeUs;
}
@@ -581,6 +585,8 @@
return NULL;
}
+ unsigned layer = 4 - ((header >> 17) & 3);
+
sp<ABuffer> accessUnit = new ABuffer(frameSize);
memcpy(accessUnit->data(), data, frameSize);
@@ -597,7 +603,24 @@
if (mFormat == NULL) {
mFormat = new MetaData;
- mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
+
+ switch (layer) {
+ case 1:
+ mFormat->setCString(
+ kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I);
+ break;
+ case 2:
+ mFormat->setCString(
+ kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
+ break;
+ case 3:
+ mFormat->setCString(
+ kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
+ break;
+ default:
+ TRESPASS();
+ }
+
mFormat->setInt32(kKeySampleRate, samplingRate);
mFormat->setInt32(kKeyChannelCount, numChannels);
}
diff --git a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
new file mode 100644
index 0000000..f55be6e
--- /dev/null
+++ b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
@@ -0,0 +1,715 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MPEG2PSExtractor"
+#include <utils/Log.h>
+
+#include "include/MPEG2PSExtractor.h"
+
+#include "AnotherPacketSource.h"
+#include "ESQueue.h"
+
+#include <media/stagefright/foundation/ABitReader.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
+#include <utils/String8.h>
+
+namespace android {
+
+struct MPEG2PSExtractor::Track : public MediaSource {
+ Track(MPEG2PSExtractor *extractor,
+ unsigned stream_id, unsigned stream_type);
+
+ virtual status_t start(MetaData *params);
+ virtual status_t stop();
+ virtual sp<MetaData> getFormat();
+
+ virtual status_t read(
+ MediaBuffer **buffer, const ReadOptions *options);
+
+protected:
+ virtual ~Track();
+
+private:
+ friend struct MPEG2PSExtractor;
+
+ MPEG2PSExtractor *mExtractor;
+
+ unsigned mStreamID;
+ unsigned mStreamType;
+ ElementaryStreamQueue *mQueue;
+ sp<AnotherPacketSource> mSource;
+
+ status_t appendPESData(
+ unsigned PTS_DTS_flags,
+ uint64_t PTS, uint64_t DTS,
+ const uint8_t *data, size_t size);
+
+ DISALLOW_EVIL_CONSTRUCTORS(Track);
+};
+
+struct MPEG2PSExtractor::WrappedTrack : public MediaSource {
+ WrappedTrack(const sp<MPEG2PSExtractor> &extractor, const sp<Track> &track);
+
+ virtual status_t start(MetaData *params);
+ virtual status_t stop();
+ virtual sp<MetaData> getFormat();
+
+ virtual status_t read(
+ MediaBuffer **buffer, const ReadOptions *options);
+
+protected:
+ virtual ~WrappedTrack();
+
+private:
+ sp<MPEG2PSExtractor> mExtractor;
+ sp<MPEG2PSExtractor::Track> mTrack;
+
+ DISALLOW_EVIL_CONSTRUCTORS(WrappedTrack);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+MPEG2PSExtractor::MPEG2PSExtractor(const sp<DataSource> &source)
+ : mDataSource(source),
+ mOffset(0),
+ mFinalResult(OK),
+ mBuffer(new ABuffer(0)),
+ mScanning(true),
+ mProgramStreamMapValid(false) {
+ for (size_t i = 0; i < 500; ++i) {
+ if (feedMore() != OK) {
+ break;
+ }
+ }
+
+ // Remove all tracks that were unable to determine their format.
+ for (size_t i = mTracks.size(); i-- > 0;) {
+ if (mTracks.valueAt(i)->getFormat() == NULL) {
+ mTracks.removeItemsAt(i);
+ }
+ }
+
+ mScanning = false;
+}
+
+MPEG2PSExtractor::~MPEG2PSExtractor() {
+}
+
+size_t MPEG2PSExtractor::countTracks() {
+ return mTracks.size();
+}
+
+sp<MediaSource> MPEG2PSExtractor::getTrack(size_t index) {
+ if (index >= mTracks.size()) {
+ return NULL;
+ }
+
+ return new WrappedTrack(this, mTracks.valueAt(index));
+}
+
+sp<MetaData> MPEG2PSExtractor::getTrackMetaData(size_t index, uint32_t flags) {
+ if (index >= mTracks.size()) {
+ return NULL;
+ }
+
+ return mTracks.valueAt(index)->getFormat();
+}
+
+sp<MetaData> MPEG2PSExtractor::getMetaData() {
+ sp<MetaData> meta = new MetaData;
+ meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2PS);
+
+ return meta;
+}
+
+uint32_t MPEG2PSExtractor::flags() const {
+ return CAN_PAUSE;
+}
+
+status_t MPEG2PSExtractor::feedMore() {
+ Mutex::Autolock autoLock(mLock);
+
+ // How much data we're reading at a time
+ static const size_t kChunkSize = 8192;
+
+ for (;;) {
+ status_t err = dequeueChunk();
+
+ if (err == -EAGAIN && mFinalResult == OK) {
+ memmove(mBuffer->base(), mBuffer->data(), mBuffer->size());
+ mBuffer->setRange(0, mBuffer->size());
+
+ if (mBuffer->size() + kChunkSize > mBuffer->capacity()) {
+ size_t newCapacity = mBuffer->capacity() + kChunkSize;
+ sp<ABuffer> newBuffer = new ABuffer(newCapacity);
+ memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
+ newBuffer->setRange(0, mBuffer->size());
+ mBuffer = newBuffer;
+ }
+
+ ssize_t n = mDataSource->readAt(
+ mOffset, mBuffer->data() + mBuffer->size(), kChunkSize);
+
+ if (n < (ssize_t)kChunkSize) {
+ mFinalResult = (n < 0) ? (status_t)n : ERROR_END_OF_STREAM;
+ return mFinalResult;
+ }
+
+ mBuffer->setRange(mBuffer->offset(), mBuffer->size() + n);
+ mOffset += n;
+ } else if (err != OK) {
+ mFinalResult = err;
+ return err;
+ } else {
+ return OK;
+ }
+ }
+}
+
+status_t MPEG2PSExtractor::dequeueChunk() {
+ if (mBuffer->size() < 4) {
+ return -EAGAIN;
+ }
+
+ if (memcmp("\x00\x00\x01", mBuffer->data(), 3)) {
+ return ERROR_MALFORMED;
+ }
+
+ unsigned chunkType = mBuffer->data()[3];
+
+ ssize_t res;
+
+ switch (chunkType) {
+ case 0xba:
+ {
+ res = dequeuePack();
+ break;
+ }
+
+ case 0xbb:
+ {
+ res = dequeueSystemHeader();
+ break;
+ }
+
+ default:
+ {
+ res = dequeuePES();
+ break;
+ }
+ }
+
+ if (res > 0) {
+ if (mBuffer->size() < (size_t)res) {
+ return -EAGAIN;
+ }
+
+ mBuffer->setRange(mBuffer->offset() + res, mBuffer->size() - res);
+ res = OK;
+ }
+
+ return res;
+}
+
+ssize_t MPEG2PSExtractor::dequeuePack() {
+ // 32 + 2 + 3 + 1 + 15 + 1 + 15+ 1 + 9 + 1 + 22 + 1 + 1 | +5
+
+ if (mBuffer->size() < 14) {
+ return -EAGAIN;
+ }
+
+ unsigned pack_stuffing_length = mBuffer->data()[13] & 7;
+
+ return pack_stuffing_length + 14;
+}
+
+ssize_t MPEG2PSExtractor::dequeueSystemHeader() {
+ if (mBuffer->size() < 6) {
+ return -EAGAIN;
+ }
+
+ unsigned header_length = U16_AT(mBuffer->data() + 4);
+
+ return header_length + 6;
+}
+
+ssize_t MPEG2PSExtractor::dequeuePES() {
+ if (mBuffer->size() < 6) {
+ return -EAGAIN;
+ }
+
+ unsigned PES_packet_length = U16_AT(mBuffer->data() + 4);
+ CHECK_NE(PES_packet_length, 0u);
+
+ size_t n = PES_packet_length + 6;
+
+ if (mBuffer->size() < n) {
+ return -EAGAIN;
+ }
+
+ ABitReader br(mBuffer->data(), n);
+
+ unsigned packet_startcode_prefix = br.getBits(24);
+
+ LOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);
+
+ if (packet_startcode_prefix != 1) {
+ LOGV("Supposedly payload_unit_start=1 unit does not start "
+ "with startcode.");
+
+ return ERROR_MALFORMED;
+ }
+
+ CHECK_EQ(packet_startcode_prefix, 0x000001u);
+
+ unsigned stream_id = br.getBits(8);
+ LOGV("stream_id = 0x%02x", stream_id);
+
+ /* unsigned PES_packet_length = */br.getBits(16);
+
+ if (stream_id == 0xbc) {
+ // program_stream_map
+
+ if (!mScanning) {
+ return n;
+ }
+
+ mStreamTypeByESID.clear();
+
+ /* unsigned current_next_indicator = */br.getBits(1);
+ /* unsigned reserved = */br.getBits(2);
+ /* unsigned program_stream_map_version = */br.getBits(5);
+ /* unsigned reserved = */br.getBits(7);
+ /* unsigned marker_bit = */br.getBits(1);
+ unsigned program_stream_info_length = br.getBits(16);
+
+ size_t offset = 0;
+ while (offset < program_stream_info_length) {
+ if (offset + 2 > program_stream_info_length) {
+ return ERROR_MALFORMED;
+ }
+
+ unsigned descriptor_tag = br.getBits(8);
+ unsigned descriptor_length = br.getBits(8);
+
+ LOGI("found descriptor tag 0x%02x of length %u",
+ descriptor_tag, descriptor_length);
+
+ if (offset + 2 + descriptor_length > program_stream_info_length) {
+ return ERROR_MALFORMED;
+ }
+
+ br.skipBits(8 * descriptor_length);
+
+ offset += 2 + descriptor_length;
+ }
+
+ unsigned elementary_stream_map_length = br.getBits(16);
+
+ offset = 0;
+ while (offset < elementary_stream_map_length) {
+ if (offset + 4 > elementary_stream_map_length) {
+ return ERROR_MALFORMED;
+ }
+
+ unsigned stream_type = br.getBits(8);
+ unsigned elementary_stream_id = br.getBits(8);
+
+ LOGI("elementary stream id 0x%02x has stream type 0x%02x",
+ elementary_stream_id, stream_type);
+
+ mStreamTypeByESID.add(elementary_stream_id, stream_type);
+
+ unsigned elementary_stream_info_length = br.getBits(16);
+
+ if (offset + 4 + elementary_stream_info_length
+ > elementary_stream_map_length) {
+ return ERROR_MALFORMED;
+ }
+
+ offset += 4 + elementary_stream_info_length;
+ }
+
+ /* unsigned CRC32 = */br.getBits(32);
+
+ mProgramStreamMapValid = true;
+ } else if (stream_id != 0xbe // padding_stream
+ && stream_id != 0xbf // private_stream_2
+ && stream_id != 0xf0 // ECM
+ && stream_id != 0xf1 // EMM
+ && stream_id != 0xff // program_stream_directory
+ && stream_id != 0xf2 // DSMCC
+ && stream_id != 0xf8) { // H.222.1 type E
+ CHECK_EQ(br.getBits(2), 2u);
+
+ /* unsigned PES_scrambling_control = */br.getBits(2);
+ /* unsigned PES_priority = */br.getBits(1);
+ /* unsigned data_alignment_indicator = */br.getBits(1);
+ /* unsigned copyright = */br.getBits(1);
+ /* unsigned original_or_copy = */br.getBits(1);
+
+ unsigned PTS_DTS_flags = br.getBits(2);
+ LOGV("PTS_DTS_flags = %u", PTS_DTS_flags);
+
+ unsigned ESCR_flag = br.getBits(1);
+ LOGV("ESCR_flag = %u", ESCR_flag);
+
+ unsigned ES_rate_flag = br.getBits(1);
+ LOGV("ES_rate_flag = %u", ES_rate_flag);
+
+ unsigned DSM_trick_mode_flag = br.getBits(1);
+ LOGV("DSM_trick_mode_flag = %u", DSM_trick_mode_flag);
+
+ unsigned additional_copy_info_flag = br.getBits(1);
+ LOGV("additional_copy_info_flag = %u", additional_copy_info_flag);
+
+ /* unsigned PES_CRC_flag = */br.getBits(1);
+ /* PES_extension_flag = */br.getBits(1);
+
+ unsigned PES_header_data_length = br.getBits(8);
+ LOGV("PES_header_data_length = %u", PES_header_data_length);
+
+ unsigned optional_bytes_remaining = PES_header_data_length;
+
+ uint64_t PTS = 0, DTS = 0;
+
+ if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
+ CHECK_GE(optional_bytes_remaining, 5u);
+
+ CHECK_EQ(br.getBits(4), PTS_DTS_flags);
+
+ PTS = ((uint64_t)br.getBits(3)) << 30;
+ CHECK_EQ(br.getBits(1), 1u);
+ PTS |= ((uint64_t)br.getBits(15)) << 15;
+ CHECK_EQ(br.getBits(1), 1u);
+ PTS |= br.getBits(15);
+ CHECK_EQ(br.getBits(1), 1u);
+
+ LOGV("PTS = %llu", PTS);
+ // LOGI("PTS = %.2f secs", PTS / 90000.0f);
+
+ optional_bytes_remaining -= 5;
+
+ if (PTS_DTS_flags == 3) {
+ CHECK_GE(optional_bytes_remaining, 5u);
+
+ CHECK_EQ(br.getBits(4), 1u);
+
+ DTS = ((uint64_t)br.getBits(3)) << 30;
+ CHECK_EQ(br.getBits(1), 1u);
+ DTS |= ((uint64_t)br.getBits(15)) << 15;
+ CHECK_EQ(br.getBits(1), 1u);
+ DTS |= br.getBits(15);
+ CHECK_EQ(br.getBits(1), 1u);
+
+ LOGV("DTS = %llu", DTS);
+
+ optional_bytes_remaining -= 5;
+ }
+ }
+
+ if (ESCR_flag) {
+ CHECK_GE(optional_bytes_remaining, 6u);
+
+ br.getBits(2);
+
+ uint64_t ESCR = ((uint64_t)br.getBits(3)) << 30;
+ CHECK_EQ(br.getBits(1), 1u);
+ ESCR |= ((uint64_t)br.getBits(15)) << 15;
+ CHECK_EQ(br.getBits(1), 1u);
+ ESCR |= br.getBits(15);
+ CHECK_EQ(br.getBits(1), 1u);
+
+ LOGV("ESCR = %llu", ESCR);
+ /* unsigned ESCR_extension = */br.getBits(9);
+
+ CHECK_EQ(br.getBits(1), 1u);
+
+ optional_bytes_remaining -= 6;
+ }
+
+ if (ES_rate_flag) {
+ CHECK_GE(optional_bytes_remaining, 3u);
+
+ CHECK_EQ(br.getBits(1), 1u);
+ /* unsigned ES_rate = */br.getBits(22);
+ CHECK_EQ(br.getBits(1), 1u);
+
+ optional_bytes_remaining -= 3;
+ }
+
+ br.skipBits(optional_bytes_remaining * 8);
+
+ // ES data follows.
+
+ CHECK_GE(PES_packet_length, PES_header_data_length + 3);
+
+ unsigned dataLength =
+ PES_packet_length - 3 - PES_header_data_length;
+
+ if (br.numBitsLeft() < dataLength * 8) {
+ LOGE("PES packet does not carry enough data to contain "
+ "payload. (numBitsLeft = %d, required = %d)",
+ br.numBitsLeft(), dataLength * 8);
+
+ return ERROR_MALFORMED;
+ }
+
+ CHECK_GE(br.numBitsLeft(), dataLength * 8);
+
+ ssize_t index = mTracks.indexOfKey(stream_id);
+ if (index < 0 && mScanning) {
+ unsigned streamType;
+
+ ssize_t streamTypeIndex;
+ if (mProgramStreamMapValid
+ && (streamTypeIndex =
+ mStreamTypeByESID.indexOfKey(stream_id)) >= 0) {
+ streamType = mStreamTypeByESID.valueAt(streamTypeIndex);
+ } else if ((stream_id & ~0x1f) == 0xc0) {
+ // ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7
+ // or ISO/IEC 14496-3 audio
+ streamType = ATSParser::STREAMTYPE_MPEG2_AUDIO;
+ } else if ((stream_id & ~0x0f) == 0xe0) {
+ // ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC 14496-2 video
+ streamType = ATSParser::STREAMTYPE_MPEG2_VIDEO;
+ } else {
+ streamType = ATSParser::STREAMTYPE_RESERVED;
+ }
+
+ index = mTracks.add(
+ stream_id, new Track(this, stream_id, streamType));
+ }
+
+ status_t err = OK;
+
+ if (index >= 0) {
+ err =
+ mTracks.editValueAt(index)->appendPESData(
+ PTS_DTS_flags, PTS, DTS, br.data(), dataLength);
+ }
+
+ br.skipBits(dataLength * 8);
+
+ if (err != OK) {
+ return err;
+ }
+ } else if (stream_id == 0xbe) { // padding_stream
+ CHECK_NE(PES_packet_length, 0u);
+ br.skipBits(PES_packet_length * 8);
+ } else {
+ CHECK_NE(PES_packet_length, 0u);
+ br.skipBits(PES_packet_length * 8);
+ }
+
+ return n;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+MPEG2PSExtractor::Track::Track(
+ MPEG2PSExtractor *extractor, unsigned stream_id, unsigned stream_type)
+ : mExtractor(extractor),
+ mStreamID(stream_id),
+ mStreamType(stream_type),
+ mQueue(NULL) {
+ bool supported = true;
+ ElementaryStreamQueue::Mode mode;
+
+ switch (mStreamType) {
+ case ATSParser::STREAMTYPE_H264:
+ mode = ElementaryStreamQueue::H264;
+ break;
+ case ATSParser::STREAMTYPE_MPEG2_AUDIO_ATDS:
+ mode = ElementaryStreamQueue::AAC;
+ break;
+ case ATSParser::STREAMTYPE_MPEG1_AUDIO:
+ case ATSParser::STREAMTYPE_MPEG2_AUDIO:
+ mode = ElementaryStreamQueue::MPEG_AUDIO;
+ break;
+
+ case ATSParser::STREAMTYPE_MPEG1_VIDEO:
+ case ATSParser::STREAMTYPE_MPEG2_VIDEO:
+ mode = ElementaryStreamQueue::MPEG_VIDEO;
+ break;
+
+ case ATSParser::STREAMTYPE_MPEG4_VIDEO:
+ mode = ElementaryStreamQueue::MPEG4_VIDEO;
+ break;
+
+ default:
+ supported = false;
+ break;
+ }
+
+ if (supported) {
+ mQueue = new ElementaryStreamQueue(mode);
+ } else {
+ LOGI("unsupported stream ID 0x%02x", stream_id);
+ }
+}
+
+MPEG2PSExtractor::Track::~Track() {
+ delete mQueue;
+ mQueue = NULL;
+}
+
+status_t MPEG2PSExtractor::Track::start(MetaData *params) {
+ if (mSource == NULL) {
+ return NO_INIT;
+ }
+
+ return mSource->start(params);
+}
+
+status_t MPEG2PSExtractor::Track::stop() {
+ if (mSource == NULL) {
+ return NO_INIT;
+ }
+
+ return mSource->stop();
+}
+
+sp<MetaData> MPEG2PSExtractor::Track::getFormat() {
+ if (mSource == NULL) {
+ return NULL;
+ }
+
+ return mSource->getFormat();
+}
+
+status_t MPEG2PSExtractor::Track::read(
+ MediaBuffer **buffer, const ReadOptions *options) {
+ if (mSource == NULL) {
+ return NO_INIT;
+ }
+
+ status_t finalResult;
+ while (!mSource->hasBufferAvailable(&finalResult)) {
+ if (finalResult != OK) {
+ return ERROR_END_OF_STREAM;
+ }
+
+ status_t err = mExtractor->feedMore();
+
+ if (err != OK) {
+ mSource->signalEOS(err);
+ }
+ }
+
+ return mSource->read(buffer, options);
+}
+
+status_t MPEG2PSExtractor::Track::appendPESData(
+ unsigned PTS_DTS_flags,
+ uint64_t PTS, uint64_t DTS,
+ const uint8_t *data, size_t size) {
+ if (mQueue == NULL) {
+ return OK;
+ }
+
+ int64_t timeUs;
+ if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
+ timeUs = (PTS * 100) / 9;
+ } else {
+ timeUs = 0;
+ }
+
+ status_t err = mQueue->appendData(data, size, timeUs);
+
+ if (err != OK) {
+ return err;
+ }
+
+ sp<ABuffer> accessUnit;
+ while ((accessUnit = mQueue->dequeueAccessUnit()) != NULL) {
+ if (mSource == NULL) {
+ sp<MetaData> meta = mQueue->getFormat();
+
+ if (meta != NULL) {
+ LOGV("Stream ID 0x%02x now has data.", mStreamID);
+
+ mSource = new AnotherPacketSource(meta);
+ mSource->queueAccessUnit(accessUnit);
+ }
+ } else if (mQueue->getFormat() != NULL) {
+ mSource->queueAccessUnit(accessUnit);
+ }
+ }
+
+ return OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+MPEG2PSExtractor::WrappedTrack::WrappedTrack(
+ const sp<MPEG2PSExtractor> &extractor, const sp<Track> &track)
+ : mExtractor(extractor),
+ mTrack(track) {
+}
+
+MPEG2PSExtractor::WrappedTrack::~WrappedTrack() {
+}
+
+status_t MPEG2PSExtractor::WrappedTrack::start(MetaData *params) {
+ return mTrack->start(params);
+}
+
+status_t MPEG2PSExtractor::WrappedTrack::stop() {
+ return mTrack->stop();
+}
+
+sp<MetaData> MPEG2PSExtractor::WrappedTrack::getFormat() {
+ return mTrack->getFormat();
+}
+
+status_t MPEG2PSExtractor::WrappedTrack::read(
+ MediaBuffer **buffer, const ReadOptions *options) {
+ return mTrack->read(buffer, options);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool SniffMPEG2PS(
+ const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ sp<AMessage> *) {
+ uint8_t header[5];
+ if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
+ return false;
+ }
+
+ if (memcmp("\x00\x00\x01\xba", header, 4) || (header[4] >> 6) != 1) {
+ return false;
+ }
+
+ *confidence = 0.25f; // Slightly larger than .mp3 extractor's confidence
+
+ mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MPEG2PS);
+
+ return true;
+}
+
+} // namespace android
diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp
index 4ecb92f..3f4cdb5 100644
--- a/media/libstagefright/rtsp/APacketSource.cpp
+++ b/media/libstagefright/rtsp/APacketSource.cpp
@@ -34,8 +34,8 @@
#include <media/stagefright/foundation/AString.h>
#include <media/stagefright/foundation/base64.h>
#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
#include <utils/Vector.h>
@@ -402,43 +402,15 @@
return csd;
}
-static bool GetClockRate(const AString &desc, uint32_t *clockRate) {
- ssize_t slashPos = desc.find("/");
- if (slashPos < 0) {
- return false;
- }
-
- const char *s = desc.c_str() + slashPos + 1;
-
- char *end;
- unsigned long x = strtoul(s, &end, 10);
-
- if (end == s || (*end != '\0' && *end != '/')) {
- return false;
- }
-
- *clockRate = x;
-
- return true;
-}
-
APacketSource::APacketSource(
const sp<ASessionDescription> &sessionDesc, size_t index)
: mInitCheck(NO_INIT),
- mFormat(new MetaData),
- mEOSResult(OK),
- mIsAVC(false),
- mScanForIDR(true),
- mRTPTimeBase(0),
- mNormalPlayTimeBaseUs(0),
- mLastNormalPlayTimeUs(0) {
+ mFormat(new MetaData) {
unsigned long PT;
AString desc;
AString params;
sessionDesc->getFormatType(index, &PT, &desc, ¶ms);
- CHECK(GetClockRate(desc, &mClockRate));
-
int64_t durationUs;
if (sessionDesc->getDurationUs(&durationUs)) {
mFormat->setInt64(kKeyDuration, durationUs);
@@ -448,8 +420,6 @@
mInitCheck = OK;
if (!strncmp(desc.c_str(), "H264/", 5)) {
- mIsAVC = true;
-
mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
int32_t width, height;
@@ -602,137 +572,8 @@
return mInitCheck;
}
-status_t APacketSource::start(MetaData *params) {
- return OK;
-}
-
-status_t APacketSource::stop() {
- return OK;
-}
-
sp<MetaData> APacketSource::getFormat() {
return mFormat;
}
-status_t APacketSource::read(
- MediaBuffer **out, const ReadOptions *) {
- *out = NULL;
-
- Mutex::Autolock autoLock(mLock);
- while (mEOSResult == OK && mBuffers.empty()) {
- mCondition.wait(mLock);
- }
-
- if (!mBuffers.empty()) {
- const sp<ABuffer> buffer = *mBuffers.begin();
-
- updateNormalPlayTime_l(buffer);
-
- int64_t timeUs;
- CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-
- MediaBuffer *mediaBuffer = new MediaBuffer(buffer);
- mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
-
- *out = mediaBuffer;
-
- mBuffers.erase(mBuffers.begin());
- return OK;
- }
-
- return mEOSResult;
-}
-
-void APacketSource::updateNormalPlayTime_l(const sp<ABuffer> &buffer) {
- uint32_t rtpTime;
- CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
-
- mLastNormalPlayTimeUs =
- (((double)rtpTime - (double)mRTPTimeBase) / mClockRate)
- * 1000000ll
- + mNormalPlayTimeBaseUs;
-}
-
-void APacketSource::queueAccessUnit(const sp<ABuffer> &buffer) {
- int32_t damaged;
- if (buffer->meta()->findInt32("damaged", &damaged) && damaged) {
- LOGV("discarding damaged AU");
- return;
- }
-
- if (mScanForIDR && mIsAVC) {
- // This pretty piece of code ensures that the first access unit
- // fed to the decoder after stream-start or seek is guaranteed to
- // be an IDR frame. This is to workaround limitations of a certain
- // hardware h.264 decoder that requires this to be the case.
-
- if (!IsIDR(buffer)) {
- LOGV("skipping AU while scanning for next IDR frame.");
- return;
- }
-
- mScanForIDR = false;
- }
-
- Mutex::Autolock autoLock(mLock);
- mBuffers.push_back(buffer);
- mCondition.signal();
-}
-
-void APacketSource::signalEOS(status_t result) {
- CHECK(result != OK);
-
- Mutex::Autolock autoLock(mLock);
- mEOSResult = result;
- mCondition.signal();
-}
-
-void APacketSource::flushQueue() {
- Mutex::Autolock autoLock(mLock);
- mBuffers.clear();
-
- mScanForIDR = true;
-}
-
-int64_t APacketSource::getNormalPlayTimeUs() {
- Mutex::Autolock autoLock(mLock);
- return mLastNormalPlayTimeUs;
-}
-
-void APacketSource::setNormalPlayTimeMapping(
- uint32_t rtpTime, int64_t normalPlayTimeUs) {
- Mutex::Autolock autoLock(mLock);
-
- mRTPTimeBase = rtpTime;
- mNormalPlayTimeBaseUs = normalPlayTimeUs;
-}
-
-int64_t APacketSource::getQueueDurationUs(bool *eos) {
- Mutex::Autolock autoLock(mLock);
-
- *eos = (mEOSResult != OK);
-
- if (mBuffers.size() < 2) {
- return 0;
- }
-
- const sp<ABuffer> first = *mBuffers.begin();
- const sp<ABuffer> last = *--mBuffers.end();
-
- int64_t firstTimeUs;
- CHECK(first->meta()->findInt64("timeUs", &firstTimeUs));
-
- int64_t lastTimeUs;
- CHECK(last->meta()->findInt64("timeUs", &lastTimeUs));
-
- if (lastTimeUs < firstTimeUs) {
- LOGE("Huh? Time moving backwards? %lld > %lld",
- firstTimeUs, lastTimeUs);
-
- return 0;
- }
-
- return lastTimeUs - firstTimeUs;
-}
-
} // namespace android
diff --git a/media/libstagefright/rtsp/APacketSource.h b/media/libstagefright/rtsp/APacketSource.h
index 7a77fc6..530e537 100644
--- a/media/libstagefright/rtsp/APacketSource.h
+++ b/media/libstagefright/rtsp/APacketSource.h
@@ -19,63 +19,27 @@
#define A_PACKET_SOURCE_H_
#include <media/stagefright/foundation/ABase.h>
-#include <media/stagefright/MediaSource.h>
-#include <utils/threads.h>
-#include <utils/List.h>
+#include <media/stagefright/MetaData.h>
+#include <utils/RefBase.h>
namespace android {
-struct ABuffer;
struct ASessionDescription;
-struct APacketSource : public MediaSource {
+struct APacketSource : public RefBase {
APacketSource(const sp<ASessionDescription> &sessionDesc, size_t index);
status_t initCheck() const;
- virtual status_t start(MetaData *params = NULL);
- virtual status_t stop();
virtual sp<MetaData> getFormat();
- virtual status_t read(
- MediaBuffer **buffer, const ReadOptions *options = NULL);
-
- void queueAccessUnit(const sp<ABuffer> &buffer);
- void signalEOS(status_t result);
-
- void flushQueue();
-
- int64_t getNormalPlayTimeUs();
-
- void setNormalPlayTimeMapping(
- uint32_t rtpTime, int64_t normalPlayTimeUs);
-
- int64_t getQueueDurationUs(bool *eos);
-
protected:
virtual ~APacketSource();
private:
status_t mInitCheck;
- Mutex mLock;
- Condition mCondition;
-
sp<MetaData> mFormat;
- List<sp<ABuffer> > mBuffers;
- status_t mEOSResult;
-
- bool mIsAVC;
- bool mScanForIDR;
-
- uint32_t mClockRate;
-
- uint32_t mRTPTimeBase;
- int64_t mNormalPlayTimeBaseUs;
-
- int64_t mLastNormalPlayTimeUs;
-
- void updateNormalPlayTime_l(const sp<ABuffer> &buffer);
DISALLOW_EVIL_CONSTRUCTORS(APacketSource);
};
diff --git a/media/libstagefright/rtsp/ARTSPController.cpp b/media/libstagefright/rtsp/ARTSPController.cpp
deleted file mode 100644
index 2ebae7e..0000000
--- a/media/libstagefright/rtsp/ARTSPController.cpp
+++ /dev/null
@@ -1,214 +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.
- */
-
-#include "ARTSPController.h"
-
-#include "MyHandler.h"
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MediaSource.h>
-#include <media/stagefright/MetaData.h>
-
-namespace android {
-
-ARTSPController::ARTSPController(const sp<ALooper> &looper)
- : mState(DISCONNECTED),
- mLooper(looper),
- mUIDValid(false),
- mSeekDoneCb(NULL),
- mSeekDoneCookie(NULL),
- mLastSeekCompletedTimeUs(-1) {
- mReflector = new AHandlerReflector<ARTSPController>(this);
- looper->registerHandler(mReflector);
-}
-
-ARTSPController::~ARTSPController() {
- CHECK_EQ((int)mState, (int)DISCONNECTED);
- mLooper->unregisterHandler(mReflector->id());
-}
-
-void ARTSPController::setUID(uid_t uid) {
- mUIDValid = true;
- mUID = uid;
-}
-
-status_t ARTSPController::connect(const char *url) {
- Mutex::Autolock autoLock(mLock);
-
- if (mState != DISCONNECTED) {
- return ERROR_ALREADY_CONNECTED;
- }
-
- sp<AMessage> msg = new AMessage(kWhatConnectDone, mReflector->id());
-
- mHandler = new MyHandler(url, mLooper, mUIDValid, mUID);
-
- mState = CONNECTING;
-
- mHandler->connect(msg);
-
- while (mState == CONNECTING) {
- mCondition.wait(mLock);
- }
-
- if (mState != CONNECTED) {
- mHandler.clear();
- }
-
- return mConnectionResult;
-}
-
-void ARTSPController::disconnect() {
- Mutex::Autolock autoLock(mLock);
-
- if (mState == CONNECTING) {
- mState = DISCONNECTED;
- mConnectionResult = ERROR_IO;
- mCondition.broadcast();
-
- mHandler.clear();
- return;
- } else if (mState != CONNECTED) {
- return;
- }
-
- sp<AMessage> msg = new AMessage(kWhatDisconnectDone, mReflector->id());
- mHandler->disconnect(msg);
-
- while (mState == CONNECTED) {
- mCondition.wait(mLock);
- }
-
- mHandler.clear();
-}
-
-void ARTSPController::seekAsync(
- int64_t timeUs,
- void (*seekDoneCb)(void *), void *cookie) {
- Mutex::Autolock autoLock(mLock);
-
- CHECK(seekDoneCb != NULL);
- CHECK(mSeekDoneCb == NULL);
-
- // Ignore seek requests that are too soon after the previous one has
- // completed, we don't want to swamp the server.
-
- bool tooEarly =
- mLastSeekCompletedTimeUs >= 0
- && ALooper::GetNowUs() < mLastSeekCompletedTimeUs + 500000ll;
-
- if (mState != CONNECTED || tooEarly) {
- (*seekDoneCb)(cookie);
- return;
- }
-
- mSeekDoneCb = seekDoneCb;
- mSeekDoneCookie = cookie;
-
- sp<AMessage> msg = new AMessage(kWhatSeekDone, mReflector->id());
- mHandler->seek(timeUs, msg);
-}
-
-size_t ARTSPController::countTracks() {
- if (mHandler == NULL) {
- return 0;
- }
-
- return mHandler->countTracks();
-}
-
-sp<MediaSource> ARTSPController::getTrack(size_t index) {
- CHECK(mHandler != NULL);
-
- return mHandler->getPacketSource(index);
-}
-
-sp<MetaData> ARTSPController::getTrackMetaData(
- size_t index, uint32_t flags) {
- CHECK(mHandler != NULL);
-
- return mHandler->getPacketSource(index)->getFormat();
-}
-
-void ARTSPController::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatConnectDone:
- {
- Mutex::Autolock autoLock(mLock);
-
- CHECK(msg->findInt32("result", &mConnectionResult));
- mState = (mConnectionResult == OK) ? CONNECTED : DISCONNECTED;
-
- mCondition.signal();
- break;
- }
-
- case kWhatDisconnectDone:
- {
- Mutex::Autolock autoLock(mLock);
- mState = DISCONNECTED;
- mCondition.signal();
- break;
- }
-
- case kWhatSeekDone:
- {
- LOGI("seek done");
-
- mLastSeekCompletedTimeUs = ALooper::GetNowUs();
-
- void (*seekDoneCb)(void *) = mSeekDoneCb;
- mSeekDoneCb = NULL;
-
- (*seekDoneCb)(mSeekDoneCookie);
- break;
- }
-
- default:
- TRESPASS();
- break;
- }
-}
-
-int64_t ARTSPController::getNormalPlayTimeUs() {
- CHECK(mHandler != NULL);
- return mHandler->getNormalPlayTimeUs();
-}
-
-int64_t ARTSPController::getQueueDurationUs(bool *eos) {
- *eos = true;
-
- int64_t minQueuedDurationUs = 0;
- for (size_t i = 0; i < mHandler->countTracks(); ++i) {
- sp<APacketSource> source = mHandler->getPacketSource(i);
-
- bool newEOS;
- int64_t queuedDurationUs = source->getQueueDurationUs(&newEOS);
-
- if (!newEOS) {
- *eos = false;
- }
-
- if (i == 0 || queuedDurationUs < minQueuedDurationUs) {
- minQueuedDurationUs = queuedDurationUs;
- }
- }
-
- return minQueuedDurationUs;
-}
-
-} // namespace android
diff --git a/media/libstagefright/rtsp/Android.mk b/media/libstagefright/rtsp/Android.mk
index 8530ff3..8230347 100644
--- a/media/libstagefright/rtsp/Android.mk
+++ b/media/libstagefright/rtsp/Android.mk
@@ -15,7 +15,6 @@
ARTPSource.cpp \
ARTPWriter.cpp \
ARTSPConnection.cpp \
- ARTSPController.cpp \
ASessionDescription.cpp \
LOCAL_C_INCLUDES:= \
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index 8128813..af7dd23 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -94,12 +94,24 @@
}
struct MyHandler : public AHandler {
+ enum {
+ kWhatConnected = 'conn',
+ kWhatDisconnected = 'disc',
+ kWhatSeekDone = 'sdon',
+
+ kWhatAccessUnit = 'accU',
+ kWhatEOS = 'eos!',
+ kWhatSeekDiscontinuity = 'seeD',
+ kWhatNormalPlayTimeMapping = 'nptM',
+ };
+
MyHandler(
- const char *url, const sp<ALooper> &looper,
+ const char *url,
+ const sp<AMessage> ¬ify,
bool uidValid = false, uid_t uid = 0)
- : mUIDValid(uidValid),
+ : mNotify(notify),
+ mUIDValid(uidValid),
mUID(uid),
- mLooper(looper),
mNetLooper(new ALooper),
mConn(new ARTSPConnection(mUIDValid, mUID)),
mRTPConn(new ARTPConnection),
@@ -145,12 +157,9 @@
mSessionHost = host;
}
- void connect(const sp<AMessage> &doneMsg) {
- mDoneMsg = doneMsg;
-
- mLooper->registerHandler(this);
- mLooper->registerHandler(mConn);
- (1 ? mNetLooper : mLooper)->registerHandler(mRTPConn);
+ void connect() {
+ looper()->registerHandler(mConn);
+ (1 ? mNetLooper : looper())->registerHandler(mRTPConn);
sp<AMessage> notify = new AMessage('biny', id());
mConn->observeBinaryData(notify);
@@ -159,33 +168,16 @@
mConn->connect(mOriginalSessionURL.c_str(), reply);
}
- void disconnect(const sp<AMessage> &doneMsg) {
- mDoneMsg = doneMsg;
-
+ void disconnect() {
(new AMessage('abor', id()))->post();
}
- void seek(int64_t timeUs, const sp<AMessage> &doneMsg) {
+ void seek(int64_t timeUs) {
sp<AMessage> msg = new AMessage('seek', id());
msg->setInt64("time", timeUs);
- msg->setMessage("doneMsg", doneMsg);
msg->post();
}
- int64_t getNormalPlayTimeUs() {
- int64_t maxTimeUs = 0;
- for (size_t i = 0; i < mTracks.size(); ++i) {
- int64_t timeUs = mTracks.editItemAt(i).mPacketSource
- ->getNormalPlayTimeUs();
-
- if (i == 0 || timeUs > maxTimeUs) {
- maxTimeUs = timeUs;
- }
- }
-
- return maxTimeUs;
- }
-
static void addRR(const sp<ABuffer> &buf) {
uint8_t *ptr = buf->data() + buf->size();
ptr[0] = 0x80 | 0;
@@ -619,7 +611,9 @@
for (size_t i = 0; i < mTracks.size(); ++i) {
TrackInfo *info = &mTracks.editItemAt(i);
- info->mPacketSource->signalEOS(ERROR_END_OF_STREAM);
+ if (!mFirstAccessUnit) {
+ postQueueEOS(i, ERROR_END_OF_STREAM);
+ }
if (!info->mUsingInterleavedTCP) {
mRTPConn->removeStream(info->mRTPSocket, info->mRTCPSocket);
@@ -690,11 +684,10 @@
case 'quit':
{
- if (mDoneMsg != NULL) {
- mDoneMsg->setInt32("result", UNKNOWN_ERROR);
- mDoneMsg->post();
- mDoneMsg = NULL;
- }
+ sp<AMessage> msg = mNotify->dup();
+ msg->setInt32("what", kWhatDisconnected);
+ msg->setInt32("result", UNKNOWN_ERROR);
+ msg->post();
break;
}
@@ -795,17 +788,12 @@
case 'seek':
{
- sp<AMessage> doneMsg;
- CHECK(msg->findMessage("doneMsg", &doneMsg));
-
- if (mSeekPending) {
- doneMsg->post();
- break;
- }
-
if (!mSeekable) {
LOGW("This is a live stream, ignoring seek request.");
- doneMsg->post();
+
+ sp<AMessage> msg = mNotify->dup();
+ msg->setInt32("what", kWhatSeekDone);
+ msg->post();
break;
}
@@ -831,7 +819,6 @@
sp<AMessage> reply = new AMessage('see1', id());
reply->setInt64("time", timeUs);
- reply->setMessage("doneMsg", doneMsg);
mConn->sendRequest(request.c_str(), reply);
break;
}
@@ -842,7 +829,8 @@
for (size_t i = 0; i < mTracks.size(); ++i) {
TrackInfo *info = &mTracks.editItemAt(i);
- info->mPacketSource->flushQueue();
+ postQueueSeekDiscontinuity(i);
+
info->mRTPAnchor = 0;
info->mNTPAnchorUs = -1;
}
@@ -866,11 +854,7 @@
request.append("\r\n");
- sp<AMessage> doneMsg;
- CHECK(msg->findMessage("doneMsg", &doneMsg));
-
sp<AMessage> reply = new AMessage('see2', id());
- reply->setMessage("doneMsg", doneMsg);
mConn->sendRequest(request.c_str(), reply);
break;
}
@@ -915,10 +899,9 @@
mSeekPending = false;
- sp<AMessage> doneMsg;
- CHECK(msg->findMessage("doneMsg", &doneMsg));
-
- doneMsg->post();
+ sp<AMessage> msg = mNotify->dup();
+ msg->setInt32("what", kWhatSeekDone);
+ msg->post();
break;
}
@@ -1056,8 +1039,14 @@
LOGV("track #%d: rtpTime=%u <=> npt=%.2f", n, rtpTime, npt1);
- info->mPacketSource->setNormalPlayTimeMapping(
- rtpTime, (int64_t)(npt1 * 1E6));
+ info->mNormalPlayTimeRTP = rtpTime;
+ info->mNormalPlayTimeUs = (int64_t)(npt1 * 1E6);
+
+ if (!mFirstAccessUnit) {
+ postNormalPlayTimeMapping(
+ trackIndex,
+ info->mNormalPlayTimeRTP, info->mNormalPlayTimeUs);
+ }
++n;
}
@@ -1065,11 +1054,15 @@
mSeekable = true;
}
- sp<APacketSource> getPacketSource(size_t index) {
+ sp<MetaData> getTrackFormat(size_t index, int32_t *timeScale) {
CHECK_GE(index, 0u);
CHECK_LT(index, mTracks.size());
- return mTracks.editItemAt(index).mPacketSource;
+ const TrackInfo &info = mTracks.itemAt(index);
+
+ *timeScale = info.mTimeScale;
+
+ return info.mPacketSource->getFormat();
}
size_t countTracks() const {
@@ -1089,6 +1082,9 @@
int64_t mNTPAnchorUs;
int32_t mTimeScale;
+ uint32_t mNormalPlayTimeRTP;
+ int64_t mNormalPlayTimeUs;
+
sp<APacketSource> mPacketSource;
// Stores packets temporarily while no notion of time
@@ -1096,9 +1092,9 @@
List<sp<ABuffer> > mPackets;
};
+ sp<AMessage> mNotify;
bool mUIDValid;
uid_t mUID;
- sp<ALooper> mLooper;
sp<ALooper> mNetLooper;
sp<ARTSPConnection> mConn;
sp<ARTPConnection> mRTPConn;
@@ -1127,8 +1123,6 @@
Vector<TrackInfo> mTracks;
- sp<AMessage> mDoneMsg;
-
void setupTrack(size_t index) {
sp<APacketSource> source =
new APacketSource(mSessionDesc, index);
@@ -1158,6 +1152,8 @@
info->mNewSegment = true;
info->mRTPAnchor = 0;
info->mNTPAnchorUs = -1;
+ info->mNormalPlayTimeRTP = 0;
+ info->mNormalPlayTimeUs = 0ll;
unsigned long PT;
AString formatDesc;
@@ -1283,9 +1279,17 @@
LOGV("onAccessUnitComplete track %d", trackIndex);
if (mFirstAccessUnit) {
- mDoneMsg->setInt32("result", OK);
- mDoneMsg->post();
- mDoneMsg = NULL;
+ sp<AMessage> msg = mNotify->dup();
+ msg->setInt32("what", kWhatConnected);
+ msg->post();
+
+ for (size_t i = 0; i < mTracks.size(); ++i) {
+ TrackInfo *info = &mTracks.editItemAt(i);
+
+ postNormalPlayTimeMapping(
+ i,
+ info->mNormalPlayTimeRTP, info->mNormalPlayTimeUs);
+ }
mFirstAccessUnit = false;
}
@@ -1303,12 +1307,12 @@
track->mPackets.erase(track->mPackets.begin());
if (addMediaTimestamp(trackIndex, track, accessUnit)) {
- track->mPacketSource->queueAccessUnit(accessUnit);
+ postQueueAccessUnit(trackIndex, accessUnit);
}
}
if (addMediaTimestamp(trackIndex, track, accessUnit)) {
- track->mPacketSource->queueAccessUnit(accessUnit);
+ postQueueAccessUnit(trackIndex, accessUnit);
}
}
@@ -1344,6 +1348,39 @@
return true;
}
+ void postQueueAccessUnit(
+ size_t trackIndex, const sp<ABuffer> &accessUnit) {
+ sp<AMessage> msg = mNotify->dup();
+ msg->setInt32("what", kWhatAccessUnit);
+ msg->setSize("trackIndex", trackIndex);
+ msg->setObject("accessUnit", accessUnit);
+ msg->post();
+ }
+
+ void postQueueEOS(size_t trackIndex, status_t finalResult) {
+ sp<AMessage> msg = mNotify->dup();
+ msg->setInt32("what", kWhatEOS);
+ msg->setSize("trackIndex", trackIndex);
+ msg->setInt32("finalResult", finalResult);
+ msg->post();
+ }
+
+ void postQueueSeekDiscontinuity(size_t trackIndex) {
+ sp<AMessage> msg = mNotify->dup();
+ msg->setInt32("what", kWhatSeekDiscontinuity);
+ msg->setSize("trackIndex", trackIndex);
+ msg->post();
+ }
+
+ void postNormalPlayTimeMapping(
+ size_t trackIndex, uint32_t rtpTime, int64_t nptUs) {
+ sp<AMessage> msg = mNotify->dup();
+ msg->setInt32("what", kWhatNormalPlayTimeMapping);
+ msg->setSize("trackIndex", trackIndex);
+ msg->setInt32("rtpTime", rtpTime);
+ msg->setInt64("nptUs", nptUs);
+ msg->post();
+ }
DISALLOW_EVIL_CONSTRUCTORS(MyHandler);
};
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index a9b539b..dc6c011 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -947,7 +947,12 @@
if (mSendObjectFileSize - initialData > 0) {
mfr.offset = initialData;
- mfr.length = mSendObjectFileSize - initialData;
+ if (mSendObjectFileSize == 0xFFFFFFFF) {
+ // tell driver to read until it receives a short packet
+ mfr.length = 0xFFFFFFFF;
+ } else {
+ mfr.length = mSendObjectFileSize - initialData;
+ }
LOGV("receiving %s\n", (const char *)mSendObjectFilePath);
// transfer the file
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 4c7f84e..0b4f403 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -768,6 +768,9 @@
* {@link GLSurfaceView#setEGLWindowSurfaceFactory(EGLWindowSurfaceFactory)}
*/
public interface EGLWindowSurfaceFactory {
+ /**
+ * @return null if the surface cannot be constructed.
+ */
EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display, EGLConfig config,
Object nativeWindow);
void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface);
@@ -777,7 +780,19 @@
public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display,
EGLConfig config, Object nativeWindow) {
- return egl.eglCreateWindowSurface(display, config, nativeWindow, null);
+ EGLSurface result = null;
+ try {
+ result = egl.eglCreateWindowSurface(display, config, nativeWindow, null);
+ } catch (IllegalArgumentException e) {
+ // This exception indicates that the surface flinger surface
+ // is not valid. This can happen if the surface flinger surface has
+ // been torn down, but the application has not yet been
+ // notified via SurfaceHolder.Callback.surfaceDestroyed.
+ // In theory the application should be notified first,
+ // but in practice sometimes it is not. See b/4588890
+ Log.e(TAG, "eglCreateWindowSurface", e);
+ }
+ return result;
}
public void destroySurface(EGL10 egl, EGLDisplay display,
@@ -1041,9 +1056,8 @@
int error = mEgl.eglGetError();
if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {
Log.e("EglHelper", "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
- return null;
}
- throwEglException("createWindowSurface", error);
+ return null;
}
/*
diff --git a/packages/BackupRestoreConfirmation/res/values-af/strings.xml b/packages/BackupRestoreConfirmation/res/values-af/strings.xml
index 0d7422e..8ee5550 100644
--- a/packages/BackupRestoreConfirmation/res/values-af/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-af/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Laai my data terug"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Moenie herstel nie"</string>
<string name="current_password_text" msgid="8268189555578298067">"Voer asseblief jou huidige rugsteunwagwoord hieronder in:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Voer jou toestelenkripsie-wagwoord hier onder in."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Voer jou toestelenkripsie-wagwoord hier onder in. Dit sal ook gebruik word om die rugsteunargief te enkripteer."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Voer asb. \'n wagwoord in om te gebruik vir enkripsie van die volle rugsteundata. As dit leeg gelaat word, sal jou huidige rugsteunwagwoord gebruik word:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"As jy die volle rugsteundata wil enkripteer, voer \'n wagwoord hieronder in:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"As die hersteldata geïnkripteer word, voer asb. die wagwoord hieronder in:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-am/strings.xml b/packages/BackupRestoreConfirmation/res/values-am/strings.xml
index 41fa6a0..512d917 100644
--- a/packages/BackupRestoreConfirmation/res/values-am/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-am/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"ውሂቤን እነበረበት መልስ"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"እነበረበት አትመልስ"</string>
<string name="current_password_text" msgid="8268189555578298067">"እባክዎ የአሁኑን የመጠባበቂያ ይለፍቃል ከታች ያስገቡ፡"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"እባክህ የመሳሪያህ ምስጠራ የይለፍ ቃል ከታች አስገባ፡፡"</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"እባክህ የመሳሪያህ ምስጠራ የይለፍ ቃል ከታች አስገባ፡፡ይሄ ለምትኬ መዝገብ ለመመስጠርም ይጠቅማል፡፡"</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"እባክዎ የሙሉ ውሂብ መጠበቂያ ማመስጠር ለመጠቅም የይለፍ ቃል ያስገቡ። ይህም ባዶ ከሆነ፣ የእርስዎ የአሁኑ የመጠበቂያ ይለፍ ቃል ይወሰዳል፡"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"ሙሉ የውሂብ መጠበቂያ ለማመስጠር ከፈለጉ ከታች የይለፍ ቃል ያስገቡ፡"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"ውሂብ እነበረበት መልስ የተመሳጠረ ከሆነ፣ እባክዎ ከታች የይለፍ ቃል ያስገቡ"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-ar/strings.xml b/packages/BackupRestoreConfirmation/res/values-ar/strings.xml
index ceabaaf..2e9ec40 100644
--- a/packages/BackupRestoreConfirmation/res/values-ar/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ar/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"استرداد بياناتي"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"عدم الاسترداد"</string>
<string name="current_password_text" msgid="8268189555578298067">"الرجاء إدخال كلمة مرور النسخ الاحتياطي أدناه:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"الرجاء إدخال كلمة مرور تشفير جهازك أدناه."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"الرجاء إدخال كلمة مرور تشفير الجهاز. سيتم استخدام ذلك أيضًا لتشفير أرشيف النسخ الاحتياطي."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"الرجاء إدخال كلمة المرور للاستخدام لتشفير بيانات النسخة الاحتياطية بالكامل. إذا تم ترك هذا فارغًا، فسيتم استخدام كلمة مرور النسخ الاحتياطي الحالية:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"إذا كنت ترغب في تشفير بيانات النسخة الاحتياطية بالكامل، فأدخل كلمة المرور أدناه:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"إذا كانت بيانات الاسترداد مشفرة، فالرجاء إدخال كلمة المرور أدناه:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-bg/strings.xml b/packages/BackupRestoreConfirmation/res/values-bg/strings.xml
index f90b666..914750a 100644
--- a/packages/BackupRestoreConfirmation/res/values-bg/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-bg/strings.xml
@@ -25,6 +25,10 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Възстановяване на данните ми"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Без възстановяване"</string>
<string name="current_password_text" msgid="8268189555578298067">"Моля, въведете текущата си парола за резервно копие по-долу:"</string>
+ <!-- no translation found for device_encryption_restore_text (1570864916855208992) -->
+ <skip />
+ <!-- no translation found for device_encryption_backup_text (5866590762672844664) -->
+ <skip />
<string name="backup_enc_password_text" msgid="4981585714795233099">"Моля, въведете парола, която да използвате за шифроване на пълното резервно копие на данните. Ако не е попълнена, ще бъде използвана текущата ви парола за резервно копие:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Ако искате да шифровате пълното резервно копие на данните, въведете парола по-долу:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Ако възстановените данни са шифровани, моля, въведете паролата по-долу:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-ca/strings.xml b/packages/BackupRestoreConfirmation/res/values-ca/strings.xml
index d4b9cd2..c511510 100644
--- a/packages/BackupRestoreConfirmation/res/values-ca/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ca/strings.xml
@@ -19,12 +19,14 @@
<string name="backup_confirm_title" msgid="827563724209303345">"Fes una còpia de seguretat completa"</string>
<string name="restore_confirm_title" msgid="5469365809567486602">"Restaura completament"</string>
<string name="backup_confirm_text" msgid="1878021282758896593">"S\'ha sol·licitat una còpia de seguretat completa de totes les dades a un equip de sobretaula connectat. Vols permetre que això passi?"\n" "\n"Si no has sol·licitat la còpia de seguretat tu mateix, no permetis que continuï l\'operació."</string>
- <string name="allow_backup_button_label" msgid="4217228747769644068">"Còpia seg. de les meves dades"</string>
+ <string name="allow_backup_button_label" msgid="4217228747769644068">"Còpia de seguretat de dades"</string>
<string name="deny_backup_button_label" msgid="6009119115581097708">"No en facis una còpia de seguretat"</string>
<string name="restore_confirm_text" msgid="7499866728030461776">"S\'ha sol·licitat una restauració completa de totes les dades d\'un equip d\'escriptori connectat. Vols permetre que això passi?"\n" "\n"Si no has sol·licitat la restauració tu mateix, no permetis que continuï l\'operació. Això reemplaçarà les dades que hi hagi actualment a l\'equip."</string>
<string name="allow_restore_button_label" msgid="3081286752277127827">"Restaura les meves dades"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"No ho restauris"</string>
<string name="current_password_text" msgid="8268189555578298067">"Introdueix la teva contrasenya actual de còpia de seguretat a continuació:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Introdueix la contrasenya d\'encriptació del dispositiu a continuació."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Introdueix la contrasenya d\'encriptació del dispositiu a continuació. També es farà servir per encriptar l\'arxiu de seguretat."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Introdueix una contrasenya que utilitzaràs per a l\'encriptació de les dades de còpia de la seguretat completa. Si es deixa en blanc, s\'utilitzarà la teva contrasenya de còpia de seguretat actual:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Si vols xifrar les dades de la còpia de seguretat completa, introdueix una contrasenya a continuació:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Si la recuperació de dades està xifrada, introdueix la contrasenya a continuació:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-cs/strings.xml b/packages/BackupRestoreConfirmation/res/values-cs/strings.xml
index 89085f3..0732cd8 100644
--- a/packages/BackupRestoreConfirmation/res/values-cs/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-cs/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Obnovit moje data"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Neobnovovat"</string>
<string name="current_password_text" msgid="8268189555578298067">"Zadejte prosím aktuální heslo pro zálohy níže:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Zadejte prosím své heslo pro šifrování zařízení."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Sem prosím zadejte bezpečnostní gesto. Toto gesto se použije také při šifrování záložního archivu."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Zadejte prosím heslo pro šifrování dat úplné zálohy. Pokud pole ponecháte prázdné, použije se aktuální heslo pro zálohy:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Chcete-li data úplné zálohy zašifrovat, zadejte heslo:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Pokud jsou obnovená data šifrována, zadejte prosím heslo níže:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-da/strings.xml b/packages/BackupRestoreConfirmation/res/values-da/strings.xml
index 5cbaab4..b3756d9 100644
--- a/packages/BackupRestoreConfirmation/res/values-da/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-da/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Gendan mine data"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Gendan ikke"</string>
<string name="current_password_text" msgid="8268189555578298067">"Indtast din aktuelle adgangskode til sikkerhedskopiering nedenfor:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Indtast adgangskoden til kryptering for din enhed nedenfor."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Indtast adgangskoden til kryptering for din enhed nedenfor. Denne bliver også brugt til at kryptere sikkerhedskopien af arkivet."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Angiv en adgangskode, som skal bruges til kryptering af alle dine sikkerhedsdata. Hvis dette felt er tomt, bruges din aktuelle adgangskode til sikkerhedskopiering:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Hvis du ønsker at kryptere sikkerhedsdataene, skal du indtaste en adgangskode nedenfor:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Hvis gendannelsesdataene er krypteret, skal du angive adgangskoden nedenfor:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-de/strings.xml b/packages/BackupRestoreConfirmation/res/values-de/strings.xml
index e4bdb6b..7a19b2e 100644
--- a/packages/BackupRestoreConfirmation/res/values-de/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-de/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Meine Daten wiederherstellen"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Nicht wiederherstellen"</string>
<string name="current_password_text" msgid="8268189555578298067">"Geben Sie Ihr aktuelles Sicherungspasswort unten ein:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Geben Sie Ihr Passwort zur Geräteverschlüsselung unten ein."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Geben Sie Ihr Passwort zur Geräteverschlüsselung unten ein. Damit wird ebenfalls das Sicherungsarchiv verschlüsselt."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Geben Sie ein Passwort für die Verschlüsselung der vollständigen Sicherungsdaten ein. Wenn Sie dieses Feld leer lassen, wird Ihr aktuelles Sicherungspasswort verwendet:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Wenn Sie die gesamten Sicherungsdaten verschlüsseln möchten, geben Sie unten ein Passwort ein:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Geben Sie das Passwort unten ein, wenn die Daten für die Wiederherstellung verschlüsselt sind:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-el/strings.xml b/packages/BackupRestoreConfirmation/res/values-el/strings.xml
index 8571860..13a78cb 100644
--- a/packages/BackupRestoreConfirmation/res/values-el/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-el/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Αποκατάσταση των δεδομένων μου"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Να μην γίνει επαναφορά"</string>
<string name="current_password_text" msgid="8268189555578298067">"Εισαγάγετε τον τρέχοντα κωδικό πρόσβασής αντιγράφων ασφαλείας παρακάτω:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Εισαγάγετε τον κωδικό πρόσβασης κρυπτογράφησης συσκευής παρακάτω."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Εισαγάγετε τον κωδικό πρόσβασης για την κρυπτογράφηση συσκευής παρακάτω. Ο κωδικός αυτός θα χρησιμοποιηθεί και για την κρυπτογράφηση του αρχείου αντιγράφων ασφαλείας."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Εισαγάγετε έναν κωδικό πρόσβασης για χρήση για την κωδικοποίηση του πλήρους αντιγράφου ασφαλείας δεδομένων. Αν μείνει κενό, θα χρησιμοποιηθεί ο τρέχων κωδικός σας πρόσβασης:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Αν θέλετε να κρυπτογραφήσετε τα πλήρη δεδομένα αντιγράφων ασφαλείας, πληκτρολογήστε έναν κωδικό πρόσβασης παρακάτω:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Εάν η επαναφορά των δεδομένων είναι κρυπτογραφημένη, εισάγετε τον κωδικό πρόσβασης παρακάτω:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-en-rGB/strings.xml b/packages/BackupRestoreConfirmation/res/values-en-rGB/strings.xml
index b7d15cd..7b94e2e 100644
--- a/packages/BackupRestoreConfirmation/res/values-en-rGB/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-en-rGB/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Restore my data"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Do not restore"</string>
<string name="current_password_text" msgid="8268189555578298067">"Please enter your current backup password below:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Please enter your device encryption password below."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Please enter your device encryption password below. This will also be used to encrypt the backup archive."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Please enter a password to use for encrypting the full backup data. If this is left blank, your current backup password will be used:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"If you wish to encrypt the full backup data, enter a password below:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"If the restore data is encrypted, please enter the password below:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-es-rUS/strings.xml b/packages/BackupRestoreConfirmation/res/values-es-rUS/strings.xml
index 264f3fc..7a732df 100644
--- a/packages/BackupRestoreConfirmation/res/values-es-rUS/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-es-rUS/strings.xml
@@ -25,12 +25,14 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Restaurar mis datos"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"No restaurar"</string>
<string name="current_password_text" msgid="8268189555578298067">"Introduce tu contraseña actual de copia de seguridad a continuación:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Introduce tu contraseña de encriptación del dispositivo a continuación:"</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Introduce tu contraseña de encriptación del dispositivo a continuación. Esto también se utilizará para encriptar la copia de seguridad."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Introduce una contraseña para encriptar los datos de la copia de seguridad completa. Si dejas este campo en blanco, se utilizará tu contraseña actual de copia de seguridad:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Si deseas encriptar los datos de la copia de seguridad completa, introduce una contraseña a continuación:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Si los datos de recuperación están encriptados, vuelve a introducir la contraseña a continuación:"</string>
- <string name="toast_backup_started" msgid="550354281452756121">"Realizando la copia de seguridad..."</string>
+ <string name="toast_backup_started" msgid="550354281452756121">"Iniciando copia de seguridad..."</string>
<string name="toast_backup_ended" msgid="3818080769548726424">"La realización de la copia de seguridad finalizó."</string>
- <string name="toast_restore_started" msgid="7881679218971277385">"Restaurando..."</string>
+ <string name="toast_restore_started" msgid="7881679218971277385">"Iniciando restauración..."</string>
<string name="toast_restore_ended" msgid="1764041639199696132">"La restauración finalizó."</string>
- <string name="toast_timeout" msgid="5276598587087626877">"La operación caducó."</string>
+ <string name="toast_timeout" msgid="5276598587087626877">"Se agotó el tiempo de espera para la operación."</string>
</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-es/strings.xml b/packages/BackupRestoreConfirmation/res/values-es/strings.xml
index 8ae4762..ef97e3c 100644
--- a/packages/BackupRestoreConfirmation/res/values-es/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-es/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Restaurar mis datos"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"No restaurar"</string>
<string name="current_password_text" msgid="8268189555578298067">"Introduce a continuación la contraseña actual de copia de seguridad:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Introduce a continuación la contraseña de encriptación del dispositivo."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Introduce a continuación la contraseña de encriptación del dispositivo. Esta contraseña se usará también para encriptar el archivo de copia de seguridad."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Introduce la contraseña que quieras usar para cifrar los datos de la copia de seguridad completa. Si dejas este campo en blanco, se usará tu contraseña de copia de seguridad actual:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Si quieres cifrar los datos de la copia de seguridad completa, introduce la contraseña a continuación:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Si los datos de restauración están cifrados, introduce la contraseña a continuación:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-fa/strings.xml b/packages/BackupRestoreConfirmation/res/values-fa/strings.xml
index c4f8da4..d202d74 100644
--- a/packages/BackupRestoreConfirmation/res/values-fa/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-fa/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"بازیابی دادههای من"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"بازیابی نشود"</string>
<string name="current_password_text" msgid="8268189555578298067">"لطفاً گذرواژه نسخه پشتیبان فعلی خود را در زیر وارد کنید:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"لطفاً گذرواژه رمزگذاری دستگاه خود را در زیر وارد کنید."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"لطفاً گذرواژه رمزگذاری دستگاه خود را در زیر وارد کنید. این برای رمزگذاری بایگانی پشتیبان نیز مورد استفاده قرار میگیرد."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"لطفاً یک گذرواژه برای رمزگذاری دادههای کامل نسخه پشتیبانی وارد کنید. اگر این خالی بماند، گذرواژه فعلی نسخه پشتیبان مورد استفاده قرار خواهد گرفت:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"اگر میخواهید تمام نسخه پشتیبانی داده را رمزدار کنید، یک گذرواژه در زیر وارد کنید:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"اگر داده بازیابی شده رمزگذاری شده است، لطفاً گذرواژه را در زیر وارد کنید:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-fi/strings.xml b/packages/BackupRestoreConfirmation/res/values-fi/strings.xml
index f50ce6a..80da29b 100644
--- a/packages/BackupRestoreConfirmation/res/values-fi/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-fi/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Palauta omat tiedot"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Älä palauta"</string>
<string name="current_password_text" msgid="8268189555578298067">"Kirjoita nykyinen varmuuskopioinnin salasana alla:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Kirjoita laitteen salauksen salasana alle."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Kirjoita laitteen salauksen salasana alle. Salasanaa käytetään myös varmuuskopioarkiston salaamiseen."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Anna salasana kaikkien varmuuskopiotietojen salaamiseksi. Jos tämä jätetään tyhjäksi, nykyistä varmuuskopioinnin salasanaa käytetään:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Jos haluat salata kaikki varmuuskopiotiedot, kirjoita salasana alle:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Jos palautustiedot on salattu, anna salasana alla:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-fr/strings.xml b/packages/BackupRestoreConfirmation/res/values-fr/strings.xml
index 0f0a9df..9af37b0 100644
--- a/packages/BackupRestoreConfirmation/res/values-fr/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-fr/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Restaurer mes données"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Ne pas restaurer"</string>
<string name="current_password_text" msgid="8268189555578298067">"Veuillez saisir votre mot de passe de sauvegarde actuel ci-dessous :"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Veuillez saisir le mot de passe de chiffrement de l\'appareil ci-dessous."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Veuillez saisir le mot de passe de chiffrement de l\'appareil ci-dessous. Il permettra également de chiffrer les archives de sauvegarde."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Veuillez saisir un mot de passe à utiliser pour chiffrer les données de sauvegarde complète. Si ce champ n\'est pas renseigné, votre mot de passe de sauvegarde actuel sera utilisé :"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Si vous souhaitez chiffrer l\'ensemble des données de sauvegarde, veuillez saisir un mot de passe ci-dessous :"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Si les données de restauration sont chiffrées, veuillez saisir le mot de passe ci-dessous :"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-hi/strings.xml b/packages/BackupRestoreConfirmation/res/values-hi/strings.xml
new file mode 100644
index 0000000..ccac982
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-hi/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="backup_confirm_title" msgid="827563724209303345">"पूर्ण बैकअप"</string>
+ <string name="restore_confirm_title" msgid="5469365809567486602">"पूर्ण पुनर्स्थापना"</string>
+ <string name="backup_confirm_text" msgid="1878021282758896593">"कनेक्ट किए गए डेस्कटॉप कंप्यूटर से सभी डेटा के संपूर्ण बैकअप का अनुरोध किया गया है. क्या आप इसकी अनुमति देना चाहते हैं?"\n\n"यदि आपने स्वयं बैकअप का अनुरोध नहीं किया है, तो प्रक्रिया जारी रखने की अनुमति न दें."</string>
+ <string name="allow_backup_button_label" msgid="4217228747769644068">"मेरे डेटा का बैकअप लें"</string>
+ <string name="deny_backup_button_label" msgid="6009119115581097708">"बैकअप न लें"</string>
+ <string name="restore_confirm_text" msgid="7499866728030461776">"कनेक्ट किए गए डेस्कटॉप कंप्यूटर से सभी डेटा की पूर्ण पुनर्स्थापना का अनुरोध किया गया है. क्या आप इसकी अनुमति देना चाहते हैं?"\n\n"यदि आपने स्वयं पुनर्प्राप्ति का अनुरोध नहीं किया है, तो प्रक्रिया जारी रखने की अनुमति न दें. इससे वर्तमान में आपके उपकरण पर मौजूद डेटा बदल जाएगा!"</string>
+ <string name="allow_restore_button_label" msgid="3081286752277127827">"मेरा डेटा पुनर्स्थापित करें"</string>
+ <string name="deny_restore_button_label" msgid="1724367334453104378">"पुनर्स्थापित न करें"</string>
+ <string name="current_password_text" msgid="8268189555578298067">"कृपया नीचे अपना वर्तमान बैकअप पासवर्ड दर्ज करें:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"कृपया नीचे अपना उपकरण एन्क्रिप्शन पासवर्ड दर्ज करें."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"कृपया अपना उपकरण एन्क्रिप्शन पासवर्ड नीचे दर्ज करें. बैकअप संग्रहण को एन्क्रिप्ट करने के लिए भी इसका उपयोग किया जाएगा."</string>
+ <string name="backup_enc_password_text" msgid="4981585714795233099">"कृपया संपूर्ण बैकअप डेटा को एन्क्रिप्ट करने में उपयोग के लिए पासवर्ड दर्ज करें. यदि यह खाली छोड़ दिया जाता है, तो आपके वर्तमान बैकअप पासवर्ड का उपयोग किया जाएगा:"</string>
+ <string name="backup_enc_password_optional" msgid="1350137345907579306">"यदि आप संपूर्ण बैकअप डेटा एन्क्रिप्ट करना चाहते हैं, तो नीचे पासवर्ड दर्ज करें:"</string>
+ <string name="restore_enc_password_text" msgid="6140898525580710823">"यदि पुनर्स्थापित डेटा को एन्क्रिप्ट किया गया है, तो कृपया नीचे पासवर्ड दर्ज करें:"</string>
+ <string name="toast_backup_started" msgid="550354281452756121">"बैकअप प्रारंभ हो रहा है..."</string>
+ <string name="toast_backup_ended" msgid="3818080769548726424">"बैकअप पूर्ण"</string>
+ <string name="toast_restore_started" msgid="7881679218971277385">"पुनर्स्थापना प्रारंभ हो रही है..."</string>
+ <string name="toast_restore_ended" msgid="1764041639199696132">"पुनर्स्थापना समाप्त"</string>
+ <string name="toast_timeout" msgid="5276598587087626877">"कार्यवाही समयबाह्य हो गई"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-hr/strings.xml b/packages/BackupRestoreConfirmation/res/values-hr/strings.xml
index ce06db9f..0c4cfd9 100644
--- a/packages/BackupRestoreConfirmation/res/values-hr/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-hr/strings.xml
@@ -25,6 +25,10 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Vrati moje podatke"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Ne vraćaj"</string>
<string name="current_password_text" msgid="8268189555578298067">"U nastavku unesite trenutačnu zaporku za sigurnosnu kopiju:"</string>
+ <!-- no translation found for device_encryption_restore_text (1570864916855208992) -->
+ <skip />
+ <!-- no translation found for device_encryption_backup_text (5866590762672844664) -->
+ <skip />
<string name="backup_enc_password_text" msgid="4981585714795233099">"Unesite zaporku koju ćete upotrebljavati za kriptiranje podataka potpune sigurnosne kopije. Ako je ostavite praznom, bit će upotrijebljena vaša trenutačna zaporka za sigurnosno kopiranje:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Ako želite kriptirati podatke potpune sigurnosne kopije, u nastavku unesite zaporku:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Ako su podaci za vraćanje kriptirani, unesite zaporku u nastavku:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-hu/strings.xml b/packages/BackupRestoreConfirmation/res/values-hu/strings.xml
index b244f26..c2901c1 100644
--- a/packages/BackupRestoreConfirmation/res/values-hu/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-hu/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Adatok visszaállítása"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Ne állítsa vissza"</string>
<string name="current_password_text" msgid="8268189555578298067">"Kérjük, adja meg a jelenlegi biztonsági jelszót alább:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Kérjük, adja meg az eszköz titkosítási jelszavát."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Kérjük, adja meg az eszköz titkosítási jelszavát. Ezt használjuk a biztonsági mentések archívumának titkosításához is."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Kérjük, írjon be egy jelszót a teljes biztonsági mentés adatainak titkosításához. Ha üresen hagyja, jelenlegi biztonsági jelszavát fogjuk használni:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Ha minden mentett adatot szeretne titkosítani, adjon meg egy jelszót alább:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Ha a visszaállítási adatok titkosítva vannak, kérjük, adja meg a jelszót alább:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-in/strings.xml b/packages/BackupRestoreConfirmation/res/values-in/strings.xml
index 5a26304..65196bd 100644
--- a/packages/BackupRestoreConfirmation/res/values-in/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-in/strings.xml
@@ -25,6 +25,10 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Memulihkan data saya"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Jangan pulihkan"</string>
<string name="current_password_text" msgid="8268189555578298067">"Masukkan sandi cadangan Anda saat ini di bawah:"</string>
+ <!-- no translation found for device_encryption_restore_text (1570864916855208992) -->
+ <skip />
+ <!-- no translation found for device_encryption_backup_text (5866590762672844664) -->
+ <skip />
<string name="backup_enc_password_text" msgid="4981585714795233099">"Masukkan sandi yang digunakan untuk mengenkripsi data cadangan lengkap. Jika bidang ini dikosongkan, sandi cadangan Anda saat ini akan digunakan:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Jika Anda ingin mengenkripsi data cadangan lengkap, masukkan sandi di bawah:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Jika data pemulihan dienkripsi, masukkan sandi di bawah:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-it/strings.xml b/packages/BackupRestoreConfirmation/res/values-it/strings.xml
index 1722222..9442ae3 100644
--- a/packages/BackupRestoreConfirmation/res/values-it/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-it/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="backup_confirm_title" msgid="827563724209303345">"Backup totale"</string>
+ <string name="backup_confirm_title" msgid="827563724209303345">"Backup completo"</string>
<string name="restore_confirm_title" msgid="5469365809567486602">"Ripristino totale"</string>
<string name="backup_confirm_text" msgid="1878021282758896593">"È stato richiesto un backup completo di tutti i dati su un computer desktop connesso. Consentire l\'operazione?"\n\n"Se non hai richiesto il backup, non consentire all\'operazione di procedere."</string>
<string name="allow_backup_button_label" msgid="4217228747769644068">"Effettua backup dei miei dati"</string>
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Ripristina i miei dati"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Non ripristinare"</string>
<string name="current_password_text" msgid="8268189555578298067">"Inserisci la tua password di backup corrente di seguito:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Inserisci la tua password di crittografia dispositivo di seguito."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Inserisci la tua password di crittografia dispositivo di seguito. Verrà utilizzata anche per crittografare l\'archivio di backup."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Inserisci una password da utilizzare per la crittografia dei dati di backup completi. Se non ne inserisci una, verrà utilizzata la tua password di backup corrente:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Se desideri crittografare tutti i dati di backup, inserisci una password qui di seguito:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Se i dati di ripristino sono crittografati, inserisci la password qui di seguito:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-iw/strings.xml b/packages/BackupRestoreConfirmation/res/values-iw/strings.xml
index 056b245..a41944a 100644
--- a/packages/BackupRestoreConfirmation/res/values-iw/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-iw/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"שחזר את הנתונים שלי"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"אל תשחזר"</string>
<string name="current_password_text" msgid="8268189555578298067">"הזן את סיסמת הגיבוי הנוכחית למטה:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"הזן את סיסמת ההצפנה של המכשיר שלך בהמשך."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"הזן את סיסמת ההצפנה של המכשיר שלך בהמשך. הסיסמה תשמש גם להצפנת ארכיון הגיבוי."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"הזן סיסמה שתשמש להצפנה של נתוני הגיבוי המלא. אם תשאיר שדה זה ריק, ייעשה שימוש בסיסמת הגיבוי הנוכחית שלך:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"אם אתה רוצה להצפין את נתוני הגיבוי המלא, הזן סיסמה בהמשך:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"אם נתוני השחזור מוצפנים, הזן את הסיסמה למטה:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-ja/strings.xml b/packages/BackupRestoreConfirmation/res/values-ja/strings.xml
index 9b575c9..5ddcc22 100644
--- a/packages/BackupRestoreConfirmation/res/values-ja/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ja/strings.xml
@@ -25,6 +25,10 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"データを復元する"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"復元しない"</string>
<string name="current_password_text" msgid="8268189555578298067">"以下に現在のバックアップ用のパスワードを入力してください:"</string>
+ <!-- no translation found for device_encryption_restore_text (1570864916855208992) -->
+ <skip />
+ <!-- no translation found for device_encryption_backup_text (5866590762672844664) -->
+ <skip />
<string name="backup_enc_password_text" msgid="4981585714795233099">"フルバックアップデータの暗号化に使用するパスワードを入力してください。空白のままにした場合、現在のバックアップ用のパスワードが使用されます:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"フルバックアップのデータを暗号化する場合は、以下にパスワードを入力してください:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"復元するデータが暗号化されている場合、以下にパスワードを入力してください:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-ko/strings.xml b/packages/BackupRestoreConfirmation/res/values-ko/strings.xml
index 0fca3cd..4137058 100644
--- a/packages/BackupRestoreConfirmation/res/values-ko/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ko/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"데이터 복원"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"복원하지 않음"</string>
<string name="current_password_text" msgid="8268189555578298067">"아래에 현재 사용 중인 백업 비밀번호를 입력하세요."</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"아래에 기기 암호화 비밀번호를 입력하세요."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"아래에 기기 암호화 비밀번호를 입력하세요. 백업 자료실을 암호화할 때에도 사용됩니다."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"전체 백업 데이터를 암호화하려면 사용할 비밀번호를 입력하세요. 공백으로 남겨 두면 현재 백업 비밀번호가 사용됩니다."</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"전체 백업 데이터를 암호화하려면 아래에 비밀번호를 입력하세요."</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"복원 데이터가 암호화되어 있는 경우, 아래에 비밀번호를 입력하세요."</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-lt/strings.xml b/packages/BackupRestoreConfirmation/res/values-lt/strings.xml
index bd49320..4e9efc5 100644
--- a/packages/BackupRestoreConfirmation/res/values-lt/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-lt/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Atkurti mano duomenis"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Neatkurti"</string>
<string name="current_password_text" msgid="8268189555578298067">"Toliau įveskite dabartinį atsarginės kopijos slaptažodį:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Toliau įveskite įrenginio šifruotės slaptažodį."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Toliau įveskite įrenginio šifruotės slaptažodį. Jis bus naudojamas ir atsarginės kopijos archyvui šifruoti."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Įveskite slaptažodį, kuris bus naudojamas visai atsarginei duomenų kopijai šifruoti. Jei reikšmės neįvesite, bus naudojamas dabartinis atsarginės kopijos slaptažodis:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Jei norite užšifruoti visą atsarginę duomenų kopiją, įveskite slaptažodį:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Jei atkūrimo duomenys užšifruoti, įveskite toliau nurodytą slaptažodį:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-lv/strings.xml b/packages/BackupRestoreConfirmation/res/values-lv/strings.xml
index a6f3d67..b8ce24b 100644
--- a/packages/BackupRestoreConfirmation/res/values-lv/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-lv/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Atjaunot manus datus"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Neatjaunot"</string>
<string name="current_password_text" msgid="8268189555578298067">"Lūdzu, tālāk ievadiet pašreizējo dublējuma paroli:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Lūdzu, ievadiet ierīces šifrēšanas paroli."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Lūdzu, ievadiet ierīces šifrēšanas paroli. Tā tiks arī izmantota, lai šifrētu dublējuma arhīvu."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Lūdzu, ievadiet paroli, kas tiks izmantota dublējuma datu pilnīgai šifrēšanai. Ja paroles lauciņu atstāsiet tukšu, tiks izmantota jūsu pašreizējā dublējuma parole:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Ja vēlaties pilnībā šifrēt dublējuma datus, tālāk ievadiet paroli:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Ja atjaunošanas dati ir šifrēti, lūdzu, ievadiet tālāk paroli:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-ms/strings.xml b/packages/BackupRestoreConfirmation/res/values-ms/strings.xml
index f0b6b62..bcfa615 100644
--- a/packages/BackupRestoreConfirmation/res/values-ms/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ms/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Pulihkan data saya"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Jangan kembalikan"</string>
<string name="current_password_text" msgid="8268189555578298067">"Sila masukkan kata laluan sandaran semasa anda di bawah:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Sila masukkan kata laluan penyulitan peranti anda di bawah."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Sila masukkan kata laluan penyulitan peranti anda di bawah. Ini juga akan digunakan untuk menyulitkan arkib sandaran."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Sila masukkan kata laluan yang hendak digunakan untuk menyulitkan data sandaran lengkap. Jika dibiarkan kosong, kata laluan sandaran semasa anda akan digunakan:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Jika anda ingin menyulitkan data sandaran lengkap, masukkan kata laluan di bawah:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Jika pemulihan data disulitkan, sila masukkan kata laluan di bawah:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-nb/strings.xml b/packages/BackupRestoreConfirmation/res/values-nb/strings.xml
index a54138d..a04d90d 100644
--- a/packages/BackupRestoreConfirmation/res/values-nb/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-nb/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Gjenopprett dataene mine"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Ikke gjenopprett"</string>
<string name="current_password_text" msgid="8268189555578298067">"Skriv inn ditt nåværende passord for sikkerhetskopiering nedenfor:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Skriv inn krypteringspassordet for enheten din nedenfor."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Skriv inn krypteringspassordet for enheten din nedenfor. Dette brukes også til å kryptere arkivet for sikkerhetskopier."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Skriv inn et passord for kryptering av full sikkerhetskopi. Hvis feltet er tomt, brukes det gjeldende passordet ditt for sikkerhetskopiering:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Hvis du vil kryptere alle de sikkerhetskopierte dataene, skriver du inn et passord nedenfor:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Hvis de gjenopprettede dataene er krypterte, må du skrive inn passordet nedenfor:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-nl/strings.xml b/packages/BackupRestoreConfirmation/res/values-nl/strings.xml
index 24e6c3b..d525429 100644
--- a/packages/BackupRestoreConfirmation/res/values-nl/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-nl/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Mijn gegevens herstellen"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Niet herstellen"</string>
<string name="current_password_text" msgid="8268189555578298067">"Geef hieronder uw huidige back-upwachtwoord op:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Geef hieronder uw wachtwoord voor apparaatcodering op."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Geef hieronder uw wachtwoord voor apparaatcodering op. Dit wordt ook gebruikt om het back-uparchief te coderen."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Geef een wachtwoord op dat u wilt gebruiken voor het coderen van de gegevens van de volledige back-up. Als u dit leeg laat, wordt uw huidige back-upwachtwoord gebruikt:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Als u de gegevens van de volledige back-up wilt coderen, geeft u daarvoor hieronder een wachtwoord op:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Als deze herstelgegevens zijn gecodeerd, geeft u hieronder het wachtwoord op:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-pl/strings.xml b/packages/BackupRestoreConfirmation/res/values-pl/strings.xml
index 04552d6..1a70bb0 100644
--- a/packages/BackupRestoreConfirmation/res/values-pl/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-pl/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Przywróć moje dane"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Nie przywracaj"</string>
<string name="current_password_text" msgid="8268189555578298067">"Wpisz poniżej aktualne hasło kopii zapasowej:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Wpisz poniżej hasło szyfrowania urządzenia."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Wpisz poniżej hasło szyfrowania urządzenia. Służy ono również do szyfrowania archiwum kopii zapasowych."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Wpisz hasło do zaszyfrowania pełnej kopii zapasowej. Jeśli pozostawisz puste pole, zostanie użyte aktualne hasło kopii zapasowej:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Jeśli chcesz zaszyfrować pełną kopię zapasową, wprowadź poniżej hasło:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Jeśli przywracane dane są zaszyfrowane, wpisz poniżej hasło:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml b/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml
index 3eca061..9540300 100644
--- a/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Restaurar os meus dados"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Não restaurar"</string>
<string name="current_password_text" msgid="8268189555578298067">"Introduza a palavra-passe de cópia de segurança atual abaixo:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Introduza a palavra-passe de encriptação do aparelho abaixo."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Introduza a palavra-passe de encriptação do aparelho abaixo. Esta também será utilizada para encriptar o arquivo da cópia de segurança."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Introduza uma palavra-passe a utilizar para encriptar os dados da cópia de segurança completa. Se deixar o campo em branco, será utilizada a palavra-passe de cópia de segurança atual."</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Se pretender encriptar os dados da cópia de segurança completa, introduza uma palavra-passe abaixo:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Se os dados a restaurar estiverem encriptados, introduza a palavra-passe abaixo:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-pt/strings.xml b/packages/BackupRestoreConfirmation/res/values-pt/strings.xml
index 680b538..99fd2e1 100644
--- a/packages/BackupRestoreConfirmation/res/values-pt/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-pt/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Restaurar meus dados"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Não restaurar"</string>
<string name="current_password_text" msgid="8268189555578298067">"Digite sua senha de backup atual abaixo:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Insira sua senha de criptografia do dispositivo abaixo."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Insira sua senha de criptografia do dispositivo abaixo. Ela também será usada para criptografar o arquivo de backup."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Digite uma senha para usar para criptografar os dados de backup por completo. Se isso for deixado em branco, sua senha atual de backup será usada:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Se você deseja criptografar os dados de backup por completo, digite uma senha abaixo:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Se os dados restaurados forem criptografada, digite a senha abaixo:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-ro/strings.xml b/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
index b36680f..82cdfaf 100644
--- a/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
@@ -25,6 +25,10 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Restabiliţi datele dvs."</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Nu restabiliţi"</string>
<string name="current_password_text" msgid="8268189555578298067">"Introduceţi mai jos parola actuală pentru copia de rezervă:"</string>
+ <!-- no translation found for device_encryption_restore_text (1570864916855208992) -->
+ <skip />
+ <!-- no translation found for device_encryption_backup_text (5866590762672844664) -->
+ <skip />
<string name="backup_enc_password_text" msgid="4981585714795233099">"Introduceţi o parolă pentru a o utiliza la criptarea datelor copiei de rezervă complete. Dacă acest câmp rămâne necompletat, pentru copierea de rezervă se va utiliza parola dvs. actuală."</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Dacă doriţi să criptaţi datele copiei de rezervă complete, introduceţi o parolă mai jos:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Dacă datele pentru restabilire sunt criptate, introduceţi parola mai jos:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-ru/strings.xml b/packages/BackupRestoreConfirmation/res/values-ru/strings.xml
index 91c5755..2ce3ff6 100644
--- a/packages/BackupRestoreConfirmation/res/values-ru/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ru/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Восстановить данные"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Не восстанавливать"</string>
<string name="current_password_text" msgid="8268189555578298067">"Введите пароль для резервного копирования:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Введите пароль для шифрования устройства."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Введите пароль для шифрования устройства, а также архива резервных копий."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Введите пароль для шифрования всех резервных данных. Если поле останется пустым, будет использован текущий пароль:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Чтобы зашифровать все резервные данные, введите пароль:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Если восстановленные данные зашифрованы, введите пароль:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-sk/strings.xml b/packages/BackupRestoreConfirmation/res/values-sk/strings.xml
index bc8ff97..b432165 100644
--- a/packages/BackupRestoreConfirmation/res/values-sk/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sk/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Obnoviť údaje"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Neobnoviť"</string>
<string name="current_password_text" msgid="8268189555578298067">"Zadajte svoje aktuálne heslo pre zálohu nižšie:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Zadajte svoje heslo na šifrovanie zariadenia nižšie."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Zadajte svoje heslo na šifrovanie zariadenia nižšie. Bude tiež použité na šifrovanie archívu zálohy."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Zadajte heslo, ktoré sa použije pri šifrovaní údajov úplnej zálohy. Ak pole ponecháte prázdne, použije sa vaše aktuálne heslo zálohy:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Ak chcete šifrovať údaje úplnej zálohy, zadajte heslo nižšie:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Ak sú údaje obnovenia šifrované, zadajte heslo nižšie:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-sl/strings.xml b/packages/BackupRestoreConfirmation/res/values-sl/strings.xml
index 1ca2e53..5df0449 100644
--- a/packages/BackupRestoreConfirmation/res/values-sl/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sl/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="backup_confirm_title" msgid="827563724209303345">"Popolna varnostna kopija"</string>
+ <string name="backup_confirm_title" msgid="827563724209303345">"Polna varnostna kopija"</string>
<string name="restore_confirm_title" msgid="5469365809567486602">"Popolna obnova"</string>
<string name="backup_confirm_text" msgid="1878021282758896593">"Zahtevano je popolno varnostno kopiranje vseh podatkov v povezanem računalniku. Ali želite to dovoliti?"\n\n"Če varnostnega kopiranja niste zahtevali, ne dovolite nadaljevanja postopka."</string>
<string name="allow_backup_button_label" msgid="4217228747769644068">"Varnostno kopiraj moje podatke"</string>
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Obnovi moje podatke"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Ne obnovi"</string>
<string name="current_password_text" msgid="8268189555578298067">"Spodaj vnesite trenutno geslo za varnostno kopiranje:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Vnesite geslo za šifriranje naprave spodaj."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Vnesite geslo za šifriranje naprave spodaj. Uporabljeno bo tudi za šifriranje arhiva varnostnih kopij."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Vnesite geslo za šifriranje podatkov popolnega varnostnega kopiranja. Če to pustite prazno, bo uporabljeno trenutno geslo za varnostno kopiranje:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Če želite šifrirati vse varnostno kopirane podatke, spodaj vnesite geslo:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Če so podatki za obnovitev šifrirani, spodaj vnesite geslo:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-sr/strings.xml b/packages/BackupRestoreConfirmation/res/values-sr/strings.xml
index 5b3b250..0a5859e 100644
--- a/packages/BackupRestoreConfirmation/res/values-sr/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sr/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Врати моје податке"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Не враћај"</string>
<string name="current_password_text" msgid="8268189555578298067">"Унесите тренутну лозинку резервне копије у наставку:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Унесите лозинку уређаја за шифровање у наставку."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Унесите лозинку уређаја за шифровање. Ово ће се користити и за шифровање резервне архиве."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Унесите лозинку коју ћете користити за шифровање података потпуне резервне копије. Ако то поље оставите празно, користиће се тренутна лозинка резервне копије:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Ако желите да шифрујете податке потпуне резервне копије, унесите лозинку у наставку."</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Ако су подаци за враћање шифровани, унесите лозинку у наставку:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-sv/strings.xml b/packages/BackupRestoreConfirmation/res/values-sv/strings.xml
index 4ac0a54..167fce3 100644
--- a/packages/BackupRestoreConfirmation/res/values-sv/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sv/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Återställ mina data"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Återställ inte"</string>
<string name="current_password_text" msgid="8268189555578298067">"Ange det aktuella lösenordet för säkerhetskopian nedan:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Ange lösenordet för enhetskryptering nedan."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Ange lösenordet för enhetskryptering nedan. Lösenordet kommer även att användas för att kryptera säkerhetskopian."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Ange ett lösenord för kryptering av alla säkerhetskopierade data. Om det här lämnas tomt kommer ditt nuvarande lösenord för säkerhetskopior att användas:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Om du vill kryptera alla säkerhetskopierade data anger du ett lösenord nedan:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Om återställda data är krypterade anger du lösenordet nedan:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-sw/strings.xml b/packages/BackupRestoreConfirmation/res/values-sw/strings.xml
index 2069d83..f0961a2 100644
--- a/packages/BackupRestoreConfirmation/res/values-sw/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sw/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Rejesha upya data yangu"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Usirejeshe upya"</string>
<string name="current_password_text" msgid="8268189555578298067">"Tafadhali ingiza nenosiri lako la chelezo hapo chini:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Tafadhali ingiza nenosiri ya usimbaji fiche ya kifaa chako hapo chini."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Tafadhali ingiza nenosiri yako ya msimbo fiche hapo chini. Hii pia itatumika kusimba fiche jalidi ya hifadhi."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Tafadhali ingiza nenosiri la kutumia kwa usimbaji fiche wa chelezo ya data kamili. Ikiwa hii itawachwa wazi, nenosiri lako la sasa litatumika:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Ikiwa unataka kusimba fiche data nzima ya kucheleza, ingiza nenosiri la hapo chini:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Ikiwa data iliyorejeshwa upya, tafadhali ingiza nenosiri lililo hapo chini:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-th/strings.xml b/packages/BackupRestoreConfirmation/res/values-th/strings.xml
index dc76577..2d08620 100644
--- a/packages/BackupRestoreConfirmation/res/values-th/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-th/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"คืนค่าข้อมูลของฉัน"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"ไม่คืนค่า"</string>
<string name="current_password_text" msgid="8268189555578298067">"โปรดป้อนรหัสผ่านการสำรองข้อมูลปัจจุบันของคุณด้านล่างนี้:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"โปรดป้อนรหัสผ่านการเข้ารหัสอุปกรณ์ของคุณด้านล่าง"</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"โปรดป้อนรหัสผ่านการเข้ารหัสอุปกรณ์ของคุณด้านล่างนี้ ซึ่งจะใช้ในการเข้ารหัสที่เก็บข้อมูลสำรองด้วย"</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"โปรดป้อนรหัสผ่านเพื่อใช้สำหรับเข้ารหัสข้อมูลที่สำรองแบบเต็มรูปแบบ หากเว้นว่างไว้ รหัสผ่านการสำรองข้อมูลปัจจุบันของคุณจะถูกใช้:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"หากคุณต้องการเข้ารหัสข้อมูลที่สำรองเต็มรูปแบบ โปรดป้อนรหัสผ่านด้านล่างนี้:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"หากมีการเข้ารหัสข้อมูลที่คืนค่า โปรดป้อนรหัสผ่านด้านล่างนี้:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-tl/strings.xml b/packages/BackupRestoreConfirmation/res/values-tl/strings.xml
index 99f2e48..97662b5 100644
--- a/packages/BackupRestoreConfirmation/res/values-tl/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-tl/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Ipanumbalik ang aking data"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Huwag ipanumbalik"</string>
<string name="current_password_text" msgid="8268189555578298067">"Pakilagay ang iyong kasalukuyang backup na password sa ibaba:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Mangyaring ilagay ang password ng pag-encrypt ng iyong device sa ibaba."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Mangyaring ilagay ang password ng pag-encrypt ng iyong device sa ibaba. Gagamitin rin ito upang i-encrypt ang backup na archive."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Mangyaring maglagay ng password na gamitin sa pag-e-encrypt ng buong data sa pag-backup. Kung iiwanan itong blangko, gagamitin ang iyong kasalukuyang backup na password:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Kung nais mong i-encrypt ang buong data ng backup, maglagay ng password sa ibaba:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Kung naka-encrypt ang data sa pagpapanumbalik, pakilagay ang password sa ibaba:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-tr/strings.xml b/packages/BackupRestoreConfirmation/res/values-tr/strings.xml
index 2bbdd33..62b9f4b 100644
--- a/packages/BackupRestoreConfirmation/res/values-tr/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-tr/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Verilerimi geri yükle"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Geri yükleme"</string>
<string name="current_password_text" msgid="8268189555578298067">"Lütfen mevcut yedekleme şifrenizi aşağıya girin:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Lütfen cihazı şifrelemek için kullandığınız şifreyi aşağıya girin."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Lütfen cihazınızı şifrelemek için kullandığınız şifreyi aşağıya girin. Bu şifre aynı zamanda yedekleme arşivini şifrelemek için de kullanılacaktır."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Tam yedekleme verilerini şifrelemek için lütfen bir şifre girin. Boş bırakılırsa, mevcut yedekleme şifreniz kullanılır:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Yedeklenen tüm verileri şifrelemek isterseniz, aşağıya bir şifre girin:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Geri yükleme verileri şifreliyse, lütfen şifreyi aşağıya girin:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-uk/strings.xml b/packages/BackupRestoreConfirmation/res/values-uk/strings.xml
index 9b2df90..f3dfa1c 100644
--- a/packages/BackupRestoreConfirmation/res/values-uk/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-uk/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Відновити мої дані"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Не відновлювати"</string>
<string name="current_password_text" msgid="8268189555578298067">"Введіть свій поточний пароль резервного копіювання нижче:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Нижче введіть свій пароль шифрування пристрою."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Нижче введіть свій пароль шифрування пристрою. Він також використовуватиметься для шифрування архіву резервної копії."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Введіть пароль, який використовується для шифрування повного резервного копіювання даних. Якщо залишити це поле порожнім, буде використано поточний пароль резервного копіювання."</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Якщо ви хочете зашифрувати повне резервне копіювання даних, введіть пароль нижче:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Якщо дані для відновлення зашифровано, введіть пароль нижче:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-vi/strings.xml b/packages/BackupRestoreConfirmation/res/values-vi/strings.xml
index ad98262..ac34a993 100644
--- a/packages/BackupRestoreConfirmation/res/values-vi/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-vi/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Khôi phục dữ liệu của tôi"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Không khôi phục"</string>
<string name="current_password_text" msgid="8268189555578298067">"Vui lòng nhập mật khẩu sao lưu hiện tại của bạn bên dưới:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Vui lòng nhập mật khẩu mã hóa thiết bị của bạn bên dưới."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Vui lòng nhập mật khẩu mã hóa thiết bị của bạn bên dưới. Mật khẩu này cũng được sử dụng để mã hóa kho lưu trữ sao lưu."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Vui lòng nhập mật khẩu dùng để mã hóa toàn bộ dữ liệu sao lưu. Nếu trường này bị bỏ trống, mật khẩu sao lưu hiện tại của bạn sẽ được sử dụng:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Nếu bạn muốn mã hóa toàn bộ dữ liệu sao lưu, hãy nhập mật khẩu bên dưới:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Nếu dữ liệu khôi phục được mã hóa, vui lòng nhập mật khẩu bên dưới:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-zh-rCN/strings.xml b/packages/BackupRestoreConfirmation/res/values-zh-rCN/strings.xml
index 40a1d1f..5f3ca05 100644
--- a/packages/BackupRestoreConfirmation/res/values-zh-rCN/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-zh-rCN/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"恢复我的数据"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"不恢复"</string>
<string name="current_password_text" msgid="8268189555578298067">"请在下方输入您的当前备份密码:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"请在下方输入您的设备加密密码。"</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"请在下方输入您的设备加密密码。此密码还会用于加密备份存档。"</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"请输入用于加密完整备份数据的密码。如果留空,系统将会使用您当前的备份密码:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"如果您想为整个备份数据加密,请在下方输入密码:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"如果恢复数据已加密,请在下方输入密码:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-zh-rTW/strings.xml b/packages/BackupRestoreConfirmation/res/values-zh-rTW/strings.xml
index 00c24df..5afb226 100644
--- a/packages/BackupRestoreConfirmation/res/values-zh-rTW/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-zh-rTW/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"還原我的資料"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"不要還原"</string>
<string name="current_password_text" msgid="8268189555578298067">"請在下面輸入您目前的備份密碼:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"請在下方輸入您的裝置加密密碼。"</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"請在下方輸入您的裝置加密密碼,這也會用來加密備份封存檔。"</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"請輸入完整備份資料加密專用的密碼。如果您沒有輸入密碼,系統會使用您目前的備用密碼:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"如果您想要將完整備份資料進行加密,請在下面輸入一組密碼:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"如果還原的資料經過加密處理,請在下面輸入密碼:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-zu/strings.xml b/packages/BackupRestoreConfirmation/res/values-zu/strings.xml
index 98e76cd..2fe0c0f 100644
--- a/packages/BackupRestoreConfirmation/res/values-zu/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-zu/strings.xml
@@ -25,6 +25,8 @@
<string name="allow_restore_button_label" msgid="3081286752277127827">"Buyisela esimweni imininingo yami"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Ungabuyiseli esimweni"</string>
<string name="current_password_text" msgid="8268189555578298067">"Sicela ufake i-password yakho yamanje yokwenza isipele ngezansi:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Uyacelwa ukuba ufake ihasiwedi efakwe kudivayisi ngezansi."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Uyacelwa ukuba ufake iphasiwedi efakwe kudivayisi yakho ngezansi. lokhu kuzosetshenziswa ukufaka kusilondoloza sokusiza lapho kudingeka."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Sicela ufake i-password ezosetshenziselwa ukubhala ngokufihlekileyo imininingo eyesekwe ngokulondoloza. Uma lokhu kushiywe kungabhalwe lutho, kuzosetshenziswa i-password yokweseka ngokulondoloza yamanje:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Uma ufuna ukufaka ikhowudi kwimininingo yonke eyesekelwe ngokulondoloza faka i-passowrd engezansi:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Uma insiza yokubuyiselwa esimweni kwmininingo ibhalwe ngokufihlekileyo, sicela ufake i-password ngezansi:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values/strings.xml b/packages/BackupRestoreConfirmation/res/values/strings.xml
index e91c6e2..5c90fd0 100644
--- a/packages/BackupRestoreConfirmation/res/values/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values/strings.xml
@@ -35,8 +35,12 @@
<!-- Text for message to user that they must enter their predefined backup password in order to perform this operation. -->
<string name="current_password_text">Please enter your current backup password below:</string>
+ <!-- Text for message to user that they must enter their device encryption password in order to perform this restore operation. -->
+ <string name="device_encryption_restore_text">Please enter your device encryption password below.</string>
+ <!-- Text for message to user that they must enter their device encryption password in order to perform this backup operation. -->
+ <string name="device_encryption_backup_text">Please enter your device encryption password below. This will also be used to encrypt the backup archive.</string>
- <!-- Text for message to user that they can must enter an encryption password to use for the full backup operation. -->
+ <!-- Text for message to user that they must enter an encryption password to use for the full backup operation. -->
<string name="backup_enc_password_text">Please enter a password to use for encrypting the full backup data. If this is left blank, your current backup password will be used:</string>
<!-- Text for message to user that they may optionally supply an encryption password to use for a full backup operation. -->
<string name="backup_enc_password_optional">If you wish to encrypt the full backup data, enter a password below:</string>
diff --git a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
index fbdf3cc..7f1d059 100644
--- a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
+++ b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
@@ -27,6 +27,8 @@
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.storage.IMountService;
+import android.util.Log;
import android.util.Slog;
import android.view.View;
import android.widget.Button;
@@ -60,8 +62,10 @@
Handler mHandler;
IBackupManager mBackupManager;
+ IMountService mMountService;
FullObserver mObserver;
int mToken;
+ boolean mIsEncrypted;
boolean mDidAcknowledge;
TextView mStatusView;
@@ -152,6 +156,7 @@
}
mBackupManager = IBackupManager.Stub.asInterface(ServiceManager.getService(Context.BACKUP_SERVICE));
+ mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
mHandler = new ObserverHandler(getApplicationContext());
final Object oldObserver = getLastNonConfigurationInstance();
@@ -174,8 +179,23 @@
mEncPassword = (TextView) findViewById(R.id.enc_password);
TextView curPwDesc = (TextView) findViewById(R.id.password_desc);
- // We vary the password prompt depending on whether one is predefined
- if (!haveBackupPassword()) {
+ // We vary the password prompt depending on whether one is predefined, and whether
+ // the device is encrypted.
+ mIsEncrypted = deviceIsEncrypted();
+ if (mIsEncrypted) {
+ Log.d(TAG, "Device is encrypted: requiring encryption pw");
+ TextView pwPrompt = (TextView) findViewById(R.id.password_desc);
+ // this password is mandatory; we hide the other options during backup
+ if (layoutId == R.layout.confirm_backup) {
+ pwPrompt.setText(R.string.device_encryption_backup_text);
+ TextView tv = (TextView) findViewById(R.id.enc_password);
+ tv.setVisibility(View.GONE);
+ tv = (TextView) findViewById(R.id.enc_password_desc);
+ tv.setVisibility(View.GONE);
+ } else {
+ pwPrompt.setText(R.string.device_encryption_restore_text);
+ }
+ } else if (!haveBackupPassword()) {
curPwDesc.setVisibility(View.GONE);
mCurPassword.setVisibility(View.GONE);
if (layoutId == R.layout.confirm_backup) {
@@ -226,10 +246,12 @@
mDidAcknowledge = true;
try {
+ CharSequence encPassword = (mIsEncrypted)
+ ? mCurPassword.getText() : mEncPassword.getText();
mBackupManager.acknowledgeFullBackupOrRestore(mToken,
allow,
String.valueOf(mCurPassword.getText()),
- String.valueOf(mEncPassword.getText()),
+ String.valueOf(encPassword),
mObserver);
} catch (RemoteException e) {
// TODO: bail gracefully if we can't contact the backup manager
@@ -237,6 +259,16 @@
}
}
+ boolean deviceIsEncrypted() {
+ try {
+ return (mMountService.getEncryptionState() != IMountService.ENCRYPTION_STATE_NONE);
+ } catch (Exception e) {
+ // If we can't talk to the mount service we have a serious problem; fail
+ // "secure" i.e. assuming that the device is encrypted.
+ return true;
+ }
+ }
+
boolean haveBackupPassword() {
try {
return mBackupManager.hasBackupPassword();
diff --git a/packages/DefaultContainerService/res/values-hi/strings.xml b/packages/DefaultContainerService/res/values-hi/strings.xml
new file mode 100644
index 0000000..ad85379
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-hi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="service_name" msgid="4841491635055379553">"पैकेज पहुंच सहायक"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/drawable-hdpi/ic_launcher_settings.png b/packages/SettingsProvider/res/drawable-hdpi/ic_launcher_settings.png
index ff34a7f..8a5a2f7 100644
--- a/packages/SettingsProvider/res/drawable-hdpi/ic_launcher_settings.png
+++ b/packages/SettingsProvider/res/drawable-hdpi/ic_launcher_settings.png
Binary files differ
diff --git a/packages/SettingsProvider/res/drawable-mdpi/ic_launcher_settings.png b/packages/SettingsProvider/res/drawable-mdpi/ic_launcher_settings.png
index b08ad3b..803439f 100644
--- a/packages/SettingsProvider/res/drawable-mdpi/ic_launcher_settings.png
+++ b/packages/SettingsProvider/res/drawable-mdpi/ic_launcher_settings.png
Binary files differ
diff --git a/packages/SettingsProvider/res/drawable-xhdpi/ic_launcher_settings.png b/packages/SettingsProvider/res/drawable-xhdpi/ic_launcher_settings.png
new file mode 100644
index 0000000..ec3c8ea
--- /dev/null
+++ b/packages/SettingsProvider/res/drawable-xhdpi/ic_launcher_settings.png
Binary files differ
diff --git a/packages/SettingsProvider/res/values-hi/strings.xml b/packages/SettingsProvider/res/values-hi/strings.xml
new file mode 100644
index 0000000..0b0bd8a
--- /dev/null
+++ b/packages/SettingsProvider/res/values-hi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="4567566098528588863">"सेटिंग संग्रहण"</string>
+</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index b851ab7..2444829 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -350,16 +350,21 @@
private byte[] getSystemSettings() {
Cursor cursor = getContentResolver().query(Settings.System.CONTENT_URI, PROJECTION, null,
null, null);
- byte[] result = extractRelevantValues(cursor, Settings.System.SETTINGS_TO_BACKUP);
- cursor.close();
- return result;
+ try {
+ return extractRelevantValues(cursor, Settings.System.SETTINGS_TO_BACKUP);
+ } finally {
+ cursor.close();
+ }
}
private byte[] getSecureSettings() {
Cursor cursor = getContentResolver().query(Settings.Secure.CONTENT_URI, PROJECTION, null,
null, null);
- byte[] result = extractRelevantValues(cursor, Settings.Secure.SETTINGS_TO_BACKUP);
- return result;
+ try {
+ return extractRelevantValues(cursor, Settings.Secure.SETTINGS_TO_BACKUP);
+ } finally {
+ cursor.close();
+ }
}
private void restoreSettings(BackupDataInput data, Uri contentUri) {
diff --git a/packages/SharedStorageBackup/AndroidManifest.xml b/packages/SharedStorageBackup/AndroidManifest.xml
index 39c36f1..fc21df3 100644
--- a/packages/SharedStorageBackup/AndroidManifest.xml
+++ b/packages/SharedStorageBackup/AndroidManifest.xml
@@ -23,7 +23,6 @@
<application android:allowClearUserData="false"
android:permission="android.permission.CONFIRM_FULL_BACKUP"
- android:backupAgent=".SharedStorageAgent"
- android:allowBackup="false" >
+ android:backupAgent="SharedStorageAgent" >
</application>
</manifest>
diff --git a/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/SharedStorageAgent.java b/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/SharedStorageAgent.java
index 6c677b8..a6415b2 100644
--- a/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/SharedStorageAgent.java
+++ b/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/SharedStorageAgent.java
@@ -2,11 +2,8 @@
import android.app.backup.FullBackupAgent;
import android.app.backup.FullBackup;
-import android.app.backup.BackupDataInput;
-import android.app.backup.BackupDataOutput;
import android.app.backup.FullBackupDataOutput;
import android.content.Context;
-import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
@@ -40,6 +37,7 @@
// hierarchy backup process on them. By convention in the Storage Manager, the
// "primary" shared storage volume is first in the list.
if (mVolumes != null) {
+ if (DEBUG) Slog.i(TAG, "Backing up " + mVolumes.length + " shared volumes");
for (int i = 0; i < mVolumes.length; i++) {
StorageVolume v = mVolumes[i];
// Express the contents of volume N this way in the tar stream:
@@ -58,7 +56,7 @@
public void onRestoreFile(ParcelFileDescriptor data, long size,
int type, String domain, String relpath, long mode, long mtime)
throws IOException {
- Slog.d(TAG, "Shared restore: [ " + domain + " : " + relpath + "]");
+ if (DEBUG) Slog.d(TAG, "Shared restore: [ " + domain + " : " + relpath + "]");
File outFile = null;
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index a2452c4..64c54d9 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -101,5 +101,21 @@
android:taskAffinity="com.android.systemui.net"
android:excludeFromRecents="true" />
+ <!-- started from ... somewhere -->
+ <activity
+ android:name=".Nyandroid"
+ android:exported="true"
+ android:label="Nyandroid"
+ android:icon="@drawable/nyandroid04"
+ android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
+ android:hardwareAccelerated="true"
+ android:launchMode="singleInstance"
+ android:excludeFromRecents="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.DREAM" />
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
index 3adcbec..4a1d37e 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png
index d7a591c..9378fac 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/recents_callout_line.9.png b/packages/SystemUI/res/drawable-hdpi/recents_callout_line.9.png
deleted file mode 100644
index 335d5a8..0000000
--- a/packages/SystemUI/res/drawable-hdpi/recents_callout_line.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.9.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.9.png
new file mode 100644
index 0000000..d000f7e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_normal.9.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_normal.9.png
new file mode 100644
index 0000000..d000f7e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
index 277dcb8..6e84546 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png
index edc1760..c56905e 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
index fbc6b99..11ffbde 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
index fb938e8..2bb923e 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
index 2d35517..783ad175 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
index fe68c3c..e499f9d 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
index 49411bd..39e3df0 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png
index 77924f0..b4920c3 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/recents_callout_line.9.png b/packages/SystemUI/res/drawable-mdpi/recents_callout_line.9.png
deleted file mode 100644
index 724a5cd..0000000
--- a/packages/SystemUI/res/drawable-mdpi/recents_callout_line.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.9.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.9.png
new file mode 100644
index 0000000..f19dc93
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_normal.9.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_normal.9.png
new file mode 100644
index 0000000..f19dc93
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
index 000e98b..31c0936 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
index 62b940a..7e9b752 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
index 5beb543..3209234d 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
index f70d315..95c56ed 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
index be9953f..11b9a93 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
index de20bdd..0f85ca0 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid00.png b/packages/SystemUI/res/drawable-nodpi/nyandroid00.png
new file mode 100644
index 0000000..6cea873
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/nyandroid00.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid01.png b/packages/SystemUI/res/drawable-nodpi/nyandroid01.png
new file mode 100644
index 0000000..82b8a21
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/nyandroid01.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid02.png b/packages/SystemUI/res/drawable-nodpi/nyandroid02.png
new file mode 100644
index 0000000..fde0033
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/nyandroid02.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid03.png b/packages/SystemUI/res/drawable-nodpi/nyandroid03.png
new file mode 100644
index 0000000..54c5f46
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/nyandroid03.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid04.png b/packages/SystemUI/res/drawable-nodpi/nyandroid04.png
new file mode 100644
index 0000000..35e5ab5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/nyandroid04.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid05.png b/packages/SystemUI/res/drawable-nodpi/nyandroid05.png
new file mode 100644
index 0000000..d3eaace
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/nyandroid05.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid06.png b/packages/SystemUI/res/drawable-nodpi/nyandroid06.png
new file mode 100644
index 0000000..0e0d3b1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/nyandroid06.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid07.png b/packages/SystemUI/res/drawable-nodpi/nyandroid07.png
new file mode 100644
index 0000000..edb0b17
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/nyandroid07.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid08.png b/packages/SystemUI/res/drawable-nodpi/nyandroid08.png
new file mode 100644
index 0000000..10fc4f6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/nyandroid08.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid09.png b/packages/SystemUI/res/drawable-nodpi/nyandroid09.png
new file mode 100644
index 0000000..57ade54
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/nyandroid09.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid10.png b/packages/SystemUI/res/drawable-nodpi/nyandroid10.png
new file mode 100644
index 0000000..36feb2f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/nyandroid10.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid11.png b/packages/SystemUI/res/drawable-nodpi/nyandroid11.png
new file mode 100644
index 0000000..125935b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/nyandroid11.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/star0.png b/packages/SystemUI/res/drawable-nodpi/star0.png
new file mode 100644
index 0000000..f2ca960
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/star0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/star1.png b/packages/SystemUI/res/drawable-nodpi/star1.png
new file mode 100644
index 0000000..69ef4da
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/star1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/star2.png b/packages/SystemUI/res/drawable-nodpi/star2.png
new file mode 100644
index 0000000..b95968a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/star2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/star3.png b/packages/SystemUI/res/drawable-nodpi/star3.png
new file mode 100644
index 0000000..ad0f589
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/star3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/star4.png b/packages/SystemUI/res/drawable-nodpi/star4.png
new file mode 100644
index 0000000..934c45b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/star4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/star5.png b/packages/SystemUI/res/drawable-nodpi/star5.png
new file mode 100644
index 0000000..46a4435
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/star5.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_in.png
index 8a3d90c..3d67766 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_inout.png
index 45dda51c..b74e070 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_out.png
index 18e019c..24485e1 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_in.png
index cb8ed3a..390d500 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_inout.png
index ab4ad05..78998f9 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_out.png
index 956b6c1..c539615 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_in.png
index 9d95f17..5c38d45 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_inout.png
index e68d57d..6a79695 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_out.png
index 4ac361d9..99dbe1b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_in.png
index 5e7ecdc..6a73a89 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_inout.png
index 462fad4..7042f2b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_out.png
index d284c02..3da781e8 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_in.png
index 4a5e701..cf63e24 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_inout.png
index 9a08949..8f68e1f 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_out.png
index 314f422..894c63b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_in.png
index 4e0a48a..1ec5b49 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_inout.png
index 4eeae1d..9ca3ca8 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_out.png
index 1a6f1ef..74241e0 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
index d853993..faeee29 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png
index 2e6e3ac..f7e7102 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_callout_line.9.png b/packages/SystemUI/res/drawable-xhdpi/recents_callout_line.9.png
deleted file mode 100644
index 1bd018a..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/recents_callout_line.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg.9.png b/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg.9.png
new file mode 100644
index 0000000..80fc849
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_normal.9.png b/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_normal.9.png
new file mode 100644
index 0000000..80fc849
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png
index 2864ec3..cc9c49f 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png
index 0bb0c72..5a313c5 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png
index f23dd60..373a4a4 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png
index b1c3168..d299daf 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png
index 5e41470..dcfdb7b 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png
index 639842b..fb8125a 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/notification_row_bg.xml b/packages/SystemUI/res/drawable/notification_row_bg.xml
index dc626d1..1bb2172 100644
--- a/packages/SystemUI/res/drawable/notification_row_bg.xml
+++ b/packages/SystemUI/res/drawable/notification_row_bg.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:exitFadeDuration="@android:integer/config_mediumAnimTime">
- <item android:state_pressed="true" android:drawable="@android:color/holo_blue_light" />
+ <item android:state_pressed="true" android:drawable="@drawable/notification_item_background_color_pressed" />
<item android:state_pressed="false" android:drawable="@drawable/notification_item_background_color" />
</selector>
diff --git a/packages/SystemUI/res/drawable/nyandroid_anim.xml b/packages/SystemUI/res/drawable/nyandroid_anim.xml
new file mode 100644
index 0000000..855a0c2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/nyandroid_anim.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animation-list
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:oneshot="false">
+ <item android:drawable="@drawable/nyandroid00" android:duration="80" />
+ <item android:drawable="@drawable/nyandroid01" android:duration="80" />
+ <item android:drawable="@drawable/nyandroid02" android:duration="80" />
+ <item android:drawable="@drawable/nyandroid03" android:duration="80" />
+ <item android:drawable="@drawable/nyandroid04" android:duration="80" />
+ <item android:drawable="@drawable/nyandroid05" android:duration="80" />
+ <item android:drawable="@drawable/nyandroid06" android:duration="80" />
+ <item android:drawable="@drawable/nyandroid07" android:duration="80" />
+ <item android:drawable="@drawable/nyandroid08" android:duration="80" />
+ <item android:drawable="@drawable/nyandroid09" android:duration="80" />
+ <item android:drawable="@drawable/nyandroid10" android:duration="80" />
+ <item android:drawable="@drawable/nyandroid11" android:duration="80" />
+</animation-list>
+
diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_bg.xml b/packages/SystemUI/res/drawable/recents_thumbnail_bg.xml
deleted file mode 100644
index 320ed40..0000000
--- a/packages/SystemUI/res/drawable/recents_thumbnail_bg.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/recents_thumbnail_bg_dragging" android:state_activated="true" />
- <item android:drawable="@*android:color/transparent"/>
-</selector>
diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_fg.xml b/packages/SystemUI/res/drawable/recents_thumbnail_fg.xml
index d683af9..7033077 100644
--- a/packages/SystemUI/res/drawable/recents_thumbnail_fg.xml
+++ b/packages/SystemUI/res/drawable/recents_thumbnail_fg.xml
@@ -16,5 +16,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/recents_thumbnail_bg_press" android:state_selected="true" />
<item android:drawable="@drawable/recents_thumbnail_bg_press" android:state_pressed="true" />
+ <item android:drawable="@drawable/recents_thumbnail_bg_dragging" android:state_activated="true" />
<item android:drawable="@*android:color/transparent"/>
</selector>
diff --git a/packages/SystemUI/res/drawable/star_anim.xml b/packages/SystemUI/res/drawable/star_anim.xml
new file mode 100644
index 0000000..d7f2d8f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/star_anim.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animation-list
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:oneshot="false">
+ <item android:drawable="@drawable/star0" android:duration="200" />
+ <item android:drawable="@drawable/star1" android:duration="200" />
+ <item android:drawable="@drawable/star2" android:duration="200" />
+ <item android:drawable="@drawable/star3" android:duration="200" />
+ <item android:drawable="@drawable/star4" android:duration="200" />
+ <item android:drawable="@drawable/star5" android:duration="200" />
+</animation-list>
+
diff --git a/packages/SystemUI/res/drawable/status_bar_recents_background.xml b/packages/SystemUI/res/drawable/status_bar_recents_background.xml
new file mode 100644
index 0000000..8b22bf1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/status_bar_recents_background.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <gradient name="status_bar_recents_background"
+ android:startColor="#cc000000"
+ android:endColor="#66000000"
+ android:angle="@integer/status_bar_recents_bg_gradient_degrees"
+ />
+</shape>
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
index 58355bd..83c4faf 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
@@ -26,16 +26,17 @@
android:paddingRight="@dimen/status_bar_recents_item_padding">
<RelativeLayout android:id="@+id/recent_item"
- android:layout_gravity="bottom"
+ android:layout_gravity="center_vertical"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:paddingBottom="@*android:dimen/status_bar_height">
+ android:paddingTop="@*android:dimen/status_bar_height">
<FrameLayout android:id="@+id/app_thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
+ android:layout_marginTop="@dimen/status_bar_recents_thumbnail_top_margin"
android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
android:background="@drawable/recents_thumbnail_bg"
android:foreground="@drawable/recents_thumbnail_fg">
@@ -44,19 +45,22 @@
android:layout_height="@dimen/status_bar_recents_thumbnail_height"
android:visibility="invisible"
/>
-
- <ImageView android:id="@+id/app_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
- android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
- android:maxWidth="@dimen/status_bar_recents_app_icon_max_width"
- android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"
- android:adjustViewBounds="true"
- android:visibility="invisible"
- />
</FrameLayout>
+ <ImageView android:id="@+id/app_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
+ android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:maxWidth="@dimen/status_bar_recents_app_icon_max_width"
+ android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"
+ android:scaleType="centerInside"
+ android:adjustViewBounds="true"
+ android:visibility="invisible"
+ />
+
<TextView android:id="@+id/app_label"
android:layout_width="@dimen/status_bar_recents_app_label_width"
android:layout_height="wrap_content"
@@ -67,6 +71,7 @@
android:layout_alignLeft="@id/app_thumbnail"
android:layout_below="@id/app_thumbnail"
android:layout_marginTop="@dimen/status_bar_recents_text_description_padding"
+ android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
android:singleLine="true"
android:ellipsize="marquee"
android:visibility="invisible"
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
index 8c82eb1..3d8b9d6 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
@@ -26,32 +26,10 @@
android:paddingBottom="@dimen/status_bar_recents_item_padding">
<RelativeLayout android:id="@+id/recent_item"
+ android:layout_gravity="center_horizontal"
android:layout_height="wrap_content"
- android:layout_width="match_parent">
+ android:layout_width="wrap_content">
- <FrameLayout android:id="@+id/app_thumbnail"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
- android:background="@drawable/recents_thumbnail_bg"
- android:foreground="@drawable/recents_thumbnail_fg">
- <ImageView android:id="@+id/app_thumbnail_image"
- android:layout_width="@dimen/status_bar_recents_thumbnail_width"
- android:layout_height="@dimen/status_bar_recents_thumbnail_height"
- android:visibility="invisible"
- />
- <ImageView android:id="@+id/app_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
- android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
- android:maxWidth="@dimen/status_bar_recents_app_icon_max_width"
- android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"
- android:adjustViewBounds="true"
- />
- </FrameLayout>
<TextView android:id="@+id/app_label"
android:layout_width="@dimen/status_bar_recents_app_label_width"
android:layout_height="wrap_content"
@@ -61,12 +39,26 @@
android:scrollHorizontally="true"
android:layout_alignParentLeft="true"
android:layout_alignTop="@id/app_icon"
+ android:paddingTop="2dp"
android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
android:singleLine="true"
android:ellipsize="marquee"
android:textColor="@color/status_bar_recents_app_label_color"
/>
-
+ <FrameLayout android:id="@+id/app_thumbnail"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_toRightOf="@id/app_label"
+ android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
+ android:background="@drawable/recents_thumbnail_bg"
+ android:foreground="@drawable/recents_thumbnail_fg">
+ <ImageView android:id="@+id/app_thumbnail_image"
+ android:layout_width="@dimen/status_bar_recents_thumbnail_width"
+ android:layout_height="@dimen/status_bar_recents_thumbnail_height"
+ android:visibility="invisible"
+ />
+ </FrameLayout>
<View android:id="@+id/recents_callout_line"
android:layout_width="@dimen/status_bar_recents_app_label_width"
android:layout_height="1dip"
@@ -79,6 +71,18 @@
android:background="@drawable/recents_callout_line"
/>
+ <ImageView android:id="@+id/app_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/app_label"
+ android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
+ android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
+ android:maxWidth="@dimen/status_bar_recents_app_icon_max_width"
+ android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"
+ android:scaleType="centerInside"
+ android:adjustViewBounds="true"
+ />
+
<TextView android:id="@+id/app_description"
android:layout_width="@dimen/status_bar_recents_app_label_width"
android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml
index 6cb8799..6d70135 100644
--- a/packages/SystemUI/res/layout/global_screenshot.xml
+++ b/packages/SystemUI/res/layout/global_screenshot.xml
@@ -25,6 +25,7 @@
android:id="@+id/global_screenshot_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_gravity="center"
android:background="@drawable/global_screenshot_background"
android:visibility="gone">
<ImageView android:id="@+id/global_screenshot"
@@ -32,9 +33,4 @@
android:layout_height="wrap_content"
android:adjustViewBounds="true" />
</FrameLayout>
- <ImageView android:id="@+id/global_screenshot_flash"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#FFFFFFFF"
- android:visibility="gone" />
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index a63893e..af2c93c 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -77,7 +77,6 @@
android:layout_height="match_parent"
android:singleLine="true"
android:paddingRight="6dip"
- android:textSize="16sp"
android:gravity="center_vertical|left"
/>
</LinearLayout>
@@ -89,17 +88,19 @@
android:animationCache="false"
android:orientation="horizontal" >
<ImageSwitcher android:id="@+id/tickerIcon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_marginRight="8dip"
+ android:layout_width="@dimen/status_bar_icon_size"
+ android:layout_height="@dimen/status_bar_icon_size"
+ android:layout_marginRight="4dip"
>
<com.android.systemui.statusbar.AnimatedImageView
- android:layout_width="25dip"
- android:layout_height="25dip"
+ android:layout_width="@dimen/status_bar_icon_size"
+ android:layout_height="@dimen/status_bar_icon_size"
+ android:scaleType="center"
/>
<com.android.systemui.statusbar.AnimatedImageView
- android:layout_width="25dip"
- android:layout_height="25dip"
+ android:layout_width="@dimen/status_bar_icon_size"
+ android:layout_height="@dimen/status_bar_icon_size"
+ android:scaleType="center"
/>
</ImageSwitcher>
<com.android.systemui.statusbar.phone.TickerView android:id="@+id/tickerText"
@@ -109,13 +110,13 @@
android:paddingTop="2dip"
android:paddingRight="10dip">
<TextView
- android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
+ android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
/>
<TextView
- android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
+ android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 3e2def5..cd4e37c 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -35,7 +35,7 @@
android:background="@drawable/notification_header_bg"
>
<com.android.systemui.statusbar.policy.DateView android:id="@+id/date"
- android:textAppearance="@style/TextAppearance.StatusBar.Clock"
+ android:textAppearance="@style/TextAppearance.StatusBar.Date"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
diff --git a/packages/SystemUI/res/layout/status_bar_no_recent_apps.xml b/packages/SystemUI/res/layout/status_bar_no_recent_apps.xml
index 47ffb83..1675773 100644
--- a/packages/SystemUI/res/layout/status_bar_no_recent_apps.xml
+++ b/packages/SystemUI/res/layout/status_bar_no_recent_apps.xml
@@ -27,8 +27,8 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textSize="24dp"
- android:textColor="#ffffffff"
+ android:textSize="20dp"
+ android:textColor="@android:color/holo_blue_light"
android:text="@string/status_bar_no_recent_apps"
android:gravity="center_horizontal"
android:layout_gravity="center"
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index 3220e62..abbc89a 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -41,7 +41,7 @@
android:layout_width="match_parent"
android:layout_height="@dimen/notification_divider_height"
android:layout_alignParentBottom="true"
- android:background="@drawable/notification_item_background_color"
+ android:background="@drawable/status_bar_notification_row_background_color"
/>
</RelativeLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index f90c6cc..58c929a 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Verwyder uit lys"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Program Info"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Geen onlangse programme nie"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Maak onlangse programme toe"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 onlangse program"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d onlangse programme"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Geen kennisgewings"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Voortdurend"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Kennisgewings"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Koppel asseblief herlaaier"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Koppel asseblief herlaaier"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Die battery raak pap."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> oor"</string>
<string name="invalid_charger" msgid="4549105996740522523">"USB-laaiery nie ondersteun nie."\n"Gebruik net die laaier wat verskaf is."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"DEMP"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"OUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Kennisgewings"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Onlangs"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Geen onlangse programme nie."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Apps"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-verbind"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Stel invoermetodes op"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Stel invoermetodes op"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Gebruik fisiese sleutelbord"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Laat die program <xliff:g id="APPLICATION">%1$s</xliff:g> toe om die USB-toestel te gebruik?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Laat die program <xliff:g id="APPLICATION">%1$s</xliff:g> toe om die USB-toebehoorsel te gebruik?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Maak <xliff:g id="ACTIVITY">%1$s</xliff:g> oop wanneer hierdie USB-toestel gekoppel is?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Maak <xliff:g id="ACTIVITY">%1$s</xliff:g> oop wanneer hierdie USB-toebehoorsel gekoppel is?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Geen geïnstalleerde programme werk met hierdie USB-toebehoorsel nie. Kom meer te wete oor hierdie toebehoorsel by <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB-toebehoorsel"</string>
<string name="label_view" msgid="6304565553218192990">"Sien"</string>
<string name="always_use_device" msgid="1450287437017315906">"Gebruik by verstek vir hierdie USB-toestel"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Gebruik by verstek vir hierdie USB-toebehoorsel"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoem om skerm te vul"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Strek om skerm te vul"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Versoenbaarheid-zoem"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Versoenbaarheid-zoem"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"As \'n program vir \'n kleiner skerm ontwerp is, sal \'n zoemkontrole naby die horlosie verskyn"</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Skermkiekie in galery gestoor"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Kon nie skermkiekie stoor nie. Eksterne geheue kan dalk in gebruik wees."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB-lêeroordrag-opsies"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Heg as \'n mediaspeler (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Heg as \'n kamera (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Installeer Android-lêeroordragprogram vir Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Installeer Android-lêeroordragprogram vir Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Terug"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Tuis"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Kieslys"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Onlangse programme"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Onlangse programme"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Knoppie vir wissel van invoermetode."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Versoenbaarheid-zoem se knoppie."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoem kleiner na groter skerm."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data, twee stawe."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data, drie stawe."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Datasein vol."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Geen Wi-Fi nie."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi, een staaf."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi, twee stawe."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi, drie stawe."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi-sein vol."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Geen Wi-Fi nie."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Wi-Fi, een staaf."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi, twee stawe."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi, drie stawe."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Wi-Fi-sein vol."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"EDGE"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Geen SIM nie."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-verbinding."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Vliegtuigmodus."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> persent."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Instellingsknoppie."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Kennisgewingsknoppie."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Verwyder kennisgewing."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Stelselinstellings"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Kennisgewings"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Verwyder kennisgewing"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS geaktiveer."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS soek ligging."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter geaktiveer."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Luitoestel-vibreer."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Luitoestel stil."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G-data gedeaktiveer"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G data gedeaktiveer"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobieldata gedeaktiveer"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data gedeaktiveer"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Die gespesifiseerde datagebruiklimiet is bereik. "\n\n" Addisionele datagebruik kan lei tot diensverskafferkostes."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Die gespesifiseerde datagebruiklimiet is bereik. "\n\n" Addisionele datagebruik kan lei tot diensverskafferkostes."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Heraktiveer data"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Geen internetverbinding nie"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi gekoppel"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Soek vir GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Ligging deur GPS gestel"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Verwyder alle kennisgewings."</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 4c4b326..c726f5f 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"ከዝርዝር አስወግድ"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"የትግበራ መረጃ"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"ምንም የቅርብ ጊዜ ትግበራዎች የሉም"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"የቅርብ ጊዜ መተግበሪያዎችን አሰናብት"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 የቅርብ ጊዜ መተግበሪያ"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d የቅርብ ጊዜ መተግበሪያዎች"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"ምንም ማሳወቂያዎች የሉም"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"በመካሄድ ላይ ያለ"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"ማሳወቂያዎች"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"እባክዎ ኃይልመሙያ ያያይዙ"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"እባክዎ ኃይልመሙያ ያያይዙ"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"ባትሪው እያነሰ ነው።"</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> ቀሪ"</string>
<string name="invalid_charger" msgid="4549105996740522523">"USB ኃይል መሙያ አይታገዝም።"\n" የቀረበውን ኃይል መሙያ ብቻ ተጠቀም።"</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"ድምጽ አጥፋ"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"ራስ ሰር"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"ማሳወቂያዎች"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"የቅርብ ጊዜ"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"ምንም የቅርብ ጊዜ ትግበራዎች የሉም።"</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"ትግበራዎች"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"ብሉቱዝ አያይዝ"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"ግቤት ሜተዶችንአዋቀር"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ግቤት ሜተዶችንአዋቀር"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"የቁልፍ ሰሌዳ ተጠቀም"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"<xliff:g id="APPLICATION">%1$s</xliff:g> ትግበራ የUSB መሣሪያለመድረስ ይፈቅዳል?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"<xliff:g id="APPLICATION">%1$s</xliff:g> ትግበራ የUSB ተቀጥላለመድረስ ይፈቅዳል?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"የዚህ USB ተቀጥላ ሲያያዝ <xliff:g id="ACTIVITY">%1$s</xliff:g>ይከፈት?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"የዚህ USB ተቀጥላ ሲያያዝ <xliff:g id="ACTIVITY">%1$s</xliff:g> ይከፈት?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"ምንም የተጫኑ ትግበራዎችከዚህ የUSB ተቀጥላ ጋር አይሰሩም። በ<xliff:g id="URL">%1$s</xliff:g> ስለዚህ ተቀጥላ የበለጠ ይረዱ።"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"የUSB ተቀጥላ"</string>
<string name="label_view" msgid="6304565553218192990">"ዕይታ"</string>
<string name="always_use_device" msgid="1450287437017315906">"ለዚህ USB መሣሪያ በነባሪነት ተጠቀም"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"ለዚህ USB ተቀጥላ በነባሪነት ተጠቀም"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"ማያ እንዲሞላ አጉላ"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"ማያ ለመሙለት ሳብ"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"የተኳኋኝነት አጉላ"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"የተኳኋኝነት አጉላ"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"ትግበራ ለትንሽ ማያ ሲነደፍ፣ የአጉላ መቆመጣጠሪያ በሰዓት በኩል ብቅ ይላል።"</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"የማያፎቶዎችወደ ማዕከለ ስዕላት ተቀምጠዋል"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"የማያ ፎቶማስቀመጥ አልተቻለም። ውጫዊ ማከማቻም አገልግሎት ላይ ሊሆን ይችላል።"</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"የUSB ፋይል ሰደዳ አማራጮች"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"እንደ ማህደረ አጫዋች (MTP) ሰካ"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"እንደ ካሜራ (PTP) ሰካ"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"ለMac የAndroid ፋይል ሰደዳ ትግበራ ጫን"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"ለMac የAndroid ፋይል ሰደዳ ትግበራ ጫን"</string>
<string name="accessibility_back" msgid="567011538994429120">"ተመለስ"</string>
<string name="accessibility_home" msgid="8217216074895377641">"መነሻ"</string>
<string name="accessibility_menu" msgid="316839303324695949">"ምናሌ"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"የቅርብ ጊዜ ትግበራዎች"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"የቅርብ ጊዜ መተግበሪያዎች"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"የግቤት ሜተድ አዝራር ቀይር"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"የተኳኋኝአጉላ አዝራር።"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"አነስተኛውን ማያ ወደ ትልቅ አጉላ።"</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"የውሂብ ሁለት አሞሌዎች።"</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"የውሂብ ሦስት አሞሌዎች።"</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"የውሂብ አመልካች ሙሉ ነው።"</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"ምንም WiFi የለም።"</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"የWiFi አንድ አሞሌ።"</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"የWiFi ሁለትአሞሌዎች።"</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"የWiFi ሦስት አሞሌዎች።"</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"የWiFi አመልካች ሙሉ ነው።"</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"ምንም WiFi የለም።"</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"የWiFi አንድ አሞሌ።"</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"የWiFi ሁለትአሞሌዎች።"</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"የWiFi ሦስት አሞሌዎች።"</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"የWiFi አመልካች ሙሉ ነው።"</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"ምንም SIM የለም።"</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ብሉቱዝ ማያያዝ።"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"የአውሮፕላን ሁነታ።"</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"የባትሪ <xliff:g id="NUMBER">%d</xliff:g> መቶኛ።"</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"የቅንብሮች አዝራር።"</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"የማሳወቂያዎች አዝራር።"</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"ማሳወቂያ አስወግድ።"</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"የስርዓት ቅንጅቶች"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"ማሳወቂያዎች"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"ማሳወቂያ አጥራ"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ነቅቷል።"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS በማግኘት ላይ።"</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter ነቅቷል።"</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"የስልክ ጥሪ ይንዘር።"</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"የስልክ ጥሪ ፀጥታ።"</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G ውሂብ ቦዝኗል"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G ውሂብ ቦዝኗል"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"የተንቀሳቃሽ ውሂብ ቦዝኗል"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"ውሂብ ቦዝኗል"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"የተጠቀሰው የውሂብ አጠቃቀም ወሰን ደርሷል።"\n\n" ተጨማሪ የውሂብ አጠቃቀም የድምጸ ተያያዥ ሞደም ክፍያን ሊጨምር ይችላል።"</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"የተጠቀሰው የውሂብ አጠቃቀም ወሰን ደርሷል።"\n\n" ተጨማሪ የውሂብ አጠቃቀም የድምጸ ተያያዥ ሞደም ክፍያን ሊጨምር ይችላል።"</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"ውሂብ ድጋሚ አንቃ"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"ምንም በይነመረብ ተያያዥ የለም።"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi ተያይዟል"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"ለGPS በመፈለግ ላይ"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"በ GPS የተዘጋጀ ሥፍራ"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"ሁሉንም ማሳወቂያዎች አጽዳ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index d418957..73c06da 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"إزالة من القائمة"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"معلومات التطبيق"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"ليس هناك تطبيقات حديثة"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"إزالة التطبيقات الحديثة"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"تطبيق حديث واحد"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d من التطبيقات الحديثة"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"ليس هناك أي تنبيهات"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"مستمر"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"التنبيهات"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"الرجاء توصيل الشاحن"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"الرجاء توصيل الشاحن"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"انخفضت طاقة البطارية."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"المتبقي: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"شحن USB غير معتمد."\n"استخدم الشاحن الموفر فقط."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"كتم"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"تلقائي"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"التنبيهات"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"حديثة"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"ليس هناك أية تطبيقات حديثة."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"التطبيقات"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"تم إنشاء الاتصال بالإنترنت عن طريق البلوتوث."</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"تهيئة طرق الإدخال"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"تهيئة طرق الإدخال"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"استخدام لوحة المفاتيح الفعلية"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"هل تريد السماح للتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالدخول إلى جهاز USB؟"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"هل تريد السماح للتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالدخول إلى ملحق USB؟"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"هل تريد فتح <xliff:g id="ACTIVITY">%1$s</xliff:g> عند توصيل جهاز USB هذا؟"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"هل تريد فتح <xliff:g id="ACTIVITY">%1$s</xliff:g> عند توصيل ملحق USB هذا؟"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"لا يعمل أي تطبيق مثبت مع ملحق UEB هذا. تعرف على المزيد عن هذا الملحق على <xliff:g id="URL">%1$s</xliff:g>."</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"ملحق USB"</string>
<string name="label_view" msgid="6304565553218192990">"عرض"</string>
<string name="always_use_device" msgid="1450287437017315906">"الاستخدام بشكل افتراضي لجهاز USB هذا"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"الاستخدام بشكل افتراضي لملحق USB هذا"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"تكبير/تصغير لملء الشاشة"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"توسيع بملء الشاشة"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"تكبير/تصغير التوافق"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"تكبير/تصغير التوافق"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"عند تصميم تطبيق لشاشة أصغر، سيظهر عنصر تحكم في التكبير/التصغير بجوار الساعة."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"تم حفظ لقطة الشاشة في معرض الصور."</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"تعذر حفظ لقطة الشاشة. قد يكون التخزين الخارجي قيد الاستخدام."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"خيارات نقل الملفات عبر USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"تحميل كمشغل وسائط (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"تحميل ككاميرا (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"تثبيت تطبيق Android File Transfer لـ Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"تثبيت تطبيق Android File Transfer لـ Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"رجوع"</string>
<string name="accessibility_home" msgid="8217216074895377641">"الرئيسية"</string>
<string name="accessibility_menu" msgid="316839303324695949">"القائمة"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"التطبيقات الحديثة"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"التطبيقات الحديثة"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"زر تبديل طريقة الإدخال."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"زر تكبير/تصغير للتوافق."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"استخدام التكبير/التصغير لتحويل شاشة صغيرة إلى شاشة أكبر"</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"إشارة البيانات تتكون من شريطين."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"إشارة البيانات تتكون من ثلاثة أشرطة."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"إشارة البيانات كاملة."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"ليست هناك إشارة WiFi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"إشارة WiFi تتكون من شريط واحد."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"إشارة WiFi تتكون من شريطين."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"إشارة WiFi تتكون من ثلاثة أشرطة."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"إشارة WiFi كاملة."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"ليست هناك إشارة WiFi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"إشارة WiFi تتكون من شريط واحد."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"إشارة WiFi تتكون من شريطين."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"إشارة WiFi تتكون من ثلاثة أشرطة."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"إشارة WiFi كاملة."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"شبكة الجيل الثالث"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"شبكة 3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"شبكة الجيل الرابع"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"ليست هناك بطاقة SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ربط البلوتوث."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"وضع الطائرة."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"مستوى البطارية <xliff:g id="NUMBER">%d</xliff:g> في المائة."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"زر الإعدادات."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"زر التنبيهات."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"إزالة التنبيه."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"إعدادات النظام."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"الإشعارات."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"محو الإشعار."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"تم تمكين GPS."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"الحصول على GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"تم تمكين المبرقة الكاتبة."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"رنين مع الاهتزاز."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"رنين صامت."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"تم تعطيل بيانات شبكات الجيل الثاني والجيل الثالث"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"تم تعطيل بيانات شبكة الجيل الرابع"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"تم تعطيل بيانات الجوال"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"تم تعطيل البيانات"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"تم بلوغ الحد المحدد لاستخدام البيانات."\n\n"قد يؤدي الاستخدام الإضافي للبيانات إلى تحصيل رسوم من قبل مشغل شبكة الجوال."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"تم بلوغ الحد المحدد لاستخدام البيانات."\n\n"قد يؤدي الاستخدام الإضافي للبيانات إلى تحصيل رسوم من قبل مشغل شبكة الجوال."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"إعادة تمكين البيانات"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"لا يوجد اتصال إنترنت"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi متصل"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"جارٍ البحث عن GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"تم تعيين الموقع بواسطة GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"محو جميع الإشعارات."</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 586b976..f151572 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Премахване от списъка"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Информация за приложението"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Няма скорошни приложения"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Отхвърляне на скорошните приложения"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 скорошно приложение"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d скорошни приложения"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Няма известия"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"В момента"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Известия"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Моля, включете зарядно устройство"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Моля, включете зарядно устройство"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Батерията се изтощава."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"Остава: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Не се поддържа зареждане през USB."\n"Използвайте само доставеното зарядно устройство."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"БЕЗ"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"АВТ."</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Известия"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Скорошни"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Няма скорошни приложения."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Приложения"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth има връзка с тетъринг"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Конфигуриране на въвеждането"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Конфигуриране на въвеждането"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Използване на физ. клав."</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Да се разреши ли на приложението <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до USB устройството?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Да се разреши ли на приложението <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до аксесоара за USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Да се отвори ли <xliff:g id="ACTIVITY">%1$s</xliff:g>, когато това USB устройство е свързано?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Да се отвори ли <xliff:g id="ACTIVITY">%1$s</xliff:g>, когато този аксесоар за USB е свързан?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Инсталираните приложения не работят с този аксесоар за USB. Научете повече на адрес <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Аксесоар за USB"</string>
<string name="label_view" msgid="6304565553218192990">"Преглед"</string>
<string name="always_use_device" msgid="1450287437017315906">"Използване по подразб. за това USB устройство"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Използване по подразб. за този аксесоар за USB"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Мащаб – запълва екрана"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Разпъване – запълва екрана"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Промяна на мащаба за съвместимост"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Промяна на мащаба за съвместимост"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Когато дадено приложение е създадено за по-малък екран, до часовника ще се покаже управление за промяна на мащаба."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Екранната снимка е запазена в галерията"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Екранната снимка не можа да бъде запазена. Възможно е външното хранилище да се използва."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Опции за пренос на файлове чрез USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Свързване като медиен плейър (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Свързване като камера (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Инсталиране на Android File Transfer за Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Инсталиране на Android File Transfer за Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Назад"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Начало"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Меню"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Скорошни приложения"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Скорошни приложения"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Бутон за превключване на метода на въвеждане."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Бутон за промяна на мащаба с цел съвместимост."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Промяна на мащаба на екрана от по-малък до по-голям."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Данните са с две чертички."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Данните са с три чертички."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Сигналът за данни е пълен."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Няма WiFi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"WiFi е с една чертичка."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"WiFi е с две чертички."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi е с три чертички."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Сигналът за WiFi е пълен."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Няма WiFi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"WiFi е с една чертичка."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"WiFi е с две чертички."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"WiFi е с три чертички."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Сигналът за WiFi е пълен."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Няма SIM карта."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Тетъринг през Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Самолетен режим."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> процента батерия."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Бутон за настройки."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Бутон за известия."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Премахване на известие."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Системни настройки."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Известия."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Изчистване на известието."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS е активиран."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS се придобива."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter бе активиран."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Вибрира при звънене."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Звънът е заглушен."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G данните са деактивирани"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G данните са деактивирани"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Мобилните данни са деактивирани"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Трафикът на данни е деактивиран"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Определеният лимит за използване на данни е достигнат."\n\n"Допълнителната употреба може да доведе до таксуване от оператора."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Определеният лимит за използване на данни е достигнат."\n\n"Допълнителната употреба може да доведе до таксуване от оператора."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Активиране на данните отново"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Няма връзка с интернет"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: Има връзка"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Търси се GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Местоположението е зададено от GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Изчистване на всички известия."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 275db65..317ea2a 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Elimina de la llista"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informació de l\'aplicació"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"No hi ha aplicacions recents"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Omet les aplicacions recents"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"Una aplicació recent"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d aplicacions recents"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Cap notificació"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Continu"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificacions"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Connecteu el carregador"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Connecteu el carregador"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"La bateria comença a estar baixa."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restant"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Càrrega d\'USB no admesa."\n"Utilitza només el carregador proporcionat."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"Silen."</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTOM."</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificacions"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Recents"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"No hi ha aplicacions recents."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Apps"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth sense fil"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configura mètodes d\'entrada"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configura mètodes d\'entrada"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilitza un teclat físic"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Vols permetre que l\'aplicació <xliff:g id="APPLICATION">%1$s</xliff:g> accedeixi al dispositiu USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Vols permetre que l\'aplicació <xliff:g id="APPLICATION">%1$s</xliff:g> accedeixi a l\'accessori USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vols que s\'obri <xliff:g id="ACTIVITY">%1$s</xliff:g> quan aquest dispositiu USB estigui connectat?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Vols que s\'obri <xliff:g id="ACTIVITY">%1$s</xliff:g> quan aquest accessori USB estigui connectat?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Cap de les aplicacions instal·lades no funciona amb aquest accessori USB. Més informació a <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Accessori USB"</string>
<string name="label_view" msgid="6304565553218192990">"Mostra"</string>
<string name="always_use_device" msgid="1450287437017315906">"Utilitza de manera predet. per al dispositiu USB"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Utilitza de manera predet. per a l\'accessori USB"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoom per omplir pantalla"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Estira per omplir pant."</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom de compatibilitat"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom de compatibilitat"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Quan una aplicació s\'hagi dissenyat per a una pantalla més petita, apareixerà un control de zoom al costat del rellotge."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Captura de pantalla desada a la galeria"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"No s\'ha pogut desar la captura de pantalla. És possible que l\'emmagatzematge extern estigui en ús."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opcions transf. fitxers USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Munta com a reproductor multimèdia (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Munta com a càmera (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Instal·la aplic. transf. fitxers Android per a Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Instal·la aplic. transf. fitxers Android per a Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Enrere"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Pàgina d\'inici"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menú"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Aplicacions recents"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Aplicacions recents"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Botó de canvi del mètode d\'entrada."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botó de zoom de compatibilitat."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Amplia menys com més gran sigui la pantalla."</string>
@@ -90,40 +107,43 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Senyal de dades: dues barres."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Senyal de dades: tres barres."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Senyal de dades: complet."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Senyal Wi-Fi: no n\'hi ha"</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Senyal Wi-Fi: una barra."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Senyal Wi-Fi: dues barres."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Senyal Wi-Fi: tres barres."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Senyal Wi-Fi: complet."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Senyal Wi-Fi: no n\'hi ha"</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Senyal Wi-Fi: una barra."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Senyal Wi-Fi: dues barres."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Senyal Wi-Fi: tres barres."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Senyal Wi-Fi: complet."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Vora"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"No hi ha cap targeta SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Connexió Bluetooth mitjançant dispositiu portàtil"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode d\'avió."</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Botó Configuració."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Botó de notificacions."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Elimina la notificació."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Configuració del sistema."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificacions."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Esborra la notificació."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS activat."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"S\'està adquirint el GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Teletip activat."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Mode vibració."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Mode silenci."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Dades 2G-3G desactivades"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dades 4G desactivades"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Dades mòbils desactivades"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Dades desactivades"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"S\'ha assolit el límit d\'ús de dades especificat."\n\n"Si s\'utilitzen més dades, l\'operador hi podria aplicar càrrecs."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"S\'ha assolit el límit d\'ús de dades especificat."\n\n"Si s\'utilitzen més dades, l\'operador hi podria aplicar càrrecs."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Torna a activar les dades"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"No hi ha connexió a Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: connectada"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"S\'està cercant un GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"S\'ha establert la ubicació per GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Esborra totes les notificacions."</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 238a770..a6d0986 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Odebrat ze seznamu"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informace o aplikaci"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Žádné nové aplikace"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Zavřít nové aplikace"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 nová aplikace"</item>
+ <item quantity="other" msgid="1040784359794890744">"nové aplikace: %d"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Žádná oznámení"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Probíhající"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Oznámení"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Prosím připojte dobíjecí zařízení"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Prosím připojte dobíjecí zařízení"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Baterie je vybitá."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"Zbývá <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Nabíjení pomocí rozhraní USB není podporováno."\n"Používejte pouze nabíječku, která byla dodána se zařízením."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"ZTLUM."</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTOM."</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Oznámení"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Nejnovější"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Žádné nedávno použité aplikace."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplikace"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Datové připojení Bluetooth se sdílí"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Nakonfigurovat metody vstupu"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Nakonfigurovat metody vstupu"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Použít fyz. klávesnici"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k zařízení USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k perifernímu zařízení USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Chcete při připojení tohoto zařízení USB otevřít aplikaci <xliff:g id="ACTIVITY">%1$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Chcete při připojení tohoto periferního zařízení USB otevřít aplikaci <xliff:g id="ACTIVITY">%1$s</xliff:g>?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"S tímto periferním zařízením USB nefunguje žádná nainstalovaná aplikace. Další informace naleznete na stránkách <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Periferní zařízení USB"</string>
<string name="label_view" msgid="6304565553218192990">"Zobrazit"</string>
<string name="always_use_device" msgid="1450287437017315906">"Pro toto zařízení USB použít jako výchozí"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Pro toto periferní zařízení USB použít jako výchozí"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Přiblížit na celou obrazovku"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Na celou obrazovku"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Kompatibilní přiblížení"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Kompatibilní přiblížení"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Pokud je aplikace navržena pro menší obrazovku, zobrazí se vedle hodin ovládací prvek přiblížení."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Snímek obrazovky byl uložen do Galerie"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Snímek obrazovky se nepodařilo uložit. Je možné, že se externí úložiště právě používá."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Možnosti přenosu souborů pomocí rozhraní USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Připojit jako přehrávač médií (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Připojit jako fotoaparát (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Instalovat aplikaci Android File Transfer pro Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Instalovat aplikaci Android File Transfer pro Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Zpět"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Domů"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Naposledy použité aplikace"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Nové aplikace"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Tlačítko přepnutí metody vstupu"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Tlačítko úpravy velikosti z důvodu kompatibility"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zvětšit menší obrázek na větší obrazovku."</string>
@@ -90,40 +107,43 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Dvě čárky signálu datové sítě."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Tři čárky signálu datové sítě."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Plný signál datové sítě."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Síť Wi-Fi není dostupná."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Jedna čárka signálu sítě Wi-Fi."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Dvě čárky signálu sítě Wi-Fi."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Tři čárky signálu sítě Wi-Fi."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Plný signál sítě Wi-Fi."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Síť Wi-Fi není dostupná."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Jedna čárka signálu sítě Wi-Fi."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Dvě čárky signálu sítě Wi-Fi."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Tři čárky signálu sítě Wi-Fi."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Plný signál sítě Wi-Fi."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Žádná karta SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Tethering přes Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Režim V letadle."</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Tlačítko Nastavení."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Tlačítko upozornění."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Odebrat oznámení"</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Systémová nastavení."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Oznámení."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Vymazat oznámení."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS je povoleno."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Zaměřování GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Rozhraní TeleTypewriter zapnuto."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibrační vyzvánění."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Tiché vyzvánění."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Datové přenosy 2G a 3G jsou zakázány"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datové přenosy 4G jsou zakázány"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilní data jsou zakázána"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Přenos dat vypnut"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Dosáhli jste zadaného limitu množství přenesených dat."\n\n"Za další datové přenosy vám operátor může účtovat poplatky."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Dosáhli jste zadaného limitu množství přenesených dat."\n\n"Za další datové přenosy vám operátor může účtovat poplatky."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Znovu povolit data"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Žádné přip. k internetu"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: připojeno"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Vyhledávání satelitů GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Poloha nastavena pomocí systému GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazat všechna oznámení."</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 1d004f9..156e557 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Fjern fra listen"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Oplysninger om appen"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Der er ingen seneste apps"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Afvis de seneste apps"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 seneste app"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d seneste apps"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ingen meddelelser"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"I gang"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Meddelelser"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Forbind oplader"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Forbind oplader"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Batteriet er ved at være fladt."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> tilbage"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Opladning via USB understøttes ikke."\n"Brug kun den medfølgende oplader."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"LYDLØS"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Meddelelser"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Seneste"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Der er ingen nye applikationer."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Programmer"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-tethering anvendt"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurer inputmetoder"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurer inputmetoder"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Brug fysisk tastatur"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Vil du tillade, at applikationen <xliff:g id="APPLICATION">%1$s</xliff:g> får adgang til USB-enheden?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Vil du tillade, at applikationen <xliff:g id="APPLICATION">%1$s</xliff:g> får adgang til USB-ekstraudstyret?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vil du åbne <xliff:g id="ACTIVITY">%1$s</xliff:g>, når denne USB-enhed er tilsluttet?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Vil du åbne <xliff:g id="ACTIVITY">%1$s</xliff:g>, når dette USB-ekstraudstyr er tilsluttet?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Ingen inst. applikationer virker med USB-ekstraudstyret. Få oplysninger om ekstraudstyret på <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB-ekstraudstyr"</string>
<string name="label_view" msgid="6304565553218192990">"Vis"</string>
<string name="always_use_device" msgid="1450287437017315906">"Brug som standard til denne USB-enhed"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Brug som standard til dette USB-tilbehør"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoom til fuld skærm"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Stræk til fuld skærm"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Kompatibilitetszoom"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Kompatibilitetszoom"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Når en app er udviklet til en mindre skærm, vises der en zoomfunktion ved uret."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Skærmbilledet gemmes i Galleri"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Kunne ikke gemme skærmbillede. Ekstern lagring kan være i brug."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Muligheder for USB-filoverførsel"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Isæt som en medieafspiller (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Isæt som et kamera (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Installer appen Android File Transfer Manager til Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Installer appen Android File Transfer Manager til Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Tilbage"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Startside"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Seneste applikationer"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Seneste apps"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Skift indtastningsmetode-knappen."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Knap for kompatibilitetszoom."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom mindre til større skærm."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data to bjælker."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data tre bjælker."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Datasignal fuldt."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Ingen Wi-Fi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi en bjælke."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi to bjælker."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi tre bjælker."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi-signal fuldt."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Ingen Wi-Fi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Wi-Fi en bjælke."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi to bjælker."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi tre bjælker."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Wi-Fi-signal fuldt."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Intet SIM-kort."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-netdeling."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Flytilstand."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Batteri <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Knappen Indstillinger."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Knappen Meddelelser."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Fjern meddelelse."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Systemindstillinger."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Meddelelser."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Ryd meddelelse."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS aktiveret."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS samler data."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter aktiveret."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Ringervibration."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Lydløs."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G-data er deaktiveret"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-data er deaktiveret"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobildata er deaktiveret"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data er deaktiveret"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Den angivne grænse for dataforbrug er nået."\n\n"Yderligere dataforbrug kan koste ekstra hos mobilselskabet."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Den angivne grænse for dataforbrug er nået."\n\n"Yderligere dataforbrug kan koste ekstra hos mobilselskabet."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Genaktiver data"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Ingen internetforb."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi er forbundet"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Søger efter GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Placeringen er angivet ved hjælp af GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Ryd alle meddelelser."</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index ee00670..d1500ca 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Aus Liste entfernen"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"App-Info"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Keine neuen Apps"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Kürzlich verwendete Apps schließen"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 kürzlich verwendete App"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d kürzlich verwendete Apps"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Keine Benachrichtigungen"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Aktuell"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Benachrichtigungen"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Ladegerät anschließen"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Ladegerät anschließen"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Akku ist fast leer."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"Noch <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"USB-Aufladung wird nicht unterstützt."\n"Verwenden Sie das mitgelieferte Aufladegerät."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"STUMM"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Benachrichtigungen"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Zuletzt verwendet"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Keine zuletzt verwendeten Anwendungen"</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Google Apps"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-Tethering aktiv"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Eingabemethoden konfigurieren"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Eingabemethoden konfigurieren"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Physische Tastatur"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"App <xliff:g id="APPLICATION">%1$s</xliff:g> Zugriff auf USB-Gerät gewähren?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"App <xliff:g id="APPLICATION">%1$s</xliff:g> Zugriff auf USB-Zubehör gewähren?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"<xliff:g id="ACTIVITY">%1$s</xliff:g> öffnen, wenn dieses USB-Gerät verbunden ist?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"<xliff:g id="ACTIVITY">%1$s</xliff:g> öffnen, wenn dieses USB-Zubehör verbunden ist?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Keine installierten Anwendungen für dieses USB-Zubehör. Weitere Informationen unter <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB-Zubehör"</string>
<string name="label_view" msgid="6304565553218192990">"Anzeigen"</string>
<string name="always_use_device" msgid="1450287437017315906">"Standardmäßig für dieses USB-Gerät verwenden"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Standardmäßig für dieses USB-Zubehör verwenden"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoom auf Bildschirmgröße"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Auf Bildschirmgröße anpassen"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Kompatibilitätszoom"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Kompatibilitätszoom"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Wenn eine App für einen kleineren Bildschirm ausgelegt ist, wird ein Zoom-Steuerelement neben der Uhr angezeigt."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Screenshot in Galerie gespeichert"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Screenshot konnte nicht gespeichert werden. Möglicherweise wird der externe Speicher gerade verwendet."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB-Dateiübertragungsoptionen"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Als Medienplayer (MTP) bereitstellen"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Als Kamera (PTP) bereitstellen"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"App \"Android File Transfer\" für Mac installieren"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"App \"Android File Transfer\" für Mac installieren"</string>
<string name="accessibility_back" msgid="567011538994429120">"Zurück"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Startbildschirm"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menü"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Zuletzt verwendete Apps"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Kürzlich verwendete Apps"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Schaltfläche zum Ändern der Eingabemethode"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Schaltfläche für Kompatibilitätszoom"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom auf einen größeren Bildschirm"</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Datensignal - zwei Balken"</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Datensignal - drei Balken"</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Volle Datensignalstärke"</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Kein WLAN"</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"WLAN - ein Balken"</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"WLAN - zwei Balken"</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WLAN - drei Balken"</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Volle WLAN-Signalstärke"</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Kein WLAN"</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"WLAN - ein Balken"</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"WLAN - zwei Balken"</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"WLAN - drei Balken"</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Volle WLAN-Signalstärke"</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WLAN"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WLAN"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Keine SIM-Karte"</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-Tethering"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Flugmodus"</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Akku bei <xliff:g id="NUMBER">%d</xliff:g> Prozent"</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Schaltfläche für Einstellungen"</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Benachrichtigungsschaltfläche"</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Benachrichtigung entfernen"</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Systemeinstellungen"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Benachrichtigungen"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Benachrichtigung löschen"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS aktiviert"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS-Signal abrufen"</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Schreibtelefonie aktiviert"</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Klingeltonmodus \"Vibration\""</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Klingelton lautlos"</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-/3G-Daten deaktiviert"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-Daten deaktiviert"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobile Daten deaktiviert"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Daten deaktiviert"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Das für die Datennutzung festgelegte Limit wurde erreicht."\n\n"Eine weitere Datennutzung kann mit zusätzlichen Kosten vonseiten des Mobilfunkanbieters verbunden sein."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Das für die Datennutzung festgelegte Limit wurde erreicht."\n\n"Eine weitere Datennutzung kann mit zusätzlichen Kosten vonseiten des Mobilfunkanbieters verbunden sein."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Daten erneut aktivieren"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Keine Internetverbindung"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"WLAN verbunden"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS wird gesucht"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Standort durch GPS festgelegt"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Alle Benachrichtigungen löschen"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 6db0d3c..62c0802 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Κατάργηση από τη λίστα"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Πληροφορίες εφαρμογής"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Δεν υπάρχουν πρόσφατες εφαρμογές"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Παράβλεψη πρόσφατων εφαρμογών"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 πρόσφατη εφαρμογή"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d πρόσφατες εφαρμογές"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Δεν υπάρχουν ειδοποιήσεις"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Εν εξελίξει"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Ειδοποιήσεις"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Συνδέστε τον φορτιστή"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Συνδέστε τον φορτιστή"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Η στάθμη της μπαταρίας είναι χαμηλή."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"Απομένει <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Δεν υποστηρίζεται η φόρτιση USB."\n"Χρησιμοποιείτε μόνο τον φορτιστή που παρέχεται."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"ΣΙΓΑΣΗ"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"ΑΥΤΟΜ."</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Ειδοποιήσεις"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Πρόσφατα"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Δεν υπάρχουν πρόσφατες εφαρμογές."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Google Apps"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Έγινε σύνδεση μέσω Bluetooth"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Διαμόρφωση μεθόδων εισαγωγής"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Διαμόρφωση μεθόδων εισαγωγής"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Χρήση κανονικού πληκτρολ."</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στη συσκευή USB;"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στο αξεσουάρ USB;"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Άνοιγμα του <xliff:g id="ACTIVITY">%1$s</xliff:g> κατά τη σύνδεση αυτής της συσκευής USB;"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Άνοιγμα του <xliff:g id="ACTIVITY">%1$s</xliff:g> κατά τη σύνδεση αυτού του αξεσουάρ USB;"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Καμία εγκατ. εφαρμ. δεν συνεργ. με το αξ. USB. Μάθετε περισ. για το αξ. στο <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Αξεσουάρ USB"</string>
<string name="label_view" msgid="6304565553218192990">"Προβολή"</string>
<string name="always_use_device" msgid="1450287437017315906">"Χρήση από προεπιλογή για αυτή τη συσκευή USB"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Χρήση από προεπιλογή για αυτό το εξάρτημα USB"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Ζουμ σε πλήρη οθόνη"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Προβoλή σε πλήρη οθ."</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Ζουμ για συμβατότητα"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Ζουμ για συμβατότητα"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Όταν μια εφαρμογή έχει σχεδιαστεί για προβολή σε μικρότερη οθόνη, δίπλα από το ρολόι θα εμφανιστεί ένα στοιχείο ελέγχου ζουμ."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Το στιγμιότυπο οθόνης αποθηκεύτηκε στη συλλογή"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Δεν ήταν δυνατή η αποθήκευση στιγμιότυπου οθόνης. Μπορεί να χρησιμοποιείται εξωτερικός χώρος αποθήκευσης."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Επιλογές μεταφοράς αρχείων μέσω USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Προσάρτηση ως μονάδας αναπαραγωγής μέσων (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Προσάρτηση ως κάμερας (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Εγκατάσταση της εφαρμογής μεταφοράς αρχείων Android για Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Εγκατάσταση της εφαρμογής μεταφοράς αρχείων Android για Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Πίσω"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Αρχική σελίδα"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Μενού"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Πρόσφατες εφαρμογές"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Πρόσφατες εφαρμογές"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Κουμπί εναλλαγής μεθόδου εισόδου"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Κουμπί εστίασης συμβατότητας."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Ζουμ από μικρότερη σε μεγαλύτερη οθόνη."</string>
@@ -90,40 +107,43 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Δύο γραμμές δεδομένων."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Τρεις γραμμές δεδομένων."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Πλήρες σήμα δεδομένων."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Δεν υπάρχει WiFi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Μία γραμμή WiFi."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Δύο γραμμές WiFi."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Τρεις γραμμές WiFi."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Πλήρες σήμα WiFi."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Δεν υπάρχει WiFi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Μία γραμμή WiFi."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Δύο γραμμές WiFi."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Τρεις γραμμές WiFi."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Πλήρες σήμα WiFi."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Δεν υπάρχει SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth tethering"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Λειτουργία πτήσης."</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Κουμπί ρυθμίσεων."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Κουμπί ειδοοποιήσεων"</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Κατάργηση ειδοποίησης."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Ρυθμίσεις συστήματος."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Ειδοποιήσεις."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Εκκαθάριση ειδοποίησης."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"Το GPS ενεργοποιήθηκε."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Προσδιορισμός GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Το TeleTypewriter ενεργοποιήθηκε."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Δόνηση ειδοποίησης ήχου."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Ειδοποίηση ήχου στο αθόρυβο."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Τα δεδομένα 2G-3G απενεργοποιήθηκαν"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Τα δεδομένα 4G απενεργοποιήθηκαν"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Τα δεδομένα κινητής τηλεφωνίας απενεργοποιήθηκαν"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Απενεργοποιήθηκαν τα δεδομένα"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Το καθορισμένο όριο χρήσης δεδομένων συμπληρώθηκε."\n\n"Πρόσθετη χρήση δεδομένων ενδέχεται να επιφέρει χρεώσεις από την εταιρεία κινητής τηλεφωνίας."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Το καθορισμένο όριο χρήσης δεδομένων συμπληρώθηκε."\n\n"Πρόσθετη χρήση δεδομένων ενδέχεται να επιφέρει χρεώσεις από την εταιρεία κινητής τηλεφωνίας."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Νέα ενεργοποίηση δεδομένων"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Χωρ. σύνδ. στο Διαδ."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi συνδεδεμένο"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Αναζήτηση για GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Ρύθμιση τοποθεσίας με GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Εκκαθάριση όλων των ειδοποιήσεων."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 61d497f..e675804 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Remove from list"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"App info"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"No recent apps"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Dismiss recent apps"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 recent app"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d recent apps"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No notifications"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Ongoing"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notifications"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Please connect charger"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Please connect charger"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"The battery is getting low."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> remaining"</string>
<string name="invalid_charger" msgid="4549105996740522523">"USB charging not supported."\n"Use only the supplied charger."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"MUTE"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notifications"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Recent"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"No recent applications."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Apps"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tethered"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configure input methods"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configure input methods"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Use physical keyboard"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Allow the application <xliff:g id="APPLICATION">%1$s</xliff:g> to access the USB device?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Allow the application <xliff:g id="APPLICATION">%1$s</xliff:g> to access the USB accessory?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Open <xliff:g id="ACTIVITY">%1$s</xliff:g> when this USB device is connected?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Open <xliff:g id="ACTIVITY">%1$s</xliff:g> when this USB accessory is connected?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"No installed applications work with this USB accessory. Learn more about this accessory at <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB accessory"</string>
<string name="label_view" msgid="6304565553218192990">"View"</string>
<string name="always_use_device" msgid="1450287437017315906">"Use by default for this USB device"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Use by default for this USB accessory"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoom to fill screen"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Stretch to fill screen"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Compatibility Zoom"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Compatibility Zoom"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"When an app was designed for a smaller screen, a zoom control will appear by the clock."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Screenshot saved to Gallery"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Could not save screenshot. External storage may be in use."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Mount as a media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Mount as a camera (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Install Android File Transfer application for Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Install Android File Transfer application for Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Back"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Home"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Recent applications"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Recent apps"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Switch input method button."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Compatibility zoom button."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom smaller to larger screen."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data two bars."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data three bars."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Data signal full."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"No Wi-Fi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi one bar."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi two bars."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi three bars."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi signal full."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"No Wi-Fi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Wi-Fi one bar."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi two bars."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi three bars."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Wi-Fi signal full."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"No SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth tethering"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Airplane mode"</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Settings button."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Notifications button."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Remove notification."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"System settings"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Clear notification."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS enabled."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS acquiring."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter enabled."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Ringer vibrate."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Ringer silent."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G data disabled"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G data disabled"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobile data disabled"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data disabled"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"The specified data usage limit has been reached."\n\n"Additional data use may incur operator charges."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"The specified data usage limit has been reached."\n\n"Additional data use may incur operator charges."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Reenable data"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"No Internet connection"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi connected"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Searching for GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Location set by GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Clear all notifications."</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 050f72e..297a307 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Eliminar de la lista"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Información de la aplicación"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Ninguna aplicación reciente"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Rechazar aplicaciones recientes"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 aplicación reciente"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d aplicaciones recientes"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No hay notificaciones"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Continuo"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificaciones"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Conecta el cargador"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Conecta el cargador"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Hay poca batería."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"Quedan <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"No admite la carga USB."\n"Usa sólo el cargador provisto."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"SILENC"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificaciones"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Reciente"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"No hay aplicaciones recientes."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplicaciones"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth anclado"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurar métodos de entrada"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos de entrada"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Usar teclado físico"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"¿Permitir la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> para acceder al dispositivo USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"¿Permitir la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> para acceder al accesorio USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"¿Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> cuando este dispositivo USB esté conectado?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"¿Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> cuando este accesorio USB esté conectado?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Las aplicaciones instaladas no funcionan con este accesorio USB. Obtener más información acerca de este accesorio en <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Accesorio USB"</string>
<string name="label_view" msgid="6304565553218192990">"Ver"</string>
<string name="always_use_device" msgid="1450287437017315906">"Se usa de forma predeterminada para este dispositivo USB."</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Se usa de forma predeterminada para este accesorio USB."</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoom para ocupar la pantalla"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Estirar p/ ocupar la pantalla"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom de compatibilidad"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom de compatibilidad"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Cuando una aplicación fue diseñada para una pantalla más pequeña, aparece un control de zoom junto al reloj."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Captura de pantalla guardada en la Galería"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"No se pudo guardar la captura de pantalla. Es posible que el almacenamiento externo esté en uso."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opciones de transferencia de archivos por USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Activar como reproductor de medios (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Activar como cámara (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Instalar la aplicación para transferir archivos de Android para Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Instalar la aplicación para transferir archivos de Android para Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Atrás"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Página principal"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menú"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Aplicaciones recientes"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Aplicaciones recientes"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Botón Cambiar método de entrada"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botón de zoom de compatibilidad"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de pantalla más pequeña a más grande"</string>
@@ -90,40 +107,43 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Dos barras de datos"</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Tres barras de datos"</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Señal de datos completa"</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"No hay Wi-Fi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Una barra de Wi-Fi"</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Dos barras de Wi-Fi"</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Tres barras de Wi-Fi"</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Señal de Wi-Fi completa"</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"No hay Wi-Fi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Una barra de Wi-Fi"</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Dos barras de Wi-Fi"</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Tres barras de Wi-Fi"</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Señal de Wi-Fi completa"</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"No hay tarjeta SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Conexión mediante Bluetooth"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo de avión"</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Botón de configuración"</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Botón de notificaciones"</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Eliminar notificación"</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Configuración del sistema"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificaciones"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Borrar notificación"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS habilitado"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Adquisición de GPS"</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter habilitado"</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Timbre en vibración"</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Timbre en silencio"</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Datos de 2G-3G inhabilitados"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datos de 4G inhabilitados"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Se inhabilitaron los datos móviles"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Datos inhabilitados"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Se ha alcanzado el límite de uso de datos especificado."\n\n"El uso de datos adicionales puede conllevar cargos para el proveedor."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Se ha alcanzado el límite de uso de datos especificado."\n\n"El uso de datos adicionales puede conllevar cargos para el proveedor."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Volver a habilitar datos"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Sin conexión a Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi conectado"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Buscando GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"La ubicación se estableció por GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Borrar todas las notificaciones"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index f4c1be9..5322212 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Eliminar de la lista"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Información de la aplicación"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"No hay aplicaciones recientes."</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Ignorar aplicaciones recientes"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 aplicación reciente"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d aplicaciones recientes"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No tienes notificaciones"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Entrante"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificaciones"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Conecta el cargador"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Conecta el cargador"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Se está agotando la batería."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restante"</string>
<string name="invalid_charger" msgid="4549105996740522523">"No se admite la carga por USB."\n"Utiliza solo el cargador proporcionado."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"SILENC"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificaciones"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Reciente"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"No hay aplicaciones recientes."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplicaciones"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth anclado"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurar métodos de introducción"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos de introducción"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizar teclado físico"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"¿Permitir que la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> acceda al dispositivo USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"¿Permitir que la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> acceda al accesorio USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"¿Quieres abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> al conectar este dispositivo USB?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"¿Quieres abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> al conectar este accesorio USB?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Ninguna aplicación instalada funciona con este accesorio USB. Más información: <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Accesorio USB"</string>
<string name="label_view" msgid="6304565553218192990">"Ver"</string>
<string name="always_use_device" msgid="1450287437017315906">"Usar de forma predeterminada para este dispositivo USB"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Usar de forma predeterminada para este accesorio USB"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoom para ajustar"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Expandir para ajustar"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom de compatibilidad"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom de compatibilidad"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Si la aplicación se ha diseñado para una pantalla más pequeña, aparecerá un control de zoom junto al reloj."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Captura de pantalla guardada en la galería"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"No se ha podido guardar la captura de pantalla. Es posible que el almacenamiento externo esté en uso."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opciones de transferencia de archivos por USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Activar como reproductor de medios (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Activar como cámara (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Instalar Android File Transfer para Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Instalar Android File Transfer para Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Atrás"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Inicio"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menú"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Aplicaciones recientes"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Aplicaciones recientes"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Botón Cambiar método de introducción"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botón de zoom de compatibilidad"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de pantalla más pequeña a más grande"</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Dos barras de datos"</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Tres barras de datos"</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Señal de datos al máximo"</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Sin redes Wi-Fi"</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Una barra de Wi-Fi"</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Dos barras de Wi-Fi"</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Tres barras de Wi-Fi"</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Señal de Wi-Fi al máximo"</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Sin redes Wi-Fi"</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Una barra de Wi-Fi"</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Dos barras de Wi-Fi"</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Tres barras de Wi-Fi"</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Señal de Wi-Fi al máximo"</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5 G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Tipo Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Sin tarjeta SIM"</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Anclaje de Bluetooth"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo avión"</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> por ciento de batería"</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Botón de ajustes"</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Botón de notificaciones"</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Eliminar notificación"</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Ajustes del sistema"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificaciones"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Borrar notificación"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS habilitado"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Obteniendo ubicación..."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Teletipo habilitado"</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Modo vibración"</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Modo silencio"</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Datos 2G-3G inhabilitados"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datos 4G inhabilitados"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Datos móviles inhabilitados"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Datos inhabilitados"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Se ha alcanzado el límite de uso de datos especificado."\n\n"Se pueden aplicar cargos adicionales si utilizas más datos."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Se ha alcanzado el límite de uso de datos especificado."\n\n"Se pueden aplicar cargos adicionales si utilizas más datos."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Volver a habilitar los datos"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Sin conexión a Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Con conexión Wi-Fi"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Buscando GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Ubicación definida por GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Borrar todas las notificaciones"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 04ff8bd0..c6e0dff 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"حذف از لیست"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"اطلاعات برنامه"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"برنامه جدیدی موجود نیست"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"رد کردن برنامههای اخیر"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 برنامه اخیر"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d برنامه اخیر"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"اعلانی موجود نیست"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"در حال انجام"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"اعلان ها"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"لطفاً شارژر را وصل کنید"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"لطفاً شارژر را وصل کنید"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"باتری در حال کم شدن است."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> باقیمانده است"</string>
<string name="invalid_charger" msgid="4549105996740522523">"شارژ USB پشتیبانی نمی شود."\n"فقط از شارژر ارائه شده استفاده کنید."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"بیصدا"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"خودکار"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"اعلان ها"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"اخیر"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"برنامه اخیری موجود نیست."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"برنامه های کاربردی"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"اتصال اینترنتی با بلوتوث تلفن همراه"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"پیکربندی روش های ورودی"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"پیکربندی روش های ورودی"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"از صفحه کلید فیزیکی استفاده کنید"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"به برنامه <xliff:g id="APPLICATION">%1$s</xliff:g> اجازه می دهید به دستگاه USB وصل شود؟"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"به برنامه <xliff:g id="APPLICATION">%1$s</xliff:g> اجازه می دهید به وسیله جانبی USB وصل شود؟"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"وقتی این دستگاه USB وصل است، <xliff:g id="ACTIVITY">%1$s</xliff:g> باز شود؟"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"وقتی این وسیله جانبی USB وصل است، <xliff:g id="ACTIVITY">%1$s</xliff:g> باز شود؟"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"برنامه های نصب شده با این وسیله جانبی USB کار می کنند. در <xliff:g id="URL">%1$s</xliff:g>راجع به این لوازم جانبی بیشتر بیاموزید"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"لوازم جانبی USB"</string>
<string name="label_view" msgid="6304565553218192990">"مشاهده"</string>
<string name="always_use_device" msgid="1450287437017315906">"استفاده به صورت پیش فرض برای این دستگاه USB"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"استفاده به صورت پیش فرض برای این دستگاه USB"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"بزرگنمایی برای پر کردن صفحه"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"گسترده کردن برای پر کردن صفحه"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"بزرگنمایی سازگاری"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"بزرگنمایی سازگاری"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"اگر یک برنامه برای صفحه کوچک تری طراحی شده باشد، یک کنترل بزرگنمایی توسط ساعت نشان داده می شود."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"تصویر از صفحه در گالری ذخیره شد"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"نمیتواند عکس صفحه را ذخیره کند. ممکن است محل ذخیره خارجی در حال استفاده باشد."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"گزینه های انتقال فایل USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"نصب به عنوان دستگاه پخش رسانه (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"تصب به عنوان دوربین (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"نصب برنامه انتقال فایل Android برای Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"نصب برنامه انتقال فایل Android برای Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"برگشت"</string>
<string name="accessibility_home" msgid="8217216074895377641">"صفحه اصلی"</string>
<string name="accessibility_menu" msgid="316839303324695949">"منو"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"برنامههای اخیر"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"برنامههای اخیر"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"کلید تغییر روش ورود متن."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"دکمه بزرگنمایی سازگار."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"بزرگنمایی از صفحههای کوچک تا بزرگ."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"دو نوار برای داده."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"سه نوار برای داده."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"قدرت سیگنال داده کامل است."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Wi-Fi موجود نیست."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"یک نوار برای WiFi."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"دو نوار برای WiFi."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"سه نوار برای WiFi."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"قدرت سیگنال WiFi کامل است."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Wi-Fi موجود نیست."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"یک نوار برای WiFi."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"دو نوار برای WiFi."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"سه نوار برای WiFi."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"قدرت سیگنال WiFi کامل است."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wifi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wifi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"بدون سیم کارت."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"اتصال اینترنت با بلوتوث تلفن همراه."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"حالت هواپیما."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"باتری <xliff:g id="NUMBER">%d</xliff:g> درصد."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"دکمه تنظیمات."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"دکمه اعلانها."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"حذف اعلان."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"تنظیمات سیستم."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"اعلانها."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"پاک کردن اعلان"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS فعال شد."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"دستیابی به GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter فعال شد."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"زنگ لرزشی."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"زنگ بیصدا."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"داده 2G-3G غیرفعال شد"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"داده 4G غیر فعال شد"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"دادههای تلفن همراه غیرفعال است"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"داده غیرفعال شد"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"به حداکثر محدودیت استفاده از داده رسیدهاید."\n\n"استفاده از داده بیشتر سبب افزایش هزینههای شرکت مخابراتی میشود."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"به حداکثر محدودیت استفاده از داده رسیدهاید."\n\n"استفاده از داده بیشتر سبب افزایش هزینههای شرکت مخابراتی میشود."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"فعال کردن مجدد داده"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"اتصال اینترنتی وجود ندارد"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi متصل شد"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"جستجو برای GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"مکان تنظیم شده توسط GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"پاک کردن تمام اعلانها"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index ce633e9..c1c280f 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Poista luettelosta"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Sovelluksen tiedot"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Ei viimeisimpiä sovelluksia"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Hylkää viimeaikaiset sovellukset"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 viimeaikainen sovellus"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d viimeaikaista sovellusta"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ei ilmoituksia"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Käynnissä olevat"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Ilmoitukset"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Kytke laturi"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Kytke laturi"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Akun virta on vähissä."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> jäljellä"</string>
<string name="invalid_charger" msgid="4549105996740522523">"USB-latausta ei tueta."\n"Käytä laitteen mukana tullutta laturia."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"ÄÄNET."</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Ilmoitukset"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Viimeisimmät"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Ei viimeaikaisia sovelluksia."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Sovellukset"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth yhdistetty"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Määritä syöttötavat"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Määritä syöttötavat"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Käytä fyysistä näppäimistöä"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Annetaanko sovellukselle <xliff:g id="APPLICATION">%1$s</xliff:g> lupa käyttää USB-laitetta?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Annetaanko sovellukselle <xliff:g id="APPLICATION">%1$s</xliff:g> lupa käyttää USB-lisälaitetta?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Avataanko <xliff:g id="ACTIVITY">%1$s</xliff:g> tämän USB-laitteen ollessa kytkettynä?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Avataanko <xliff:g id="ACTIVITY">%1$s</xliff:g> tämän USB-lisälaitteen ollessa kytkettynä?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Asennetut sov. eivät toimi tämän USB-lisälaitteen kanssa. Lisätietoja lisälaitteesta os. <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB-lisälaite"</string>
<string name="label_view" msgid="6304565553218192990">"Näytä"</string>
<string name="always_use_device" msgid="1450287437017315906">"Käytä oletuksena tällä USB-laitteella"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Käytä oletuksena tällä USB-lisälaitteella"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoomaa koko näyttöön"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Venytä koko näyttöön"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Yhteensopivuustilan zoomaus"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Yhteensopivuustilan zoomaus"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Jos sovellus on suunniteltu pienemmälle näytölle, kellon viereen tulee näkyviin zoomaussäädin."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Kuvakaappaus on tallennettu galleriaan"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Kuvakaappauksen tallennus epäonnistui. Ulkoinen tallennustila voi olla käytössä."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB-tiedostonsiirtoasetukset"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Käytä mediasoittimena (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Käytä kamerana (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Asenna Android File Transfer -sovellus Macille"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Asenna Android File Transfer -sovellus Macille"</string>
<string name="accessibility_back" msgid="567011538994429120">"Takaisin"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Aloituspainike"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Valikko"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Viimeaikaiset sovellukset"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Viimeaikaiset sovellukset"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Syöttötavan vaihtopainike."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Yhteensopivuuszoomaus-painike."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoomaa pienemmältä suuremmalle ruudulle."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Datasignaali - kaksi palkkia."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Datasignaali - kolme palkkia"</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Vahva kuuluvuus."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Ei wifi-yhteyttä."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wifi-signaali - yksi palkki."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wifi-signaali - kaksi palkkia."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wifi-signaali - kolme palkkia."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Vahva wifi-signaali."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Ei wifi-yhteyttä."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Wifi-signaali - yksi palkki."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wifi-signaali - kaksi palkkia."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wifi-signaali - kolme palkkia."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Vahva wifi-signaali."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wifi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wifi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Ei SIM-korttia."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Internetyhteyden jakaminen Bluetoothin kautta."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Lentokonetila."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Akun virta <xliff:g id="NUMBER">%d</xliff:g> prosenttia."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Asetukset-painike."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Ilmoitukset-painike."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Poista ilmoitus."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Järjestelmän asetukset"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Ilmoitukset"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Tyhjennä ilmoitus"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS käytössä."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Haetaan GPS-signaalia."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Tekstipuhelin käytössä."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Soittoääni: värinä."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Soittoääni: äänetön."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G-tiedonsiirto pois käytöstä"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-tiedonsiirto pois käytöstä"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobiilitiedonsiirto pois käytöstä"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Tiedonsiirto pois käytöstä"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Asetettu tiedonsiirtoraja on täynnä."\n\n"Operaattori voi veloittaa lisätiedonsiirrosta."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Asetettu tiedonsiirtoraja on täynnä."\n\n"Operaattori voi veloittaa lisätiedonsiirrosta."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Ota tiedonsiirto käyttöön"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Ei internetyhteyttä"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wifi yhdistetty"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Haetaan GPS-yhteyttä"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Sijainti määritetty GPS:n avulla"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Tyhjennä kaikki ilmoitukset."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index b20142f..d402ea6 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Supprimer de la liste"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informations sur l\'application"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Aucune application récente."</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Masquer les applications récentes"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 application récente"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d applications récentes"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Aucune notification"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"En cours"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notifications"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Branchez le chargeur"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Branchez le chargeur"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Le niveau de la batterie est faible."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restant(s)"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Chargement USB non disponible."\n"Vous devez utiliser le chargeur fourni."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"MUET"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notifications"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Récentes"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Aucune application récente"</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Applications"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Connexion Bluetooth partagée"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurer les modes de saisie"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurer les modes de saisie"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utiliser clavier physique"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Autoriser l\'application <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder au périphérique USB ?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Autoriser l\'application <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à l\'accessoire USB ?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Ouvrir <xliff:g id="ACTIVITY">%1$s</xliff:g> lors de la connexion de ce périphérique USB ?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Ouvrir <xliff:g id="ACTIVITY">%1$s</xliff:g> lors de la connexion de cet accessoire USB ?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Aucune application installée n\'est compatible avec cet accessoire USB. En savoir plus sur <xliff:g id="URL">%1$s</xliff:g>."</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Accessoire USB"</string>
<string name="label_view" msgid="6304565553218192990">"Afficher"</string>
<string name="always_use_device" msgid="1450287437017315906">"Utiliser par défaut pour ce périphérique USB"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Utiliser par défaut pour cet accessoire USB"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoomer pour remplir l\'écran"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Étirer pour remplir l\'écran"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom de compatibilité"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom de compatibilité"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Si une application a été conçue pour un écran plus petit, une commande de zoom s\'affiche à côté de l\'horloge."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Capture d\'écran enregistrée dans la galerie."</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Impossible d\'enregistrer la capture d\'écran. Il est possible que le périphérique de stockage externe soit en cours d\'utilisation."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Options transfert fichiers USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Installer en tant que lecteur multimédia (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Installer en tant qu\'appareil photo (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Installer application Android File Transfer pour Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Installer application Android File Transfer pour Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Retour"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Accueil"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Applications récentes"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Applications récentes"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Bouton \"Changer le mode de saisie\""</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Bouton \"Zoom de compatibilité\""</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de compatibilité avec la taille de l\'écran"</string>
@@ -90,40 +107,43 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Signal moyen"</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Signal bon"</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Signal excellent"</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Aucune connexion Wi-Fi"</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Signal Wi-Fi faible"</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Signal Wi-Fi : moyen"</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Signal Wi-Fi : bon"</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Signal Wi-Fi excellent"</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Aucune connexion Wi-Fi"</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Signal Wi-Fi faible"</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Signal Wi-Fi : moyen"</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Signal Wi-Fi : bon"</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Signal Wi-Fi excellent"</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3G+"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"EDGE"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Aucune carte SIM"</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Partage de connexion Bluetooth"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode Avion"</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Bouton \"Paramètres\""</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Bouton \"Notifications\""</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Supprimer la notification"</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Paramètres système"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Supprimer la notification"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS activé"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Acquisition de données GPS"</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Téléscripteur activé"</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Sonnerie en mode vibreur"</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Sonnerie en mode silencieux"</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Données 2G-3G désactivées"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Données 4G désactivées"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Données mobiles désactivées"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Données désactivées"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Vous avez atteint la limite d\'utilisation de données spécifiée."\n\n"L\'utilisation supplémentaire de données peut entraîner la facturation de frais par votre opérateur."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Vous avez atteint la limite d\'utilisation de données spécifiée."\n\n"L\'utilisation supplémentaire de données peut entraîner la facturation de frais par votre opérateur."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Réactiver connexion données"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Aucune connexion"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Connecté au Wi-Fi"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Recherche de GPS..."</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Position définie par GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi-land/strings.xml b/packages/SystemUI/res/values-hi-land/strings.xml
new file mode 100644
index 0000000..de6a6c9
--- /dev/null
+++ b/packages/SystemUI/res/values-hi-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * 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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"स्क्रीन को अभी भूदृश्य अभिविन्यास में लॉक किया गया है."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-hi-large/strings.xml b/packages/SystemUI/res/values-hi-large/strings.xml
new file mode 100644
index 0000000..7bcfcdd
--- /dev/null
+++ b/packages/SystemUI/res/values-hi-large/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * 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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="status_bar_clear_all_button" msgid="4661583896803349732">"सभी साफ़ करें"</string>
+ <string name="notifications_off_title" msgid="1860117696034775851">"सूचनाएं बंद"</string>
+ <string name="notifications_off_text" msgid="1439152806320786912">"सूचनाओं को पुन: चालू करने के लिए यहां टैप करें."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
new file mode 100644
index 0000000..2038fc6
--- /dev/null
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="7164937344850004466">"सिस्टम UI"</string>
+ <string name="status_bar_clear_all_button" msgid="7774721344716731603">"साफ़ करें"</string>
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"परेशान न करें"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"सूचनाएं दिखाएं"</string>
+ <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"सूची से निकालें"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"एप्लिकेशन जानकारी"</string>
+ <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"कोई हाल ही के एप्लिकेशन नहीं"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"हाल ही के एप्लिकेशन ख़ारिज करें"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 हाल ही का एप्लिकेशन"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d हाल ही के एप्लिकेशन"</item>
+ </plurals>
+ <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"कोई सूचना नहीं"</string>
+ <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"ऑनगोइंग"</string>
+ <string name="status_bar_latest_events_title" msgid="6594767438577593172">"सूचनाएं"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"कृपया चार्जर कनेक्ट करें"</string>
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"बैटरी कम हो रही है."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> शेष"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"USB चार्जिंग समर्थित नहीं है."\n"केवल आपूर्ति किए गए चार्जर का उपयोग करें."</string>
+ <string name="battery_low_why" msgid="7279169609518386372">"बैटरी उपयोग"</string>
+ <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"सेटिंग"</string>
+ <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
+ <string name="status_bar_settings_airplane" msgid="4879879698500955300">"हवाई जहाज मोड"</string>
+ <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"स्क्रीन स्वत: घुमाएं"</string>
+ <string name="status_bar_settings_mute_label" msgid="554682549917429396">"म्यूट करें"</string>
+ <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"स्वत:"</string>
+ <string name="status_bar_settings_notifications" msgid="397146176280905137">"सूचनाएं"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth टीदर किया गया"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"इनपुट पद्धतियां कॉन्फ़िगर करें"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"भौतिक कीबोर्ड का उपयोग करें"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
+ <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"जब यह USB उपकरण कनेक्ट किया जाए, तब <xliff:g id="ACTIVITY">%1$s</xliff:g> को खोलें?"</string>
+ <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"जब यह USB एसेसरी कनेक्ट की जाए, तब <xliff:g id="ACTIVITY">%1$s</xliff:g> को खोलें?"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
+ <string name="title_usb_accessory" msgid="4966265263465181372">"USB सहायक साधन"</string>
+ <string name="label_view" msgid="6304565553218192990">"देखें"</string>
+ <string name="always_use_device" msgid="1450287437017315906">"इस USB उपकरण के लिए डिफ़ॉल्ट रूप से उपयोग करें"</string>
+ <string name="always_use_accessory" msgid="1210954576979621596">"इस USB एसेसरी के लिए डिफ़ॉल्ट रूप से उपयोग करें"</string>
+ <string name="compat_mode_on" msgid="6623839244840638213">"स्क्रीन भरने हेतु ज़ूम करें"</string>
+ <string name="compat_mode_off" msgid="4434467572461327898">"स्क्रीन को भरने के लिए खींचें"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"संगतता ज़ूम"</string>
+ <string name="compat_mode_help_body" msgid="4946726776359270040">"जब किसी छोटी स्क्रीन के लिए एप्लिकेशन को डिज़ाइन किया जाता है, तो ज़ूम नियंत्रण क्लॉक के पास दिखाई देगा."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
+ <string name="usb_preference_title" msgid="6551050377388882787">"USB फ़ाइल स्थानांतरण विकल्प"</string>
+ <string name="use_mtp_button_title" msgid="4333504413563023626">"मीडिया प्लेयर के रूप में माउंट करें (MTP)"</string>
+ <string name="use_ptp_button_title" msgid="7517127540301625751">"कैमरे के रूप में माउंट करें (PTP)"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac के लिए Android फ़ाइल स्थानां. एप्लि. इंस्टॉल करें"</string>
+ <string name="accessibility_back" msgid="567011538994429120">"वापस जाएं"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"होम"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"मेनू"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"हाल ही के एप्लिकेशन"</string>
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"इनपुट पद्धति बटन स्विच करें."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"संगतता ज़ूम बटन."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"छोटी से बड़ी स्क्रीन पर ज़ूम करें."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth कनेक्ट किया गया."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth डिस्कनेक्ट किया गया."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"कोई बैटरी नहीं."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"बैटरी एक बार."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"बैटरी दो बार."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"बैटरी तीन बार."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"बैटरी पूर्ण."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"कोई फ़ोन नहीं."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"फ़ोन एक बार."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"फ़ोन दो बार."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"फोन तीन बार."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"फ़ोन सिग्नल पूर्ण."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"कोई डेटा नहीं."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"डेटा एक बार."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"डेटा दो बार."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"डेटा तीन बार."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"पूर्ण डेटा सिग्नल."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"कोई WiFi नहीं."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"WiFi एक बार."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"WiFi दो बार."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"WiFi तीन बार."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"पूर्ण WiFi सिग्नल."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"किनारा"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"कोई सिम नहीं."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth टेदरिंग."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"हवाई जहाज मोड."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> प्रतिशत बैटरी."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"सिस्टम सेटिंग."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"सूचनाएं."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"सूचना साफ़ करें"</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS सक्षम."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS प्राप्त करना."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"टेलीटाइपराइटर सक्षम."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"रिंगर कंपन."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"रिंगर मौन."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
+ <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G डेटा अक्षम"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G डेटा अक्षम"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"मोबाइल डेटा अक्षम"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"डेटा अक्षम"</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"डेटा उपयोग की निर्दिष्ट सीमा पूरी हो गई है."\n\n"अतिरिक्त डेटा का उपयोग करने पर वाहक शुल्क लगाए जा सकते है."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"डेटा पुन: सक्षम करें"</string>
+ <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"कोई इंटरनेट कनेक्शन नहीं"</string>
+ <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi कनेक्ट किया गया"</string>
+ <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS को खोजा जा रहा है"</string>
+ <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS द्वारा सेट किया गया स्थान"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"सभी सूचनाएं साफ़ करें."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 07a9a65..368ac23 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Ukloni s popisa"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informacije o aplikaciji"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Nema nedavnih aplikacija"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Odbaci nedavne aplikacije"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 nedavna aplikacija"</item>
+ <item quantity="other" msgid="1040784359794890744">"Nedavnih aplikacija: %d"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Bez obavijesti"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"U tijeku"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Obavijesti"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Priključite punjač"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Priključite punjač"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Baterija će uskoro biti potrošena."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> preostalo"</string>
<string name="invalid_charger" msgid="4549105996740522523">"USB punjenje nije podržano."\n"Upotrijebite samo priloženi punjač."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"Bez zv."</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTOM."</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Obavijesti"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Nedavni"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Nema nedavnih aplikacija."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplikacije"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth posredno povezan"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfiguriraj načine ulaza"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfiguriraj načine ulaza"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Rabi fizičku tipkovnicu"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> da pristupi ovom USB uređaju?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> da pristupi ovom USB dodatku?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Otvoriti <xliff:g id="ACTIVITY">%1$s</xliff:g> kad se spoji ovaj USB uređaj?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Otvoriti <xliff:g id="ACTIVITY">%1$s</xliff:g> kad se spoji ovaj USB dodatak?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Nijedna instalirana aplikacija ne radi s ovim USB dodatkom. Saznajte više o ovom dodatku na <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB pribor"</string>
<string name="label_view" msgid="6304565553218192990">"Prikaži"</string>
<string name="always_use_device" msgid="1450287437017315906">"Koristi se prema zadanim postavkama za ovaj USB uređaj"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Koristi se prema zadanim postavkama za ovaj USB pribor"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zumiraj i ispuni zaslon"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Rastegni i ispuni zaslon"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Kompatibilni zum"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Kompatibilni zum"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Kada je aplikacija dizajnirana za manji zaslon, kontrole zumiranja prikazuju se pored sata."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Snimak zaslona spremljen u Galeriju"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Ne mogu spremiti snimak zaslona. Možda se upotrebljava vanjska pohrana."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prijenosa datoteka"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Učitaj kao media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Učitaj kao fotoaparat (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Instalacija aplikacije Android File Transfer za Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Instalacija aplikacije Android File Transfer za Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Natrag"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Početna"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Izbornik"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Nedavne aplikacije"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Nedavne aplikacije"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Gumb za promjenu načina unosa."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Gumb za kompatibilnost zumiranja."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zumiranje manjeg zaslona na veći."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Podatkovni signal dva stupca."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Podatkovni signal tri stupca."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Podatkovni signal pun."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Nema WiFi signala."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"WiFi signal jedan stupac."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"WiFi signal dva stupca ."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi tri stupca."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"WiFi signal pun."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Nema WiFi signala."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"WiFi signal jedan stupac."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"WiFi signal dva stupca ."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"WiFi tri stupca."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"WiFi signal pun."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Nema SIM kartice."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Posredno povezivanje Bluetootha."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Način rada u zrakoplovu"</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Baterija <xliff:g id="NUMBER">%d</xliff:g> posto."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Gumb postavki."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Gumb obavijesti."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Ukloni obavijest."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Postavke sustava."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Obavijesti."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Brisanje obavijesti"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS je omogućen."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Dohvaćanje GPS-a."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter je omogućen."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibracija softvera zvona."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Softver zvona utišan."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Onemogućeni su 2G-3G podaci"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Onemogućeni su 4G podaci"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Onemogućeni su mobilni podaci"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Podaci su onemogućeni"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Dosegnuto je navedeno ograničenje upotrebe podataka."\n\n"Dodatna upotreba podataka može se naplaćivati."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Dosegnuto je navedeno ograničenje upotrebe podataka."\n\n"Dodatna upotreba podataka može se naplaćivati."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Ponovo omogući podatke"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nema internetske veze"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi povezan"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Traženje GPS-a"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokaciju utvrdio GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Brisanje svih obavijesti."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index fa2219dd..071ce78 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Eltávolítás a listából"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Alkalmazásinformáció"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Nincs újabb alkalmazás"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Újabb alkalmazások elvetése"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 újabb alkalmazás"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d újabb alkalmazás"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nincs értesítés"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Folyamatban van"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Értesítések"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Kérjük, csatlakoztassa a töltőt"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Kérjük, csatlakoztassa a töltőt"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Az akkufeszültség alacsony."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> maradt"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Az USB-n keresztüli töltés nincs támogatva."\n"Használja a kapott töltőt."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"NÉMÍT"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Értesítések"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Legutóbbiak"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Nincsenek nemrég használt alkalmazások"</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Alkalmazások"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth megosztva"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Beviteli módok konfigurálása"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Beviteli módok konfigurálása"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Valódi bill. használata"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"<xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás hozzáférhet az USB-eszközhöz?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"<xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás hozzáférhet az USB-kiegészítőhöz?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"<xliff:g id="ACTIVITY">%1$s</xliff:g> megnyitása, ha USB-kiegészítő csatlakoztatva van?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"<xliff:g id="ACTIVITY">%1$s</xliff:g> megnyitása, ha ez az USB-kiegészítő csatlakoztatva van?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"A telepített alkalmazások nem működnek ezzel az USB-kiegészítővel. Bővebben: <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB-kellék"</string>
<string name="label_view" msgid="6304565553218192990">"Megtekintés"</string>
<string name="always_use_device" msgid="1450287437017315906">"Alapértelmezett használat ehhez az USB-eszközhöz"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Alapértelmezett használat ehhez az USB-kiegészítőhöz"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Nagyítás a kitöltéshez"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Nyújtás kitöltéshez"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Kompatibilitás -- nagyítás/kicsinyítés"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Kompatibilitás -- nagyítás/kicsinyítés"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Ha egy alkalmazást kisebb képernyőre terveztek, akkor a nagyítás/kicsinyítés vezérlője az óra mellett jelenik meg."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Képernyőkép mentve a galériába"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Nem lehet menteni a képernyőképet. Lehet, hogy a külső tároló használatban van."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB-fájlátvitel beállításai"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Csatlakoztatás médialejátszóként (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Csatlakoztatás kameraként (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Android fájlátviteli alkalmazás telepítése Machez"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Android fájlátviteli alkalmazás telepítése Machez"</string>
<string name="accessibility_back" msgid="567011538994429120">"Vissza"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Főoldal"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menü"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Nemrég használt alkalmazások"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Legújabb alkalmazás"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Beviteli mód váltása gomb."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Kompatibilitási zoom gomb."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Kicsinyítsen a nagyobb képernyőhöz."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Adat két sáv."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Adat három sáv."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Adatjel teljes."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Nincs Wi-Fi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi egy sáv."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi két sáv."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi három sáv."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi jel teljes."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Nincs Wi-Fi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Wi-Fi egy sáv."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi két sáv."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi három sáv."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Wi-Fi jel teljes."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Nincs SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth megosztása."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Repülőgép üzemmód."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Akkumulátor <xliff:g id="NUMBER">%d</xliff:g> százalék."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Beállítások gomb."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Értesítések gomb."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Értesítés eltávolítása."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Rendszerbeállítások"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Értesítések"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Értesítés törlése"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS engedélyezve."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS lekérése."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter engedélyezve."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Csengő rezeg."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Csengő néma."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G adatforgalom letiltva"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G adatforgalom letiltva"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobil adatforgalom letiltva"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Adatok letiltva"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Elérte a megadott adathasználati korlátot."\n\n"További adathasználatért a szolgáltató díjat számolhat fel."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Elérte a megadott adathasználati korlátot."\n\n"További adathasználatért a szolgáltató díjat számolhat fel."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Adatforgalom engedélyezése"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nincs internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi csatlakoztatva"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS keresése"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"A GPS beállította a helyet"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Minden értesítés törlése"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 3347ce9..7d65587 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Hapus dari daftar"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Info apl"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Tidak ada apl terbaru"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Singkirkan aplikasi terbaru"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 apl terbaru"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d apl terbaru"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Tidak ada pemberitahuan"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Berkelanjutan"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Pemberitahuan"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Harap hubungkan ke pengisi daya"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Harap hubungkan ke pengisi daya"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Baterai semakin lemah."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> tersisa"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Pengisian daya USB tidak didukung."\n"Gunakan hanya pengisi daya yang disediakan."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"BUNGKAM"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Pemberitahuan"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Terbaru"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Tidak ada aplikasi terbaru."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Apps"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tertambat"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurasikan metode masukan"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurasikan metode masukan"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Gunakan keyboard fisik"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Izinkan aplikasi <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses perangkat USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Izinkan aplikasi <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses aksesori USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Buka <xliff:g id="ACTIVITY">%1$s</xliff:g> ketika perangkat USB ini tersambung?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Buka <xliff:g id="ACTIVITY">%1$s</xliff:g> ketika aksesori USB ini tersambung?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Tidak ada aplikasi terpasang yang bekerja dengan aksesori USB ini. Pelajari aksesori ini lebih lanjut di <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Aksesori USB"</string>
<string name="label_view" msgid="6304565553218192990">"Lihat"</string>
<string name="always_use_device" msgid="1450287437017315906">"Gunakan secara bawaan untuk perangkat USB ini"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Gunakan secara bawaan untuk aksesori USB ini"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Perbesar utk mengisi layar"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Rentangkn utk mngisi layar"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom Kompatibilitas"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom Kompatibilitas"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Saat apl dirancang untuk layar yang lebih kecil, kontrol zoom akan tampil di dekat jam."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Tangkapan layar disimpan ke Galeri"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Tidak dapat menyimpan tangkapan layar. Penyimpan eksternal mungkin sedang digunakan."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opsi transfer berkas USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Pasang sebagai pemutar media (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Pasang sebagai kamera (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Pasang aplikasi Transfer Berkas Android untuk Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Pasang aplikasi Transfer Berkas Android untuk Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Kembali"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Utama"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Aplikasi terbaru"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Apl terbaru"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Tombol beralih metode masukan."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Tombol perbesar/perkecil kompatibilitas."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Perbesar dari layar kecil ke besar."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data dua batang."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data tiga batang."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Sinyal data penuh."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Tidak ada WiFi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"WiFi satu batang."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"WiFi dua batang."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi tiga batang."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Sinyal WiFi penuh."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Tidak ada WiFi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"WiFi satu batang."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"WiFi dua batang."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"WiFi tiga batang."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Sinyal WiFi penuh."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Tidak ada SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Penambatan bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode pesawat."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Baterai <xliff:g id="NUMBER">%d</xliff:g> persen."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Tombol setelan."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Tombol pemberitahuan."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Hapus pemberitahuan."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Setelan sistem."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Pemberitahuan."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Menghapus pemberitahuan."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS diaktifkan."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Memperoleh GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter diaktifkan."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Pendering bergetar."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Pendering senyap."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Data 2G-3G dinonaktifkan"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data 4G dinonaktifkan"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Data seluler dinonaktifkan"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data dinonaktifkan"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Telah mencapai batas penggunaan data yang ditetapkan."\n\n"Penggunaan data tambahan mungkin akan dikenai biaya operator."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Telah mencapai batas penggunaan data yang ditetapkan."\n\n"Penggunaan data tambahan mungkin akan dikenai biaya operator."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Aktifkan ulang data"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Tidak ada sambungan internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi tersambung"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Menelusuri GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi yang disetel oleh GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Menghapus semua pemberitahuan."</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 197d989..a52b0e0 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Rimuovi dall\'elenco"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informazioni applicazione"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Nessuna applicazione recente"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Ignora applicazioni recenti"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 applicazione recente"</item>
+ <item quantity="other" msgid="1040784359794890744">"Applicazioni recenti in %d"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nessuna notifica"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"In corso"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notifiche"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Collegare il caricabatterie"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Collegare il caricabatterie"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Batteria quasi scarica."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> rimanente"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Ricarica tramite USB non supportata."\n"Utilizza solo il caricatore in dotazione."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"MUTE"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notifiche"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Recenti"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Nessuna applicazione recente."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Applicazioni"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth con tethering"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configura metodi di input"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configura metodi di input"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizza tastiera fisica"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Consentire all\'applicazione <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere al dispositivo USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Consentire all\'applicazione <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere all\'accessorio USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Aprire <xliff:g id="ACTIVITY">%1$s</xliff:g> quando questo dispositivo USB è collegato?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Aprire <xliff:g id="ACTIVITY">%1$s</xliff:g> quando questo accessorio USB è collegato?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Applicazioni installate non funzionano con accessorio USB. Altre informazioni su accessorio su <xliff:g id="URL">%1$s</xliff:g>."</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Accessorio USB"</string>
<string name="label_view" msgid="6304565553218192990">"Visualizza"</string>
<string name="always_use_device" msgid="1450287437017315906">"Usa per impostazione predef. per dispositivo USB"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Usa per impostazione predef. per accessorio USB"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoom per riempire schermo"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Estendi per riemp. schermo"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom compatibilità"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom compatibilità"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Se un\'applicazione è stata progettata per uno schermo più piccolo, accanto all\'orologio viene visualizzato un controllo dello zoom."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Screenshot salvato nella galleria"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Impossibile salvare lo screenshot. L\'archivio esterno potrebbe essere in uso."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opzioni trasferimento file USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Monta come lettore multimediale (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Monta come videocamera (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Installa l\'applicazione Android File Transfer per Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Installa l\'applicazione Android File Transfer per Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Indietro"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Home"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Applicazioni recenti"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Applicazioni recenti"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Pulsante per cambiare metodo di immissione."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Pulsante zoom compatibilità."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom inferiore per schermo più grande."</string>
@@ -90,40 +107,43 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Dati: due barre."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Dati: tre barre."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Massimo segnale dati."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Nessun segnale Wi-Fi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi: una barra."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi: due barre."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi: tre barre."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Massimo segnale Wi-Fi."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Nessun segnale Wi-Fi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Wi-Fi: una barra."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi: due barre."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi: tre barre."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Massimo segnale Wi-Fi."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Nessuna SIM presente."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Tethering Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Modalità aereo."</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Pulsante Impostazioni."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Pulsante per le notifiche."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Rimuovi la notifica."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Impostazioni di sistema."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifiche."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Cancella notifica."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS abilitato."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Acquisizione GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Telescrivente abilitata."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Suoneria vibrazione."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Suoneria silenziosa."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Dati 2G-3G disattivati"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dati 4G disattivati"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Dati mobili disattivati"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Dati disabilati"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Il limite di utilizzo dei dati specificato è stato raggiunto."\n\n"Un ulteriore utilizzo di dati può comportare l\'applicazione di costi da parte dell\'operatore."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Il limite di utilizzo dei dati specificato è stato raggiunto."\n\n"Un ulteriore utilizzo di dati può comportare l\'applicazione di costi da parte dell\'operatore."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Riattiva dati"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nessuna connessione"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi connesso"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Ricerca del GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Posizione stabilita dal GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Cancella tutte le notifiche."</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 8194542..29c5c97 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"הסר מהרשימה"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"פרטי יישום"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"אין יישומים אחרונים"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"סגור יישומים אחרונים"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"יישום אחרון אחד"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d היישומים האחרונים"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"אין התראות"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"מתמשך"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"התראות"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"חבר מטען"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"חבר מטען"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"הסוללה נחלשת."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"נותרו <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"טעינה באמצעות USB אינה נתמכת."\n"השתמש אך ורק במטען שסופק."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"השתק"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"אוטומטי"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"התראות"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"נוצרו לאחרונה"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"אין יישומים חדשים."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Google Apps"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth קשור"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"הגדרת שיטות קלט"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"הגדרת שיטות קלט"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"השתמש במקלדת הפיזית"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"האם לאפשר ליישום <xliff:g id="APPLICATION">%1$s</xliff:g> לגשת למכשיר ה-USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"האם לאפשר ליישום <xliff:g id="APPLICATION">%1$s</xliff:g> לגשת לאביזר ה-USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"האם לפתוח את <xliff:g id="ACTIVITY">%1$s</xliff:g> כאשר מכשיר USB זה מחובר?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"האם לפתוח את <xliff:g id="ACTIVITY">%1$s</xliff:g> כאשר אביזר USB זה מחובר?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"אין יישומים מותקנים הפועלים עם אביזר ה-USB. למידע נוסף על אביזר זה בקר בכתובת <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"אביזר USB"</string>
<string name="label_view" msgid="6304565553218192990">"הצג"</string>
<string name="always_use_device" msgid="1450287437017315906">"השתמש כברירת מחדל עבור מכשיר USB זה"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"השתמש כברירת מחדל עבור אביזר USB זה"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"הגדל תצוגה כדי למלא את המסך"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"מתח כדי למלא את המסך"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"שינוי מרחק מתצוגה לתאימות"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"שינוי מרחק מתצוגה לתאימות"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"כאשר יישום מיועד למסך קטן יותר, פקד של מרחק מתצוגה יופיע ליד השעון."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"צילום המסך נשמר בגלריה"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"אין אפשרות לשמור את צילום המסך. ייתכן שנעשה שימוש באמצעי אחסון חיצוני."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"אפשרויות העברת קבצים ב-USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"טען כנגן מדיה (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"טען כמצלמה (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"התקן את יישום העברת הקבצים של Android עבור Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"התקן את יישום העברת הקבצים של Android עבור Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"הקודם"</string>
<string name="accessibility_home" msgid="8217216074895377641">"בית"</string>
<string name="accessibility_menu" msgid="316839303324695949">"תפריט"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"יישומים אחרונים"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"יישומים אחרונים"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"לחצן החלפת שיטת קלט."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"לחצן מרחק מתצוגה של תאימות."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"שנה מרחק מתצוגה של מסך קטן לגדול יותר."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"שני פסים של נתונים."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"שלושה פסים של נתונים."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"אות הנתונים מלא."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"אין WiFi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"פס אחד של WiFi."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"שני פסים של WiFi."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"שלושה פסים של WiFi."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"אות ה-WiFi מלא."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"אין WiFi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"פס אחד של WiFi."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"שני פסים של WiFi."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"שלושה פסים של WiFi."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"אות ה-WiFi מלא."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"קצה"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"אין כרטיס SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"שיתוף אינטרנט בין ניידים של Bluetooth"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"מצב טיסה"</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> אחוזים של סוללה."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"לחצן הגדרות."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"לחצן ההתראות"</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"הסר התראה."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"הגדרות מערכת"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"התראות"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"נקה התראה"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS מופעל."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"השגת GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter מופעל"</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"צלצול ורטט."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"צלצול שקט."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"נתוני 2G-3G מושבתים"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"נתוני 4G מושבתים"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"נתונים לנייד מושבתים"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"הנתונים מושבתים"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"הגעת למגבלת השימוש בנתונים שצוינה."\n\n"ייתכן שתחויב בתשלום לספק על שימוש נוסף בנתונים."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"הגעת למגבלת השימוש בנתונים שצוינה."\n\n"ייתכן שתחויב בתשלום לספק על שימוש נוסף בנתונים."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"הפעל מחדש את הנתונים"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"אין חיבור לאינטרנט"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi מחובר"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"מחפש GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"מיקום מוגדר על ידי GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"נקה את כל ההתראות."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index f2fb58b..49c5e3c 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"リストから削除"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"アプリ情報"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"最近使ったアプリはありません"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"最近使ったアプリをクリア"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"最近使ったアプリ: 1"</item>
+ <item quantity="other" msgid="1040784359794890744">"最近使ったアプリ: %d"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"通知なし"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"実行中"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"通知"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"充電してください"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"充電してください"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"電池が残り少なくなっています。"</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"残り<xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"USB充電には対応していません。"\n"付属の充電器をお使いください。"</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"ミュート"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"オート"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"通知"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"新着"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"新着のアプリケーションはありません。"</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"アプリ"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetoothテザリング接続"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"入力方法の設定"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"入力方法の設定"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"物理キーボードを使用"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"アプリケーション<xliff:g id="APPLICATION">%1$s</xliff:g>にUSBデバイスへのアクセスを許可しますか?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"アプリケーション<xliff:g id="APPLICATION">%1$s</xliff:g>にUSBアクセサリへのアクセスを許可しますか?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"このUSBデバイスが接続されたときに<xliff:g id="ACTIVITY">%1$s</xliff:g>を開きますか?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"このUSBアクセサリが接続されたときに<xliff:g id="ACTIVITY">%1$s</xliff:g>を開きますか?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"このUSBアクセサリを扱うアプリはインストールされていません。詳細は <xliff:g id="URL">%1$s</xliff:g> をご覧ください。"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USBアクセサリ"</string>
<string name="label_view" msgid="6304565553218192990">"表示"</string>
<string name="always_use_device" msgid="1450287437017315906">"このUSBデバイスにデフォルトで使用する"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"このUSBアクセサリにデフォルトで使用する"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"画面サイズに合わせて拡大"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"画面サイズに合わせて拡大"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"互換ズーム"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"互換ズーム"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"より小型の画面向けのアプリの場合は、ズームコントロールが時計のそばに表示されます。"</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"スクリーンショットがギャラリーに保存されました"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"スクリーンショットを保存できませんでした。外部ストレージが使用中の可能性があります。"</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USBファイル転送オプション"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"メディアプレーヤー(MTP)としてマウント"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"カメラ(PTP)としてマウント"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Mac版Android File Transferアプリのインストール"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac版Android File Transferアプリのインストール"</string>
<string name="accessibility_back" msgid="567011538994429120">"戻る"</string>
<string name="accessibility_home" msgid="8217216074895377641">"ホーム"</string>
<string name="accessibility_menu" msgid="316839303324695949">"メニュー"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"最近使ったアプリケーション"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"最近使ったアプリ"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"入力方法の切り替えボタン。"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"互換ズームボタン。"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"小さい画面から大きい画面に拡大。"</string>
@@ -90,40 +107,43 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"データ信号:レベル2"</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"データ信号:レベル3"</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"データ信号:フル"</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Wi-Fi電波:なし"</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi電波:レベル1"</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi電波:レベル2"</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi電波:レベル3"</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi電波:フル"</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Wi-Fi電波:なし"</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Wi-Fi電波:レベル1"</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi電波:レベル2"</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi電波:レベル3"</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Wi-Fi電波:フル"</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"EDGE"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"SIMがありません。"</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetoothテザリング。"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"機内モード。"</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
- <string name="accessibility_settings_button" msgid="7913780116850379698">"設定ボタン。"</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"通知ボタン。"</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"通知を削除。"</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"システム設定。"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"通知を消去。"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPSが有効です。"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS取得中です。"</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"テレタイプライターが有効です。"</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"バイブレーション着信。"</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"マナーモード着信。"</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G~3Gデータが無効になりました"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4Gデータが無効になりました"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"モバイルデータが無効になりました"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"データが無効になりました"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"指定したデータ使用上限に達しました。"\n\n"これ以上データを使用すると、携帯通信会社への料金が発生する可能性があります。"</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"指定したデータ使用上限に達しました。"\n\n"これ以上データを使用すると、携帯通信会社への料金が発生する可能性があります。"</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"データ接続を再度有効にする"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"インターネット未接続"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi接続済み"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"GPSで検索中"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPSにより現在地が設定されました"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"通知をすべて消去。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index ceceda4..8a7eff186 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"목록에서 삭제"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"앱 정보"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"최근에 사용한 앱 없음"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"최근에 사용한 앱 숨기기"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"최근에 사용한 앱 1개"</item>
+ <item quantity="other" msgid="1040784359794890744">"최근에 사용한 앱 %d개"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"알림 없음"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"진행 중"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"알림"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"충전기를 연결하세요."</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"충전기를 연결하세요."</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"배터리가 얼마 남지 않았습니다."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g>개 남음"</string>
<string name="invalid_charger" msgid="4549105996740522523">"USB 충전이 지원되지 않습니다."\n"제공된 충전기만 사용하세요."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"무시"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"자동"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"알림"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"최근 사용한 앱"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"최근에 사용한 애플리케이션이 없습니다."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"애플리케이션"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"블루투스 테더링됨"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"입력 방법 구성"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"입력 방법 구성"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"물리적 키보드 사용"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"애플리케이션 <xliff:g id="APPLICATION">%1$s</xliff:g>(이)가 USB 기기에 액세스하도록 허용하시겠습니까?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"애플리케이션 <xliff:g id="APPLICATION">%1$s</xliff:g>(이)가 USB 액세서리에 액세스하도록 허용하시겠습니까"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"USB 기기가 연결될 때 <xliff:g id="ACTIVITY">%1$s</xliff:g>(을)를 여시겠습니까?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"USB 액세서리가 연결될 때 <xliff:g id="ACTIVITY">%1$s</xliff:g>(을)를 여시겠습니까?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"이 USB와 호환되는 설치 애플리케이션이 없습니다. <xliff:g id="URL">%1$s</xliff:g>에서 세부정보를 참조하세요."</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB 액세서리"</string>
<string name="label_view" msgid="6304565553218192990">"보기"</string>
<string name="always_use_device" msgid="1450287437017315906">"이 USB 기기에 기본값으로 사용"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"이 USB 액세서리에 기본값으로 사용"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"전체화면 모드로 확대"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"전체화면 모드로 확대"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"호환성 확대/축소"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"호환성 확대/축소"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"앱이 작은 화면에 맞도록 설계된 경우 시계 옆에 확대/축소 컨트롤이 표시됩니다."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"캡쳐화면이 갤러리에 저장되었습니다."</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"캡쳐 화면을 저장할 수 없습니다. 외부 저장소를 사용 중인 것 같습니다."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB 파일 전송 옵션"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"미디어 플레이어로 마운트(MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"카메라로 마운트(PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Mac용 Android 파일 전송 애플리케이션 설치"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac용 Android 파일 전송 애플리케이션 설치"</string>
<string name="accessibility_back" msgid="567011538994429120">"뒤로"</string>
<string name="accessibility_home" msgid="8217216074895377641">"홈"</string>
<string name="accessibility_menu" msgid="316839303324695949">"메뉴"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"최근 애플리케이션"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"최근에 사용한 앱"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"입력 방법 버튼을 전환합니다."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"호환성 확대/축소 버튼입니다."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"작은 화면을 큰 화면으로 확대합니다."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"데이터 신호 막대가 두 개입니다."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"데이터 신호 막대가 세 개입니다."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"데이터 신호가 강합니다."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"WiFi가 없습니다."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"WiFi 신호 막대가 하나입니다."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"WiFi 신호 막대가 두 개입니다."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi 신호 막대가 세 개입니다."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"WiFi 신호가 강합니다."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"WiFi가 없습니다."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"WiFi 신호 막대가 하나입니다."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"WiFi 신호 막대가 두 개입니다."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"WiFi 신호 막대가 세 개입니다."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"WiFi 신호가 강합니다."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"SIM이 없습니다."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"블루투스 테더링입니다."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"비행기 모드입니다."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"배터리 <xliff:g id="NUMBER">%d</xliff:g>퍼센트"</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"설정 버튼입니다."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"알림 버튼입니다."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"알림을 삭제합니다."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"시스템 설정"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"알림"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"알림 지우기"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS가 사용 설정되었습니다."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS를 가져오는 중입니다."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"전신 타자기(TTY)가 사용 설정되었습니다."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"벨소리가 진동입니다."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"벨소리가 무음입니다."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G 데이터 사용중지됨"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G 데이터 사용중지됨"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"모바일 데이터 사용중지됨"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"데이터 사용중지됨"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"지정된 데이터 사용 한도에 도달했습니다."\n\n"데이터를 추가로 사용하면 이동통신사에서 요금을 부과할 수 있습니다."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"지정된 데이터 사용 한도에 도달했습니다."\n\n"데이터를 추가로 사용하면 이동통신사에서 요금을 부과할 수 있습니다."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"데이터 연결 다시 사용"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"인터넷에 연결되지 않음"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi 연결됨"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS 검색 중"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS에서 위치 설정"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"모든 알림 지우기"</string>
</resources>
diff --git a/packages/SystemUI/res/values-land/config.xml b/packages/SystemUI/res/values-land/config.xml
new file mode 100644
index 0000000..bbae18d
--- /dev/null
+++ b/packages/SystemUI/res/values-land/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources>
+ <!-- Whether we're using the tablet-optimized recents interface (we use this
+ value at runtime for some things) -->
+ <integer name="status_bar_recents_bg_gradient_degrees">90</integer>
+</resources>
+
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 32ebc80..e7c8b1f 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -23,15 +23,18 @@
<!-- How far the thumbnail for a recent app appears from left edge -->
<dimen name="status_bar_recents_thumbnail_left_margin">0dp</dimen>
<!-- How far the thumbnail for a recent app appears from top edge -->
- <dimen name="status_bar_recents_thumbnail_top_margin">12dp</dimen>
+ <dimen name="status_bar_recents_thumbnail_top_margin">28dp</dimen>
<!-- Padding for text descriptions -->
<dimen name="status_bar_recents_text_description_padding">8dp</dimen>
<!-- Width of application label text -->
<dimen name="status_bar_recents_app_label_width">156dip</dimen>
<!-- Left margin of application label text -->
- <dimen name="status_bar_recents_app_label_left_margin">16dip</dimen>
+ <dimen name="status_bar_recents_app_label_left_margin">12dip</dimen>
<!-- Margin between recents container and glow on the right -->
<dimen name="status_bar_recents_right_glow_margin">0dip</dimen>
<!-- Padding between recents items -->
<dimen name="status_bar_recents_item_padding">2dip</dimen>
+ <!-- Where to place the app icon over the thumbnail -->
+ <dimen name="status_bar_recents_app_icon_left_margin">8dp</dimen>
+ <dimen name="status_bar_recents_app_icon_top_margin">8dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 94fe4e6..5724812 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Pašalinti iš sąrašo"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Programos informacija"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Nėra naujausių programų"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Atsisakyti naujausių programų"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 naujausia programa"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d naujausios programos"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nėra įspėjimų"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Vykstantys"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Įspėjimai"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Prijunkite kroviklį"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Prijunkite kroviklį"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Akumuliatorius senka."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"Liko <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"USB krovimas nepalaikomas."\n"Naudokite tik pateiktą įkroviklį."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"NUTILD."</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTOM."</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Pranešimai"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Naujos"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Nėra naujausių programų."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Apps"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"„Bluetooth“ susieta"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigūruoti įvesties metodus"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigūruoti įvesties metodus"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Naudoti fizinę klaviatūrą"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Leisti programai „<xliff:g id="APPLICATION">%1$s</xliff:g>“ pasiekti USB įrenginį?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Leisti programai „<xliff:g id="APPLICATION">%1$s</xliff:g>“ pasiekti USB priedą?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Atidaryti <xliff:g id="ACTIVITY">%1$s</xliff:g>, kai prijungtas šis USB įrenginys?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Atidaryti <xliff:g id="ACTIVITY">%1$s</xliff:g>, kai prijungtas šis USB priedas?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Su šiuo USB pr. nev. jokios įdieg. pr. Suž. daugiau apie šį pr. šiuo adr.: <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB reikmuo"</string>
<string name="label_view" msgid="6304565553218192990">"Žiūrėti"</string>
<string name="always_use_device" msgid="1450287437017315906">"Šiam USB įreng. naudoti pagal numat. nustatymus"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Šiam USB priedui naudoti pagal numat. nustatymus"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Keisti mast., kad atit. ekr."</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Ištempti, kad atit. ekr."</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Suderinamumo mastelio keitimas"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Suderinamumo mastelio keitimas"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Kai programa bus pritaikyta mažesniam ekranui, mastelio keitimo valdiklis bus parodytas šalia laikrodžio."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Ekrano kopija išsaugota galerijoje"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Nepavyko išsaugoti ekrano kopijos. Gali būti naudojama išorinė atmintis."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB failo perdavimo parinktys"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Įmontuoti kaip medijos grotuvą (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Įmontuoti kaip fotoaparatą (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Įdiegti „Mac“ skirtą „Android“ failų perd. progr."</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Įdiegti „Mac“ skirtą „Android“ failų perd. progr."</string>
<string name="accessibility_back" msgid="567011538994429120">"Atgal"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Pagrindinis"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Meniu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Naujausios programos"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Naujausios programos"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Perjungti įvesties metodo mygtuką."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Suderinamumo priartinimo mygtukas."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Padidinti ekraną."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Dvi duomenų juostos."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Trys duomenų juostos."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Stiprus duomenų signalas."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Nėra „Wi-Fi“."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Viena „Wi-Fi“ juosta."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Dvi „Wi-Fi“ juostos."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Trys „Wi-Fi“ juostos."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"„Wi-Fi“ signalas stiprus."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Nėra „Wi-Fi“."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Viena „Wi-Fi“ juosta."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Dvi „Wi-Fi“ juostos."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Trys „Wi-Fi“ juostos."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"„Wi-Fi“ signalas stiprus."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Kraštas"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Nėra SIM kortelės."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"„Bluetooth“ įrenginio kaip modemo naudojimas."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Lėktuvo režimas."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Akumuliatorius: <xliff:g id="NUMBER">%d</xliff:g> proc."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Nustatymų mygtukas."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Pranešimų mygtukas."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Pašalinti pranešimą."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Sistemos nustatymai"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Pranešimai."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Išvalyti pranešimą."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS įgalintas."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Gaunama GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"„TeleTypewriter“ įgalinta."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibracija skambinant."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Skambutis tylus."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G–3G duomenys neleidžiami"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G duomenys neleidžiami"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilieji duomenys neleidžiami"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Duomenys neleidžiami"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Pasiektas nurodytas duomenų naudojimo apribojimas."\n\n"Naudojant papildomų duomenų gali būti taikomi operatoriaus mokesčiai."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Pasiektas nurodytas duomenų naudojimo apribojimas."\n\n"Naudojant papildomų duomenų gali būti taikomi operatoriaus mokesčiai."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Iš naujo įgalinti duomenis"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nėra interneto ryš."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Prisij. prie „Wi-Fi“"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Ieškoma GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS nustatyta vieta"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Išvalyti visus pranešimus."</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index b381f05..c5909bb 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Noņemšana no saraksta"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Lietotnes informācija"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Nav nesen izmantotu lietotņu."</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Nerādīt nesen izmantotās lietotnes"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 nesen izmantotā lietotne"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d nesen izmantotās lietotnes"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nav paziņojumu"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Notiekošs"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Paziņojumi"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Lūdzu, pievienojiet uzlādes ierīci."</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Lūdzu, pievienojiet uzlādes ierīci."</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Akumulators drīz izlādēsies."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"Atlicis: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"USB lādēšana netiek atbalstīta."\n"Izmantojiet tikai komplektā iekļauto lādētāju."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"IZ. SK."</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTOM."</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Paziņojumi"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Nesens"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Nav nesenu lietojumprogrammu."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Lietotnes"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth piesaiste"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurēt ievades metodes"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurēt ievades metodes"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Izmantot fizisku tastatūru"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Vai ļaut lietojumprogrammai <xliff:g id="APPLICATION">%1$s</xliff:g> piekļūt šai USB ierīcei?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Vai ļaut lietojumprogrammai <xliff:g id="APPLICATION">%1$s</xliff:g> piekļūt šim USB piederumam?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vai atvērt darbību <xliff:g id="ACTIVITY">%1$s</xliff:g>, kad tiek pievienota šī USB ierīce?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Vai atvērt darbību <xliff:g id="ACTIVITY">%1$s</xliff:g>, kad tiek pievienots šis USB piederums?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Neinst. lietojumpr. darbojas ar šo USB pied. Uzz. vairāk par šo piederumu: <xliff:g id="URL">%1$s</xliff:g>."</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB piederums"</string>
<string name="label_view" msgid="6304565553218192990">"Skatīt"</string>
<string name="always_use_device" msgid="1450287437017315906">"Pēc noklusējuma izmantot šai USB ierīcei"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Pēc noklusējuma izmantot šim USB piederumam"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Tālumm., lai aizp. ekr."</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Stiepiet, lai aizp. ekr."</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Saderības tālummaiņa"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Saderības tālummaiņa"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Ja lietotne ir paredzēta mazākam ekrānam, blakus pulkstenim tiks parādīta tālummaiņas vadīkla."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Ekrānuzņēmums ir saglabāts galerijā."</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Nevarēja saglabāt ekrānuzņēmumu. Iespējams, tiek izmantota ārējā atmiņa."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB failu pārsūtīšanas opcijas"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Pievienot kā multivides atskaņotāju (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Pievienot kā kameru (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Instalēt Android failu pārsūt. liet. Mac datoram"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Instalēt Android failu pārsūt. liet. Mac datoram"</string>
<string name="accessibility_back" msgid="567011538994429120">"Atpakaļ"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Sākums"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Izvēlne"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Jaunākās lietojumprogrammas"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Nesen izmantotās lietotnes"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Ievades metodes maiņas poga."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Saderības tālummaiņas poga."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Veikt tālummaiņu no mazāka ekrāna uz lielāku."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Dati: divas joslas."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Dati: trīs joslas."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Pilna piekļuve datu signālam."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Nav Wi-Fi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi: viena josla."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi: divas joslas."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi: trīs joslas."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Pilna piekļuve Wi-Fi signālam"</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Nav Wi-Fi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Wi-Fi: viena josla."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi: divas joslas."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi: trīs joslas."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Pilna piekļuve Wi-Fi signālam"</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"EDGE"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Nav SIM kartes."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth piesaiste."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Lidmašīnas režīms."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Akumulators: <xliff:g id="NUMBER">%d</xliff:g> procenti"</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Iestatījumu poga."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Paziņojumu poga."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Noņemt paziņojumu."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Sistēmas iestatījumi"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Paziņojumi"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Notīrīt paziņojumu"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ir iespējots."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS iegūšana."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Teletaips ir iespējots."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Zvana signāls — vibrācija."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Zvana signāls — kluss."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G–3G dati atspējoti"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G dati atspējoti"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilie dati atspējoti"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Dati atspējoti"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Norādītais datu izmantošanas ierobežojums ir sasniegts."\n\n"Izmantojot papildu datus, sakaru operators var no jums iekasēt maksu."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Norādītais datu izmantošanas ierobežojums ir sasniegts."\n\n"Izmantojot papildu datus, sakaru operators var no jums iekasēt maksu."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Atkārtoti iespējot datus"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nav interneta sav."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Izv. sav. ar Wi-Fi"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Notiek GPS meklēšana..."</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS iestatītā atrašanās vieta"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Notīrīt visus paziņojumus"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index cfdd68a..4288f9d 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Alih keluar dari senarai"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Maklumat aplikasi"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Tiada aplikasi terbaharu"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Buang aplikasi terbaharu"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 aplikasi terbaharu"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d aplikasi terbaharu"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Tiada pemberitahuan"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Sedang berlangsung"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Pemberitahuan"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Sila sambungkan pengecas"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Sila sambungkan pengecas"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Bateri semakin lemah."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"Berbaki <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Pengecasan USB tidak disokong."\n"Gunakan hanya pengecas yang dibekalkan."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"REDAM"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Pemberitahuan"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Baru-baru ini"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Tiada aplikasi terbaru."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Apl"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth ditambatkan"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurasikan kaedah input"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurasikan kaedah input"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Guna ppn kekunci fizikal"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Benarkan aplikasi <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses peranti USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Benarkan aplikasi <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses aksesori USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Buka <xliff:g id="ACTIVITY">%1$s</xliff:g> apabila peranti USB ini disambungkan?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Buka <xliff:g id="ACTIVITY">%1$s</xliff:g> apabila aksesori USB ini disambungkan?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Tiada apl yg dipsg boleh berfgsi dgn aksri USB ini. Ketahui ttg aksri ini di <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Aksesori USB"</string>
<string name="label_view" msgid="6304565553218192990">"Lihat"</string>
<string name="always_use_device" msgid="1450287437017315906">"Gunakan secara lalai untuk peranti USB ini"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Gunakan secara lalai untuk aksesori USB ini"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zum untuk memenuhi skrin"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Regang utk memenuhi skrin"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Keserasian Zum"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Keserasian Zum"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Apabila apl direka untuk skrin yang lebih kecil, kawalan zum akan muncul di tepi jam."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Tangkapan skrin disimpan ke Galeri"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Tidak boleh menyimpan tangkapan skrin. Storan luaran mungkin sedang digunakan."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Pilihan pemindahan fail USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Lekapkan sebagai pemain media (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Lekapkan sebagai kamera (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Pasang aplikasi Pemindahan Fail Android untuk Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Pasang aplikasi Pemindahan Fail Android untuk Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Kembali"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Rumah"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Aplikasi terbaru"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Aplikasi terbaharu"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Butang tukar kaedah input."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Butang zum keserasian."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Skrin zum lebih kecil kepada lebih besar."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data dua bar."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data tiga bar."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Isyarat data penuh."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Tiada WiFi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"WiFi satu bar."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"WiFi dua bar."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi tiga bar."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Isyarat WiFi penuh."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Tiada WiFi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"WiFi satu bar."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"WiFi dua bar."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"WiFi tiga bar."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Isyarat WiFi penuh."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Tiada SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Penambatan Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Mod pesawat"</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Bateri <xliff:g id="NUMBER">%d</xliff:g> peratus."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Butang tetapan."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Butang pemberitahuan."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Alih keluar pemberitahuan."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Tetapan sistem."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Pemberitahuan."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Padamkan pemberitahuan."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS didayakan."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS sedang mendapatkan."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Mesin Teletaip didayakan."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Pendering bergetar."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Pendering senyap."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Data 2G-3G dilumpuhkan"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data 4G dilumpuhkan"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Data mudah alih dilumpuhkan"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data dilumpuhkan"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Had penggunaan data yang ditentukan telah dicapai."\n\n"Penggunaan data tambahan mungkin dikenakan caj oleh pembawa."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Had penggunaan data yang ditentukan telah dicapai."\n\n"Penggunaan data tambahan mungkin dikenakan caj oleh pembawa."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Dayakan semula data"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Tiada smbg Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi disambungkan"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Mencari GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi ditetapkan oleh GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Padamkan semua pemberitahuan."</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index b5ead99..b51665f 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Fjern fra listen"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Info om app"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Ingen nylige apper"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Avvis nylige apper"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"Én nylig app"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d nylige apper"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ingen varslinger"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Aktiviteter"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Varslinger"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Koble til en lader"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Koble til en lader"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Lavt batterinivå."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> gjenværende"</string>
<string name="invalid_charger" msgid="4549105996740522523">"USB-lading støttes ikke."\n"Bruk kun den medfølgende laderen."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"DEMPET"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Varslinger"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Nylig"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Ingen nylig brukte programmer."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Programmer"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tilknyttet"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurer inndatametoder"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurer inndatametoder"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Bruk fysisk tastatur"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Vil du tillate at applikasjonen <xliff:g id="APPLICATION">%1$s</xliff:g> får tilgang til USB-enheten?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Vil du tillate at applikasjonen <xliff:g id="APPLICATION">%1$s</xliff:g> får tilgang til USB-tilbehøret?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vil du åpne <xliff:g id="ACTIVITY">%1$s</xliff:g> når denne USB-enheten er tilkoblet?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Vil du åpne <xliff:g id="ACTIVITY">%1$s</xliff:g> når dette USB-tilbehøret er tilkoblet?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Ingen installerte applikasjoner støtter dette USB-tilbehøret. Les mer om tilbehøret på <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB-enhet"</string>
<string name="label_view" msgid="6304565553218192990">"Vis"</string>
<string name="always_use_device" msgid="1450287437017315906">"Bruk som standard for denne USB-enheten"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Bruk som standard for dette USB-tilbehøret"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoom for å fylle skjermen"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Strekk for å fylle skjerm"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Kompatibilitets-zooming"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Kompatibilitets-zooming"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Når en app er utformet for en mindre skjerm, vises det en zoomkontroll ved klokken."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Skjermdump ble lagret i galleriet"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Kunne ikke lagre skjermdump. Det kan hende at ekstern lagring er i bruk."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Altern. for USB-filoverføring"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Sett inn som mediespiller (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Sett inn som kamera (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Installer Android File Transfer for Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Installer Android File Transfer for Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Tilbake"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Startside"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Meny"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Nyere applikasjoner"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Nylige apper"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Bytt knapp for inndatametode."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Zoomknapp for kompatibilitet."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom fra mindre til større skjerm."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data – to stolper."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data – tre stolper."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Datasignal er fullt."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Ingen Wi-Fi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi – én stolpe."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi – to stolper."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi – tre stolper."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi-signal er fullt."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Ingen Wi-Fi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Wi-Fi – én stolpe."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi – to stolper."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi – tre stolper."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Wi-Fi-signal er fullt."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Uten SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-deling."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Flymodus."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Batteri – <xliff:g id="NUMBER">%d</xliff:g> prosent."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Innstillinger-knapp."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Knapp for varslinger"</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Fjern varsling."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Systeminnstillinger."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Varslinger."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Fjern varsling"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS er aktivert."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Henting av GPS-signal."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter er aktivert."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibreringsmodus."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Stille modus."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G-data er deaktivert"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-data er deaktivert"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobildata er deaktivert"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data deaktivert"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Den angitte databruksgrensen er nådd."\n\n"Ytterligere databruk kan medføre høyere kostnader hos leverandøren."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Den angitte databruksgrensen er nådd."\n\n"Ytterligere databruk kan medføre høyere kostnader hos leverandøren."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Aktiver data på nytt"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Ingen Internett-forbindelse"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi tilkoblet"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Søker etter GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Posisjon angitt av GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Fjern alle varslinger."</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 44e1b54..038bcdd 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Verwijderen uit lijst"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"App-info"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Geen recente apps"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Recente apps negeren"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 recente app"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d recente apps"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Geen meldingen"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Actief"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Meldingen"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Sluit de oplader aan"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Sluit de oplader aan"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"De accu raakt leeg."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> resterend"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Opladen via USB niet ondersteund."\n"Gebruik alleen de bijgeleverde oplader."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"DEMPEN"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Meldingen"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Recent"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Geen recente apps."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Apps"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth getetherd"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Invoermethoden configureren"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Invoermethoden configureren"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Fysiek toetsenbord gebruiken"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"De applicatie <xliff:g id="APPLICATION">%1$s</xliff:g> toegang tot het USB-apparaat geven?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"De applicatie <xliff:g id="APPLICATION">%1$s</xliff:g> toegang tot het USB-accessoire geven?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"<xliff:g id="ACTIVITY">%1$s</xliff:g> openen wanneer dit USB-apparaat wordt aangesloten?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"<xliff:g id="ACTIVITY">%1$s</xliff:g> openen wanneer dit USB-accessoire wordt aangesloten?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Er zijn geen geïnstalleerde applicaties die werken met dit USB-accessoire. Meer informatie over dit accessoire vindt u op <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB-accessoire"</string>
<string name="label_view" msgid="6304565553218192990">"Weergeven"</string>
<string name="always_use_device" msgid="1450287437017315906">"Standaard gebruiken voor dit USB-apparaat"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Standaard gebruiken voor dit USB-accessoire"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoom om scherm te vullen"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Rek uit v. schermvulling"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Compatibiliteitszoom"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Compatibiliteitszoom"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Wanneer een app is ontworpen voor een kleiner scherm, wordt naast de klok een zoomknop weergegeven."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Schermafbeelding is opgeslagen in de galerij"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Kan schermafbeelding niet opslaan. Mogelijk is de externe opslag in gebruik."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opties voor USB-bestandsoverdracht"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Koppelen als mediaspeler (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Koppelen als camera (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Applicatie Android File Transfer voor Mac installeren"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Applicatie Android File Transfer voor Mac installeren"</string>
<string name="accessibility_back" msgid="567011538994429120">"Terug"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Startpagina"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Recente apps"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Recente apps"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Knop voor wijzigen invoermethode."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Knop voor compatibiliteitszoom."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Kleiner scherm uitzoomen naar groter scherm."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Gegevens: twee streepjes."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Gegevens: drie streepjes."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Gegevenssignaal is op volle sterkte."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Geen Wi-Fi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi: één streepje."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi: twee streepjes."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi: drie streepjes."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi-signaal is op volledige sterkte."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Geen Wi-Fi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Wi-Fi: één streepje."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi: twee streepjes."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi: drie streepjes."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Wi-Fi-signaal is op volledige sterkte."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Geen simkaart."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-tethering."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Vliegmodus."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Accu: <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"De knop \'Instellingen\'."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Knop voor meldingen."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Melding verwijderen."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Systeeminstellingen."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Meldingen."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Melding wissen"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ingeschakeld."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Verbinding maken met GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter ingeschakeld."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Belsoftware trilt."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Belsoftware stil."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-/3G-gegevens uitgeschakeld"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-gegevens uitgeschakeld"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobiele gegevens uitgeschakeld"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Gegevens uitgeschakeld"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"De opgegeven limiet voor gegevensgebruik is bereikt."\n\n"Aanvullend gegevensgebruik kan leiden tot providerkosten."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"De opgegeven limiet voor gegevensgebruik is bereikt."\n\n"Aanvullend gegevensgebruik kan leiden tot providerkosten."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Gegevens opnieuw inschakelen"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Geen internetverbinding"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Verbonden via Wi-Fi"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Zoeken naar GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Locatie bepaald met GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Alle meldingen wissen."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 58b852d..e4b96ba 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Usuń z listy"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informacje o aplikacji"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Brak ostatnio uruchomionych aplikacji."</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Ukryj ostatnie aplikacje"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 ostatnia aplikacja"</item>
+ <item quantity="other" msgid="1040784359794890744">"Ostatnie aplikacje: %d"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Brak powiadomień"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Bieżące"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Powiadomienia"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Podłącz ładowarkę"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Podłącz ładowarkę"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Bateria wkrótce zostanie rozładowana."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"Pozostało: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Ładowanie przy użyciu złącza USB nie jest obsługiwane."\n"Należy używać tylko dołączonej ładowarki."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"WYGAŚ"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTOM."</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Powiadomienia"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Najnowsze"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Brak ostatnio używanych aplikacji."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplikacje"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth – podłączono"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfiguruj metody wprowadzania"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfiguruj metody wprowadzania"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Używaj klawiatury fizycznej"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Czy zezwolić aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na dostęp do urządzenia USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Czy zezwolić aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na dostęp do akcesorium USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Czy otworzyć <xliff:g id="ACTIVITY">%1$s</xliff:g> po podłączeniu tego urządzenia USB?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Czy otworzyć <xliff:g id="ACTIVITY">%1$s</xliff:g> po podłączeniu tego akcesorium USB?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Zainstalowane aplikacje nie działają z tym akcesorium USB. Więcej informacji: <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Akcesorium USB"</string>
<string name="label_view" msgid="6304565553218192990">"Wyświetl"</string>
<string name="always_use_device" msgid="1450287437017315906">"Używaj domyślnie dla tego urządzenia USB"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Używaj domyślnie dla tego akcesorium USB"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Powiększ, aby wypełnić ekran"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Rozciągnij, aby wypełnić ekran"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Powiększenie w trybie zgodności"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Powiększenie w trybie zgodności"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Jeśli aplikacja została przystosowana do mniejszego ekranu, obok zegara zostanie wyświetlony element sterujący powiększeniem."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Zrzut ekranu został zapisany w galerii."</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Nie można zapisać zrzutu ekranu. Pamięć zewnętrzna może być używana."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB – opcje przesyłania plików"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Podłącz jako odtwarzacz multimedialny (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Podłącz jako aparat (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Zainstaluj aplikację Android File Transfer dla Mac OS"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Zainstaluj aplikację Android File Transfer dla Mac OS"</string>
<string name="accessibility_back" msgid="567011538994429120">"Wróć"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Ekran główny"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Najnowsze aplikacje"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Ostatnie aplikacje"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Przycisk przełączania metody wprowadzania."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Przycisk powiększenia na potrzeby zgodności."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Powiększa mniejszy ekran do większego."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Dane: dwa paski."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Dane: trzy paski."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Dane: pełna moc sygnału."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Brak sieci Wi-Fi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Sieć Wi-Fi: jeden pasek."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Sieć Wi-Fi: dwa paski."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Sieć Wi-Fi: trzy paski."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Sieć Wi-Fi: pełna moc sygnału."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Brak sieci Wi-Fi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Sieć Wi-Fi: jeden pasek."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Sieć Wi-Fi: dwa paski."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Sieć Wi-Fi: trzy paski."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Sieć Wi-Fi: pełna moc sygnału."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Brak karty SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Powiązanie Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Tryb samolotowy."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria: <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Przycisk Ustawienia."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Przycisk powiadomień."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Usuń powiadomienie."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Ustawienia systemu."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Powiadomienia."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Usuń powiadomienie."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS włączony."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Pobieranie danych GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Dalekopis (TTY) włączony."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Dzwonek z wibracjami."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Dzwonek wyciszony."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Wyłączono transmisję danych 2G/3G"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Wyłączono transmisję danych 4G"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Wyłączono komórkową transmisję danych"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Wyłączono transmisję danych"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Osiągnięto określony limit transmisji danych."\n\n"Operator może pobierać opłaty za przesyłanie dodatkowych danych."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Osiągnięto określony limit transmisji danych."\n\n"Operator może pobierać opłaty za przesyłanie dodatkowych danych."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Włącz transmisję danych"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Brak internetu"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: połączono"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Wyszukiwanie sygnału GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokalizacja ustawiona według GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Usuń wszystkie powiadomienia."</string>
</resources>
diff --git a/packages/SystemUI/res/values-port/config.xml b/packages/SystemUI/res/values-port/config.xml
new file mode 100644
index 0000000..bbae18d
--- /dev/null
+++ b/packages/SystemUI/res/values-port/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources>
+ <!-- Whether we're using the tablet-optimized recents interface (we use this
+ value at runtime for some things) -->
+ <integer name="status_bar_recents_bg_gradient_degrees">90</integer>
+</resources>
+
diff --git a/packages/SystemUI/res/values-port/dimens.xml b/packages/SystemUI/res/values-port/dimens.xml
index 2bafd30..de7b836 100644
--- a/packages/SystemUI/res/values-port/dimens.xml
+++ b/packages/SystemUI/res/values-port/dimens.xml
@@ -18,15 +18,18 @@
<resources>
<!-- Recent Applications parameters -->
<!-- How far the thumbnail for a recent app appears from left edge -->
- <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen>
+ <dimen name="status_bar_recents_thumbnail_left_margin">20dp</dimen>
<!-- Padding for text descriptions -->
<dimen name="status_bar_recents_text_description_padding">8dp</dimen>
<!-- Width of application label text -->
<dimen name="status_bar_recents_app_label_width">88dip</dimen>
<!-- Left margin of application label text -->
- <dimen name="status_bar_recents_app_label_left_margin">16dip</dimen>
+ <dimen name="status_bar_recents_app_label_left_margin">0dip</dimen>
<!-- Margin between recents container and glow on the right -->
<dimen name="status_bar_recents_right_glow_margin">100dip</dimen>
<!-- Padding between recents items -->
<dimen name="status_bar_recents_item_padding">0dip</dimen>
+ <!-- Where to place the app icon over the thumbnail -->
+ <dimen name="status_bar_recents_app_icon_left_margin">0dp</dimen>
+ <dimen name="status_bar_recents_app_icon_top_margin">8dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index d2a6dc4..193c9a8 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Remover da lista"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informações da aplicação"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Não existem aplicações recentes"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Rejeitar aplicações recentes"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 aplicação recente"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d aplicações recentes"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Sem notificações"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Em curso"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificações"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Ligue o carregador"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Ligue o carregador"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"A bateria está a ficar fraca."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restante"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Carregamento USB não suportado. "\n"Utilize apenas o carregador fornecido."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"D. SOM"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificações"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Nenhuma aplicação recente."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplicações"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth ligado"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurar métodos de entrada"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos de entrada"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizar teclado físico"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Permitir que a aplicação <xliff:g id="APPLICATION">%1$s</xliff:g> aceda ao dispositivo USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Permitir que a aplicação <xliff:g id="APPLICATION">%1$s</xliff:g> aceda ao acessório USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> quando este dispositivo USB estiver ligado?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> quando este acessório USB estiver ligado?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Nenhuma das aplicações instaladas funciona com este acessório USB. Saiba mais sobre este acessório em <xliff:g id="URL">%1$s</xliff:g>."</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Acessório USB"</string>
<string name="label_view" msgid="6304565553218192990">"Ver"</string>
<string name="always_use_device" msgid="1450287437017315906">"Utilizar por predefinição para este aparelho USB"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Utilizar por predefinição para este acessório USB"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoom para preencher o ecrã"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Esticar p. caber em ec. int."</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Compatibilidade de zoom"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Compatibilidade de zoom"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Sempre que uma aplicação tiver sido concebida para ecrãs mais pequenos, aparecerá um controlo de zoom junto ao relógio."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Captura de ecrã guardada na Galeria"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Não foi possível guardar a captura de ecrã. O armazenamento externo poderá estar a ser utilizado."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opções de transm. de fich. USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Montar como leitor de multimédia (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montar como câmara (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Instalar a ap. Trans. de Fic. do Android para Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Instalar a ap. Trans. de Fic. do Android para Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Anterior"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Página inicial"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Aplicações recentes"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Aplicações recentes"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Alternar botão de método de introdução."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botão zoom de compatibilidade."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom menor para ecrã maior."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Duas barras de dados."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Três barras de dados."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Sinal de dados completo."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Sem Wi-Fi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Uma barra de Wi-FI."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Duas barras de Wi-Fi."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Três barras de Wi-Fi."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Sinal Wi-Fi completo."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Sem Wi-Fi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Uma barra de Wi-FI."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Duas barras de Wi-Fi."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Três barras de Wi-Fi."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Sinal Wi-Fi completo."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Sem SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Ligação Bluetooth via telemóvel."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo de avião"</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria a <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Botão Definições."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Botão de notificações."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Remover notificação."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Definições do sistema"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificações."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Limpar notificações"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ativado."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Adquirir GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Teletipo ativado."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Campainha em vibração."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Campainha em silêncio."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Os dados 2G-3G estão desativados"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Os dados 4G estão desativados"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Os dados móveis estão desativados"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Dados desativados"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"O limite de utilização de dados especificado foi atingido."\n\n"A utilização de dados adicionais poderá estar sujeita a tarifas por parte do operador."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"O limite de utilização de dados especificado foi atingido."\n\n"A utilização de dados adicionais poderá estar sujeita a tarifas por parte do operador."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Reativar dados"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Sem ligação internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi ligado"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"A procurar GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Localização definida por GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index faa46a9..afb4729 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Remover da lista"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informações do aplicativo"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Nenhum aplicativo recente"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Dispensar aplicativos recentes"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 aplicativo recente"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d aplicativos recentes"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Sem notificações"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Em andamento"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificações"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Conecte o carregador"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Conecte o carregador"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"A bateria está ficando baixa."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restante"</string>
<string name="invalid_charger" msgid="4549105996740522523">"O carregamento via USB não é suportado."\n"Use apenas o carregador fornecido."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"MUDO"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificações"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Nenhum aplicativo recente."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplicativos"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth vinculado"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurar métodos de entrada"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos de entrada"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Usar o teclado físico"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Permitir que o aplicativo <xliff:g id="APPLICATION">%1$s</xliff:g> acesse o dispositivo USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Permitir que o aplicativo <xliff:g id="APPLICATION">%1$s</xliff:g> acesse o acessório USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> quando este dispositivo USB estiver conectado?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> quando este acessório USB estiver conectado?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Nenhum apl. instalado funciona com o acess. USB. Saiba mais sobre o acessório em <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Acessório USB"</string>
<string name="label_view" msgid="6304565553218192990">"Visualizar"</string>
<string name="always_use_device" msgid="1450287437017315906">"Usar por padrão para este dispositivo USB"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Usar por padrão para este acessório USB"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoom p/ preencher a tela"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Ampliar p/ preencher tela"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom em modo de compatibilidade"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom em modo de compatibilidade"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Quando um aplicativo é desenvolvido para uma tela menor, um controle de zoom é exibido perto do relógio."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"A captura de tela foi salva na Galeria"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Não foi possível salvar a captura de tela. Armazenamento externo pode estar em uso."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opções transf. arq. por USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Conectar como media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montar como uma câmera (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Instalar aplic. Android File Transfer para Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Instalar aplic. Android File Transfer para Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Voltar"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Página inicial"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Aplicações recentes"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Aplicativos recentes"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Alterar botão do método de entrada."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botão de zoom da compatibilidade."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Aumentar a tela com zoom."</string>
@@ -90,40 +107,43 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Duas barras de sinal de dados."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Três barras do sinal de dados."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Sinal de dados cheio."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Sem Wi-Fi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Uma barra de sinal Wi-Fi."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Duas barras de sinal Wi-Fi."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Três barras de sinal Wi-Fi."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Sinal do Wi-Fi cheio."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Sem Wi-Fi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Uma barra de sinal Wi-Fi."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Duas barras de sinal Wi-Fi."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Três barras de sinal Wi-Fi."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Sinal do Wi-Fi cheio."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Sem SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Vínculo Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo de avião."</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Botão Configurações."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Botão de notificações."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Remover notificação."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Configurações do sistema"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificações."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Limpar notificação."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ativado."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Aquisição de GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTYpewriter ativado."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibração da campainha."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Campainha silenciosa."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Dados 2G e 3G desativados"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dados 4G desativados"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Dados móveis desativados"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Dados desativados"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"O limite de uso de dados especificado foi alcançado."\n\n"O uso de dados adicionais poderá gerar cobranças da operadora."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"O limite de uso de dados especificado foi alcançado."\n\n"O uso de dados adicionais poderá gerar cobranças da operadora."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Reativar dados"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Sem conexão à Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi conectado"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Buscando GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Local definido por GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
</resources>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index bef7f2c..17f62dd 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -32,10 +32,14 @@
<skip />
<!-- no translation found for status_bar_no_recent_apps (6576392951053994640) -->
<skip />
+ <!-- no translation found for status_bar_accessibility_dismiss_recents (4576076075226540105) -->
+ <skip />
+ <!-- no translation found for status_bar_accessibility_recent_apps:one (5854176083865845541) -->
+ <!-- no translation found for status_bar_accessibility_recent_apps:other (1040784359794890744) -->
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nagins avis"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Actual"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Avis"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Connectar il chargiabattarias"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Connectar il chargiabattarias"</string>
<!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"L\'accu è prest vid."</string>
<!-- no translation found for battery_low_percent_format (1077244949318261761) -->
<skip />
@@ -56,26 +60,21 @@
<skip />
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
- <string name="recent_tasks_title" msgid="3691764623638127888">"Utilisà sco ultim"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
- <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (3504292471512317827) -->
<skip />
<!-- no translation found for status_bar_use_physical_keyboard (3695516942412442936) -->
<skip />
- <!-- no translation found for usb_device_permission_prompt (3816016361969816903) -->
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
<skip />
- <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) -->
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
<skip />
<!-- no translation found for usb_device_confirm_prompt (5161205258635253206) -->
<skip />
<!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) -->
<skip />
- <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) -->
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
<skip />
<!-- no translation found for title_usb_accessory (4966265263465181372) -->
<skip />
@@ -89,13 +88,23 @@
<skip />
<!-- no translation found for compat_mode_off (4434467572461327898) -->
<skip />
- <!-- no translation found for compat_mode_help_header (7020175705401506719) -->
+ <!-- no translation found for compat_mode_help_header (7969493989397529910) -->
<skip />
<!-- no translation found for compat_mode_help_body (4946726776359270040) -->
<skip />
- <!-- no translation found for screenshot_saving_toast (8592630119048713208) -->
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
<skip />
- <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
<skip />
<!-- no translation found for usb_preference_title (6551050377388882787) -->
<skip />
@@ -103,7 +112,7 @@
<skip />
<!-- no translation found for use_ptp_button_title (7517127540301625751) -->
<skip />
- <!-- no translation found for installer_cd_button_title (8485631662288445893) -->
+ <!-- no translation found for installer_cd_button_title (2312667578562201583) -->
<skip />
<!-- no translation found for accessibility_back (567011538994429120) -->
<skip />
@@ -111,7 +120,7 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
- <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <!-- no translation found for accessibility_recent (8571350598987952883) -->
<skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
@@ -153,15 +162,15 @@
<skip />
<!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
<skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
+ <!-- no translation found for accessibility_no_wifi (7455607460517331976) -->
<skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
+ <!-- no translation found for accessibility_wifi_one_bar (6854947280074467207) -->
<skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
+ <!-- no translation found for accessibility_wifi_two_bars (3344340012058984348) -->
<skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
+ <!-- no translation found for accessibility_wifi_three_bars (928322805193265041) -->
<skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
+ <!-- no translation found for accessibility_wifi_signal_full (4826278754383492058) -->
<skip />
<!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
<skip />
@@ -175,7 +184,7 @@
<skip />
<!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
<skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
+ <!-- no translation found for accessibility_data_connection_wifi (2324496756590645221) -->
<skip />
<!-- no translation found for accessibility_no_sim (8274017118472455155) -->
<skip />
@@ -185,11 +194,11 @@
<skip />
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
+ <!-- no translation found for accessibility_settings_button (799583911231893380) -->
<skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
+ <!-- no translation found for accessibility_notifications_button (4498000369779421892) -->
<skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
+ <!-- no translation found for accessibility_remove_notification (3603099514902182350) -->
<skip />
<!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
<skip />
@@ -201,6 +210,8 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
<!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
@@ -209,7 +220,7 @@
<skip />
<!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <!-- no translation found for data_usage_disabled_dialog (3853117269051806280) -->
<skip />
<!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
@@ -221,4 +232,6 @@
<skip />
<!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
+ <!-- no translation found for accessibility_clear_all (5235938559247164925) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index cdb7c26..79ac357 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Eliminaţi din listă"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informaţii despre aplicaţie"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Nu există aplicaţii recente"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Renunţaţi la aplicaţiile recente"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 aplicaţie recentă"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d (de) aplicaţii recente"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nicio notificare"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"În desfăşurare"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificări"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Conectaţi încărcătorul"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Conectaţi încărcătorul"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Bateria este descărcată."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"Rămas: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Încărcarea USB nu este acceptată. "\n"Utilizaţi numai încărcătorul furnizat."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"DEZAC."</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTOM."</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificări"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Nu există aplicaţii recente."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplicaţii"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Conectat prin tethering prin Bluetooth"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configuraţi metode de intrare"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configuraţi metode de intrare"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizaţi tastat. fizică"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Permiteţi aplicaţiei <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze dispozitivul USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Permiteţi aplicaţiei <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze accesoriul USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Deschideţi <xliff:g id="ACTIVITY">%1$s</xliff:g> la conectarea acestui dispozitiv USB?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Deschideţi <xliff:g id="ACTIVITY">%1$s</xliff:g> la conectarea acestui accesoriu USB?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Aplic. instal. nu funcţ. cu acest acces. USB. Aflaţi despre acest acces. la <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Accesoriu USB"</string>
<string name="label_view" msgid="6304565553218192990">"Afişaţi"</string>
<string name="always_use_device" msgid="1450287437017315906">"Utilizaţi în mod prestabilit pt. acest dispoz. USB"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Utiliz. în mod prestabilit pt. acest accesoriu USB"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoom pt. a umple ecranul"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Înt. pt. a umple ecranul"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom de compatibilitate"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom de compatibilitate"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Atunci când o aplicaţie a fost concepută pentru un ecran mai mic, o comandă pentru mărire/micşorare va apărea alături de ceas."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Captura de ecran a fost salvată în Galerie"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Captura de ecran nu a putut fi salvată. Este posibil să fie utilizată stocarea externă."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opţiuni pentru transferul de fişiere prin USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Montaţi ca player media (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montaţi drept cameră foto (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Instalaţi aplicaţia Transfer de fişiere Android pentru Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Instalaţi aplicaţia Transfer de fişiere Android pentru Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Înapoi"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Ecranul de pornire"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Meniu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Aplicaţii recente"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Aplicaţii recente"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Buton pentru comutarea metodei de introducere."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Buton zoom pentru compatibilitate."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Faceţi zoom de la o imagine mai mică la una mai mare."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Semnal pentru date: două bare."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Semnal pentru date: trei bare."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Semnal pentru date: complet."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Nu există semnal Wi-Fi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Semnal Wi-Fi: o bară."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Semnal Wi-Fi: două bare."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Semnal Wi-Fi: trei bare."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Semnal Wi-Fi: complet."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Nu există semnal Wi-Fi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Semnal Wi-Fi: o bară."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Semnal Wi-Fi: două bare."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Semnal Wi-Fi: trei bare."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Semnal Wi-Fi: complet."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"EDGE"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Niciun card SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Conectarea ca modem prin Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Mod Avion."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Baterie: <xliff:g id="NUMBER">%d</xliff:g> procente."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Butonul Setări."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Buton pentru notificări."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Eliminaţi notificarea."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Setări de sistem."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificări."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Ştergeţi notificarea."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS activat."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Se obţine GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter activat."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibrare sonerie."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Sonerie silenţioasă."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Datele 2G-3G au fost dezactivate"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datele 4G au fost dezactivate"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Datele mobile au fost dezactivate"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Utilizare date dezactivată"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"A fost atinsă limita de utilizare a datelor specificată."\n\n"Utilizarea unor date suplimentare poate atrage costuri impuse de operator."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"A fost atinsă limita de utilizare a datelor specificată."\n\n"Utilizarea unor date suplimentare poate atrage costuri impuse de operator."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Reactivaţi datele"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Fără conex. internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi conectat"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Se caută GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Locaţie setată prin GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Ştergeţi toate notificările."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index ff1fa0d..b7f9b69 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -23,13 +23,18 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Очистить"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Не беспокоить"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Показать уведомления"</string>
- <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Удаление приложения из списка"</string>
- <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Сведения о приложении"</string>
+ <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Удаление из списка"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"О приложении"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Нет данных"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Закрыть недавние приложения"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"Недавних приложений: 1"</item>
+ <item quantity="other" msgid="1040784359794890744">"Недавних приложений: %d"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Нет уведомлений"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Текущие"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Уведомления"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Подключите зарядное устройство"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Подключите зарядное устройство"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Батарея разряжена."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"Осталось: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Зарядка через порт USB не поддерживается."\n"Используйте только зарядное устройство из комплекта поставки."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"ВЫКЛ."</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"АВТО"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Уведомления"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Недавние"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Новых приложений нет"</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Приложения"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Общий модем доступен через Bluetooth"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Настроить способ ввода"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Настроить способ ввода"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Использовать физическую клавиатуру"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Разрешить приложению <xliff:g id="APPLICATION">%1$s</xliff:g> доступ к USB-устройству?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Разрешить приложению <xliff:g id="APPLICATION">%1$s</xliff:g> доступ к USB-аксессуару?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Запускать <xliff:g id="ACTIVITY">%1$s</xliff:g> при подключении этого USB-устройства?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Запускать <xliff:g id="ACTIVITY">%1$s</xliff:g> при подключении этого USB-аксессуара?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Установленные приложения не поддерживают этот USB-аксессуар. Подробнее о нем читайте здесь: <xliff:g id="URL">%1$s</xliff:g>."</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB-устройство"</string>
<string name="label_view" msgid="6304565553218192990">"Просмотр"</string>
<string name="always_use_device" msgid="1450287437017315906">"Использовать по умолчанию для этого USB-устройства"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Использовать по умолчанию для этого USB-аксессуара"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Подогнать по размерам экрана"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Растянуть на весь экран"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Масштаб и совместимость"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Масштаб и совместимость"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Если приложение рассчитано на экран меньших размеров, рядом с часами появятся средства масштабирования."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Скриншот сохранен в галерее"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Не удается сохранить скриншот. Возможно, внешние накопители используются."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Параметры передачи через USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Подключить как мультимедийный проигрыватель (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Установить как камеру (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Установить Android File Transfer для Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Установить Android File Transfer для Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Назад"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Главная страница"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Меню"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Последние приложения"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Недавние приложения"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Кнопка переключения способа ввода."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Кнопка масштабирования (режим совместимости)"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Уменьшение изображения для увеличения свободного места на экране."</string>
@@ -90,40 +107,43 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Сигнал передачи данных: два деления."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Сигнал передачи данных: три деления."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Надежный сигнал передачи данных."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Сигнал Wi-Fi отсутствует."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi: одно деление."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi: два деления."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi: три деления."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Надежный сигнал Wi-Fi."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Сигнал Wi-Fi отсутствует."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Wi-Fi: одно деление."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi: два деления."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi: три деления."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Надежный сигнал Wi-Fi."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"SIM-карта отсутствует."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Общий Bluetooth-модем."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим полета."</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Кнопка вызова настроек."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Кнопка вызова панели уведомлений"</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Удалить уведомление."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Настройки системы"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Уведомления"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Удалить уведомление"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"Система GPS включена."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Установление связи с GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Телетайп включен."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Вибровызов."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Беззвучный режим."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Передача данных по каналам 2G и 3G отключена"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Передача данных по каналу 4G отключена"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Мобильный Интернет отключен"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Передача данных отключена"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Достигнут лимит трафика."\n\n"За загрузку дополнительных данных оператор может взимать плату."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Достигнут лимит трафика."\n\n"За загрузку дополнительных данных оператор может взимать плату."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Восстановить подключение"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Нет подключения к Интернету"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi подключено"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Поиск GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Местоположение установлено с помощью GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Удалить все уведомления"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 1b91da8..7ae9240 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Odstrániť zo zoznamu"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informácie o aplikácii"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Žiadne nedávne aplikácie"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Odmietnuť nové aplikácie"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 nová aplikácia"</item>
+ <item quantity="other" msgid="1040784359794890744">"Počet nových aplikácií: %d"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Žiadne upozornenia"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Prebiehajúce"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Upozornenia"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Pripojte nabíjačku"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Pripojte nabíjačku"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Batéria je skoro vybitá."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"Zostáva: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Nabíjanie pomocou rozhrania USB nie je podporované."\n"Používajte iba nabíjačku, ktorá bola dodaná spolu so zariadením."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"STLMIŤ"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Upozornenia"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Najnovšie"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Žiadne nedávno použité aplikácie."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplikácie"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Zdieľané dátové pripojenie cez Bluetooth"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurovať metódy vstupu"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurovať metódy vstupu"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Použiť fyzickú klávesnicu"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k zariadeniu USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k periférnemu zariadeniu USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Chcete pri pripojení tohto zariadenia USB otvoriť aplikáciu <xliff:g id="ACTIVITY">%1$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Chcete pri pripojení tohto periférneho zariadenia USB otvoriť aplikáciu <xliff:g id="ACTIVITY">%1$s</xliff:g>?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"S týmto periférnym zariad. USB nefunguje žiadna nainštalovaná aplikácia. Viac informácií nájdete na stránkach <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Periférne zariadenie USB"</string>
<string name="label_view" msgid="6304565553218192990">"Zobraziť"</string>
<string name="always_use_device" msgid="1450287437017315906">"Pre toto zariadenie USB použiť ako predvolené"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Pre toto periférne zar. USB použiť ako predvolené"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Priblížiť na celú obrazovku"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Na celú obrazovku"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Kompatibilné priblíženie"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Kompatibilné priblíženie"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Ak je aplikácia navrhnutá pre menšiu obrazovku, zobrazí sa vedľa hodín ovládací prvok priblíženia."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Snímka obrazovky bola uložená do Galérie"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Snímku obrazovky sa nepodarilo uložiť. Externý ukladací priestor sa možno práve používa."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Možnosti prenosu súborov USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Pripojiť ako prehrávač médií (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Pripojiť ako fotoaparát (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Inštalovať aplikáciu Prenos súborov Android pre systém Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Inštalovať aplikáciu Prenos súborov Android pre systém Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Späť"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Plocha"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Nedávne aplikácie"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Nové aplikácie"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Tlačidlo prepnutia metódy vstupu."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Tlačidlo úpravy veľkosti z dôvodu kompatibility."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zväčšiť menší obrázok na väčšiu obrazovku."</string>
@@ -90,40 +107,43 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Dve čiarky signálu dátovej siete."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Tri čiarky signálu dátovej siete."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Plný signál dátovej siete."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Žiadna sieť Wi-Fi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Jedna čiarka signálu siete Wi-Fi."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Dve čiarky signálu siete Wi-Fi."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Tri čiarky signálu siete Wi-Fi."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Plný signál siete Wi-Fi."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Žiadna sieť Wi-Fi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Jedna čiarka signálu siete Wi-Fi."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Dve čiarky signálu siete Wi-Fi."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Tri čiarky signálu siete Wi-Fi."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Plný signál siete Wi-Fi."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Žiadna karta SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Zdieľanie dátového pripojenia cez Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Režim V lietadle."</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Tlačidlo Nastavenia."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Tlačidlo upozornení."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Odstrániť upozornenie."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Nastavenia systému."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Upozornenia."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Vymazať upozornenie."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS je povolené."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Prebieha zameriavanie GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Rozhranie TeleTypewriter je povolené."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibračné zvonenie."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Tiché zvonenie."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Dátové prenosy 2G a 3G sú zakázané"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dátové prenosy 4G sú zakázané"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilné dátové prenosy sú zakázané"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Dáta boli zakázané"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Dosiahli ste zadané obmedzenie dátových prenosov."\n\n"Za ďalšie používanie dátových prenosov vám operátor môže účtovať poplatky."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Dosiahli ste zadané obmedzenie dátových prenosov."\n\n"Za ďalšie používanie dátových prenosov vám operátor môže účtovať poplatky."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Znova povoliť dátové prenosy"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Bez prip. na Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: pripojené"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Vyhľadávanie satelitov GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Poloha nastavená pomocou GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazať všetky upozornenia."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index e95b241..35aca3c 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Odstrani s seznama"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Podatki o programu"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Ni nedavnih programov"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Zapre nedavne programe"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 nedavni program"</item>
+ <item quantity="other" msgid="1040784359794890744">"Nedavni programi v %d"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ni obvestil"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Trenutno"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Obvestila"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Priključite napajalnik"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Priključite napajalnik"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Baterija je skoraj prazna."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> preostalo"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Polnjenje po povezavi USB ni podprto."\n"Uporabite priloženi polnilnik."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"TIHO"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"SAMOD."</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Obvestila"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Nedavno"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Ni novih programov."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Programi"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Internetna povezava prek Bluetootha"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Nastavitev načinov vnosa"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Nastavitev načinov vnosa"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Uporabi fizično tipkovn."</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Želite programu <xliff:g id="APPLICATION">%1$s</xliff:g> omogočiti dostop do naprave USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Želite programu <xliff:g id="APPLICATION">%1$s</xliff:g> omogočiti dostop do dodatka USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Želite, da se odpre <xliff:g id="ACTIVITY">%1$s</xliff:g>, ko priključite to napravo USB?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Želite, da se odpre <xliff:g id="ACTIVITY">%1$s</xliff:g>, ko priključite ta dodatek USB?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Noben nameščen program ne deluje s tem dodatkom USB. Več o tem dodatku: <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Dodatek USB"</string>
<string name="label_view" msgid="6304565553218192990">"Prikaži"</string>
<string name="always_use_device" msgid="1450287437017315906">"Privzeto uporabi za to napravo USB"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Privzeto uporabi za ta dodatek USB"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Povečava čez cel zaslon"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Raztegnitev čez zaslon"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Povečava združljivosti"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Povečava združljivosti"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Če je program izdelan za manjše zaslone, se ob uri pokaže kontrolnik za povečavo."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Posnetek zaslona je shranjen v galerijo"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Posnetka zaslona ni mogoče shraniti. Zunanja shramba je morda v uporabi."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Možnosti prenosa datotek prek USB-ja"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Vpni kot predvajalnik (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Vpni kot fotoaparat (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Namestite program Android File Transfer za Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Namestite program Android File Transfer za Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Nazaj"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Začetni zaslon"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Meni"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Nedavna obvestila"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Nedavni programi"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Gumb za preklop načina vnosa."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Gumb povečave za združljivost."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Povečava manjšega na večji zaslon."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Podatki z dvema črticama."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Podatki s tremi črticami."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Podatkovni signal poln."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Ni povezave Wi-Fi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"WiFi z eno črtico."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi z dvema črticama."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi s tremi črticami."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Signal Wi-Fi poln."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Ni povezave Wi-Fi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"WiFi z eno črtico."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi z dvema črticama."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"WiFi s tremi črticami."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Signal Wi-Fi poln."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Ni kartice SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Internet prek Bluetootha."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Način za letalo."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Baterija <xliff:g id="NUMBER">%d</xliff:g> odstotkov."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Gumb za nastavitve."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Gumb za obvestila."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Odstranite obvestilo."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Sistemske nastavitve."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Obvestila."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Izbriši obvestilo."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS omogočen."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Pridobivanje GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter omogočen."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Zvonjenje z vibriranjem."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Zvonjenje izklopljeno."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Podatki 2G-3G so onemogočeni"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Podatki 4G so onemogočeni"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilni podatki so onemogočeni"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Podatki onemogočeni"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Dosežena je določena omejitev porabe podatkov."\n\n"Dodatno porabo podatkov vam lahko operater zaračuna."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Dosežena je določena omejitev porabe podatkov."\n\n"Dodatno porabo podatkov vam lahko operater zaračuna."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Znova omogoči podatke"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Ni internetne povez."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi povezan"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Iskanje GPS-a"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokacija nastavljena z GPS-om"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Izbriši vsa obvestila."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 08c0dd3..3583295 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Уклањање са листе"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Информације о апликацији"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Нема недавних апликација"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Одбаци недавне апликације"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 недавна апликација"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d недавних апликација"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Нема обавештења"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Текуће"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Обавештења"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Прикључите пуњач"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Прикључите пуњач"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Батерија ће се ускоро испразнити."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"преостало је <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Пуњење преко USB-а није подржано."\n"Користите само приложени пуњач."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"УГАСИ"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"АУТОM."</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Обавештења"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Недавно"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Нема недавних апликација"</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Google Apps"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Веза преко Bluetooth-а"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Конфигуриши методе уноса"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Конфигуриши методе уноса"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Користи физичку тастатуру"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Желите ли да омогућите апликацији <xliff:g id="APPLICATION">%1$s</xliff:g> да приступи USB уређају?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Желите ли да омогућите апликацији <xliff:g id="APPLICATION">%1$s</xliff:g> да приступи USB додатку?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Желите ли да се отвори <xliff:g id="ACTIVITY">%1$s</xliff:g> када се прикључи овај USB уређај?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Желите ли да се отвори <xliff:g id="ACTIVITY">%1$s</xliff:g> када се прикључи овај USB додатак?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Ниједна инстал. апликација не функционише са овим USB додатком. Сазнајте више о додатку на <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB помоћни уређај"</string>
<string name="label_view" msgid="6304565553218192990">"Прикажи"</string>
<string name="always_use_device" msgid="1450287437017315906">"Користи подразумевано за овај USB уређај"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Користи подразумевано за овај USB додатак"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Зумирај на целом екрану"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Развуци на цео екран"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Компатибилно зумирање"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Компатибилно зумирање"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Када је апликација намењена мањем екрану, контрола зумирања приказује се поред сата."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Снимак екрана је сачуван у Галерији"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Није могуће сачувати снимак екрана. Могуће је да је спољно складиште у употреби."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Опције USB преноса датотека"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Прикључи као медија плејер (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Прикључи као камеру (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Инсталирај апликацију Android File Transfer за Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Инсталирај апликацију Android File Transfer за Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Назад"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Почетна"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Мени"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Недавне апликације"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Недавне апликације"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Дугме Промени метод уноса."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Дугме Зум компатибилности."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Зумирање са мањег на већи екран."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Сигнал за податке од две црте."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Сигнал за податке од три црте."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Сигнал за податке је најјачи."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Нема WiFi сигнала."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"WiFi сигнал од једне црте."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"WiFi сигнал од две црте."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi сигнал од три црте."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"WiFi сигнал је најјачи."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Нема WiFi сигнала."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"WiFi сигнал од једне црте."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"WiFi сигнал од две црте."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"WiFi сигнал од три црте."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"WiFi сигнал је најјачи."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Нема SIM картице."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth привезивање."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим рада у авиону."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Батерија је на <xliff:g id="NUMBER">%d</xliff:g> посто."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Дугме Подешавања."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Дугме Обавештења."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Уклони обавештење."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Системска подешавања."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Обавештења."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Обриши обавештење."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS је омогућен."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Учитавање GPS-а."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter је омогућен."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Вибрација звона."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Нечујно звоно."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G–3G подаци су онемогућени"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G подаци су онемогућени"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Подаци мобилне мреже су онемогућени"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Подаци су онемогућени"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Достигнуто је наведено ограничење потрошње података."\n\n"Мобилни оператер може додатно да наплати даљу потрошњу података."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Достигнуто је наведено ограничење потрошње података."\n\n"Мобилни оператер може додатно да наплати даљу потрошњу података."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Поново омогући податке"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Нема интернет везе"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi је повезан"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Тражи се GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Локацију је подесио GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Обриши сва обавештења."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index a5ce417..9ae1503 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Ta bort från listan"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Info om appen"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Inga nya appar"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Avvisa nya appar"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 ny app"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d nya appar"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Inga aviseringar"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Pågående"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Meddelanden"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Anslut laddaren"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Anslut laddaren"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Batteriet håller på att ta slut."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> återstår"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Det går inte att ladda via USB."\n"Använd endast den laddare som levererades med telefonen."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"TYST"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Aviseringar"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Senaste"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Inga nya appar."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Appar"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Internetdelning via Bluetooth"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurera inmatningsmetoder"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurera inmatningsmetoder"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Använd fysiska tangenter"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Vill du tillåta att programmet <xliff:g id="APPLICATION">%1$s</xliff:g> använder USB-enheten?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Vill du tillåta att programmet <xliff:g id="APPLICATION">%1$s</xliff:g> använder USB-tillbehöret?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vill du öppna <xliff:g id="ACTIVITY">%1$s</xliff:g> när den här USB-enheten ansluts?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Vill du öppna <xliff:g id="ACTIVITY">%1$s</xliff:g> när det här USB-tillbehöret ansluts?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Inga program fungerar med det här USB-tillbehöret. Läs mer om det på <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB-tillbehör"</string>
<string name="label_view" msgid="6304565553218192990">"Visa"</string>
<string name="always_use_device" msgid="1450287437017315906">"Använd som standard för den här USB-enheten"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Använd som standard för det här USB-tillbehöret"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zooma för att fylla skärm"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Dra för att fylla skärmen"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom i kompatibilitetsläge"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom i kompatibilitetsläge"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"När en app är anpassad för en mindre skärm visas ett zoomreglage vid klockan."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Skärmdumpen sparades i galleriet"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Det gick inte att spara skärmdumpen. Extern lagring kanske används."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Överföringsalternativ"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Montera som mediaspelare (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montera som kamera (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Installera Android-filöverföringsapp för Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Installera Android-filöverföringsapp för Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Tillbaka"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Startsida"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Meny"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Senaste apparna"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Senaste apparna"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Knapp för byte av inmatningsmetod."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Knapp för kompatibilitetszoom."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zooma mindre skärm till större."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data: två staplar."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data: tre staplar."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Datasignalen är full."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Ingen Wi-Fi-signal."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi: en stapel."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi: två staplar."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi: tre staplar."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi-signalen är full."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Ingen Wi-Fi-signal."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Wi-Fi: en stapel."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi: två staplar."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi: tre staplar."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Wi-Fi-signalen är full."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Inget SIM-kort."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Internetdelning via Bluetooth"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Flygplansläge"</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Batteri <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Knappen Inställningar."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Knapp för meddelanden."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Ta bort meddelandet"</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Systeminställningar."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Meddelanden."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Ta bort meddelandet."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS aktiverad."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Tar emot GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter aktiverad."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibrerande ringsignal."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Tyst ringsignal."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Data via 2G-3G har inaktiverats"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data via 4G har inaktiverats"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobildata har inaktiverats"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data har inaktiverats"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Den angivna gränsen för dataanvändning har nåtts."\n" "\n"Ytterligare dataanvändning kan medföra operatörsavgifter."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Den angivna gränsen för dataanvändning har nåtts."\n" "\n"Ytterligare dataanvändning kan medföra operatörsavgifter."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Återaktivera data"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Ingen anslutning"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi-ansluten"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Sökning efter GPS pågår"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Platsen har identifierats av GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Ta bort alla meddelanden."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 3d708d8..9636b43 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -26,10 +26,13 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Ondoa kwenye orodha"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Taarifa za programu-matumizi"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Hakuna programu za sasa"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Ondosha prog za hivi karibuni"</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for status_bar_accessibility_recent_apps:other (1040784359794890744) -->
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Hakuna arifa"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Inaendelea"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Arifa"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Tafadhali unganisha chaja"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Tafadhali unganisha chaja"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Betri inaisha."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> zimebakia"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Chaji ya USB haihamiliwi."\n" Tumia chaka iliyopeanwa."</string>
@@ -41,35 +44,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"NYAMAZISHA"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"KIOTOMATIKI"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Arifa"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Za hivi karibuni"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Hakuna programu za hivi karibuni."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Programu"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth imefungwa"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Sanidi mbinu za uingizaji"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Sanidi mbinu za uingizaji"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Tumia kibodi halisi"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Ruhusu programu <xliff:g id="APPLICATION">%1$s</xliff:g> ili kufikia kifaa cha USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Ruhusu programu <xliff:g id="APPLICATION">%1$s</xliff:g> ili kufikia kifuasi cha USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Je, ungetaka kufungua <xliff:g id="ACTIVITY">%1$s</xliff:g>wakati kifaa cha USB kimeunganishwa?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Je, ungetaka kufungua <xliff:g id="ACTIVITY">%1$s</xliff:g>wakati kifaa cha USB kimeunganishwa?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Hakuna programu zilizosakiniwa zinazofanya kazi na kifaa hiki cha USB. Jifunze zaidi kuhsu kifaa hiki kwenye <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Kifaa cha Usb"</string>
<string name="label_view" msgid="6304565553218192990">"Ona"</string>
<string name="always_use_device" msgid="1450287437017315906">"Kwa kifaa hiki cha USB tumia chaguo-msingi"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Tumia kama chaguo-msingi ya kifuasi hiki cha USB"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Kuza ili kujaza skrini"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Tanua ili kujaza skrini"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Kukuza kwa Utangamanifu"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Kukuza kwa Utangamanifu"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Wakati programu ilibuniwa kwa skrini ndogo, kidhibiti cha kukuza kitaonekana kwa saa."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Taswira za skrini zimehifadhiwa kwenye Kichanja"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Haikuweza kuhifadhi taswira za skrini. Hifadhi ya nje huenda inatumika."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Machaguo ya uhamisho wa faili la USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Angika kama kichezeshi cha midia (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Angika kama kamera (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Sakinisha programu ya Kuhamisha Faili ya Android ya Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Sakinisha programu ya Kuhamisha Faili ya Android ya Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Nyuma"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Nyumbani"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menyu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Programu za hivi karibuni"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Programu za hivi karibuni"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Swichi kitufe cha mbinu ingizi."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Kichupo cha kukuza kwa utangamanifu"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Kuza kidogo kwa skrini kubwa."</string>
@@ -90,38 +105,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Miamba miwili ya data."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Fito tatu za habari."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Ishara ya data imejaa."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Hakuna Mtandao hewa"</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Mwambaa mmoja wa Mtandao hewa"</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Miambaa mbili ya Mtandao hewa"</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Miambaa tatu ya Mtandao hewa"</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Ishara ya Mtandao hewa imejaa"</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Hakuna Mtandao hewa"</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Mwambaa mmoja wa Mtandao hewa"</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Miambaa mbili ya Mtandao hewa"</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Miambaa tatu ya Mtandao hewa"</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Ishara ya Mtandao hewa imejaa"</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Ukingo"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Hakuna SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Ufungaji wa Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Modi ya ndege."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Asilimia <xliff:g id="NUMBER">%d</xliff:g> ya betri"</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Mipangilio ya kitufe."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Kitufe cha arifa"</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Ondoa arifa"</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Mipangilio ya mfumo."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Arifa."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Futa arifa"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPRS imewezeshwa."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPRS inamiliki."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Kichapishaji cha Tele kimewezeshwa."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Mtetemo wa mlio"</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Mlio wa simu uko kimya."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Data ya 2G-3G imelemazwa"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data ya 4G imelemazwa"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Data ya kifaa cha mkononi imelemazwa"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data imelemazwa"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Kikomo cha utumizi wa data kilichobainishwa kimefikiwa. "\n" "\n" Utumizi wa data ya ziada huenda ukagharimu gharama za mbembaji."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Kikomo cha utumizi wa data kilichobainishwa kimefikiwa. "\n" "\n" Utumizi wa data ya ziada huenda ukagharimu gharama za mbembaji."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Wezesha upya data"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Hakuna muunganisho wa mtandao"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Mtandao-hewa umeunganishwa"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Inatafuta GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Mahali pamewekwa na GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Futa arifa zote."</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index b7c57b7..565c283 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"ลบจากรายการ"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"ข้อมูลแอปพลิเคชัน"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"ไม่มีแอปพลิเคชันล่าสุด"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"ปิดแอปพลิเคชันล่าสุด"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 แอปพลิเคชันล่าสุด"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d แอปพลิเคชันล่าสุด"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"ไม่มีการแจ้งเตือน"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"ดำเนินอยู่"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"การแจ้งเตือน"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"โปรดเสียบอุปกรณ์ชาร์จ"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"โปรดเสียบอุปกรณ์ชาร์จ"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"แบตเตอรี่เหลือน้อย"</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"เหลืออีก <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"ไม่สนับสนุนการชาร์จแบบ USB"\n"ใช้เฉพาะที่ชาร์จที่ให้มาเท่านั้น"</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"ปิดเสียง"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"อัตโนมัติ"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"การแจ้งเตือน"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"เมื่อเร็วๆ นี้"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"ไม่มีแอปพลิเคชันล่าสุด"</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"แอปพลิเคชัน"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"บลูทูธที่ปล่อยสัญญาณ"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"กำหนดค่าวิธีการป้อนข้อมูล"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"กำหนดค่าวิธีการป้อนข้อมูล"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"ใช้แป้นพิมพ์จริง"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"อนุญาตให้แอปพลิเคชัน <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึงอุปกรณ์ USB นี้หรือไม่"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"อนุญาตให้แอปพลิเคชัน <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึงอุปกรณ์เสริม USB นี้หรือไม่"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"เปิด <xliff:g id="ACTIVITY">%1$s</xliff:g> เมื่อมีการเชื่อมต่ออุปกรณ์ USB นี้หรือไม่"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"เปิด <xliff:g id="ACTIVITY">%1$s</xliff:g> เมื่อมีการเชื่อมต่ออุปกรณ์เสริม USB นี้หรือไม่"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"แอปพลิเคชันที่ติดตั้งใช้กับอุปกรณ์ USB นี้ไม่ได้ เรียนรู้เพิ่มเติมที่ <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"อุปกรณ์เสริม USB"</string>
<string name="label_view" msgid="6304565553218192990">"ดู"</string>
<string name="always_use_device" msgid="1450287437017315906">"ใช้ค่าเริ่มต้นสำหรับอุปกรณ์ USB นี้"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"ใช้ค่าเริ่มต้นสำหรับอุปกรณ์เสริม USB นี้"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"ขยายจนเต็มหน้าจอ"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"ยืดจนเต็มหน้าจอ"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"ความเข้ากันได้ของการย่อ/ขยาย"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"ความเข้ากันได้ของการย่อ/ขยาย"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"สำหรับแอปพลิเคชันที่ออกแบบมาสำหรับหน้าจอขนาดเล็ก ตัวควบคุมการย่อ/ขยายจะปรากฏขึ้นข้างนาฬิกา"</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"บันทึกภาพหน้าจอในแกลเลอรีแล้ว"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"ไม่สามารถบันทึกภาพหน้าจอ ที่จัดเก็บข้อมูลภายนอกอาจมีการใช้งานอยู่"</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"ตัวเลือกการถ่ายโอนไฟล์ USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"ต่อเชื่อมเป็นโปรแกรมเล่นสื่อ (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"ต่อเชื่อมเป็นกล้องถ่ายรูป (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"ติดตั้งแอปพลิเคชัน Android File Transfer ของ Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"ติดตั้งแอปพลิเคชัน Android File Transfer ของ Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"ย้อนกลับ"</string>
<string name="accessibility_home" msgid="8217216074895377641">"หน้าแรก"</string>
<string name="accessibility_menu" msgid="316839303324695949">"เมนู"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"แอปพลิเคชันล่าสุด"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"แอปพลิเคชันล่าสุด"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"ปุ่มสลับวิธีการป้อนข้อมูล"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"ปุ่มซูมที่ใช้งานร่วมกันได้"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ซูมหน้าจอให้มีขนาดใหญ่ขึ้น"</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"สัญญาณข้อมูลสองขีด"</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"สัญญาณข้อมูลสามขีด"</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"สัญญาณข้อมูลเต็ม"</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"ไม่มี WiFi"</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"สัญญาณ WiFi หนึ่งขีด"</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"สัญญาณ WiFi สองขีด"</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"สัญญาณ WiFi สามขีด"</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"สัญญาณ WiFi เต็ม"</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"ไม่มี WiFi"</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"สัญญาณ WiFi หนึ่งขีด"</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"สัญญาณ WiFi สองขีด"</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"สัญญาณ WiFi สามขีด"</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"สัญญาณ WiFi เต็ม"</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"EDGE"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"ไม่มีซิมการ์ด"</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"การปล่อยสัญญาณบลูทูธ"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"โหมดใช้งานบนเครื่องบิน"</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"แบตเตอรี่ <xliff:g id="NUMBER">%d</xliff:g> เปอร์เซ็นต์"</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"ปุ่มการตั้งค่า"</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"ปุ่มแจ้งเตือน"</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"นำการแจ้งเตือนออก"</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"การตั้งค่าระบบ"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"การแจ้งเตือน"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"ล้างการแจ้งเตือน"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"เปิดใช้งาน GPS แล้ว"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"การดึงข้อมูล GPS"</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"เปิดใช้งาน TeleTypewriter อยู่"</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"เสียงเรียกเข้าแบบสั่น"</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"เสียงเรียกเข้าแบบปิดเสียง"</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"ปิดใช้งานข้อมูล 2G-3G แล้ว"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"ปิดใช้งานข้อมูล 4G แล้ว"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"ปิดใช้งานข้อมูลมือถือแล้ว"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"ข้อมูลถูกปิดใช้งาน"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"ถึงขีดจำกัดการใช้ข้อมูลที่ระบุแล้ว"\n\n"การใช้ข้อมูลเพิ่มเติมอาจมีค่าใช้จ่ายที่เรียกเก็บโดยผู้ให้บริการ"</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"ถึงขีดจำกัดการใช้ข้อมูลที่ระบุแล้ว"\n\n"การใช้ข้อมูลเพิ่มเติมอาจมีค่าใช้จ่ายที่เรียกเก็บโดยผู้ให้บริการ"</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"เปิดใช้งานข้อมูลอีกครั้ง"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"ไม่มีอินเทอร์เน็ต"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"เชื่อมต่อ Wi-Fi แล้ว"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"กำลังค้นหา GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"ตำแหน่งที่กำหนดโดย GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"ล้างการแจ้งเตือนทั้งหมด"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index b9748e1..d9ae888 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Alisin mula sa listahan"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Impormasyon ng app"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Walang kamakailang apps"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Huwag pansinin ang kamakailang apps"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 kamakailang app"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d kamakailang apps"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Walang mga notification"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Nagpapatuloy"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Mga Notification"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Pakikonekta ang charger"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Pakikonekta ang charger"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Humihina na ang baterya."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> natitira"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Hindi sinusuportahan ang pag-charge sa USB."\n"Gamitin lang ang ibinigay na charger."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"MUTE"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Mga Notification"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Kamakailan"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Walang kamakailang mga application."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Apps"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Na-tether ang bluetooth"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"I-configure paraan ng input"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"I-configure paraan ng input"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Gamitin ang pisikal na keyboard"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Payagan ang application <xliff:g id="APPLICATION">%1$s</xliff:g> na i-access ang USB device?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Payagan ang application <xliff:g id="APPLICATION">%1$s</xliff:g> na i-access ang USB accessory?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Buksan ang <xliff:g id="ACTIVITY">%1$s</xliff:g> kapag nakakonekta ang USB device na ito?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Buksan ang <xliff:g id="ACTIVITY">%1$s</xliff:g> kapag nakakonekta ang accessory na USB na ito?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Walang gumaganang mga naka-install na application sa USB accessory na ito <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB accessory"</string>
<string name="label_view" msgid="6304565553218192990">"Tingnan"</string>
<string name="always_use_device" msgid="1450287437017315906">"Gamitin bilang default para sa USB device"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Gamitin bilang default sa USB accessory na ito"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"I-zoom upang punan screen"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"I-stretch upang mapuno screen"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom sa Pagiging Tugma"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom sa Pagiging Tugma"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Kapag nakadisenyo ang isang app para sa mas maliit na screen, isang kontrol ng zoom ang lalabas sa may orasan."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Na-save ang screenshot sa Gallery"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Hindi ma-save ang screenshot. Maaaring ginagamit ang panlabas na storage."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opsyon paglipat ng USB file"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"I-mount bilang isang media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"I-mount bilang camera (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"I-install Android File Transfer para sa Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"I-install Android File Transfer para sa Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Bumalik"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Home"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Mga kamakailang application"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Kamakailang apps"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Ilipat ang button na pamamaraan ng pag-input."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Button ng zoom ng pagiging tugma."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Mag-zoom nang mas maliit sa mas malaking screen."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data na dalawang bar."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data na tatlong bar."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Puno ang signal ng data."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Walang WiFi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"WiFi na isang bar."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"WiFi na dalawang bar."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi na tatlong bar."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Puno ang signal ng WiFi."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Walang WiFi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"WiFi na isang bar."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"WiFi na dalawang bar."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"WiFi na tatlong bar."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Puno ang signal ng WiFi."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Walang SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Pag-tether ng Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode na eroplano."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Baterya <xliff:g id="NUMBER">%d</xliff:g> (na) porsyento."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Button ng mga setting."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Button ng mga notification."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Alisin ang notification."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Mga setting ng system."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Mga Notification."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"I-clear ang notification."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"Pinapagana ang GPS."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Kumukuha ng GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Pinapagana ang TeleTypewriter."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Pag-vibrate ng ringer."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Naka-silent ang ringer."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Di pinapagana ang 2G-3G na data"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Hindi pinapagana ang 4G na data"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Hindi pinapagana ang data ng mobile"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Hindi pinapagana ang data"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Naabot na ang tinukoy na limitasyon sa paggamit ng data."\n\n"Maaaring makaipon ng mga carrier na singilin ang karagdagang paggamit sa data."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Naabot na ang tinukoy na limitasyon sa paggamit ng data."\n\n"Maaaring makaipon ng mga carrier na singilin ang karagdagang paggamit sa data."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Muling paganahin ang data"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Walang koneksyon sa Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"nakakonekta ang Wi-Fi"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Naghahanap ng GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasyong itinatakda ng GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"I-clear ang lahat ng notification."</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 2383cbb..313fd30 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Listeden kaldır"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Uygulama bilgileri"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Son uygulama yok"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Son uygulamaları kapat"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 tane son uygulama"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d tane son uygulama"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Bildirim yok"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Sürüyor"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Bildirimler"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Lütfen şarj cihazını takın"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Lütfen şarj cihazını takın"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Pil azalıyor."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> kaldı"</string>
<string name="invalid_charger" msgid="4549105996740522523">"USB üzerinden şarj desteklenmiyor."\n"Yalnızca ürünle birlikte verilen şarj cihazını kullanın."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"KAPAT"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"OTOMTK"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Bildirimler"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"En Son Görevler"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Hiçbir yeni uygulama yok."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Uygulamalar"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth paylaşımı tamam"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Giriş yöntemlerini yapılandır"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Giriş yöntemlerini yapılandır"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Fiziksel klavyeyi kullan"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının bu USB cihazına erişmesine izin verilsin mi?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının bu USB aksesuarına erişmesine izin verilsin mi?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Bu USB cihaz bağlandığında <xliff:g id="ACTIVITY">%1$s</xliff:g> açılsın mı?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Bu USB aksesuarı bağlandığında <xliff:g id="ACTIVITY">%1$s</xliff:g> açılsın mı?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Hiçbir yüklü uyg bu USB aksesuarıyla çalışmıyor. Bu aksesuar hakknd daha fazla bilgi için: <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB aksesuarı"</string>
<string name="label_view" msgid="6304565553218192990">"Görüntüle"</string>
<string name="always_use_device" msgid="1450287437017315906">"Bu USB cihazı için varsayılan olarak kullan"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Bu USB aksesuar için varsayılan olarak kullan"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Yakınlaştır (ekranı kaplasın)"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Genişlet (ekran kapansın)"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Uyumluluk Zum\'u"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Uyumluluk Zum\'u"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Uygulama küçük bir ekran için tasarlanmışsa saatin yanında bir yakınlaştırma denetimi görünür."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Ekran görüntüsü Galeri\'ye kaydedildi"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Ekran görüntüsü kaydedilemedi. Harici depolama birimi kullanımda olabilir."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB dosya aktarım seçenekleri"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Medya oynatıcı olarak ekle (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Kamera olarak ekle (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Mac için Android Dosya Aktarımı uygulamasını yükle"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac için Android Dosya Aktarımı uygulamasını yükle"</string>
<string name="accessibility_back" msgid="567011538994429120">"Geri"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Ana sayfa"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menü"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Son uygulamalar"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Son uygulamalar"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Giriş yöntemini değiştirme düğmesi."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Uyumluluk zum düğmesi."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Daha büyük ekrana daha küçük yakınlaştır."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Veri sinyali iki çubuk."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Veri sinyali üç çubuk."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Veri sinyali tam."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Kablosuz sinyali yok"</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Kablosuz sinyali bir çubuk."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Kablosuz sinyali iki çubuk."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Kablosuz sinyali üç çubuk."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Kablosuz sinyali tam."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Kablosuz sinyali yok"</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Kablosuz sinyali bir çubuk."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Kablosuz sinyali iki çubuk."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Kablosuz sinyali üç çubuk."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Kablosuz sinyali tam."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Kablosuz"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Kablosuz"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"SIM kart yok."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth İnternet paylaşımı"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Uçak modu."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Pil yüzdesi: <xliff:g id="NUMBER">%d</xliff:g>"</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Ayarlar düğmesi."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Bildirimler düğmesi."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Bildirimi kaldır."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Sistem ayarları."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Bildirimler."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Bildirimi temizle."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS etkin."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS alınıyor."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter etkin."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Telefon zili titreşim."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Telefon zili sessiz."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G verileri devre dışı bırakıldı"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G verileri devre dışı"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobil veriler devre dışı"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Veriler devre dışı"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Belirtilen veri kullanım sınırına ulaşıldı."\n\n"Ek veri kullanımında operatör ücretleri alınabilir."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Belirtilen veri kullanım sınırına ulaşıldı."\n\n"Ek veri kullanımında operatör ücretleri alınabilir."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Veriyi yeniden etkinleştir"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"İnternet bağlantısı yok"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Kablosuz bağlandı"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS aranıyor"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Konum GPS ile belirlendi"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Tüm bildirimleri temizle"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 95b2b36..ac1be4c 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Видалити зі списку"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Інформація про програму"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Немає останніх програм"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Відхилити останні програми"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 остання програма"</item>
+ <item quantity="other" msgid="1040784359794890744">"останніх програм: %d"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Немає сповіщень"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Поточні"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Сповіщення"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Підключ. заряд. пристрій"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Підключ. заряд. пристрій"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Батарея виснажується."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"Залишилося <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Заряджання USB не підтримується."\n"Використовуйте лише наданий у комплекті зарядний пристрій."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"ІГНОР."</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"АВТОМ."</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Сповіщення"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Останні"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Немає останніх програм."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Програми"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Створено прив\'язку Bluetooth"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Налаштувати методи введення"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Налаштувати методи введення"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Викор. реальну клавіатуру"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Надати програмі <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до пристрою USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Надати програмі <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до аксесуара USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Відкривати \"<xliff:g id="ACTIVITY">%1$s</xliff:g>\", коли під’єднано пристрій USB?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Відкривати \"<xliff:g id="ACTIVITY">%1$s</xliff:g>\", коли під’єднано аксесуар USB?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Установлені прогр. не працюють із цим аксесуаром USB. Більше про цей аксесуар: <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Пристрій USB"</string>
<string name="label_view" msgid="6304565553218192990">"Переглянути"</string>
<string name="always_use_device" msgid="1450287437017315906">"Використовувати за умовчанням для пристрою USB"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Використовувати за умовчанням для аксесуара USB"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Масштабув. на весь екран"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Розтягнути на весь екран"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Елемент керування масштабом для сумісності"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Елемент керування масштабом для сумісності"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Якщо програму призначено для менших екранів, елемент керування масштабом буде відображатися біля годинника."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Знімок екрана збережено в Галереї"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Не вдалося зберегти знімок екрана. Можливо, зовнішня пам’ять використовується."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Парам.передав.файлів через USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Підключити як медіапрогравач (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Підключити як камеру (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Установити програму Android File Transfer для Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Установити програму Android File Transfer для Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Назад"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Головна"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Меню"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Останні програми"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Останні програми"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Кнопка перемикання методу введення."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Кнопка масштабування сумісності."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Збільшення екрана."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Дві смужки сигналу даних."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Три смужки сигналу даних."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Максимальний сигнал даних."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Немає сигналу Wi-Fi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Одна смужка сигналу WiFi."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Дві смужки сигналу WiFi."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Три смужки сигналу WiFi."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Максимальний сигнал Wi-Fi."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Немає сигналу Wi-Fi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Одна смужка сигналу WiFi."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Дві смужки сигналу WiFi."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Три смужки сигналу WiFi."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Максимальний сигнал Wi-Fi."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Немає SIM-карти."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Прив’язка Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим польоту."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Відсотків батареї: <xliff:g id="NUMBER">%d</xliff:g>."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Кнопка налаштувань."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Кнопка сповіщень."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Видалити сповіщення."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Налаштування системи."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Сповіщення."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Очистити сповіщення."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS увімкнено."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Встановлення зв’язку з GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Телетайп увімкнено."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Дзвінок на вібросигналі."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Дзвінок беззвучний."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Дані 2G–3G вимкнено"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Дані 4G вимкнено"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Мобільне передавання даних вимкнено"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Використання даних вимкнено"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Досягнуто вказаного ліміту використання даних."\n\n"Додаткове використання даних може призвести до стягування плати оператором."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Досягнуто вказаного ліміту використання даних."\n\n"Додаткове використання даних може призвести до стягування плати оператором."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Повторно ввімкнути дані"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Немає з’єднання"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi під’єднано"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Виконується пошук GPS-сигналу"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Місцезнаходження встановлено за допомогою GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Очистити всі сповіщення."</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 16dc6d4..c27b85a 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Xóa khỏi danh sách"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Thông tin về ứng dụng"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Không có ứng dụng nào gần đây"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Loại bỏ các ứng dụng gần đây"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 ứng dụng gần đây"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d ứng dụng gần đây"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Không có thông báo nào"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Đang diễn ra"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Thông báo"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Vui lòng kết nối bộ sạc"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Vui lòng kết nối bộ sạc"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Pin đang yếu."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> còn lại"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Không hỗ trợ sạc qua USB."\n"Chỉ sử dụng bộ sạc được cung cấp."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"TẮT TIẾNG"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"TỰ ĐỘNG"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Thông báo"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Gần đây"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Không có ứng dụng nào gần đây."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Ứng dụng"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth được dùng làm điểm truy cập Internet"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Định cấu hình phương pháp nhập liệu"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Định cấu hình phương thức nhập liệu"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Sử dụng bàn phím vật lý"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Cho phép ứng dụng <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập thiết bị USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Cho phép ứng dụng <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập phụ kiện USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Mở <xliff:g id="ACTIVITY">%1$s</xliff:g> khi thiết bị USB này được kết nối?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Mở <xliff:g id="ACTIVITY">%1$s</xliff:g> khi phụ kiện USB này được kết nối?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Không có ứng dụng được cài đặt nào hoạt động với phụ kiện USB này. Tìm hiểu thêm về phụ kiện này tại <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"Phụ kiện USB"</string>
<string name="label_view" msgid="6304565553218192990">"Xem"</string>
<string name="always_use_device" msgid="1450287437017315906">"Sử dụng theo mặc định cho thiết bị USB này"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Sử dụng theo mặc định cho phụ kiện USB này"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"T.phóng để lấp đầy m.hình"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Giãn ra để lấp đầy m.hình"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Thu phóng tương thích"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Thu phóng tương thích"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Khi ứng dụng được thiết kế cho một màn hình nhỏ hơn, điều khiển thu phóng sẽ xuất hiện bên cạnh đồng hồ."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Đã lưu ảnh chụp màn hình vào Thư viện"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Không thể lưu ảnh chụp màn hình. Bộ nhớ ngoài có thể đang được sử dụng."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Tùy chọn truyền tệp USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Gắn như một trình phát đa phương tiện (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Gắn như một máy ảnh (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Cài đặt ứng dụng Truyền tệp của Android dành cho Mac"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Cài đặt ứng dụng Truyền tệp của Android dành cho Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Quay lại"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Trang chủ"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Trình đơn"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Các ứng dụng gần đây"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Ứng dụng gần đây"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Nút chuyển phương thức nhập."</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Nút thu phóng khả năng tương thích."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Thu phóng màn hình lớn hơn hoặc nhỏ hơn."</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Tín hiệu dữ liệu hai vạch."</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Tín hiệu dữ liệu ba vạch."</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Tín hiệu dữ liệu đầy đủ."</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Không có WiFi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Tín hiệu WiFi một vạch."</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Tín hiệu WiFi hai vạch."</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Tín hiệu WiFi ba vạch."</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Tín hiệu WiFi đầy đủ."</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Không có WiFi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Tín hiệu WiFi một vạch."</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Tín hiệu WiFi hai vạch."</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Tín hiệu WiFi ba vạch."</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Tín hiệu WiFi đầy đủ."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Cạnh"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Không có SIM nào."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Dùng làm điểm truy cập Internet qua Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Chế độ trên máy bay."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> phần trăm pin."</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Nút cài đặt."</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Nút thông báo."</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Xóa thông báo."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Cài đặt hệ thống"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Thông báo."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Xóa thông báo"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"Đã bật GPS."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Nhận GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"Đã bật TeleTypewriter."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Chuông rung."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Chuông im lặng."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Đã tắt dữ liệu 2G-3G"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Đã tắt dữ liệu 4G"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Dữ liệu di động bị vô hiệu hóa"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Dữ liệu đã bị vô hiệu hóa"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Đã đạt tới giới hạn sử dụng dữ liệu được chỉ định."\n\n"Nhà cung cấp có thể tính phí cho việc sử dụng thêm dữ liệu."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Đã đạt tới giới hạn sử dụng dữ liệu được chỉ định."\n\n"Nhà cung cấp có thể tính phí cho việc sử dụng thêm dữ liệu."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Bật lại dữ liệu"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Ko có k.nối Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Đã kết nối Wi-Fi"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Đang tìm kiếm GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Vị trí đặt bởi GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Xóa tất cả thông báo."</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index b728c13..66c6279 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"从列表中删除"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"应用程序信息"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"最近没有运行任何应用程序"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"关闭最近运行的应用程序"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 个最近运行的应用程序"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d 个最近运行的应用程序"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"无通知"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"正在进行的"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"通知"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"请连接充电器"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"请连接充电器"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"电池电量低。"</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"还剩 <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"不支持 USB 充电功能。"\n"只能使用随附的充电器充电。"</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"静音"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"自动"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"通知"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"近期任务"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"没有最近使用的应用程序。"</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"应用程序"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"蓝牙已绑定"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"配置输入法"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"配置输入法"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"使用物理键盘"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"允许应用程序<xliff:g id="APPLICATION">%1$s</xliff:g>访问 USB 设备吗?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"允许应用程序<xliff:g id="APPLICATION">%1$s</xliff:g>访问 USB 配件吗?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"要在连接此 USB 设备时打开<xliff:g id="ACTIVITY">%1$s</xliff:g>吗?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"要在连接此 USB 配件时打开<xliff:g id="ACTIVITY">%1$s</xliff:g>吗?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"未安装此 USB 配件适用的应用程序。要了解关于此配件的详情,请访问:<xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB 配件"</string>
<string name="label_view" msgid="6304565553218192990">"查看"</string>
<string name="always_use_device" msgid="1450287437017315906">"默认情况下用于该 USB 设备"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"默认情况下用于该 USB 配件"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"缩放以填满屏幕"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"拉伸以填满屏幕"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"兼容性缩放"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"兼容性缩放"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"如果应用程序是针对较小屏幕设计的,则时钟旁会显示缩放控件。"</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"屏幕截图已保存到“图库”"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"无法保存屏幕截图。外部存储设备可能在使用中。"</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB 文件传输选项"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"作为媒体播放器 (MTP) 装载"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"作为摄像头 (PTP) 装载"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"安装适用于苹果机的“Android 文件传输”应用程序"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"安装适用于苹果机的“Android 文件传输”应用程序"</string>
<string name="accessibility_back" msgid="567011538994429120">"返回"</string>
<string name="accessibility_home" msgid="8217216074895377641">"主屏幕"</string>
<string name="accessibility_menu" msgid="316839303324695949">"菜单"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"最近使用的应用程序"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"最近运行的应用程序"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"输入法切换按钮。"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"兼容性缩放按钮。"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"将小屏幕的图片放大在较大屏幕上显示。"</string>
@@ -90,40 +107,43 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"数据信号强度为两格。"</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"数据信号强度为三格。"</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"数据信号满格。"</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"没有 WiFi 信号。"</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"WiFi 信号强度为一格。"</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"WiFi 信号强度为两格。"</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi 信号强度为三格。"</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"WiFi 信号满格。"</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"没有 WiFi 信号。"</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"WiFi 信号强度为一格。"</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"WiFi 信号强度为两格。"</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"WiFi 信号强度为三格。"</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"WiFi 信号满格。"</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"EDGE"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"无 SIM 卡。"</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"蓝牙网络共享。"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"飞行模式。"</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
- <string name="accessibility_settings_button" msgid="7913780116850379698">"设置按钮。"</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"通知按钮。"</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"删除通知。"</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"系统设置。"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"清除通知。"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS 已启用。"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"正在获取 GPS 信号。"</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"电传打字机已启用。"</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"振铃器振动。"</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"振铃器静音。"</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G 数据网络已停用"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G 数据网络已停用"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"移动数据已停用"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"数据已停用"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"已达到指定的数据流量上限。"\n\n"如果使用额外的数据流量,运营商可能会收取相应的费用。"</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"已达到指定的数据流量上限。"\n\n"如果使用额外的数据流量,运营商可能会收取相应的费用。"</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"重新启用数据连接"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"未连接互联网"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi 已连接"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"正在搜索 GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"已通过 GPS 确定位置"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 0359bcc..6af0159 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"從清單中移除"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"應用程式資訊"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"沒有最近使用的應用程式"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"關閉最近使用的應用程式"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"1 個最近使用的應用程式"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d 個最近使用的應用程式"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"沒有通知"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"進行中"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"通知"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"請連接充電器"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"請連接充電器"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"電池電量即將不足。"</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"還剩 <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"不支援 USB 充電。"\n"僅能使用隨附的充電器。"</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"關閉"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"自動"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"通知"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"最新的"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"沒有最近用過的應用程式。"</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"應用程式"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"已透過 Bluetooth 進行網路共用"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"設定輸入方式"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"設定輸入方式"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"使用實體鍵盤"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"允許 <xliff:g id="APPLICATION">%1$s</xliff:g> 應用程式存取 USB 裝置嗎?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"允許 <xliff:g id="APPLICATION">%1$s</xliff:g> 應用程式存取 USB 配件嗎?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"連接這個 USB 裝置時啟用 <xliff:g id="ACTIVITY">%1$s</xliff:g> 嗎?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"連接這個 USB 配件時啟用 <xliff:g id="ACTIVITY">%1$s</xliff:g> 嗎?"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"已安裝的應用程式均無法存取這類 USB 配件,如要進一步瞭解這個配件,請造訪 <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"USB 配件"</string>
<string name="label_view" msgid="6304565553218192990">"查看"</string>
<string name="always_use_device" msgid="1450287437017315906">"預設用於這個 USB 裝置"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"預設用於這個 USB 配件"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"放大為全螢幕"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"放大為全螢幕"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"相容性縮放"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"相容性縮放"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"執行專為較小螢幕設計的應用程式時,系統會在時鐘旁顯示縮放控制項。"</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"螢幕擷取畫面已儲存至圖片庫"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"無法儲存螢幕擷取畫面,外部儲存裝置可能正在使用中。"</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB 檔案傳輸選項"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"掛接為媒體播放器 (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"掛接為相機 (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"安裝適用於 Mac 的「Android 檔案傳輸」"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"安裝適用於 Mac 的「Android 檔案傳輸」"</string>
<string name="accessibility_back" msgid="567011538994429120">"返回"</string>
<string name="accessibility_home" msgid="8217216074895377641">"主螢幕"</string>
<string name="accessibility_menu" msgid="316839303324695949">"選單"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"最近使用的應用程式"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"最近使用的應用程式"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"切換輸入法按鈕。"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"相容性縮放按鈕。"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"將較小螢幕的畫面放大在較大螢幕上顯示。"</string>
@@ -90,40 +107,43 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"數據網路訊號強度兩格。"</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"數據網路訊號強度三格。"</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"數據網路訊號滿格。"</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"沒有 WiFi 連線。"</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"WiFi 訊號強度一格。"</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"WiFi 訊號強度兩格。"</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi 訊號強度三格。"</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"WiFi 訊號滿格。"</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"沒有 WiFi 連線。"</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"WiFi 訊號強度一格。"</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"WiFi 訊號強度兩格。"</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"WiFi 訊號強度三格。"</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"WiFi 訊號滿格。"</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"沒有 SIM 卡。"</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"藍牙數據連線"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"飛行模式。"</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
- <string name="accessibility_settings_button" msgid="7913780116850379698">"設定按鈕。"</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"通知按鈕。"</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"移除通知。"</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"系統設定"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"清除通知。"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS 已啟用。"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"正在取得 GPS 訊號。"</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter (TTY) 已啟用。"</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"鈴聲震動。"</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"鈴聲靜音。"</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"已停用 2G-3G 數據"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"已停用 4G 數據"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"已停用行動數據"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"數據已停用"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"已達到指定的資料用量上限。"\n\n"如果使用額外的資料用量,行動通訊業者可能會向您收費。"</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"已達到指定的資料用量上限。"\n\n"如果使用額外的資料用量,行動通訊業者可能會向您收費。"</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"重新啟用數據連線"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"沒有網際網路連線"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi 已連線"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"正在搜尋 GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS 已定位"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 51f14b1..7ef2549 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -26,10 +26,15 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Susa ohlwini"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Ulwazi lwensiza"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Azikho izinhlelo zokusebenza zakamuva"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Susa izinsiza zakamumva"</string>
+ <plurals name="status_bar_accessibility_recent_apps">
+ <item quantity="one" msgid="5854176083865845541">"Insiza eyi-1 yakamumva"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d izinsiza zakamumva"</item>
+ </plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Azikho izaziso"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Okuqhubekayo"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Izaziso"</string>
- <string name="battery_low_title" msgid="7923774589611311406">"Sicela uxhume ishaja"</string>
+ <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Sicela uxhume ishaja"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Ibhetri iya ngokuphela."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"okusele okungu-<xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Ukushaja i-USB akusekelwe."\n"Sebenzisa kuphela ishaja enikeziwe."</string>
@@ -41,35 +46,47 @@
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"THULISA"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"OKUZENZAKALELAYO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Izaziso"</string>
- <string name="recent_tasks_title" msgid="3691764623638127888">"Okwakamuva"</string>
- <string name="recent_tasks_empty" msgid="1905484479067697884">"Azikho izinhlelo zokusebenza zamanje."</string>
- <string name="recent_tasks_app_label" msgid="3796483981246752469">"Izinhlelo zokusebenza"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Ukusebenzisa i-Bluetooth njengemodemu"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Misa izindlela zokufakwayo"</string>
+ <!-- outdated translation 737483394044014246 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Misa izindlela zokufakwayo"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Sebenzisa ikhibhodi ebangekayo"</string>
- <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Vumela uhlelo lokusebenza <xliff:g id="APPLICATION">%1$s</xliff:g> lufinyelele idivayisi ye-USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Vumela uhlelo lokusebenza <xliff:g id="APPLICATION">%1$s</xliff:g> ukuze ufinyelele kwizinto eziphuma ne-USB?"</string>
+ <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
+ <skip />
+ <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
+ <skip />
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vula <xliff:g id="ACTIVITY">%1$s</xliff:g> uma ledivayisi ye-USB ixhunyiwe?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Vula <xliff:g id="ACTIVITY">%1$s</xliff:g> uma le-accessory ye-USB ixhunyiwe"</string>
- <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Azikho izinhlelo zokusebenza zisebenze ngento ze-USB. Funda okwengeziwe ngalento<xliff:g id="URL">%1$s</xliff:g>"</string>
+ <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
+ <skip />
<string name="title_usb_accessory" msgid="4966265263465181372">"ama-accessory e-USB"</string>
<string name="label_view" msgid="6304565553218192990">"Buka"</string>
<string name="always_use_device" msgid="1450287437017315906">"Sebenzisa ngokuzenzakalelayo yale divayisi ye-USB"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Sebenzisa ngokuzenzakalelayo kule-accessory ye-USB"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Sondeza ukugcwalisa isikrini"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Nweba ukugcwalisa isikrini"</string>
- <string name="compat_mode_help_header" msgid="7020175705401506719">"Ukuhambelana Kokusondeza"</string>
+ <!-- outdated translation 7020175705401506719 --> <string name="compat_mode_help_header" msgid="7969493989397529910">"Ukuhambelana Kokusondeza"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Uma uhlelo lokusebenza lwenzelwe isikrini ezincane, isilawuli sokusondeza sizovela ngakuyiwashi."</string>
- <string name="screenshot_saving_toast" msgid="8592630119048713208">"Isithombe-skrini silondiwe Kugalari"</string>
- <string name="screenshot_failed_toast" msgid="1990979819772906912">"Ayikwazanga ukulondoloza isithombe-skrini. Ukugcina kwangaphandle kungenzeka kuyasetshenziswa."</string>
+ <!-- no translation found for screenshot_saving_ticker (8847274279171967058) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
+ <skip />
+ <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
+ <skip />
+ <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_title (705781116746922771) -->
+ <skip />
+ <!-- no translation found for screenshot_failed_text (5951190902073655147) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Okukhethwa kokudluliswa kwefayela ye-USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Lengisa njengesidlali semediya (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Lengisa ikhamera (PTP)"</string>
- <string name="installer_cd_button_title" msgid="8485631662288445893">"Faka uhlelo lokusebenza Lokudluliswa Kwefayela ye-Android Ohlelweni lokhompyutha"</string>
+ <!-- outdated translation 8485631662288445893 --> <string name="installer_cd_button_title" msgid="2312667578562201583">"Faka uhlelo lokusebenza Lokudluliswa Kwefayela ye-Android Ohlelweni lokhompyutha"</string>
<string name="accessibility_back" msgid="567011538994429120">"Emuva"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Ekhaya"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Imenyu"</string>
- <string name="accessibility_recent" msgid="3027675523629738534">"Izinhlelo zokusebenza zamanje"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"Izinhlelo zokusebenza zakamuva"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Vula indlela yokungena yenkinobho"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Inkinobho evumelekile yokusondeza"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Sondeza kancane esikrinini esikhudlwana"</string>
@@ -90,38 +107,41 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"Amabha amabili edatha"</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"Amabha amathathu edatha"</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"Igcwele i-signal yedatha"</string>
- <string name="accessibility_no_wifi" msgid="4017628918351949575">"Ayikho i-WiFi."</string>
- <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Ibha eyodwa ye-WiFi"</string>
- <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"ama-bar amabili e-WiFi"</string>
- <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"amabha amathathu e-WiFi"</string>
- <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"i-signal ye-WiFi igcwele"</string>
+ <!-- outdated translation 4017628918351949575 --> <string name="accessibility_no_wifi" msgid="7455607460517331976">"Ayikho i-WiFi."</string>
+ <!-- outdated translation 1914343229091303434 --> <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Ibha eyodwa ye-WiFi"</string>
+ <!-- outdated translation 7869150535859760698 --> <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"ama-bar amabili e-WiFi"</string>
+ <!-- outdated translation 2665319332961356254 --> <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"amabha amathathu e-WiFi"</string>
+ <!-- outdated translation 1275764416228473932 --> <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"i-signal ye-WiFi igcwele"</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
<string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Ekucupheleni"</string>
- <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <!-- outdated translation 1127208787254436420 --> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Ayikho i-SIM"</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Ukusebenzisa i-Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Imodi yendiza."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Iphesenti <xliff:g id="NUMBER">%d</xliff:g> lebhetri"</string>
- <string name="accessibility_settings_button" msgid="7913780116850379698">"Inkinobho yezilungiselelo"</string>
- <string name="accessibility_notifications_button" msgid="2933903195211483438">"Inkinobho Yezazisp"</string>
- <string name="accessibility_remove_notification" msgid="4883990503785778699">"Susa Isaziso."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Izilungiselelo zesistimu"</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Izaziso"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Sula isaziso"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"i-GPS inikwe amandla"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"i-GPS iyafuna"</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"i-TeleTypewriter inikwe amandla"</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Ukudlidliza kweringa."</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Isikhali sithulile."</string>
+ <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
+ <skip />
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"idatha ye-2G-3G ivimbelwe"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Idatha ye-4G ivimbelwe"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Idatha yefoni ivimbelwe"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Idatha ivimbelwe"</string>
- <string name="data_usage_disabled_dialog" msgid="6524467913290900042">"Umkhawulo wokusebenzisa idatha ocacisiwe ufinyelelwe."\n\n"Ukusebenzisa idatha okwengeziwe kungabanga izindlezo zokuthwala."</string>
+ <!-- outdated translation 6524467913290900042 --> <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Umkhawulo wokusebenzisa idatha ocacisiwe ufinyelelwe."\n\n"Ukusebenzisa idatha okwengeziwe kungabanga izindlezo zokuthwala."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Vumela futhi idatha"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Alukho uxhumano lwe-Inthanethi"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"I-Wi-Fi ixhunyiwe"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Isesha i-GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Indawo ihlelwe i-GPS"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Susa zonke izaziso."</string>
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 5ba1908..bce0bc4 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -19,13 +19,15 @@
<resources>
<drawable name="notification_number_text_color">#ffffffff</drawable>
<drawable name="notification_item_background_color">#ff111111</drawable>
+ <drawable name="notification_item_background_color_pressed">#ff257390</drawable>
<drawable name="ticker_background_color">#ff1d1d1d</drawable>
<drawable name="status_bar_background">#ff000000</drawable>
- <drawable name="status_bar_recents_background">#b3000000</drawable>
+ <drawable name="status_bar_recents_background_solid">#b3000000</drawable>
<drawable name="status_bar_recents_app_thumbnail_background">#88000000</drawable>
<color name="status_bar_recents_app_label_color">#ffffffff</color>
<drawable name="status_bar_notification_row_background_color">#ff090909</drawable>
<drawable name="notification_header_bg">#d8000000</drawable>
<drawable name="notification_tracking_bg">#d8000000</drawable>
<color name="notification_list_shadow_top">#80000000</color>
+ <drawable name="recents_callout_line">#66ffffff</drawable>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 830506c..bf19286 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -21,21 +21,18 @@
<!-- Recent Applications parameters -->
<!-- Upper width limit for application icon -->
- <dimen name="status_bar_recents_app_icon_max_width">64dp</dimen>
+ <dimen name="status_bar_recents_app_icon_max_width">48dp</dimen>
<!-- Upper height limit for application icon -->
- <dimen name="status_bar_recents_app_icon_max_height">64dp</dimen>
- <!-- Where to place the app icon over the thumbnail -->
- <dimen name="status_bar_recents_app_icon_left_margin">13dp</dimen>
- <dimen name="status_bar_recents_app_icon_top_margin">13dp</dimen>
+ <dimen name="status_bar_recents_app_icon_max_height">48dp</dimen>
<!-- Size of application thumbnail -->
<dimen name="status_bar_recents_thumbnail_width">164dp</dimen>
<dimen name="status_bar_recents_thumbnail_height">145dp</dimen>
<!-- Size of application label text -->
- <dimen name="status_bar_recents_app_label_text_size">16dip</dimen>
+ <dimen name="status_bar_recents_app_label_text_size">14dip</dimen>
<!-- Size of application description text -->
- <dimen name="status_bar_recents_app_description_text_size">16dip</dimen>
+ <dimen name="status_bar_recents_app_description_text_size">14dip</dimen>
<!-- Size of fading edge for scroll effect -->
<dimen name="status_bar_recents_fading_edge_length">20dip</dimen>
<!-- Margin between recents container and glow on the right -->
@@ -91,4 +88,10 @@
<!-- Initial acceleration of an collapse animation after fling -->
<dimen name="collapse_accel">2000dp</dimen>
+ <!-- The padding on the global screenshot background image -->
+ <dimen name="global_screenshot_bg_padding">0dp</dimen>
+ <!-- The top-left offset for the screenshot drop animation target bounds -->
+ <dimen name="global_screenshot_drop_offset_x">6dp</dimen>
+ <dimen name="global_screenshot_drop_offset_y">0dp</dimen>
+
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e971896..612c8e7 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -70,7 +70,7 @@
<string name="status_bar_latest_events_title">Notifications</string>
<!-- When the battery is low, this is displayed to the user in a dialog. The title of the low battery alert. [CHAR LIMIT=NONE]-->
- <string name="battery_low_title">Please connect charger</string>
+ <string name="battery_low_title">Connect charger</string>
<!-- When the battery is low, this is displayed to the user in a dialog. The subtitle of the low battery alert. [CHAR LIMIT=NONE] -->
<string name="battery_low_subtitle">The battery is getting low.</string>
@@ -122,16 +122,16 @@
<!-- Network connection string for Bluetooth Reverse Tethering -->
<string name="bluetooth_tethered">Bluetooth tethered</string>
<!-- Title of a button to open the settings for input methods [CHAR LIMIT=30] -->
- <string name="status_bar_input_method_settings_configure_input_methods">Configure input methods</string>
+ <string name="status_bar_input_method_settings_configure_input_methods">Set up input methods</string>
<!-- Label of a toggle switch to disable use of the physical keyboard in favor of the IME. [CHAR LIMIT=25] -->
<string name="status_bar_use_physical_keyboard">Use physical keyboard</string>
<!-- Prompt for the USB device permission dialog [CHAR LIMIT=80] -->
- <string name="usb_device_permission_prompt">Allow the application <xliff:g id="application">%1$s</xliff:g> to access the USB device?</string>
+ <string name="usb_device_permission_prompt">Allow the app <xliff:g id="application">%1$s</xliff:g> to access the USB device?</string>
<!-- Prompt for the USB accessory permission dialog [CHAR LIMIT=80] -->
- <string name="usb_accessory_permission_prompt">Allow the application <xliff:g id="application">%1$s</xliff:g> to access the USB accessory?</string>
+ <string name="usb_accessory_permission_prompt">Allow the app <xliff:g id="application">%1$s</xliff:g> to access the USB accessory?</string>
<!-- Prompt for the USB device confirm dialog [CHAR LIMIT=80] -->
<string name="usb_device_confirm_prompt">Open <xliff:g id="activity">%1$s</xliff:g> when this USB device is connected?</string>
@@ -140,7 +140,7 @@
<string name="usb_accessory_confirm_prompt">Open <xliff:g id="activity">%1$s</xliff:g> when this USB accessory is connected?</string>
<!-- Prompt for the USB accessory URI dialog [CHAR LIMIT=80] -->
- <string name="usb_accessory_uri_prompt">No installed applications work with this USB accessory. Learn more about this accessory at <xliff:g id="url">%1$s</xliff:g></string>
+ <string name="usb_accessory_uri_prompt">No installed apps work with this USB accessory. Learn more about this accessory at <xliff:g id="url">%1$s</xliff:g></string>
<!-- Title for USB accessory dialog. Used when the name of the accessory cannot be determined. [CHAR LIMIT=50] -->
<string name="title_usb_accessory">USB accessory</string>
@@ -163,15 +163,25 @@
<string name="compat_mode_off">Stretch to fill screen</string>
<!-- Compatibility mode help screen: header text. [CHAR LIMIT=50] -->
- <string name="compat_mode_help_header">Compatibility Zoom</string>
+ <string name="compat_mode_help_header">Compatibility zoom</string>
<!-- Compatibility mode help screen: body text. [CHAR LIMIT=150] -->
<string name="compat_mode_help_body">When an app was designed for a smaller screen, a zoom control will appear by the clock.</string>
- <!-- toast message displayed when a screenshot is saved to the Gallery. -->
- <string name="screenshot_saving_toast">Screenshot saved to Gallery</string>
- <!-- toast message displayed when we fail to take a screenshot. -->
- <string name="screenshot_failed_toast">Could not save screenshot. External storage may be in use.</string>
+ <!-- Notification ticker displayed when a screenshot is being saved to the Gallery. [CHAR LIMIT=30] -->
+ <string name="screenshot_saving_ticker">Saving\u2026</string>
+ <!-- Notification title displayed when a screenshot is being saved to the Gallery. [CHAR LIMIT=50] -->
+ <string name="screenshot_saving_title">Saving screenshot\u2026</string>
+ <!-- Notification text displayed when a screenshot is being saved to the Gallery. [CHAR LIMIT=100] -->
+ <string name="screenshot_saving_text">Screenshot is being saved.</string>
+ <!-- Notification title displayed when a screenshot is saved to the Gallery. [CHAR LIMIT=50] -->
+ <string name="screenshot_saved_title">Screenshot captured.</string>
+ <!-- Notification text displayed when a screenshot is saved to the Gallery. [CHAR LIMIT=100] -->
+ <string name="screenshot_saved_text">Touch to view your screenshot.</string>
+ <!-- Notification title displayed when we fail to take a screenshot. [CHAR LIMIT=50] -->
+ <string name="screenshot_failed_title">Couldn\'t capture screenshot.</string>
+ <!-- Notification text displayed when we fail to take a screenshot. [CHAR LIMIT=100] -->
+ <string name="screenshot_failed_text">Couldn\'t save screenshot. External storage may be in use.</string>
<!-- Title for the USB function chooser in UsbPreferenceActivity. [CHAR LIMIT=30] -->
<string name="usb_preference_title">USB file transfer options</string>
@@ -180,7 +190,7 @@
<!-- Label for the PTP USB function in UsbPreferenceActivity. [CHAR LIMIT=50] -->
<string name="use_ptp_button_title">Mount as a camera (PTP)</string>
<!-- Label for the installer CD image option in UsbPreferenceActivity. [CHAR LIMIT=50] -->
- <string name="installer_cd_button_title">Install Android File Transfer application for Mac</string>
+ <string name="installer_cd_button_title">Install Android File Transfer app for Mac</string>
<!-- Content description of the back button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_back">Back</string>
@@ -238,15 +248,15 @@
<string name="accessibility_data_signal_full">Data signal full.</string>
<!-- Content description of the WIFI signal when no signal for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_no_wifi">No WiFi.</string>
+ <string name="accessibility_no_wifi">No Wi-Fi.</string>
<!-- Content description of the WIFI signal when it is one bar for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_wifi_one_bar">WiFi one bar.</string>
+ <string name="accessibility_wifi_one_bar">Wi-Fi one bar.</string>
<!-- Content description of the WIFI signal when it is two bars for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_wifi_two_bars">WiFi two bars.</string>
+ <string name="accessibility_wifi_two_bars">Wi-Fi two bars.</string>
<!-- Content description of the WIFI signal when it is three bars for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_wifi_three_bars">WiFi three bars.</string>
+ <string name="accessibility_wifi_three_bars">Wi-Fi three bars.</string>
<!-- Content description of the WIFI signal when it is full for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_wifi_signal_full">WiFi signal full.</string>
+ <string name="accessibility_wifi_signal_full">Wi-Fi signal full.</string>
<!-- Content description of the data connection type GPRS for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_data_connection_gprs">GPRS</string>
@@ -267,7 +277,7 @@
<string name="accessibility_data_connection_edge">Edge</string>
<!-- Content description of the data connection type WiFi for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_data_connection_wifi">WiFi</string>
+ <string name="accessibility_data_connection_wifi">Wi-Fi</string>
<!-- Content description of the data connection with no SIM for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_no_sim">No SIM.</string>
@@ -305,6 +315,9 @@
<!-- Content description of the ringer silent icon in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_ringer_silent">Ringer silent.</string>
+ <!-- Content description to tell the user an application has been removed from recents -->
+ <string name="accessibility_recents_item_dismissed"><xliff:g id="app" example="Calendar">%s</xliff:g> dismissed.</string>
+
<!-- Title of dialog shown when 2G-3G data usage has exceeded limit and has been disabled. [CHAR LIMIT=48] -->
<string name="data_usage_disabled_dialog_3g_title">2G-3G data disabled</string>
<!-- Title of dialog shown when 4G data usage has exceeded limit and has been disabled. [CHAR LIMIT=48] -->
@@ -314,7 +327,7 @@
<!-- Title of dialog shown when data usage has exceeded limit and has been disabled. [CHAR LIMIT=48] -->
<string name="data_usage_disabled_dialog_title">Data disabled</string>
<!-- Body of dialog shown when data usage has exceeded limit and has been disabled. [CHAR LIMIT=NONE] -->
- <string name="data_usage_disabled_dialog">The specified data usage limit has been reached.\n\nAdditional data use may incur carrier charges.</string>
+ <string name="data_usage_disabled_dialog">You\'ve reached the specified data usage limit.\n\nIf you re-enable data, you may be charged by the operator.</string>
<!-- Dialog button indicating that data connection should be re-enabled. [CHAR LIMIT=28] -->
<string name="data_usage_disabled_dialog_enable">Re-enable data</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 3d49cd1..dc5c540 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -41,6 +41,13 @@
</style>
<style name="TextAppearance.StatusBar.Clock" parent="@*android:style/TextAppearance.StatusBar.Icon">
+ <!-- Note: must be dp to fit in status bar -->
+ <item name="android:textSize">16dp</item>
+ <item name="android:textStyle">normal</item>
+ <item name="android:textColor">@android:color/holo_blue_light</item>
+ </style>
+
+ <style name="TextAppearance.StatusBar.Date" parent="@*android:style/TextAppearance.StatusBar.Icon">
<item name="android:textSize">16sp</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@android:color/holo_blue_light</item>
@@ -69,4 +76,10 @@
<item name="android:windowExitAnimation">@anim/priority_alert_exit</item>
</style>
+ <style name="TextAppearance.StatusBar.PhoneTicker"
+ parent="@*android:style/TextAppearance.StatusBar.Ticker">
+ <!-- Note: must be dp to fit in status bar -->
+ <item name="android:textSize">14dp</item>
+ </style>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/Nyandroid.java b/packages/SystemUI/src/com/android/systemui/Nyandroid.java
new file mode 100644
index 0000000..6f168ba
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/Nyandroid.java
@@ -0,0 +1,253 @@
+/*);
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.animation.AnimatorSet;
+import android.animation.PropertyValuesHolder;
+import android.animation.ObjectAnimator;
+import android.animation.TimeAnimator;
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Pair;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import java.util.HashMap;
+import java.util.Random;
+
+public class Nyandroid extends Activity {
+ final static boolean DEBUG = false;
+
+ public static class Board extends FrameLayout
+ {
+ public static final boolean FIXED_STARS = true;
+ public static final int NUM_CATS = 20;
+
+ static Random sRNG = new Random();
+
+ static float lerp(float a, float b, float f) {
+ return (b-a)*f + a;
+ }
+
+ static float randfrange(float a, float b) {
+ return lerp(a, b, sRNG.nextFloat());
+ }
+
+ static int randsign() {
+ return sRNG.nextBoolean() ? 1 : -1;
+ }
+
+ static <E> E pick(E[] array) {
+ if (array.length == 0) return null;
+ return array[sRNG.nextInt(array.length)];
+ }
+
+ public class FlyingCat extends ImageView {
+ public static final float VMAX = 1000.0f;
+ public static final float VMIN = 100.0f;
+
+ public float v, vr;
+
+ public float dist;
+ public float z;
+
+ public ComponentName component;
+
+ public FlyingCat(Context context, AttributeSet as) {
+ super(context, as);
+ setImageResource(R.drawable.nyandroid_anim); // @@@
+
+ if (DEBUG) setBackgroundColor(0x80FF0000);
+ }
+
+ public String toString() {
+ return String.format("<cat (%.1f, %.1f) (%d x %d)>",
+ getX(), getY(), getWidth(), getHeight());
+ }
+
+ public void reset() {
+ final float scale = lerp(0.1f,2f,z);
+ setScaleX(scale); setScaleY(scale);
+
+ setX(-scale*getWidth()+1);
+ setY(randfrange(0, Board.this.getHeight()-scale*getHeight()));
+ v = lerp(VMIN, VMAX, z);
+
+ dist = 0;
+
+// android.util.Log.d("Nyandroid", "reset cat: " + this);
+ }
+
+ public void update(float dt) {
+ dist += v * dt;
+ setX(getX() + v * dt);
+ }
+ }
+
+ TimeAnimator mAnim;
+
+ public Board(Context context, AttributeSet as) {
+ super(context, as);
+
+ setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
+ setBackgroundColor(0xFF003366);
+ }
+
+ private void reset() {
+// android.util.Log.d("Nyandroid", "board reset");
+ removeAllViews();
+
+ final ViewGroup.LayoutParams wrap = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT);
+
+ if (FIXED_STARS) {
+ for(int i=0; i<20; i++) {
+ ImageView fixedStar = new ImageView(getContext(), null);
+ if (DEBUG) fixedStar.setBackgroundColor(0x8000FF80);
+ fixedStar.setImageResource(R.drawable.star_anim); // @@@
+ addView(fixedStar, wrap);
+ final float scale = randfrange(0.1f, 1f);
+ fixedStar.setScaleX(scale); fixedStar.setScaleY(scale);
+ fixedStar.setX(randfrange(0, getWidth()));
+ fixedStar.setY(randfrange(0, getHeight()));
+ final AnimationDrawable anim = (AnimationDrawable) fixedStar.getDrawable();
+ postDelayed(new Runnable() {
+ public void run() {
+ anim.start();
+ }}, (int) randfrange(0, 1000));
+ }
+ }
+
+ for(int i=0; i<NUM_CATS; i++) {
+ FlyingCat nv = new FlyingCat(getContext(), null);
+ addView(nv, wrap);
+ nv.z = ((float)i/NUM_CATS);
+ nv.z *= nv.z;
+ nv.reset();
+ nv.setX(randfrange(0,Board.this.getWidth()));
+ final AnimationDrawable anim = (AnimationDrawable) nv.getDrawable();
+ postDelayed(new Runnable() {
+ public void run() {
+ anim.start();
+ }}, (int) randfrange(0, 1000));
+ }
+
+ if (mAnim != null) {
+ mAnim.cancel();
+ }
+ mAnim = new TimeAnimator();
+ mAnim.setTimeListener(new TimeAnimator.TimeListener() {
+ public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
+ // setRotation(totalTime * 0.01f); // not as cool as you would think
+// android.util.Log.d("Nyandroid", "t=" + totalTime);
+
+ for (int i=0; i<getChildCount(); i++) {
+ View v = getChildAt(i);
+ if (!(v instanceof FlyingCat)) continue;
+ FlyingCat nv = (FlyingCat) v;
+ nv.update(deltaTime / 1000f);
+ final float catWidth = nv.getWidth() * nv.getScaleX();
+ final float catHeight = nv.getHeight() * nv.getScaleY();
+ if ( nv.getX() + catWidth < -2
+ || nv.getX() > getWidth() + 2
+ || nv.getY() + catHeight < -2
+ || nv.getY() > getHeight() + 2)
+ {
+ nv.reset();
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ protected void onSizeChanged (int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w,h,oldw,oldh);
+// android.util.Log.d("Nyandroid", "resized: " + w + "x" + h);
+ post(new Runnable() { public void run() {
+ reset();
+ mAnim.start();
+ } });
+ }
+
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mAnim.cancel();
+ }
+
+ @Override
+ public boolean isOpaque() {
+ return true;
+ }
+ }
+
+ private Board mBoard;
+
+ @Override
+ public void onStart() {
+ super.onStart();
+
+ getWindow().addFlags(
+ WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
+ | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+ );
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mBoard = new Board(this, null);
+ setContentView(mBoard);
+
+ mBoard.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
+ @Override
+ public void onSystemUiVisibilityChange(int vis) {
+ if (0 == (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)) {
+ Nyandroid.this.finish();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onUserInteraction() {
+// android.util.Log.d("Nyandroid", "finishing on user interaction");
+ finish();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 07281d4..14ce266 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -17,6 +17,7 @@
package com.android.systemui;
import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.Animator.AnimatorListener;
import android.animation.ValueAnimator;
@@ -40,6 +41,8 @@
public static final int X = 0;
public static final int Y = 1;
+ private static LinearInterpolator sLinearInterpolator = new LinearInterpolator();
+
private float SWIPE_ESCAPE_VELOCITY = 100f; // dp/sec
private int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
private int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms
@@ -199,6 +202,10 @@
return mDragging;
}
+ /**
+ * @param view The view to be dismissed
+ * @param velocity The desired pixels/second speed at which the view should move
+ */
public void dismissChild(final View view, float velocity) {
final View animView = mCallback.getChildContentView(view);
final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view);
@@ -221,22 +228,14 @@
duration = DEFAULT_ESCAPE_ANIMATION_DURATION;
}
+ animView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator anim = createTranslationAnimation(animView, newPos);
- anim.setInterpolator(new LinearInterpolator());
+ anim.setInterpolator(sLinearInterpolator);
anim.setDuration(duration);
- anim.addListener(new AnimatorListener() {
- public void onAnimationStart(Animator animation) {
- }
-
- public void onAnimationRepeat(Animator animation) {
- }
-
+ anim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
mCallback.onChildDismissed(view);
- }
-
- public void onAnimationCancel(Animator animation) {
- mCallback.onChildDismissed(view);
+ animView.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
anim.addUpdateListener(new AnimatorUpdateListener() {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java
index fbf00d2..886a14d 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java
@@ -121,6 +121,7 @@
createAnimation(appearing);
mContentView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ mContentView.buildLayer();
mContentAnim.start();
mVisible = appearing;
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
new file mode 100644
index 0000000..47aa849
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recent;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import android.app.ActivityManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.Process;
+import android.os.SystemClock;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.LruCache;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.tablet.TabletStatusBar;
+
+public class RecentTasksLoader {
+ static final String TAG = "RecentTasksLoader";
+ static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
+
+ private static final int DISPLAY_TASKS = 20;
+ private static final int MAX_TASKS = DISPLAY_TASKS + 1; // allow extra for non-apps
+
+ private Context mContext;
+ private RecentsPanelView mRecentsPanel;
+
+ private AsyncTask<Void, Integer, Void> mThumbnailLoader;
+ private final Handler mHandler;
+
+ private int mIconDpi;
+ private Bitmap mDefaultThumbnailBackground;
+
+ public RecentTasksLoader(Context context) {
+ mContext = context;
+
+ final Resources res = context.getResources();
+
+ // get the icon size we want -- on tablets, we use bigger icons
+ boolean isTablet = res.getBoolean(R.bool.config_recents_interface_for_tablets);
+ int density = res.getDisplayMetrics().densityDpi;
+ if (isTablet) {
+ if (density == DisplayMetrics.DENSITY_LOW) {
+ mIconDpi = DisplayMetrics.DENSITY_MEDIUM;
+ } else if (density == DisplayMetrics.DENSITY_MEDIUM) {
+ mIconDpi = DisplayMetrics.DENSITY_HIGH;
+ } else if (density == DisplayMetrics.DENSITY_HIGH) {
+ mIconDpi = DisplayMetrics.DENSITY_XHIGH;
+ } else if (density == DisplayMetrics.DENSITY_XHIGH) {
+ // We'll need to use a denser icon, or some sort of a mipmap
+ mIconDpi = DisplayMetrics.DENSITY_XHIGH;
+ }
+ } else {
+ mIconDpi = res.getDisplayMetrics().densityDpi;
+ }
+ mIconDpi = isTablet ? DisplayMetrics.DENSITY_HIGH : res.getDisplayMetrics().densityDpi;
+
+ // Render the default thumbnail background
+ int width = (int) res.getDimension(R.dimen.status_bar_recents_thumbnail_width);
+ int height = (int) res.getDimension(R.dimen.status_bar_recents_thumbnail_height);
+ int color = res.getColor(R.drawable.status_bar_recents_app_thumbnail_background);
+
+ mDefaultThumbnailBackground = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ Canvas c = new Canvas(mDefaultThumbnailBackground);
+ c.drawColor(color);
+
+ // If we're using the cache, begin listening to the activity manager for
+ // updated thumbnails
+ final ActivityManager am = (ActivityManager)
+ mContext.getSystemService(Context.ACTIVITY_SERVICE);
+
+ mHandler = new Handler();
+ }
+
+ public void setRecentsPanel(RecentsPanelView recentsPanel) {
+ mRecentsPanel = recentsPanel;
+ }
+
+ // Create an TaskDescription, returning null if the title or icon is null, or if it's the
+ // home activity
+ TaskDescription createTaskDescription(int taskId, int persistentTaskId, Intent baseIntent,
+ ComponentName origActivity, CharSequence description, ActivityInfo homeInfo) {
+ Intent intent = new Intent(baseIntent);
+ if (origActivity != null) {
+ intent.setComponent(origActivity);
+ }
+ final PackageManager pm = mContext.getPackageManager();
+ if (homeInfo == null) {
+ homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
+ .resolveActivityInfo(pm, 0);
+ }
+
+ intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
+ | Intent.FLAG_ACTIVITY_NEW_TASK);
+ final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
+ if (resolveInfo != null) {
+ final ActivityInfo info = resolveInfo.activityInfo;
+ final String title = info.loadLabel(pm).toString();
+ Drawable icon = getFullResIcon(resolveInfo, pm);
+
+ if (title != null && title.length() > 0 && icon != null) {
+ if (DEBUG) Log.v(TAG, "creating activity desc for id="
+ + persistentTaskId + ", label=" + title);
+
+ TaskDescription item = new TaskDescription(taskId,
+ persistentTaskId, resolveInfo, baseIntent, info.packageName,
+ description);
+ item.setLabel(title);
+ item.setIcon(icon);
+
+ // Don't load the current home activity.
+ if (homeInfo != null
+ && homeInfo.packageName.equals(intent.getComponent().getPackageName())
+ && homeInfo.name.equals(intent.getComponent().getClassName())) {
+ return null;
+ }
+
+ return item;
+ } else {
+ if (DEBUG) Log.v(TAG, "SKIPPING item " + persistentTaskId);
+ }
+ }
+ return null;
+ }
+
+ void loadThumbnail(TaskDescription td) {
+ final ActivityManager am = (ActivityManager)
+ mContext.getSystemService(Context.ACTIVITY_SERVICE);
+ ActivityManager.TaskThumbnails thumbs = am.getTaskThumbnails(td.persistentTaskId);
+
+ if (DEBUG) Log.v(TAG, "Loaded bitmap for task "
+ + td + ": " + thumbs.mainThumbnail);
+ synchronized (td) {
+ if (thumbs != null && thumbs.mainThumbnail != null) {
+ td.setThumbnail(thumbs.mainThumbnail);
+ } else {
+ td.setThumbnail(mDefaultThumbnailBackground);
+ }
+ }
+ }
+
+ Drawable getFullResDefaultActivityIcon() {
+ return getFullResIcon(Resources.getSystem(),
+ com.android.internal.R.mipmap.sym_def_app_icon);
+ }
+
+ Drawable getFullResIcon(Resources resources, int iconId) {
+ try {
+ return resources.getDrawableForDensity(iconId, mIconDpi);
+ } catch (Resources.NotFoundException e) {
+ return getFullResDefaultActivityIcon();
+ }
+ }
+
+ private Drawable getFullResIcon(ResolveInfo info, PackageManager packageManager) {
+ Resources resources;
+ try {
+ resources = packageManager.getResourcesForApplication(
+ info.activityInfo.applicationInfo);
+ } catch (PackageManager.NameNotFoundException e) {
+ resources = null;
+ }
+ if (resources != null) {
+ int iconId = info.activityInfo.getIconResource();
+ if (iconId != 0) {
+ return getFullResIcon(resources, iconId);
+ }
+ }
+ return getFullResDefaultActivityIcon();
+ }
+
+ public void cancelLoadingThumbnails() {
+ if (mThumbnailLoader != null) {
+ mThumbnailLoader.cancel(false);
+ mThumbnailLoader = null;
+ }
+ }
+
+ // return a snapshot of the current list of recent apps
+ ArrayList<TaskDescription> getRecentTasks() {
+ cancelLoadingThumbnails();
+
+ ArrayList<TaskDescription> tasks = new ArrayList<TaskDescription>();
+ final PackageManager pm = mContext.getPackageManager();
+ final ActivityManager am = (ActivityManager)
+ mContext.getSystemService(Context.ACTIVITY_SERVICE);
+
+ final List<ActivityManager.RecentTaskInfo> recentTasks =
+ am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
+
+ ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
+ .resolveActivityInfo(pm, 0);
+
+ HashSet<Integer> recentTasksToKeepInCache = new HashSet<Integer>();
+ int numTasks = recentTasks.size();
+
+ // skip the first task - assume it's either the home screen or the current activity.
+ final int first = 1;
+ recentTasksToKeepInCache.add(recentTasks.get(0).persistentId);
+ for (int i = first, index = 0; i < numTasks && (index < MAX_TASKS); ++i) {
+ final ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(i);
+
+ TaskDescription item = createTaskDescription(recentInfo.id,
+ recentInfo.persistentId, recentInfo.baseIntent,
+ recentInfo.origActivity, recentInfo.description, homeInfo);
+
+ if (item != null) {
+ tasks.add(item);
+ ++index;
+ }
+ }
+
+ // when we're not using the TaskDescription cache, we load the thumbnails in the
+ // background
+ loadThumbnailsInBackground(new ArrayList<TaskDescription>(tasks));
+ return tasks;
+ }
+
+ private void loadThumbnailsInBackground(final ArrayList<TaskDescription> descriptions) {
+ if (descriptions.size() > 0) {
+ if (DEBUG) Log.v(TAG, "Showing " + descriptions.size() + " tasks");
+ loadThumbnail(descriptions.get(0));
+ if (descriptions.size() > 1) {
+ mThumbnailLoader = new AsyncTask<Void, Integer, Void>() {
+ @Override
+ protected void onProgressUpdate(Integer... values) {
+ final TaskDescription td = descriptions.get(values[0]);
+ if (!isCancelled()) {
+ mRecentsPanel.onTaskThumbnailLoaded(td);
+ }
+ // This is to prevent the loader thread from getting ahead
+ // of our UI updates.
+ mHandler.post(new Runnable() {
+ @Override public void run() {
+ synchronized (td) {
+ td.notifyAll();
+ }
+ }
+ });
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ final int origPri = Process.getThreadPriority(Process.myTid());
+ Process.setThreadPriority(Process.THREAD_GROUP_BG_NONINTERACTIVE);
+ long nextTime = SystemClock.uptimeMillis();
+ for (int i=1; i<descriptions.size(); i++) {
+ TaskDescription td = descriptions.get(i);
+ loadThumbnail(td);
+ long now = SystemClock.uptimeMillis();
+ nextTime += 150;
+ if (nextTime > now) {
+ try {
+ Thread.sleep(nextTime-now);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ if (isCancelled()) {
+ break;
+ }
+ synchronized (td) {
+ publishProgress(i);
+ try {
+ td.wait(500);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ Process.setThreadPriority(origPri);
+ return null;
+ }
+ };
+ mThumbnailLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+ }
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index 58af255..f971d2d 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -32,14 +32,14 @@
import com.android.systemui.R;
import com.android.systemui.SwipeHelper;
-import com.android.systemui.recent.RecentsPanelView.ActivityDescriptionAdapter;
+import com.android.systemui.recent.RecentsPanelView.TaskDescriptionAdapter;
public class RecentsHorizontalScrollView extends HorizontalScrollView
implements SwipeHelper.Callback {
private static final String TAG = RecentsPanelView.TAG;
private static final boolean DEBUG = RecentsPanelView.DEBUG;
private LinearLayout mLinearLayout;
- private ActivityDescriptionAdapter mAdapter;
+ private TaskDescriptionAdapter mAdapter;
private RecentsCallback mCallback;
protected int mLastScrollPosition;
private SwipeHelper mSwipeHelper;
@@ -304,7 +304,7 @@
}
}
- public void setAdapter(ActivityDescriptionAdapter adapter) {
+ public void setAdapter(TaskDescriptionAdapter adapter) {
mAdapter = adapter;
mAdapter.registerDataSetObserver(new DataSetObserver() {
public void onChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index e3f5cdb..bd1fcfc 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -17,32 +17,20 @@
package com.android.systemui.recent;
import java.util.ArrayList;
-import java.util.List;
import android.animation.Animator;
import android.animation.LayoutTransition;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
-import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Handler;
-import android.os.Process;
-import android.os.SystemClock;
import android.provider.Settings;
import android.util.AttributeSet;
-import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -50,6 +38,7 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
@@ -72,66 +61,24 @@
implements OnItemClickListener, RecentsCallback, StatusBarPanel, Animator.AnimatorListener {
static final String TAG = "RecentsPanelView";
static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
- private static final int DISPLAY_TASKS = 20;
- private static final int MAX_TASKS = DISPLAY_TASKS + 1; // allow extra for non-apps
+ private Context mContext;
private StatusBar mBar;
- private ArrayList<ActivityDescription> mActivityDescriptions;
- private AsyncTask<Void, Integer, Void> mThumbnailLoader;
- private int mIconDpi;
private View mRecentsScrim;
private View mRecentsGlowView;
private View mRecentsNoApps;
private ViewGroup mRecentsContainer;
- private Bitmap mDefaultThumbnailBackground;
private boolean mShowing;
private Choreographer mChoreo;
private View mRecentsDismissButton;
- private ActivityDescriptionAdapter mListAdapter;
- private final Handler mHandler = new Handler();
- /* package */ final class ActivityDescription {
- final ActivityManager.RecentTaskInfo recentTaskInfo;
- final ResolveInfo resolveInfo;
- final int taskId; // application task id for curating apps
- final int persistentTaskId; // persistent id
- final Intent intent; // launch intent for application
- final String packageName; // used to override animations (see onClick())
- final int position; // position in list
+ private RecentTasksLoader mRecentTasksLoader;
+ private ArrayList<TaskDescription> mRecentTaskDescriptions;
+ private TaskDescriptionAdapter mListAdapter;
+ private int mThumbnailWidth;
- Matrix matrix; // arbitrary rotation matrix to correct orientation
-
- private Bitmap mThumbnail; // generated by Activity.onCreateThumbnail()
- private Drawable mIcon; // application package icon
- private CharSequence mLabel; // application package label
-
- public ActivityDescription(ActivityManager.RecentTaskInfo _recentInfo,
- ResolveInfo _resolveInfo, Intent _intent,
- int _pos, String _packageName) {
- recentTaskInfo = _recentInfo;
- resolveInfo = _resolveInfo;
- intent = _intent;
- taskId = _recentInfo.id;
- persistentTaskId = _recentInfo.persistentId;
- position = _pos;
- packageName = _packageName;
- }
-
- public CharSequence getLabel() {
- return mLabel;
- }
-
- public Drawable getIcon() {
- return mIcon;
- }
-
- public void setThumbnail(Bitmap thumbnail) {
- mThumbnail = thumbnail;
- }
-
- public Bitmap getThumbnail() {
- return mThumbnail;
- }
+ public void setRecentTasksLoader(RecentTasksLoader loader) {
+ mRecentTasksLoader = loader;
}
private final class OnLongClickDelegate implements View.OnLongClickListener {
@@ -150,18 +97,18 @@
ImageView iconView;
TextView labelView;
TextView descriptionView;
- ActivityDescription activityDescription;
+ TaskDescription taskDescription;
}
- /* package */ final class ActivityDescriptionAdapter extends BaseAdapter {
+ /* package */ final class TaskDescriptionAdapter extends BaseAdapter {
private LayoutInflater mInflater;
- public ActivityDescriptionAdapter(Context context) {
+ public TaskDescriptionAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
public int getCount() {
- return mActivityDescriptions != null ? mActivityDescriptions.size() : 0;
+ return mRecentTaskDescriptions != null ? mRecentTaskDescriptions.size() : 0;
}
public Object getItem(int position) {
@@ -189,18 +136,15 @@
holder = (ViewHolder) convertView.getTag();
}
- // activityId is reverse since most recent appears at the bottom...
- final int activityId = mActivityDescriptions.size() - position - 1;
+ // index is reverse since most recent appears at the bottom...
+ final int index = mRecentTaskDescriptions.size() - position - 1;
- final ActivityDescription activityDescription = mActivityDescriptions.get(activityId);
- holder.thumbnailViewImage.setImageBitmap(activityDescription.getThumbnail());
- holder.iconView.setImageDrawable(activityDescription.getIcon());
- holder.labelView.setText(activityDescription.getLabel());
- holder.descriptionView.setText(activityDescription.recentTaskInfo.description);
- holder.thumbnailView.setTag(activityDescription);
+ final TaskDescription taskDescription = mRecentTaskDescriptions.get(index);
+ applyTaskDescription(holder, taskDescription, false);
+
+ holder.thumbnailView.setTag(taskDescription);
holder.thumbnailView.setOnLongClickListener(new OnLongClickDelegate(convertView));
- holder.thumbnailView.setContentDescription(activityDescription.getLabel());
- holder.activityDescription = activityDescription;
+ holder.taskDescription = taskDescription;
return convertView;
}
@@ -226,14 +170,19 @@
}
public void show(boolean show, boolean animate) {
+ show(show, animate, null);
+ }
+
+ public void show(boolean show, boolean animate,
+ ArrayList<TaskDescription> recentTaskDescriptions) {
if (show) {
// Need to update list of recent apps before we set visibility so this view's
// content description is updated before it gets focus for TalkBack mode
- refreshApplicationList();
+ refreshRecentTasksList(recentTaskDescriptions);
// if there are no apps, either bring up a "No recent apps" message, or just
// quit early
- boolean noApps = (mActivityDescriptions.size() == 0);
+ boolean noApps = (mRecentTaskDescriptions.size() == 0);
if (mRecentsNoApps != null) { // doesn't exist on large devices
mRecentsNoApps.setVisibility(noApps ? View.VISIBLE : View.INVISIBLE);
} else {
@@ -242,6 +191,8 @@
return;
}
}
+ } else {
+ mRecentTasksLoader.cancelLoadingThumbnails();
}
if (animate) {
if (mShowing != show) {
@@ -255,6 +206,7 @@
mShowing = show;
setVisibility(show ? View.VISIBLE : View.GONE);
mChoreo.jumpTo(show);
+ onAnimationEnd(null);
}
if (show) {
setFocusable(true);
@@ -278,7 +230,7 @@
public void handleShowBackground(boolean show) {
if (show) {
- mRecentsScrim.setBackgroundResource(R.drawable.status_bar_recents_background);
+ mRecentsScrim.setBackgroundResource(R.drawable.status_bar_recents_background_solid);
} else {
mRecentsScrim.setBackgroundDrawable(null);
}
@@ -298,6 +250,9 @@
createCustomAnimations(transitioner);
} else {
((ViewGroup)mRecentsContainer).setLayoutTransition(null);
+ // Clear memory used by screenshots
+ mRecentTaskDescriptions.clear();
+ mListAdapter.notifyDataSetInvalidated();
}
}
@@ -349,21 +304,13 @@
public RecentsPanelView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ mContext = context;
+ updateValuesFromResources();
+ }
- Resources res = context.getResources();
- boolean xlarge = (res.getConfiguration().screenLayout
- & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE;
-
- mIconDpi = xlarge ? DisplayMetrics.DENSITY_HIGH : res.getDisplayMetrics().densityDpi;
-
- int width = (int) res.getDimension(R.dimen.status_bar_recents_thumbnail_width);
- int height = (int) res.getDimension(R.dimen.status_bar_recents_thumbnail_height);
- int color = res.getColor(R.drawable.status_bar_recents_app_thumbnail_background);
-
- // Render the default thumbnail background
- mDefaultThumbnailBackground = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(mDefaultThumbnailBackground);
- c.drawColor(color);
+ public void updateValuesFromResources() {
+ mThumbnailWidth =
+ (int) mContext.getResources().getDimension(R.dimen.status_bar_recents_thumbnail_width);
}
@Override
@@ -371,7 +318,7 @@
super.onFinishInflate();
mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mRecentsContainer = (ViewGroup) findViewById(R.id.recents_container);
- mListAdapter = new ActivityDescriptionAdapter(mContext);
+ mListAdapter = new TaskDescriptionAdapter(mContext);
if (mRecentsContainer instanceof RecentsHorizontalScrollView){
RecentsHorizontalScrollView scrollView
= (RecentsHorizontalScrollView) mRecentsContainer;
@@ -427,122 +374,50 @@
}
}
- Drawable getFullResDefaultActivityIcon() {
- return getFullResIcon(Resources.getSystem(),
- com.android.internal.R.mipmap.sym_def_app_icon);
- }
- Drawable getFullResIcon(Resources resources, int iconId) {
- try {
- return resources.getDrawableForDensity(iconId, mIconDpi);
- } catch (Resources.NotFoundException e) {
- return getFullResDefaultActivityIcon();
- }
- }
-
- private Drawable getFullResIcon(ResolveInfo info, PackageManager packageManager) {
- Resources resources;
- try {
- resources = packageManager.getResourcesForApplication(
- info.activityInfo.applicationInfo);
- } catch (PackageManager.NameNotFoundException e) {
- resources = null;
- }
- if (resources != null) {
- int iconId = info.activityInfo.getIconResource();
- if (iconId != 0) {
- return getFullResIcon(resources, iconId);
+ void applyTaskDescription(ViewHolder h, TaskDescription td, boolean anim) {
+ h.iconView.setImageDrawable(td.getIcon());
+ if (h.iconView.getVisibility() != View.VISIBLE) {
+ if (anim) {
+ h.iconView.setAnimation(AnimationUtils.loadAnimation(
+ mContext, R.anim.recent_appear));
}
+ h.iconView.setVisibility(View.VISIBLE);
}
- return getFullResDefaultActivityIcon();
- }
-
- private ArrayList<ActivityDescription> getRecentTasks() {
- ArrayList<ActivityDescription> activityDescriptions = new ArrayList<ActivityDescription>();
- final PackageManager pm = mContext.getPackageManager();
- final ActivityManager am = (ActivityManager)
- mContext.getSystemService(Context.ACTIVITY_SERVICE);
-
- final List<ActivityManager.RecentTaskInfo> recentTasks =
- am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
-
- ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
- .resolveActivityInfo(pm, 0);
-
- int numTasks = recentTasks.size();
-
- // skip the first activity - assume it's either the home screen or the current app.
- final int first = 1;
- for (int i = first, index = 0; i < numTasks && (index < MAX_TASKS); ++i) {
- final ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(i);
-
- Intent intent = new Intent(recentInfo.baseIntent);
- if (recentInfo.origActivity != null) {
- intent.setComponent(recentInfo.origActivity);
+ h.labelView.setText(td.getLabel());
+ h.thumbnailView.setContentDescription(td.getLabel());
+ if (h.labelView.getVisibility() != View.VISIBLE) {
+ if (anim) {
+ h.labelView.setAnimation(AnimationUtils.loadAnimation(
+ mContext, R.anim.recent_appear));
}
-
- // Skip the current home activity.
- if (homeInfo != null
- && homeInfo.packageName.equals(intent.getComponent().getPackageName())
- && homeInfo.name.equals(intent.getComponent().getClassName())) {
- continue;
- }
-
- intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
- | Intent.FLAG_ACTIVITY_NEW_TASK);
- final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
- if (resolveInfo != null) {
- final ActivityInfo info = resolveInfo.activityInfo;
- final String title = info.loadLabel(pm).toString();
- Drawable icon = getFullResIcon(resolveInfo, pm);
- if (title != null && title.length() > 0 && icon != null) {
- if (DEBUG) Log.v(TAG, "creating activity desc for id="
- + recentInfo.id + ", label=" + title);
- ActivityDescription item = new ActivityDescription(recentInfo,
- resolveInfo, intent, index, info.packageName);
- activityDescriptions.add(item);
- ++index;
- } else {
- if (DEBUG) Log.v(TAG, "SKIPPING item " + recentInfo.id);
+ h.labelView.setVisibility(View.VISIBLE);
+ }
+ Bitmap thumbnail = td.getThumbnail();
+ if (thumbnail != null) {
+ // Should remove the default image in the frame
+ // that this now covers, to improve scrolling speed.
+ // That can't be done until the anim is complete though.
+ h.thumbnailViewImage.setImageBitmap(thumbnail);
+ // scale to fill up the full width
+ Matrix scaleMatrix = new Matrix();
+ float scale = mThumbnailWidth / (float) thumbnail.getWidth();
+ scaleMatrix.setScale(scale, scale);
+ h.thumbnailViewImage.setScaleType(ScaleType.MATRIX);
+ h.thumbnailViewImage.setImageMatrix(scaleMatrix);
+ if (h.thumbnailViewImage.getVisibility() != View.VISIBLE) {
+ if (anim) {
+ h.thumbnailViewImage.setAnimation(
+ AnimationUtils.loadAnimation(
+ mContext, R.anim.recent_appear));
}
+ h.thumbnailViewImage.setVisibility(View.VISIBLE);
}
}
- return activityDescriptions;
+ //h.descriptionView.setText(ad.description);
}
- ActivityDescription findActivityDescription(int id)
- {
- ActivityDescription desc = null;
- for (int i = 0; i < mActivityDescriptions.size(); i++) {
- ActivityDescription item = mActivityDescriptions.get(i);
- if (item != null && item.taskId == id) {
- desc = item;
- break;
- }
- }
- return desc;
- }
-
- void loadActivityDescription(ActivityDescription ad, int index) {
- final ActivityManager am = (ActivityManager)
- mContext.getSystemService(Context.ACTIVITY_SERVICE);
- final PackageManager pm = mContext.getPackageManager();
- ActivityManager.TaskThumbnails thumbs = am.getTaskThumbnails(
- ad.recentTaskInfo.persistentId);
- CharSequence label = ad.resolveInfo.activityInfo.loadLabel(pm);
- Drawable icon = getFullResIcon(ad.resolveInfo, pm);
- if (DEBUG) Log.v(TAG, "Loaded bitmap for #" + index + " in "
- + ad + ": " + thumbs.mainThumbnail);
- synchronized (ad) {
- ad.mLabel = label;
- ad.mIcon = icon;
- if (thumbs != null && thumbs.mainThumbnail != null) {
- ad.setThumbnail(thumbs.mainThumbnail);
- }
- }
- }
-
- void applyActivityDescription(ActivityDescription ad, int index, boolean anim) {
+ void onTaskThumbnailLoaded(TaskDescription ad) {
synchronized (ad) {
if (mRecentsContainer != null) {
ViewGroup container = mRecentsContainer;
@@ -556,44 +431,8 @@
View v = container.getChildAt(i);
if (v.getTag() instanceof ViewHolder) {
ViewHolder h = (ViewHolder)v.getTag();
- if (h.activityDescription == ad) {
- if (DEBUG) Log.v(TAG, "Updating thumbnail #" + index + " in "
- + h.activityDescription
- + ": " + ad.getThumbnail());
- h.iconView.setImageDrawable(ad.getIcon());
- if (anim) {
- h.iconView.setAnimation(AnimationUtils.loadAnimation(
- mContext, R.anim.recent_appear));
- }
- h.iconView.setVisibility(View.VISIBLE);
- h.labelView.setText(ad.getLabel());
- h.thumbnailView.setContentDescription(ad.getLabel());
- if (anim) {
- h.labelView.setAnimation(AnimationUtils.loadAnimation(
- mContext, R.anim.recent_appear));
- }
- h.labelView.setVisibility(View.VISIBLE);
- Bitmap thumbnail = ad.getThumbnail();
- if (thumbnail != null) {
- // Should remove the default image in the frame
- // that this now covers, to improve scrolling speed.
- // That can't be done until the anim is complete though.
- h.thumbnailViewImage.setImageBitmap(thumbnail);
-
- // scale to fill up the full width
- Matrix scaleMatrix = new Matrix();
- float thumbnailViewWidth = h.thumbnailViewImage.getWidth();
- float scale = thumbnailViewWidth / thumbnail.getWidth();
- scaleMatrix.setScale(scale, scale);
- h.thumbnailViewImage.setScaleType(ScaleType.MATRIX);
- h.thumbnailViewImage.setImageMatrix(scaleMatrix);
-
- if (anim) {
- h.thumbnailViewImage.setAnimation(AnimationUtils.loadAnimation(
- mContext, R.anim.recent_appear));
- }
- h.thumbnailViewImage.setVisibility(View.VISIBLE);
- }
+ if (h.taskDescription == ad) {
+ applyTaskDescription(h, ad, true);
}
}
}
@@ -601,14 +440,28 @@
}
}
- private void refreshApplicationList() {
- if (mThumbnailLoader != null) {
- mThumbnailLoader.cancel(false);
- mThumbnailLoader = null;
+ private void refreshRecentTasksList(ArrayList<TaskDescription> recentTasksList) {
+ if (recentTasksList != null) {
+ mRecentTaskDescriptions = recentTasksList;
+ } else {
+ mRecentTaskDescriptions = mRecentTasksLoader.getRecentTasks();
}
+ mListAdapter.notifyDataSetInvalidated();
+ updateUiElements(getResources().getConfiguration());
+ }
- mActivityDescriptions = getRecentTasks();
- int numRecentApps = mActivityDescriptions.size();
+ public ArrayList<TaskDescription> getRecentTasksList() {
+ return mRecentTaskDescriptions;
+ }
+
+ private void updateUiElements(Configuration config) {
+ final int items = mRecentTaskDescriptions.size();
+
+ mRecentsContainer.setVisibility(items > 0 ? View.VISIBLE : View.GONE);
+ mRecentsGlowView.setVisibility(items > 0 ? View.VISIBLE : View.GONE);
+
+ // Set description for accessibility
+ int numRecentApps = mRecentTaskDescriptions.size();
String recentAppsAccessibilityDescription;
if (numRecentApps == 0) {
recentAppsAccessibilityDescription =
@@ -618,81 +471,10 @@
R.plurals.status_bar_accessibility_recent_apps, numRecentApps, numRecentApps);
}
setContentDescription(recentAppsAccessibilityDescription);
- for (ActivityDescription ad : mActivityDescriptions) {
- ad.setThumbnail(mDefaultThumbnailBackground);
- }
- mListAdapter.notifyDataSetInvalidated();
- if (mActivityDescriptions.size() > 0) {
- if (DEBUG) Log.v(TAG, "Showing " + mActivityDescriptions.size() + " apps");
- updateUiElements(getResources().getConfiguration());
- final ArrayList<ActivityDescription> descriptions =
- new ArrayList<ActivityDescription>(mActivityDescriptions);
- loadActivityDescription(descriptions.get(0), 0);
- applyActivityDescription(descriptions.get(0), 0, false);
- if (descriptions.size() > 1) {
- mThumbnailLoader = new AsyncTask<Void, Integer, Void>() {
- @Override
- protected void onProgressUpdate(Integer... values) {
- final ActivityDescription ad = descriptions.get(values[0]);
- if (!isCancelled()) {
- applyActivityDescription(ad, values[0], true);
- }
- // This is to prevent the loader thread from getting ahead
- // of our UI updates.
- mHandler.post(new Runnable() {
- @Override public void run() {
- synchronized (ad) {
- ad.notifyAll();
- }
- }
- });
- }
-
- @Override
- protected Void doInBackground(Void... params) {
- final int origPri = Process.getThreadPriority(Process.myTid());
- Process.setThreadPriority(Process.THREAD_GROUP_BG_NONINTERACTIVE);
- long nextTime = SystemClock.uptimeMillis();
- for (int i=1; i<descriptions.size(); i++) {
- ActivityDescription ad = descriptions.get(i);
- loadActivityDescription(ad, i);
- long now = SystemClock.uptimeMillis();
- nextTime += 150;
- if (nextTime > now) {
- try {
- Thread.sleep(nextTime-now);
- } catch (InterruptedException e) {
- }
- }
- if (isCancelled()) {
- break;
- }
- synchronized (ad) {
- publishProgress(i);
- try {
- ad.wait(500);
- } catch (InterruptedException e) {
- }
- }
- }
- Process.setThreadPriority(origPri);
- return null;
- }
- };
- mThumbnailLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
- }
-
- private void updateUiElements(Configuration config) {
- final int items = mActivityDescriptions.size();
-
- mRecentsContainer.setVisibility(items > 0 ? View.VISIBLE : View.GONE);
- mRecentsGlowView.setVisibility(items > 0 ? View.VISIBLE : View.GONE);
}
public void handleOnClick(View view) {
- ActivityDescription ad = ((ViewHolder) view.getTag()).activityDescription;
+ TaskDescription ad = ((ViewHolder) view.getTag()).taskDescription;
final Context context = view.getContext();
final ActivityManager am = (ActivityManager)
context.getSystemService(Context.ACTIVITY_SERVICE);
@@ -702,7 +484,8 @@
} else {
Intent intent = ad.intent;
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
- | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
+ | Intent.FLAG_ACTIVITY_TASK_ON_HOME
+ | Intent.FLAG_ACTIVITY_NEW_TASK);
if (DEBUG) Log.v(TAG, "Starting activity " + intent);
context.startActivity(intent);
}
@@ -714,14 +497,14 @@
}
public void handleSwipe(View view) {
- ActivityDescription ad = ((ViewHolder) view.getTag()).activityDescription;
+ TaskDescription ad = ((ViewHolder) view.getTag()).taskDescription;
if (DEBUG) Log.v(TAG, "Jettison " + ad.getLabel());
- mActivityDescriptions.remove(ad);
+ mRecentTaskDescriptions.remove(ad);
// Handled by widget containers to enable LayoutTransitions properly
// mListAdapter.notifyDataSetChanged();
- if (mActivityDescriptions.size() == 0) {
+ if (mRecentTaskDescriptions.size() == 0) {
hide(false);
}
@@ -730,6 +513,12 @@
final ActivityManager am = (ActivityManager)
mContext.getSystemService(Context.ACTIVITY_SERVICE);
am.removeTask(ad.persistentTaskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
+
+ // Accessibility feedback
+ setContentDescription(
+ mContext.getString(R.string.accessibility_recents_item_dismissed, ad.getLabel()));
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+ setContentDescription(null);
}
private void startApplicationDetailsActivity(String packageName) {
@@ -751,7 +540,7 @@
} else if (item.getItemId() == R.id.recent_inspect_item) {
ViewHolder viewHolder = (ViewHolder) selectedView.getTag();
if (viewHolder != null) {
- final ActivityDescription ad = viewHolder.activityDescription;
+ final TaskDescription ad = viewHolder.taskDescription;
startApplicationDetailsActivity(ad.packageName);
mBar.animateCollapse();
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
index b7e656e..813099a 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
@@ -83,7 +83,7 @@
mLinearLayout = layout;
mAttachedToWindow = true;
mBackgroundDrawable = mContext.getResources()
- .getDrawable(R.drawable.status_bar_recents_background).getConstantState();
+ .getDrawable(R.drawable.status_bar_recents_background_solid).getConstantState();
updateShowBackground();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 7853402..dc13092 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -31,13 +31,13 @@
import com.android.systemui.R;
import com.android.systemui.SwipeHelper;
-import com.android.systemui.recent.RecentsPanelView.ActivityDescriptionAdapter;
+import com.android.systemui.recent.RecentsPanelView.TaskDescriptionAdapter;
public class RecentsVerticalScrollView extends ScrollView implements SwipeHelper.Callback {
private static final String TAG = RecentsPanelView.TAG;
private static final boolean DEBUG = RecentsPanelView.DEBUG;
private LinearLayout mLinearLayout;
- private ActivityDescriptionAdapter mAdapter;
+ private TaskDescriptionAdapter mAdapter;
private RecentsCallback mCallback;
protected int mLastScrollPosition;
private SwipeHelper mSwipeHelper;
@@ -319,7 +319,7 @@
}
}
- public void setAdapter(ActivityDescriptionAdapter adapter) {
+ public void setAdapter(TaskDescriptionAdapter adapter) {
mAdapter = adapter;
mAdapter.registerDataSetObserver(new DataSetObserver() {
public void onChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java b/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java
new file mode 100644
index 0000000..dcfd6d8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recent;
+
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+
+public final class TaskDescription {
+ final ResolveInfo resolveInfo;
+ final int taskId; // application task id for curating apps
+ final int persistentTaskId; // persistent id
+ final Intent intent; // launch intent for application
+ final String packageName; // used to override animations (see onClick())
+ final CharSequence description;
+
+ private Bitmap mThumbnail; // generated by Activity.onCreateThumbnail()
+ private Drawable mIcon; // application package icon
+ private CharSequence mLabel; // application package label
+
+ public TaskDescription(int _taskId, int _persistentTaskId,
+ ResolveInfo _resolveInfo, Intent _intent,
+ String _packageName, CharSequence _description) {
+ resolveInfo = _resolveInfo;
+ intent = _intent;
+ taskId = _taskId;
+ persistentTaskId = _persistentTaskId;
+
+ description = _description;
+ packageName = _packageName;
+ }
+
+ // mark all these as locked?
+ public CharSequence getLabel() {
+ return mLabel;
+ }
+
+ public void setLabel(CharSequence label) {
+ mLabel = label;
+ }
+
+ public Drawable getIcon() {
+ return mIcon;
+ }
+
+ public void setIcon(Drawable icon) {
+ mIcon = icon;
+ }
+
+ public void setThumbnail(Bitmap thumbnail) {
+ mThumbnail = thumbnail;
+ }
+
+ public Bitmap getThumbnail() {
+ return mThumbnail;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 3fa3078..301ae73 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -19,27 +19,29 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.app.Activity;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
-import android.media.MediaScannerConnection;
+import android.graphics.PointF;
+import android.graphics.RectF;
import android.net.Uri;
import android.os.AsyncTask;
-import android.os.Binder;
import android.os.Environment;
+import android.os.Process;
import android.os.ServiceManager;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
-import android.util.Log;
import android.view.Display;
import android.view.IWindowManager;
import android.view.LayoutInflater;
@@ -48,18 +50,15 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toast;
import com.android.systemui.R;
import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
import java.io.OutputStream;
-import java.lang.Thread;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -69,7 +68,9 @@
class SaveImageInBackgroundData {
Context context;
Bitmap image;
+ Uri imageUri;
Runnable finisher;
+ int iconSize;
int result;
}
@@ -83,31 +84,89 @@
private static final String SCREENSHOT_FILE_NAME_TEMPLATE = "Screenshot_%s.png";
private static final String SCREENSHOT_FILE_PATH_TEMPLATE = "%s/%s/%s";
+ private int mNotificationId;
+ private NotificationManager mNotificationManager;
+ private Notification.Builder mNotificationBuilder;
+ private Intent mLaunchIntent;
+ private String mImageDir;
+ private String mImageFileName;
+ private String mImageFilePath;
+ private String mImageDate;
+ private long mImageTime;
+
+ // WORKAROUND: We want the same notification across screenshots that we update so that we don't
+ // spam a user's notification drawer. However, we only show the ticker for the saving state
+ // and if the ticker text is the same as the previous notification, then it will not show. So
+ // for now, we just add and remove a space from the ticker text to trigger the animation when
+ // necessary.
+ private static boolean mTickerAddSpace;
+
+ SaveImageInBackgroundTask(Context context, SaveImageInBackgroundData data,
+ NotificationManager nManager, int nId) {
+ Resources r = context.getResources();
+
+ // Prepare all the output metadata
+ mImageTime = System.currentTimeMillis();
+ mImageDate = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date(mImageTime));
+ mImageDir = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES).getAbsolutePath();
+ mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, mImageDate);
+ mImageFilePath = String.format(SCREENSHOT_FILE_PATH_TEMPLATE, mImageDir,
+ SCREENSHOTS_DIR_NAME, mImageFileName);
+
+ // Create the large notification icon
+ int imageWidth = data.image.getWidth();
+ int imageHeight = data.image.getHeight();
+ int iconWidth = data.iconSize;
+ int iconHeight = data.iconSize;
+ if (imageWidth > imageHeight) {
+ iconWidth = (int) (((float) iconHeight / imageHeight) * imageWidth);
+ } else {
+ iconHeight = (int) (((float) iconWidth / imageWidth) * imageHeight);
+ }
+ Bitmap rawIcon = Bitmap.createScaledBitmap(data.image, iconWidth, iconHeight, true);
+ Bitmap croppedIcon = Bitmap.createBitmap(rawIcon, (iconWidth - data.iconSize) / 2,
+ (iconHeight - data.iconSize) / 2, data.iconSize, data.iconSize);
+
+ // Show the intermediate notification
+ mTickerAddSpace = !mTickerAddSpace;
+ mNotificationId = nId;
+ mNotificationBuilder = new Notification.Builder(context)
+ .setLargeIcon(croppedIcon)
+ .setTicker(r.getString(R.string.screenshot_saving_ticker)
+ + (mTickerAddSpace ? " " : ""))
+ .setContentTitle(r.getString(R.string.screenshot_saving_title))
+ .setContentText(r.getString(R.string.screenshot_saving_text))
+ .setSmallIcon(android.R.drawable.ic_menu_gallery)
+ .setWhen(System.currentTimeMillis());
+ Notification n = mNotificationBuilder.getNotification();
+ n.flags |= Notification.FLAG_NO_CLEAR;
+
+ mNotificationManager = nManager;
+ mNotificationManager.notify(nId, n);
+ }
+
@Override
protected SaveImageInBackgroundData doInBackground(SaveImageInBackgroundData... params) {
if (params.length != 1) return null;
+ // By default, AsyncTask sets the worker thread to have background thread priority, so bump
+ // it back up so that we save a little quicker.
+ Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
+
Context context = params[0].context;
Bitmap image = params[0].image;
try {
- long currentTime = System.currentTimeMillis();
- String date = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date(currentTime));
- String imageDir = Environment.getExternalStoragePublicDirectory(
- Environment.DIRECTORY_PICTURES).getAbsolutePath();
- String imageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, date);
- String imageFilePath = String.format(SCREENSHOT_FILE_PATH_TEMPLATE, imageDir,
- SCREENSHOTS_DIR_NAME, imageFileName);
-
// Save the screenshot to the MediaStore
ContentValues values = new ContentValues();
ContentResolver resolver = context.getContentResolver();
- values.put(MediaStore.Images.ImageColumns.DATA, imageFilePath);
- values.put(MediaStore.Images.ImageColumns.TITLE, imageFileName);
- values.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, imageFileName);
- values.put(MediaStore.Images.ImageColumns.DATE_TAKEN, currentTime);
- values.put(MediaStore.Images.ImageColumns.DATE_ADDED, currentTime);
- values.put(MediaStore.Images.ImageColumns.DATE_MODIFIED, currentTime);
+ values.put(MediaStore.Images.ImageColumns.DATA, mImageFilePath);
+ values.put(MediaStore.Images.ImageColumns.TITLE, mImageFileName);
+ values.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, mImageFileName);
+ values.put(MediaStore.Images.ImageColumns.DATE_TAKEN, mImageTime);
+ values.put(MediaStore.Images.ImageColumns.DATE_ADDED, mImageTime);
+ values.put(MediaStore.Images.ImageColumns.DATE_MODIFIED, mImageTime);
values.put(MediaStore.Images.ImageColumns.MIME_TYPE, "image/png");
Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
@@ -118,9 +177,10 @@
// update file size in the database
values.clear();
- values.put(MediaStore.Images.ImageColumns.SIZE, new File(imageFilePath).length());
+ values.put(MediaStore.Images.ImageColumns.SIZE, new File(mImageFilePath).length());
resolver.update(uri, values, null, null);
+ params[0].imageUri = uri;
params[0].result = 0;
} catch (Exception e) {
// IOException/UnsupportedOperationException may be thrown if external storage is not
@@ -135,12 +195,26 @@
protected void onPostExecute(SaveImageInBackgroundData params) {
if (params.result > 0) {
// Show a message that we've failed to save the image to disk
- Toast.makeText(params.context, R.string.screenshot_failed_toast,
- Toast.LENGTH_SHORT).show();
+ GlobalScreenshot.notifyScreenshotError(params.context, mNotificationManager);
} else {
- // Show a message that we've saved the screenshot to disk
- Toast.makeText(params.context, R.string.screenshot_saving_toast,
- Toast.LENGTH_SHORT).show();
+ // Show the final notification to indicate screenshot saved
+ Resources r = params.context.getResources();
+
+ // Create the intent to show the screenshot in gallery
+ mLaunchIntent = new Intent(Intent.ACTION_VIEW);
+ mLaunchIntent.setDataAndType(params.imageUri, "image/png");
+ mLaunchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ mNotificationBuilder
+ .setContentTitle(r.getString(R.string.screenshot_saved_title))
+ .setContentText(r.getString(R.string.screenshot_saved_text))
+ .setContentIntent(PendingIntent.getActivity(params.context, 0, mLaunchIntent, 0))
+ .setWhen(System.currentTimeMillis())
+ .setAutoCancel(true);
+
+ Notification n = mNotificationBuilder.getNotification();
+ n.flags &= ~Notification.FLAG_NO_CLEAR;
+ mNotificationManager.notify(mNotificationId, n);
}
params.finisher.run();
};
@@ -154,22 +228,23 @@
*/
class GlobalScreenshot {
private static final String TAG = "GlobalScreenshot";
- private static final int SCREENSHOT_FADE_IN_DURATION = 900;
- private static final int SCREENSHOT_FADE_OUT_DELAY = 1000;
- private static final int SCREENSHOT_FADE_OUT_DURATION = 450;
- private static final int TOAST_FADE_IN_DURATION = 500;
- private static final int TOAST_FADE_OUT_DELAY = 1000;
- private static final int TOAST_FADE_OUT_DURATION = 500;
+ private static final int SCREENSHOT_NOTIFICATION_ID = 789;
+ private static final int SCREENSHOT_FADE_IN_DURATION = 250;
+ private static final int SCREENSHOT_FADE_OUT_DELAY = 750;
+ private static final int SCREENSHOT_FADE_OUT_DURATION = 500;
+ private static final int SCREENSHOT_FAST_FADE_OUT_DURATION = 350;
private static final float BACKGROUND_ALPHA = 0.65f;
- private static final float SCREENSHOT_SCALE = 0.85f;
- private static final float SCREENSHOT_MIN_SCALE = 0.7f;
- private static final float SCREENSHOT_ROTATION = -6.75f; // -12.5f;
+ private static final float SCREENSHOT_SCALE_FUDGE = 0.075f; // To account for the border padding
+ private static final float SCREENSHOT_SCALE = 0.55f;
+ private static final float SCREENSHOT_FADE_IN_MIN_SCALE = SCREENSHOT_SCALE * 0.975f;
+ private static final float SCREENSHOT_FADE_OUT_MIN_SCALE = SCREENSHOT_SCALE * 0.925f;
private Context mContext;
private LayoutInflater mLayoutInflater;
private IWindowManager mIWindowManager;
private WindowManager mWindowManager;
private WindowManager.LayoutParams mWindowLayoutParams;
+ private NotificationManager mNotificationManager;
private Display mDisplay;
private DisplayMetrics mDisplayMetrics;
private Matrix mDisplayMatrix;
@@ -182,34 +257,24 @@
private AnimatorSet mScreenshotAnimation;
- // General use cubic interpolator
- final TimeInterpolator mCubicInterpolator = new TimeInterpolator() {
- public float getInterpolation(float t) {
- return t*t*t;
- }
- };
- // The interpolator used to control the background alpha at the start of the animation
- final TimeInterpolator mBackgroundViewAlphaInterpolator = new TimeInterpolator() {
- public float getInterpolation(float t) {
- float tStep = 0.35f;
- if (t < tStep) {
- return t * (1f / tStep);
- } else {
- return 1f;
- }
- }
- };
+ private int mStatusBarIconSize;
+ private int mNotificationIconSize;
+ private float mDropOffsetX;
+ private float mDropOffsetY;
+ private float mBgPadding;
+ private float mBgPaddingScale;
+
/**
* @param context everything needs a context :(
*/
public GlobalScreenshot(Context context) {
+ Resources r = context.getResources();
mContext = context;
mLayoutInflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Inflate the screenshot layout
- mDisplayMetrics = new DisplayMetrics();
mDisplayMatrix = new Matrix();
mScreenshotLayout = mLayoutInflater.inflate(R.layout.global_screenshot, null);
mBackgroundView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_background);
@@ -237,7 +302,23 @@
PixelFormat.TRANSLUCENT);
mWindowLayoutParams.setTitle("ScreenshotAnimation");
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ mNotificationManager =
+ (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mDisplay = mWindowManager.getDefaultDisplay();
+ mDisplayMetrics = new DisplayMetrics();
+ mDisplay.getRealMetrics(mDisplayMetrics);
+
+ // Get the various target sizes
+ mStatusBarIconSize =
+ r.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
+ mNotificationIconSize =
+ r.getDimensionPixelSize(android.R.dimen.notification_large_icon_height);
+ mDropOffsetX = r.getDimensionPixelSize(R.dimen.global_screenshot_drop_offset_x);
+ mDropOffsetY = r.getDimensionPixelSize(R.dimen.global_screenshot_drop_offset_y);
+
+ // Scale has to account for both sides of the bg
+ mBgPadding = (float) r.getDimensionPixelSize(R.dimen.global_screenshot_bg_padding);
+ mBgPaddingScale = (2f * mBgPadding) / mDisplayMetrics.widthPixels;
}
/**
@@ -247,8 +328,10 @@
SaveImageInBackgroundData data = new SaveImageInBackgroundData();
data.context = mContext;
data.image = mScreenBitmap;
+ data.iconSize = mNotificationIconSize;
data.finisher = finisher;
- new SaveImageInBackgroundTask().execute(data);
+ new SaveImageInBackgroundTask(mContext, data, mNotificationManager,
+ SCREENSHOT_NOTIFICATION_ID).execute(data);
}
/**
@@ -257,11 +340,11 @@
private float getDegreesForRotation(int value) {
switch (value) {
case Surface.ROTATION_90:
- return 90f;
+ return 360f - 90f;
case Surface.ROTATION_180:
- return 180f;
+ return 360f - 180f;
case Surface.ROTATION_270:
- return 270f;
+ return 360f - 270f;
}
return 0f;
}
@@ -269,7 +352,7 @@
/**
* Takes a screenshot of the current display and shows an animation.
*/
- void takeScreenshot(Runnable finisher) {
+ void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible) {
// We need to orient the screenshot correctly (and the Surface api seems to take screenshots
// only in the natural orientation of the device :!)
mDisplay.getRealMetrics(mDisplayMetrics);
@@ -291,7 +374,7 @@
mDisplayMetrics.heightPixels, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(ss);
c.translate(ss.getWidth() / 2, ss.getHeight() / 2);
- c.rotate(360f - degrees);
+ c.rotate(degrees);
c.translate(-dims[0] / 2, -dims[1] / 2);
c.drawBitmap(mScreenBitmap, 0, 0, null);
c.setBitmap(null);
@@ -300,21 +383,26 @@
// If we couldn't take the screenshot, notify the user
if (mScreenBitmap == null) {
- Toast.makeText(mContext, R.string.screenshot_failed_toast,
- Toast.LENGTH_SHORT).show();
+ notifyScreenshotError(mContext, mNotificationManager);
finisher.run();
return;
}
+ // Optimizations
+ mScreenBitmap.setHasAlpha(false);
+ mScreenBitmap.prepareToDraw();
+
// Start the post-screenshot animation
- startAnimation(finisher);
+ startAnimation(finisher, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels,
+ statusBarVisible, navBarVisible);
}
/**
* Starts the animation after taking the screenshot
*/
- private void startAnimation(final Runnable finisher) {
+ private void startAnimation(final Runnable finisher, int w, int h, boolean statusBarVisible,
+ boolean navBarVisible) {
// Add the view for the animation
mScreenshotView.setImageBitmap(mScreenBitmap);
mScreenshotLayout.requestFocus();
@@ -326,7 +414,8 @@
mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
ValueAnimator screenshotFadeInAnim = createScreenshotFadeInAnimation();
- ValueAnimator screenshotFadeOutAnim = createScreenshotFadeOutAnimation();
+ ValueAnimator screenshotFadeOutAnim = createScreenshotFadeOutAnimation(w, h,
+ statusBarVisible, navBarVisible);
mScreenshotAnimation = new AnimatorSet();
mScreenshotAnimation.play(screenshotFadeInAnim).before(screenshotFadeOutAnim);
mScreenshotAnimation.addListener(new AnimatorListenerAdapter() {
@@ -337,16 +426,29 @@
mWindowManager.removeView(mScreenshotLayout);
}
});
- mScreenshotAnimation.start();
+ mScreenshotLayout.post(new Runnable() {
+ @Override
+ public void run() {
+ mScreenshotContainerView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ mScreenshotContainerView.buildLayer();
+ mScreenshotAnimation.start();
+ }
+ });
}
private ValueAnimator createScreenshotFadeInAnimation() {
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
- anim.setInterpolator(mCubicInterpolator);
+ anim.setInterpolator(new AccelerateInterpolator(1.5f));
anim.setDuration(SCREENSHOT_FADE_IN_DURATION);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
+ mBackgroundView.setAlpha(0f);
mBackgroundView.setVisibility(View.VISIBLE);
+ mScreenshotContainerView.setTranslationX(0f);
+ mScreenshotContainerView.setTranslationY(0f);
+ mScreenshotContainerView.setScaleX(SCREENSHOT_FADE_IN_MIN_SCALE);
+ mScreenshotContainerView.setScaleY(SCREENSHOT_FADE_IN_MIN_SCALE);
+ mScreenshotContainerView.setAlpha(0f);
mScreenshotContainerView.setVisibility(View.VISIBLE);
}
});
@@ -354,41 +456,98 @@
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float t = ((Float) animation.getAnimatedValue()).floatValue();
- mBackgroundView.setAlpha(mBackgroundViewAlphaInterpolator.getInterpolation(t) *
- BACKGROUND_ALPHA);
- float scaleT = SCREENSHOT_SCALE + (1f - t) * SCREENSHOT_SCALE;
- mScreenshotContainerView.setAlpha(t*t*t*t);
+ float scaleT = (SCREENSHOT_FADE_IN_MIN_SCALE)
+ + (float) t * (SCREENSHOT_SCALE - SCREENSHOT_FADE_IN_MIN_SCALE);
+ mBackgroundView.setAlpha(t * BACKGROUND_ALPHA);
mScreenshotContainerView.setScaleX(scaleT);
mScreenshotContainerView.setScaleY(scaleT);
- mScreenshotContainerView.setRotation(t * SCREENSHOT_ROTATION);
+ mScreenshotContainerView.setAlpha(t);
}
});
return anim;
}
- private ValueAnimator createScreenshotFadeOutAnimation() {
- ValueAnimator anim = ValueAnimator.ofFloat(1f, 0f);
- anim.setInterpolator(mCubicInterpolator);
+ private ValueAnimator createScreenshotFadeOutAnimation(int w, int h, boolean statusBarVisible,
+ boolean navBarVisible) {
+ ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
+ anim.setInterpolator(new DecelerateInterpolator(0.5f));
anim.setStartDelay(SCREENSHOT_FADE_OUT_DELAY);
- anim.setDuration(SCREENSHOT_FADE_OUT_DURATION);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mBackgroundView.setVisibility(View.GONE);
mScreenshotContainerView.setVisibility(View.GONE);
+ mScreenshotContainerView.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
- anim.addUpdateListener(new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- float t = ((Float) animation.getAnimatedValue()).floatValue();
- float scaleT = SCREENSHOT_MIN_SCALE +
- t*(SCREENSHOT_SCALE - SCREENSHOT_MIN_SCALE);
- mScreenshotContainerView.setAlpha(t);
- mScreenshotContainerView.setScaleX(scaleT);
- mScreenshotContainerView.setScaleY(scaleT);
- mBackgroundView.setAlpha(t * t * BACKGROUND_ALPHA);
+
+ if (!statusBarVisible || !navBarVisible) {
+ // There is no status bar/nav bar, so just fade the screenshot away in place
+ anim.setDuration(SCREENSHOT_FAST_FADE_OUT_DURATION);
+ anim.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float t = ((Float) animation.getAnimatedValue()).floatValue();
+ float scaleT = (SCREENSHOT_FADE_OUT_MIN_SCALE)
+ + (float) (1f - t) * (SCREENSHOT_SCALE - SCREENSHOT_FADE_OUT_MIN_SCALE);
+ mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
+ mScreenshotContainerView.setAlpha((1f - t) * BACKGROUND_ALPHA);
+ mScreenshotContainerView.setScaleX(scaleT);
+ mScreenshotContainerView.setScaleY(scaleT);
+ }
+ });
+ } else {
+ // Determine the bounds of how to scale
+ float halfScreenWidth = (w - 2f * mBgPadding) / 2f;
+ float halfScreenHeight = (h - 2f * mBgPadding) / 2f;
+ final RectF finalBounds = new RectF(mDropOffsetX, mDropOffsetY,
+ mDropOffsetX + mStatusBarIconSize,
+ mDropOffsetY + mStatusBarIconSize);
+ final PointF currentPos = new PointF(0f, 0f);
+ final PointF finalPos = new PointF(-halfScreenWidth + finalBounds.centerX(),
+ -halfScreenHeight + finalBounds.centerY());
+ final DecelerateInterpolator d = new DecelerateInterpolator(2f);
+ // Note: since the scale origin is in the center of the view, divide difference by 2
+ float tmpMinScale = 0f;
+ if (w > h) {
+ tmpMinScale = finalBounds.width() / (2f * w);
+ } else {
+ tmpMinScale = finalBounds.height() / (2f * h);
}
- });
+ final float minScale = tmpMinScale;
+
+ // Animate the screenshot to the status bar
+ anim.setDuration(SCREENSHOT_FADE_OUT_DURATION);
+ anim.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float t = ((Float) animation.getAnimatedValue()).floatValue();
+ float scaleT = minScale
+ + (float) (1f - t) * (SCREENSHOT_SCALE - minScale - mBgPaddingScale)
+ + mBgPaddingScale;
+ mScreenshotContainerView.setAlpha(d.getInterpolation(1f - t));
+ mScreenshotContainerView.setTranslationX(d.getInterpolation(t) * finalPos.x);
+ mScreenshotContainerView.setTranslationY(d.getInterpolation(t) * finalPos.y);
+ mScreenshotContainerView.setScaleX(scaleT);
+ mScreenshotContainerView.setScaleY(scaleT);
+ mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
+ }
+ });
+ }
return anim;
}
+
+ static void notifyScreenshotError(Context context, NotificationManager nManager) {
+ Resources r = context.getResources();
+
+ // Clear all existing notification, compose the new notification and show it
+ Notification n = new Notification.Builder(context)
+ .setTicker(r.getString(R.string.screenshot_failed_title))
+ .setContentTitle(r.getString(R.string.screenshot_failed_title))
+ .setContentText(r.getString(R.string.screenshot_failed_text))
+ .setSmallIcon(android.R.drawable.ic_menu_report_image)
+ .setWhen(System.currentTimeMillis())
+ .setAutoCancel(true)
+ .getNotification();
+ nManager.notify(SCREENSHOT_NOTIFICATION_ID, n);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index 05ff8be..456b5fa 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -17,26 +17,12 @@
package com.android.systemui.screenshot;
import android.app.Service;
-import android.app.AlertDialog;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
-import android.net.Uri;
-import android.hardware.usb.UsbAccessory;
-import android.hardware.usb.UsbManager;
-import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.internal.app.AlertActivity;
-import com.android.internal.app.AlertController;
-
-import com.android.systemui.R;
public class TakeScreenshotService extends Service {
private static final String TAG = "TakeScreenshotService";
@@ -60,7 +46,7 @@
} catch (RemoteException e) {
}
}
- });
+ }, msg.arg1 > 0, msg.arg2 > 0);
}
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
index 5959537..2e1803e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
@@ -146,4 +146,26 @@
mDoNotDisturb = new DoNotDisturb(mContext);
}
+
+ protected View updateNotificationVetoButton(View row, StatusBarNotification n) {
+ View vetoButton = row.findViewById(R.id.veto);
+ if (n.isClearable()) {
+ final String _pkg = n.pkg;
+ final String _tag = n.tag;
+ final int _id = n.id;
+ vetoButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ try {
+ mBarService.onNotificationClear(_pkg, _tag, _id);
+ } catch (RemoteException ex) {
+ // system process is dead if we're here.
+ }
+ }
+ });
+ vetoButton.setVisibility(View.VISIBLE);
+ } else {
+ vetoButton.setVisibility(View.GONE);
+ }
+ return vetoButton;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index e3a64a8..694da20 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -116,15 +116,13 @@
mDisabledFlags = disabledFlags;
- final boolean disableNavigation = ((disabledFlags & View.STATUS_BAR_DISABLE_NAVIGATION) != 0);
+ final boolean disableHome = ((disabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
+ final boolean disableRecent = ((disabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0);
final boolean disableBack = ((disabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0);
getBackButton() .setVisibility(disableBack ? View.INVISIBLE : View.VISIBLE);
- getHomeButton() .setVisibility(disableNavigation ? View.INVISIBLE : View.VISIBLE);
- getRecentsButton().setVisibility(disableNavigation ? View.INVISIBLE : View.VISIBLE);
-
- getMenuButton() .setVisibility((disableNavigation || !mShowMenu)
- ? View.INVISIBLE : View.VISIBLE);
+ getHomeButton() .setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
+ getRecentsButton().setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
}
public void setMenuVisibility(final boolean show) {
@@ -136,9 +134,7 @@
mShowMenu = show;
- getMenuButton().setVisibility(
- (0 != (mDisabledFlags & View.STATUS_BAR_DISABLE_NAVIGATION) || !mShowMenu)
- ? View.INVISIBLE : View.VISIBLE);
+ getMenuButton().setVisibility(mShowMenu ? View.VISIBLE : View.INVISIBLE);
}
public void setLowProfile(final boolean lightsOut) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 09ea6ad..b724552 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -50,7 +50,6 @@
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
-import android.view.Surface;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
@@ -74,7 +73,9 @@
import com.android.internal.statusbar.StatusBarNotification;
import com.android.systemui.R;
+import com.android.systemui.recent.RecentTasksLoader;
import com.android.systemui.recent.RecentsPanelView;
+import com.android.systemui.recent.TaskDescription;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.StatusBar;
import com.android.systemui.statusbar.StatusBarIconView;
@@ -92,7 +93,7 @@
public static final boolean DUMPTRUCK = true; // extra dumpsys info
// additional instrumentation for testing purposes; intended to be left on during development
- public static final boolean CHATTY = DEBUG || true;
+ public static final boolean CHATTY = DEBUG;
public static final String ACTION_STATUSBAR_START
= "com.android.internal.policy.statusbar.START";
@@ -193,6 +194,7 @@
// Recent apps
private RecentsPanelView mRecentsPanel;
+ private RecentTasksLoader mRecentTasksLoader;
// Tracking finger for opening/closing.
int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore
@@ -210,6 +212,8 @@
boolean mAnimatingReveal = false;
int mViewDelta;
int[] mAbsPos = new int[2];
+ Runnable mPostCollapseCleanup = null;
+
// for disabling the status bar
int mDisabled = 0;
@@ -297,18 +301,6 @@
(NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
mNavigationBarView.setDisabledFlags(mDisabled);
-
- sb.setOnSystemUiVisibilityChangeListener(
- new View.OnSystemUiVisibilityChangeListener() {
- @Override
- public void onSystemUiVisibilityChange(int visibility) {
- if (DEBUG) {
- Slog.d(TAG, "systemUi: " + visibility);
- }
- boolean hide = (0 != (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION));
- mNavigationBarView.setHidden(hide);
- }
- });
}
} catch (Resources.NotFoundException ex) {
// no nav bar for you
@@ -363,6 +355,7 @@
signalCluster.setNetworkController(mNetworkController);
// Recents Panel
+ mRecentTasksLoader = new RecentTasksLoader(context);
updateRecentsPanel();
// receive broadcasts
@@ -399,16 +392,21 @@
protected void updateRecentsPanel() {
// Recents Panel
boolean visible = false;
+ ArrayList<TaskDescription> recentTasksList = null;
if (mRecentsPanel != null) {
visible = mRecentsPanel.isShowing();
WindowManagerImpl.getDefault().removeView(mRecentsPanel);
+ if (visible) {
+ recentTasksList = mRecentsPanel.getRecentTasksList();
+ }
}
// Provide RecentsPanelView with a temporary parent to allow layout params to work.
LinearLayout tmpRoot = new LinearLayout(mContext);
mRecentsPanel = (RecentsPanelView) LayoutInflater.from(mContext).inflate(
R.layout.status_bar_recent_panel, tmpRoot, false);
-
+ mRecentsPanel.setRecentTasksLoader(mRecentTasksLoader);
+ mRecentTasksLoader.setRecentsPanel(mRecentsPanel);
mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL,
mRecentsPanel));
mRecentsPanel.setVisibility(View.GONE);
@@ -417,7 +415,7 @@
WindowManagerImpl.getDefault().addView(mRecentsPanel, lp);
mRecentsPanel.setBar(this);
if (visible) {
- mRecentsPanel.show(true, false);
+ mRecentsPanel.show(true, false, recentTasksList);
}
}
@@ -621,6 +619,10 @@
boolean orderUnchanged = notification.notification.when==oldNotification.notification.when
&& notification.priority == oldNotification.priority;
// priority now encompasses isOngoing()
+
+ boolean updateTicker = notification.notification.tickerText != null
+ && !TextUtils.equals(notification.notification.tickerText,
+ oldEntry.notification.notification.tickerText);
boolean isFirstAnyway = rowParent.indexOfChild(oldEntry.row) == 0;
if (contentsUnchanged && (orderUnchanged || isFirstAnyway)) {
if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
@@ -668,10 +670,13 @@
addNotificationViews(key, notification);
}
+ // Update the veto button accordingly (and as a result, whether this row is
+ // swipe-dismissable)
+ updateNotificationVetoButton(oldEntry.row, notification);
+
// Restart the ticker if it's still running
- if (notification.notification.tickerText != null
- && !TextUtils.equals(notification.notification.tickerText,
- oldEntry.notification.notification.tickerText)) {
+ if (updateTicker) {
+ mTicker.halt();
tick(notification);
}
@@ -714,23 +719,7 @@
View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
// wire up the veto button
- View vetoButton = row.findViewById(R.id.veto);
- if (notification.isClearable()) {
- final String _pkg = notification.pkg;
- final String _tag = notification.tag;
- final int _id = notification.id;
- vetoButton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- try {
- mBarService.onNotificationClear(_pkg, _tag, _id);
- } catch (RemoteException ex) {
- // system process is dead if we're here.
- }
- }
- });
- } else {
- vetoButton.setVisibility(View.GONE);
- }
+ View vetoButton = updateNotificationVetoButton(row, notification);
vetoButton.setContentDescription(mContext.getString(
R.string.accessibility_remove_notification));
@@ -900,23 +889,7 @@
LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
- View vetoButton = row.findViewById(R.id.veto);
- if (entry.notification.isClearable()) {
- final String _pkg = sbn.pkg;
- final String _tag = sbn.tag;
- final int _id = sbn.id;
- vetoButton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- try {
- mBarService.onNotificationClear(_pkg, _tag, _id);
- } catch (RemoteException ex) {
- // system process is dead if we're here.
- }
- }
- });
- } else {
- vetoButton.setVisibility(View.GONE);
- }
+ View vetoButton = updateNotificationVetoButton(row, sbn);
vetoButton.setContentDescription(mContext.getString(
R.string.accessibility_remove_notification));
@@ -1055,10 +1028,12 @@
flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "* " : " ");
flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
flagdbg.append(((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
- flagdbg.append(((state & StatusBarManager.DISABLE_NAVIGATION) != 0) ? "NAVIGATION" : "navigation");
- flagdbg.append(((diff & StatusBarManager.DISABLE_NAVIGATION) != 0) ? "* " : " ");
flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
flagdbg.append(((diff & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
+ flagdbg.append(((state & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
+ flagdbg.append(((diff & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
+ flagdbg.append(((state & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
+ flagdbg.append(((diff & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
flagdbg.append(((state & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
flagdbg.append(((diff & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
flagdbg.append(">");
@@ -1074,11 +1049,13 @@
}
}
- if ((diff & (StatusBarManager.DISABLE_NAVIGATION | StatusBarManager.DISABLE_BACK)) != 0) {
- // the nav bar will take care of DISABLE_NAVIGATION and DISABLE_BACK
+ if ((diff & (StatusBarManager.DISABLE_HOME
+ | StatusBarManager.DISABLE_RECENT
+ | StatusBarManager.DISABLE_BACK)) != 0) {
+ // the nav bar will take care of these
if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state);
- if ((state & StatusBarManager.DISABLE_NAVIGATION) != 0) {
+ if ((state & StatusBarManager.DISABLE_RECENT) != 0) {
// close recents if it's visible
mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
@@ -1262,6 +1239,10 @@
return;
}
mExpanded = false;
+ if (mPostCollapseCleanup != null) {
+ mPostCollapseCleanup.run();
+ mPostCollapseCleanup = null;
+ }
}
void doAnimation() {
@@ -2090,49 +2071,67 @@
}
public void onClick(View v) {
synchronized (mNotificationData) {
- // let's also queue up 400ms worth of animated dismissals
- final int N = mini(5, mPile.getChildCount());
+ // animate-swipe all dismissable notifications, then animate the shade closed
+ int numChildren = mPile.getChildCount();
- final ArrayList<View> snapshot = new ArrayList<View>(N);
- for (int i=0; i<N; i++) {
+ int scrollTop = mScrollView.getScrollY();
+ int scrollBottom = scrollTop + mScrollView.getHeight();
+ final ArrayList<View> snapshot = new ArrayList<View>(numChildren);
+ for (int i=0; i<numChildren; i++) {
final View child = mPile.getChildAt(i);
- if (mPile.canChildBeDismissed(child)) snapshot.add(child);
+ if (mPile.canChildBeDismissed(child) && child.getBottom() > scrollTop &&
+ child.getTop() < scrollBottom) {
+ snapshot.add(child);
+ }
}
+ final int N = snapshot.size();
new Thread(new Runnable() {
@Override
public void run() {
- final int ROW_DELAY = 100;
+ // Decrease the delay for every row we animate to give the sense of
+ // accelerating the swipes
+ final int ROW_DELAY_DECREMENT = 10;
+ int currentDelay = 140;
+ int totalDelay = 0;
- mHandler.postDelayed(new Runnable() {
- public void run() {
- animateCollapse(false, 0f);
- }
- }, (N-1) * ROW_DELAY);
+ // Set the shade-animating state to avoid doing other work during
+ // all of these animations. In particular, avoid layout and
+ // redrawing when collapsing the shade.
+ mPile.setViewRemoval(false);
- mHandler.postDelayed(new Runnable() {
+ mPostCollapseCleanup = new Runnable() {
public void run() {
try {
+ mPile.setViewRemoval(true);
mBarService.onClearAllNotifications();
- } catch (RemoteException ex) { }
+ } catch (Exception ex) { }
}
- }, N * ROW_DELAY + 500);
+ };
- mPile.setAnimateBounds(false); // temporarily disable some re-layouts
-
+ View sampleView = snapshot.get(0);
+ int width = sampleView.getWidth();
+ final int velocity = (int)(width * 8); // 1000/8 = 125 ms duration
for (View v : snapshot) {
final View _v = v;
- mHandler.post(new Runnable() {
+ mHandler.postDelayed(new Runnable() {
@Override
public void run() {
- mPile.dismissRowAnimated(_v, (int)(ROW_DELAY*0.25f));
+ mPile.dismissRowAnimated(_v, velocity);
}
- });
- try {
- Thread.sleep(ROW_DELAY);
- } catch (InterruptedException ex) { }
+ }, totalDelay);
+ currentDelay = Math.max(50, currentDelay - ROW_DELAY_DECREMENT);
+ totalDelay += currentDelay;
}
-
- mPile.setAnimateBounds(true); // reenable layout animation
+ // Delay the collapse animation until after all swipe animations have
+ // finished. Provide some buffer because there may be some extra delay
+ // before actually starting each swipe animation. Ideally, we'd
+ // synchronize the end of those animations with the start of the collaps
+ // exactly.
+ mHandler.postDelayed(new Runnable() {
+ public void run() {
+ animateCollapse(false);
+ }
+ }, totalDelay + 225);
}
}).start();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
index e76fe51..f5ceed0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.text.StaticLayout;
@@ -50,6 +51,7 @@
private View mTickerView;
private ImageSwitcher mIconSwitcher;
private TextSwitcher mTextSwitcher;
+ private float mIconScale;
private final class Segment {
StatusBarNotification notification;
@@ -145,6 +147,11 @@
public Ticker(Context context, View sb) {
mContext = context;
+ final Resources res = context.getResources();
+ final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
+ final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
+ mIconScale = (float)imageBounds / (float)outerBounds;
+
mTickerView = sb.findViewById(R.id.ticker);
mIconSwitcher = (ImageSwitcher)sb.findViewById(R.id.tickerIcon);
@@ -152,6 +159,8 @@
AnimationUtils.loadAnimation(context, com.android.internal.R.anim.push_up_in));
mIconSwitcher.setOutAnimation(
AnimationUtils.loadAnimation(context, com.android.internal.R.anim.push_up_out));
+ mIconSwitcher.setScaleX(mIconScale);
+ mIconSwitcher.setScaleY(mIconScale);
mTextSwitcher = (TextSwitcher)sb.findViewById(R.id.tickerText);
mTextSwitcher.setInAnimation(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 8d964e3..4f9eb38 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -61,7 +61,7 @@
// debug
static final String TAG = "StatusBar.NetworkController";
static final boolean DEBUG = false;
- static final boolean CHATTY = true; // additional diagnostics, but not logspew
+ static final boolean CHATTY = false; // additional diagnostics, but not logspew
// telephony
boolean mHspaDataDistinguishable;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
index a7342dc..3649f75e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
@@ -18,7 +18,6 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
@@ -29,7 +28,6 @@
import android.util.Log;
import android.util.Slog;
import android.view.MotionEvent;
-import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
@@ -59,6 +57,10 @@
private SwipeHelper mSwipeHelper;
+ // Flag set during notification removal animation to avoid causing too much work until
+ // animation is done
+ boolean mRemoveViews = true;
+
public NotificationRowLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@@ -117,7 +119,7 @@
public void onChildDismissed(View v) {
final View veto = v.findViewById(R.id.veto);
- if (veto != null && veto.getVisibility() != View.GONE) {
+ if (veto != null && veto.getVisibility() != View.GONE && mRemoveViews) {
veto.performClick();
}
}
@@ -170,7 +172,6 @@
final View childF = child;
if (mAnimateBounds) {
- child.setPivotY(0);
final ObjectAnimator alphaFade = ObjectAnimator.ofFloat(child, "alpha", 0f, 1f);
alphaFade.setDuration(APPEAR_ANIM_LEN);
alphaFade.addListener(new AnimatorListenerAdapter() {
@@ -189,6 +190,16 @@
}
}
+ /**
+ * Sets a flag to tell us whether to actually remove views. Removal is delayed by setting this
+ * to false during some animations to smooth out performance. Callers should restore the
+ * flag to true after the animation is done, and then they should make sure that the views
+ * get removed properly.
+ */
+ public void setViewRemoval(boolean removeViews) {
+ mRemoveViews = removeViews;
+ }
+
public void dismissRowAnimated(View child) {
dismissRowAnimated(child, 0);
}
@@ -199,16 +210,34 @@
@Override
public void removeView(View child) {
- final View childF = child;
+ if (!mRemoveViews) {
+ // This flag is cleared during an animation that removes all notifications. There
+ // should be a call to remove all notifications when the animation is done, at which
+ // time the view will be removed.
+ return;
+ }
if (mAnimateBounds) {
if (mAppearingViews.containsKey(child)) {
mAppearingViews.remove(child);
}
- child.setPivotY(0);
- final ObjectAnimator alphaFade = ObjectAnimator.ofFloat(child, "alpha", 0f);
- alphaFade.setDuration(DISAPPEAR_ANIM_LEN);
- alphaFade.addListener(new AnimatorListenerAdapter() {
+ // Don't fade it out if it already has a low alpha value, but run a non-visual
+ // animation which is used by onLayout() to animate shrinking the gap that it left
+ // in the list
+ ValueAnimator anim;
+ float currentAlpha = child.getAlpha();
+ if (currentAlpha > .1) {
+ anim = ObjectAnimator.ofFloat(child, "alpha", currentAlpha, 0);
+ } else {
+ if (currentAlpha > 0) {
+ // Just make it go away - no need to render it anymore
+ child.setAlpha(0);
+ }
+ anim = ValueAnimator.ofFloat(0, 1);
+ }
+ anim.setDuration(DISAPPEAR_ANIM_LEN);
+ final View childF = child;
+ anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (DEBUG) Slog.d(TAG, "actually removing child: " + childF);
@@ -218,9 +247,8 @@
}
});
- alphaFade.start();
-
- mDisappearingViews.put(child, alphaFade);
+ anim.start();
+ mDisappearingViews.put(child, anim);
requestLayout(); // start the container animation
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index ba52fb8..f0a10f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -77,6 +77,7 @@
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.Prefs;
+import com.android.systemui.recent.RecentTasksLoader;
import com.android.systemui.recent.RecentsPanelView;
public class TabletStatusBar extends StatusBar implements
@@ -179,6 +180,7 @@
int mDisabled = 0;
private RecentsPanelView mRecentsPanel;
+ private RecentTasksLoader mRecentTasksLoader;
private InputMethodsPanel mInputMethodsPanel;
private CompatModePanel mCompatModePanel;
@@ -299,12 +301,15 @@
}
// Recents Panel
+ mRecentTasksLoader = new RecentTasksLoader(context);
mRecentsPanel = (RecentsPanelView) View.inflate(context,
R.layout.status_bar_recent_panel, null);
mRecentsPanel.setVisibility(View.GONE);
mRecentsPanel.setSystemUiVisibility(View.STATUS_BAR_DISABLE_BACK);
mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL,
mRecentsPanel));
+ mRecentsPanel.setRecentTasksLoader(mRecentTasksLoader);
+ mRecentTasksLoader.setRecentsPanel(mRecentsPanel);
mStatusBarView.setIgnoreChildren(2, mRecentButton, mRecentsPanel);
lp = new WindowManager.LayoutParams(
@@ -392,6 +397,7 @@
mNotificationPanelParams.height = getNotificationPanelHeight();
WindowManagerImpl.getDefault().updateViewLayout(mNotificationPanel,
mNotificationPanelParams);
+ mRecentsPanel.updateValuesFromResources();
}
protected void loadDimens() {
@@ -834,6 +840,9 @@
boolean orderUnchanged = notification.notification.when==oldNotification.notification.when
&& notification.priority == oldNotification.priority;
// priority now encompasses isOngoing()
+ boolean updateTicker = notification.notification.tickerText != null
+ && !TextUtils.equals(notification.notification.tickerText,
+ oldEntry.notification.notification.tickerText);
boolean isLastAnyway = rowParent.indexOfChild(oldEntry.row) == rowParent.getChildCount()-1;
if (contentsUnchanged && (orderUnchanged || isLastAnyway)) {
if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
@@ -890,9 +899,8 @@
}
// Restart the ticker if it's still running
- if (notification.notification.tickerText != null
- && !TextUtils.equals(notification.notification.tickerText,
- oldEntry.notification.notification.tickerText)) {
+ if (updateTicker) {
+ mTicker.halt();
tick(key, notification, false);
}
@@ -958,34 +966,24 @@
mTicker.halt();
}
}
- if ((diff & (StatusBarManager.DISABLE_NAVIGATION | StatusBarManager.DISABLE_BACK)) != 0) {
- setNavigationVisibility(state &
- (StatusBarManager.DISABLE_NAVIGATION | StatusBarManager.DISABLE_BACK));
+ if ((diff & (StatusBarManager.DISABLE_RECENT
+ | StatusBarManager.DISABLE_BACK
+ | StatusBarManager.DISABLE_HOME)) != 0) {
+ setNavigationVisibility(state);
}
}
private void setNavigationVisibility(int visibility) {
- boolean disableNavigation = ((visibility & StatusBarManager.DISABLE_NAVIGATION) != 0);
+ boolean disableHome = ((visibility & StatusBarManager.DISABLE_HOME) != 0);
+ boolean disableRecent = ((visibility & StatusBarManager.DISABLE_RECENT) != 0);
boolean disableBack = ((visibility & StatusBarManager.DISABLE_BACK) != 0);
- Slog.i(TAG, "DISABLE_BACK: " + (disableBack ? "yes" : "no"));
- Slog.i(TAG, "DISABLE_NAVIGATION: " + (disableNavigation ? "yes" : "no"));
+ mBackButton.setVisibility(disableBack ? View.INVISIBLE : View.VISIBLE);
+ mHomeButton.setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
+ mRecentButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
- if (disableNavigation && disableBack) {
- mNavigationArea.setVisibility(View.INVISIBLE);
- } else {
- int backVisiblity = (disableBack ? View.INVISIBLE : View.VISIBLE);
- int navVisibility = (disableNavigation ? View.INVISIBLE : View.VISIBLE);
-
- mBackButton.setVisibility(backVisiblity);
- mHomeButton.setVisibility(navVisibility);
- mRecentButton.setVisibility(navVisibility);
- // don't change menu button visibility here
-
- mNavigationArea.setVisibility(View.VISIBLE);
- }
-
- mInputMethodSwitchButton.setScreenLocked(disableNavigation);
+ mInputMethodSwitchButton.setScreenLocked(
+ (visibility & StatusBarManager.DISABLE_SYSTEM_INFO) != 0);
}
private boolean hasTicker(Notification n) {
@@ -1740,23 +1738,7 @@
Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
workAroundBadLayerDrawableOpacity(row);
- View vetoButton = row.findViewById(R.id.veto);
- if (entry.notification.isClearable()) {
- final String _pkg = sbn.pkg;
- final String _tag = sbn.tag;
- final int _id = sbn.id;
- vetoButton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- try {
- mBarService.onNotificationClear(_pkg, _tag, _id);
- } catch (RemoteException ex) {
- // system process is dead if we're here.
- }
- }
- });
- } else {
- vetoButton.setVisibility(View.GONE);
- }
+ View vetoButton = updateNotificationVetoButton(row, entry.notification);
vetoButton.setContentDescription(mContext.getString(
R.string.accessibility_remove_notification));
diff --git a/packages/VpnDialogs/res/values-hi/strings.xml b/packages/VpnDialogs/res/values-hi/strings.xml
new file mode 100644
index 0000000..7166877
--- /dev/null
+++ b/packages/VpnDialogs/res/values-hi/strings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> एक VPN कनेक्शन बनाने का प्रयास करता है."</string>
+ <string name="warning" msgid="5470743576660160079">"जारी रखकर, आप एप्लिकेशन को सभी नेटवर्क ट्रैफ़िक अवरोधित करने की अनुमति देते हैं. "<b>"जब तक आपको एप्लिकेशन पर विश्वास न हो स्वीकार न करें."</b>" अन्यथा, आपको अपने डेटा के साथ किसी दुर्भावनापूर्ण सॉफ़्टवेयर द्वारा छेड़छाड़ किए जाने का जोखिम हो सकता है."</string>
+ <string name="accept" msgid="2889226408765810173">"मुझे इस एप्लिकेशन पर विश्वास है."</string>
+ <string name="legacy_title" msgid="192936250066580964">"VPN कनेक्ट है"</string>
+ <string name="configure" msgid="4905518375574791375">"कॉन्फ़िगर करें"</string>
+ <string name="disconnect" msgid="971412338304200056">"डिस्कनेक्ट करें"</string>
+ <string name="session" msgid="6470628549473641030">"सत्र:"</string>
+ <string name="duration" msgid="3584782459928719435">"अवधि:"</string>
+ <string name="data_transmitted" msgid="7988167672982199061">"भेजे गए:"</string>
+ <string name="data_received" msgid="4062776929376067820">"प्राप्त:"</string>
+ <string name="blank_value" msgid="6278484582661984635">"--"</string>
+ <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> बाइट / <xliff:g id="NUMBER_1">%2$s</xliff:g> पैकेट"</string>
+</resources>
diff --git a/packages/VpnDialogs/res/values-ru/strings.xml b/packages/VpnDialogs/res/values-ru/strings.xml
index 4313bfd..411c51a 100644
--- a/packages/VpnDialogs/res/values-ru/strings.xml
+++ b/packages/VpnDialogs/res/values-ru/strings.xml
@@ -25,7 +25,7 @@
<string name="session" msgid="6470628549473641030">"Сеанс:"</string>
<string name="duration" msgid="3584782459928719435">"Продолжительность:"</string>
<string name="data_transmitted" msgid="7988167672982199061">"Отправлено:"</string>
- <string name="data_received" msgid="4062776929376067820">"Полученные:"</string>
+ <string name="data_received" msgid="4062776929376067820">"Получено:"</string>
<string name="blank_value" msgid="6278484582661984635">"–"</string>
<string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> Б; пакетов: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
</resources>
diff --git a/packages/VpnDialogs/res/values-zh-rTW/strings.xml b/packages/VpnDialogs/res/values-zh-rTW/strings.xml
index 1d00e7d..f7663c2 100644
--- a/packages/VpnDialogs/res/values-zh-rTW/strings.xml
+++ b/packages/VpnDialogs/res/values-zh-rTW/strings.xml
@@ -24,8 +24,8 @@
<string name="disconnect" msgid="971412338304200056">"中斷連線"</string>
<string name="session" msgid="6470628549473641030">"工作階段:"</string>
<string name="duration" msgid="3584782459928719435">"持續時間:"</string>
- <string name="data_transmitted" msgid="7988167672982199061">"已傳送的資料:"</string>
- <string name="data_received" msgid="4062776929376067820">"已收到:"</string>
+ <string name="data_transmitted" msgid="7988167672982199061">"已傳送:"</string>
+ <string name="data_received" msgid="4062776929376067820">"已接收:"</string>
<string name="blank_value" msgid="6278484582661984635">"--"</string>
<string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> 位元組 / <xliff:g id="NUMBER_1">%2$s</xliff:g> 個封包"</string>
</resources>
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index 8569143..11b6c15 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -18,7 +18,6 @@
import android.app.Activity;
import android.app.AlertDialog;
-import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
@@ -57,8 +56,6 @@
private static final String TAG = "GlobalActions";
- private StatusBarManager mStatusBar;
-
private final Context mContext;
private final AudioManager mAudioManager;
@@ -103,13 +100,12 @@
mKeyguardShowing = keyguardShowing;
mDeviceProvisioned = isDeviceProvisioned;
if (mDialog == null) {
- mStatusBar = (StatusBarManager)mContext.getSystemService(Context.STATUS_BAR_SERVICE);
mDialog = createDialog();
}
prepareDialog();
- mStatusBar.disable(StatusBarManager.DISABLE_EXPAND);
mDialog.show();
+ mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
}
/**
@@ -249,7 +245,6 @@
/** {@inheritDoc} */
public void onDismiss(DialogInterface dialog) {
- mStatusBar.disable(StatusBarManager.DISABLE_NONE);
}
/** {@inheritDoc} */
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index 24dce1a..6614d79 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -186,6 +186,9 @@
mTransientTextManager = new TransientTextManager(mCarrierView);
+ mUpdateMonitor.registerInfoCallback(mInfoCallback);
+ mUpdateMonitor.registerSimStateCallback(mSimStateCallback);
+
resetStatusInfo();
refreshDate();
updateOwnerInfo();
@@ -606,6 +609,10 @@
public void onClockVisibilityChanged() {
// ignored
}
+
+ public void onDeviceProvisioned() {
+ // ignored
+ }
};
private SimStateCallback mSimStateCallback = new SimStateCallback() {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 10cf3aa..008f5d8 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -99,6 +99,7 @@
private static final int MSG_RINGER_MODE_CHANGED = 305;
private static final int MSG_PHONE_STATE_CHANGED = 306;
private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307;
+ private static final int MSG_DEVICE_PROVISIONED = 308;
/**
* When we receive a
@@ -178,6 +179,9 @@
case MSG_CLOCK_VISIBILITY_CHANGED:
handleClockVisibilityChanged();
break;
+ case MSG_DEVICE_PROVISIONED:
+ handleDeviceProvisioned();
+ break;
}
}
};
@@ -197,10 +201,8 @@
super.onChange(selfChange);
mDeviceProvisioned = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.DEVICE_PROVISIONED, 0) != 0;
- if (mDeviceProvisioned && mContentObserver != null) {
- // We don't need the observer anymore...
- mContext.getContentResolver().unregisterContentObserver(mContentObserver);
- mContentObserver = null;
+ if (mDeviceProvisioned) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED));
}
if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
}
@@ -212,13 +214,19 @@
// prevent a race condition between where we check the flag and where we register the
// observer by grabbing the value once again...
- mDeviceProvisioned = Settings.Secure.getInt(mContext.getContentResolver(),
+ boolean provisioned = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.DEVICE_PROVISIONED, 0) != 0;
+ if (provisioned != mDeviceProvisioned) {
+ mDeviceProvisioned = provisioned;
+ if (mDeviceProvisioned) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED));
+ }
+ }
}
// take a guess to start
mSimState = IccCard.State.READY;
- mBatteryStatus = BATTERY_STATUS_FULL;
+ mBatteryStatus = BATTERY_STATUS_UNKNOWN;
mBatteryLevel = 100;
mTelephonyPlmn = getDefaultPlmn();
@@ -271,6 +279,17 @@
}, filter);
}
+ protected void handleDeviceProvisioned() {
+ for (int i = 0; i < mInfoCallbacks.size(); i++) {
+ mInfoCallbacks.get(i).onDeviceProvisioned();
+ }
+ if (mContentObserver != null) {
+ // We don't need the observer anymore...
+ mContext.getContentResolver().unregisterContentObserver(mContentObserver);
+ mContentObserver = null;
+ }
+ }
+
protected void handlePhoneStateChanged(String newState) {
if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
@@ -477,6 +496,10 @@
*/
void onClockVisibilityChanged();
+ /**
+ * Called when the device becomes provisioned
+ */
+ void onDeviceProvisioned();
}
/**
@@ -501,6 +524,7 @@
callback.onRingerModeChanged(mRingMode);
callback.onPhoneStateChanged(mPhoneState);
callback.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn);
+ callback.onClockVisibilityChanged();
} else {
if (DEBUG) Log.e(TAG, "Object tried to add another INFO callback",
new Exception("Whoops"));
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
index 59b546d..de156c9 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
@@ -50,8 +50,6 @@
public KeyguardViewBase(Context context) {
super(context);
- setSystemUiVisibility(STATUS_BAR_DISABLE_BACK);
-
// This is a faster way to draw the background on devices without hardware acceleration
setBackgroundDrawable(new Drawable() {
@Override
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
index 90972da..0499cfa 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -171,6 +171,16 @@
}
}
+ // Disable aspects of the system/status/navigation bars that are not appropriate or
+ // useful for the lockscreen but can be re-shown by dialogs or SHOW_WHEN_LOCKED activities.
+ // Other disabled bits are handled by the KeyguardViewMediator talking directly to the
+ // status bar service.
+ int visFlags =
+ ( View.STATUS_BAR_DISABLE_BACK
+ | View.STATUS_BAR_DISABLE_HOME
+ );
+ mKeyguardHost.setSystemUiVisibility(visFlags);
+
mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
mKeyguardHost.setVisibility(View.VISIBLE);
mKeyguardView.requestFocus();
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index c25e3ca..0471dfe 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -1188,19 +1188,12 @@
}
}
+ // Disable aspects of the system/status/navigation bars that must not be re-enabled by
+ // windows that appear on top, ever
int flags = StatusBarManager.DISABLE_NONE;
if (mShowing) {
- // disable navigation status bar components if lock screen is up
- flags |= StatusBarManager.DISABLE_NAVIGATION;
- if (!mHidden) {
- // showing lockscreen exclusively (no activities in front of it)
- // disable back button too
- flags |= StatusBarManager.DISABLE_BACK;
- if (mUpdateMonitor.isClockVisible()) {
- // lockscreen showing a clock, so hide statusbar clock
- flags |= StatusBarManager.DISABLE_CLOCK;
- }
- }
+ // disable navigation status bar components (home, recents) if lock screen is up
+ flags |= StatusBarManager.DISABLE_RECENT;
if (isSecure() || !ENABLE_INSECURE_STATUS_BAR_EXPAND) {
// showing secure lockscreen; disable expanding.
flags |= StatusBarManager.DISABLE_EXPAND;
@@ -1323,4 +1316,9 @@
public void onTimeChanged() {
// ignored
}
+
+ /** {@inheritDoc} */
+ public void onDeviceProvisioned() {
+ mContext.sendBroadcast(mUserPresentIntent);
+ }
}
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 071044e..7a72dcf 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -42,13 +42,16 @@
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
+import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.IBinder;
+import android.os.Parcelable;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
@@ -98,7 +101,8 @@
private View mLockScreen;
private View mUnlockScreen;
- private boolean mScreenOn = false;
+ private volatile boolean mScreenOn = false;
+ private volatile boolean mWindowFocused = false;
private boolean mEnableFallback = false; // assume no fallback UI until we know better
private boolean mShowLockBeforeUnlock = false;
@@ -110,14 +114,27 @@
private boolean mFaceLockServiceRunning = false;
private final Object mFaceLockServiceRunningLock = new Object();
+ private final Object mFaceLockStartupLock = new Object();
private Handler mHandler;
private final int MSG_SHOW_FACELOCK_AREA_VIEW = 0;
private final int MSG_HIDE_FACELOCK_AREA_VIEW = 1;
- // Long enough to stay black while dialer comes up
- // Short enough to not be black if the user goes back immediately
- private final int FACELOCK_VIEW_AREA_EMERGENCY_HIDE_TIMEOUT = 1000;
+ // Long enough to stay visible while dialer comes up
+ // Short enough to not be visible if the user goes back immediately
+ private final int FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT = 1000;
+
+ // Long enough to stay visible while the service starts
+ // Short enough to not have to wait long for backup if service fails to start or crashes
+ // The service can take a couple of seconds to start on the first try after boot
+ private final int FACELOCK_VIEW_AREA_SERVICE_TIMEOUT = 3000;
+
+ // So the user has a consistent amount of time when brought to the backup method from FaceLock
+ private final int BACKUP_LOCK_TIMEOUT = 5000;
+
+ // Needed to keep track of failed FaceUnlock attempts
+ private int mFailedFaceUnlockAttempts = 0;
+ private static final int FAILED_FACE_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 15;
/**
* The current {@link KeyguardScreen} will use this to communicate back to us.
@@ -126,6 +143,10 @@
private boolean mRequiresSim;
+ //True if we have some sort of overlay on top of the Lockscreen
+ //Also true if we've activated a phone call, either emergency dialing or incoming
+ //This resets when the phone is turned off with no current call
+ private boolean mHasOverlay;
/**
@@ -207,6 +228,7 @@
private Runnable mRecreateRunnable = new Runnable() {
public void run() {
updateScreen(mMode, true);
+ restoreWidgetState();
}
};
@@ -221,6 +243,9 @@
// TODO: examine all widgets to derive clock status
mUpdateMonitor.reportClockVisible(false);
+
+ // TODO: We should disable the wallpaper instead
+ setBackgroundColor(0xff000000);
}
public void requestHide(View view) {
@@ -229,11 +254,22 @@
// TODO: examine all widgets to derive clock status
mUpdateMonitor.reportClockVisible(true);
+ setBackgroundDrawable(null);
+ }
+
+ public boolean isVisible(View self) {
+ // TODO: this should be up to the lockscreen to determine if the view
+ // is currently showing. The idea is it can be used for the widget to
+ // avoid doing work if it's not visible. For now just returns the view's
+ // actual visibility.
+ return self.getVisibility() == View.VISIBLE;
}
};
private TransportControlView mTransportControlView;
+ private Parcelable mSavedState;
+
/**
* @return Whether we are stuck on the lock screen because the sim is
* missing.
@@ -266,6 +302,7 @@
mUpdateMonitor = updateMonitor;
mLockPatternUtils = lockPatternUtils;
mWindowController = controller;
+ mHasOverlay = false;
mUpdateMonitor.registerInfoCallback(this);
@@ -320,12 +357,15 @@
}
public void takeEmergencyCallAction() {
+ mHasOverlay = true;
// FaceLock must be stopped if it is running when emergency call is pressed
stopAndUnbindFromFaceLock();
- // Delay hiding FaceLock area so unlock doesn't display while dialer is coming up
- mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACELOCK_AREA_VIEW,
- FACELOCK_VIEW_AREA_EMERGENCY_HIDE_TIMEOUT);
+ // Continue showing FaceLock area until dialer comes up
+ if (mLockPatternUtils.usingBiometricWeak() &&
+ mLockPatternUtils.isBiometricWeakInstalled()) {
+ showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT);
+ }
pokeWakelock(EMERGENCY_CALL_TIMEOUT);
if (TelephonyManager.getDefault().getCallState()
@@ -349,6 +389,7 @@
public void keyguardDone(boolean authenticated) {
getCallback().keyguardDone(authenticated);
+ mSavedState = null; // clear state so we re-establish when locked again
}
public void keyguardDoneDrawing() {
@@ -386,16 +427,20 @@
Slog.i(TAG, "Too many unlock attempts; device will be wiped!");
showWipeDialog(failedAttempts);
}
- } else if (usingPattern && mEnableFallback) {
- if (failedAttempts == failedAttemptWarning) {
- showAlmostAtAccountLoginDialog();
- } else if (failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {
- mLockPatternUtils.setPermanentlyLocked(true);
- updateScreen(mMode, false);
- }
} else {
- final boolean showTimeout =
+ boolean showTimeout =
(failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;
+ if (usingPattern && mEnableFallback) {
+ if (failedAttempts == failedAttemptWarning) {
+ showAlmostAtAccountLoginDialog();
+ showTimeout = false; // don't show both dialogs
+ } else if (failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {
+ mLockPatternUtils.setPermanentlyLocked(true);
+ updateScreen(mMode, false);
+ // don't show timeout dialog because we show account unlock screen next
+ showTimeout = false;
+ }
+ }
if (showTimeout) {
showTimeoutDialog();
}
@@ -408,6 +453,7 @@
}
public void reportSuccessfulUnlockAttempt() {
+ mFailedFaceUnlockAttempts = 0;
mLockPatternUtils.reportSuccessfulPasswordAttempt();
}
};
@@ -502,44 +548,99 @@
@Override
public void onScreenTurnedOff() {
+ if (DEBUG) Log.d(TAG, "screen off");
mScreenOn = false;
mForgotPattern = false;
+ mHasOverlay = mUpdateMonitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE;
if (mMode == Mode.LockScreen) {
((KeyguardScreen) mLockScreen).onPause();
} else {
((KeyguardScreen) mUnlockScreen).onPause();
}
+ saveWidgetState();
+
// When screen is turned off, need to unbind from FaceLock service if using FaceLock
stopAndUnbindFromFaceLock();
}
- @Override
- public void onScreenTurnedOn() {
- mScreenOn = true;
- show();
-
- // When screen is turned on, need to bind to FaceLock service if we are using FaceLock
- // But only if not dealing with a call
- final boolean transportInvisible = mTransportControlView == null ? true :
- mTransportControlView.getVisibility() != View.VISIBLE;
+ /** When screen is turned on and focused, need to bind to FaceLock service if we are using
+ * FaceLock, but only if we're not dealing with a call
+ */
+ private void activateFaceLockIfAble() {
+ final boolean tooManyFaceUnlockTries =
+ (mFailedFaceUnlockAttempts >= FAILED_FACE_UNLOCK_ATTEMPTS_BEFORE_BACKUP);
+ final int failedBackupAttempts = mUpdateMonitor.getFailedAttempts();
+ final boolean backupIsTimedOut =
+ (failedBackupAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT);
+ if (tooManyFaceUnlockTries) Log.i(TAG, "tooManyFaceUnlockTries: " + tooManyFaceUnlockTries);
if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
- && transportInvisible) {
+ && !mHasOverlay
+ && !tooManyFaceUnlockTries
+ && !backupIsTimedOut) {
bindToFaceLock();
- //Eliminate the black background so that the lockpattern will be visible
- //If FaceUnlock is cancelled
- mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACELOCK_AREA_VIEW, 4000);
+ // Show FaceLock area, but only for a little bit so lockpattern will become visible if
+ // FaceLock fails to start or crashes
+ if (mLockPatternUtils.usingBiometricWeak() &&
+ mLockPatternUtils.isBiometricWeakInstalled()) {
+ showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_SERVICE_TIMEOUT);
+ }
} else {
- mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+ hideFaceLockArea();
}
}
- /** Unbind from facelock if something covers this window (such as an alarm) */
+ @Override
+ public void onScreenTurnedOn() {
+ if (DEBUG) Log.d(TAG, "screen on");
+ boolean runFaceLock = false;
+ //Make sure to start facelock iff the screen is both on and focused
+ synchronized(mFaceLockStartupLock) {
+ mScreenOn = true;
+ runFaceLock = mWindowFocused;
+ }
+
+ show();
+
+ restoreWidgetState();
+
+ if (runFaceLock) activateFaceLockIfAble();
+ }
+
+ private void saveWidgetState() {
+ if (mTransportControlView != null) {
+ if (DEBUG) Log.v(TAG, "Saving widget state");
+ mSavedState = mTransportControlView.onSaveInstanceState();
+ }
+ }
+
+ private void restoreWidgetState() {
+ if (mTransportControlView != null) {
+ if (DEBUG) Log.v(TAG, "Restoring widget state");
+ if (mSavedState != null) {
+ mTransportControlView.onRestoreInstanceState(mSavedState);
+ }
+ }
+ }
+
+ /** Unbind from facelock if something covers this window (such as an alarm)
+ * bind to facelock if the lockscreen window just came into focus, and the screen is on
+ */
@Override
public void onWindowFocusChanged (boolean hasWindowFocus) {
+ if (DEBUG) Log.d(TAG, hasWindowFocus ? "focused" : "unfocused");
+ boolean runFaceLock = false;
+ //Make sure to start facelock iff the screen is both on and focused
+ synchronized(mFaceLockStartupLock) {
+ if(mScreenOn && !mWindowFocused) runFaceLock = hasWindowFocus;
+ mWindowFocused = hasWindowFocus;
+ }
if(!hasWindowFocus) {
+ mHasOverlay = true;
stopAndUnbindFromFaceLock();
- mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+ hideFaceLockArea();
+ } else if (runFaceLock) {
+ activateFaceLockIfAble();
}
}
@@ -552,10 +653,14 @@
}
if (mLockPatternUtils.usingBiometricWeak() &&
- mLockPatternUtils.isBiometricWeakInstalled()) {
- mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW);
+ mLockPatternUtils.isBiometricWeakInstalled() && !mHasOverlay) {
+ // Note that show() gets called before the screen turns off to set it up for next time
+ // it is turned on. We don't want to set a timeout on the FaceLock area here because it
+ // may be gone by the time the screen is turned on again. We set the timout when the
+ // screen turns on instead.
+ showFaceLockArea();
} else {
- mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+ hideFaceLockArea();
}
}
@@ -599,6 +704,7 @@
mShowLockBeforeUnlock = resources.getBoolean(R.bool.config_enableLockBeforeUnlockScreen);
mConfiguration = newConfig;
if (DEBUG_CONFIGURATION) Log.v(TAG, "**** re-creating lock screen since config changed");
+ saveWidgetState();
removeCallbacks(mRecreateRunnable);
post(mRecreateRunnable);
}
@@ -613,15 +719,25 @@
public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {}
@Override
public void onRingerModeChanged(int state) {}
+
@Override
- public void onClockVisibilityChanged() {}
+ public void onClockVisibilityChanged() {
+ int visFlags = getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_CLOCK;
+ setSystemUiVisibility(visFlags
+ | (mUpdateMonitor.isClockVisible() ? View.STATUS_BAR_DISABLE_CLOCK : 0));
+ }
+
+ @Override
+ public void onDeviceProvisioned() {}
//We need to stop faceunlock when a phonecall comes in
@Override
public void onPhoneStateChanged(int phoneState) {
+ if (DEBUG) Log.d(TAG, "phone state: " + phoneState);
if(phoneState == TelephonyManager.CALL_STATE_RINGING) {
+ mHasOverlay = true;
stopAndUnbindFromFaceLock();
- mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+ hideFaceLockArea();
}
}
@@ -681,6 +797,16 @@
this.removeView(mUnlockScreen);
mUnlockScreen = null;
}
+ mUpdateMonitor.removeCallback(this);
+ if (mFaceLockService != null) {
+ try {
+ mFaceLockService.unregisterCallback(mFaceLockCallback);
+ } catch (RemoteException e) {
+ // Not much we can do
+ }
+ stopFaceLock();
+ mFaceLockService = null;
+ }
}
private boolean isSecure() {
@@ -1020,14 +1146,25 @@
// Everything below pertains to FaceLock - might want to separate this out
- // Only pattern and pin unlock screens actually have a view for the FaceLock area, so it's not
- // uncommon for it to not exist. But if it does exist, we need to make sure it's shown (hiding
- // the fallback) if FaceLock is enabled, and make sure it's hidden (showing the unlock) if
- // FaceLock is disabled
+ // Take care of FaceLock area when layout is created
private void initializeFaceLockAreaView(View view) {
- mFaceLockAreaView = view.findViewById(R.id.faceLockAreaView);
- if (mFaceLockAreaView == null) {
- if (DEBUG) Log.d(TAG, "Layout does not have faceLockAreaView");
+ if (mLockPatternUtils.usingBiometricWeak() &&
+ mLockPatternUtils.isBiometricWeakInstalled()) {
+ mFaceLockAreaView = view.findViewById(R.id.faceLockAreaView);
+ if (mFaceLockAreaView == null) {
+ Log.e(TAG, "Layout does not have faceLockAreaView and FaceLock is enabled");
+ } else {
+ if (mBoundToFaceLockService) {
+ // If we are creating a layout when we are already bound to FaceLock, then we
+ // are undergoing an orientation change. Stop FaceLock and restart it in the
+ // new location.
+ if (DEBUG) Log.d(TAG, "Restarting FL - creating view while already bound");
+ stopAndUnbindFromFaceLock();
+ activateFaceLockIfAble();
+ }
+ }
+ } else {
+ mFaceLockAreaView = null; // Set to null if not using FaceLock
}
}
@@ -1044,7 +1181,7 @@
break;
case MSG_HIDE_FACELOCK_AREA_VIEW:
if (mFaceLockAreaView != null) {
- mFaceLockAreaView.setVisibility(View.GONE);
+ mFaceLockAreaView.setVisibility(View.INVISIBLE);
}
break;
default:
@@ -1054,7 +1191,34 @@
return true;
}
- // Binds to FaceLock service, but does not tell it to start
+ // Removes show and hide messages from the message queue
+ private void removeFaceLockAreaDisplayMessages() {
+ mHandler.removeMessages(MSG_SHOW_FACELOCK_AREA_VIEW);
+ mHandler.removeMessages(MSG_HIDE_FACELOCK_AREA_VIEW);
+ }
+
+ // Shows the FaceLock area immediately
+ private void showFaceLockArea() {
+ // Remove messages to prevent a delayed hide message from undo-ing the show
+ removeFaceLockAreaDisplayMessages();
+ mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW);
+ }
+
+ // Hides the FaceLock area immediately
+ private void hideFaceLockArea() {
+ // Remove messages to prevent a delayed show message from undo-ing the hide
+ removeFaceLockAreaDisplayMessages();
+ mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+ }
+
+ // Shows the FaceLock area for a period of time
+ private void showFaceLockAreaWithTimeout(long timeoutMillis) {
+ showFaceLockArea();
+ mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACELOCK_AREA_VIEW, timeoutMillis);
+ }
+
+ // Binds to FaceLock service. This call does not tell it to start, but it causes the service
+ // to call the onServiceConnected callback, which then starts FaceLock.
public void bindToFaceLock() {
if (mLockPatternUtils.usingBiometricWeak() &&
mLockPatternUtils.isBiometricWeakInstalled()) {
@@ -1079,13 +1243,21 @@
if (mBoundToFaceLockService) {
if (DEBUG) Log.d(TAG, "before unbind from FaceLock service");
+ if (mFaceLockService != null) {
+ try {
+ mFaceLockService.unregisterCallback(mFaceLockCallback);
+ } catch (RemoteException e) {
+ // Not much we can do
+ }
+ }
mContext.unbindService(mFaceLockConnection);
if (DEBUG) Log.d(TAG, "after unbind from FaceLock service");
mBoundToFaceLockService = false;
} else {
- // This could probably happen after the session when someone activates FaceLock
- // because it wasn't active when the phone was turned on
- Log.w(TAG, "Attempt to unbind from FaceLock when not bound");
+ // This is usually not an error when this happens. Sometimes we will tell it to
+ // unbind multiple times because it's called from both onWindowFocusChanged and
+ // onDetachedFromWindow.
+ if (DEBUG) Log.d(TAG, "Attempt to unbind from FaceLock when not bound");
}
}
}
@@ -1099,7 +1271,10 @@
try {
mFaceLockService.registerCallback(mFaceLockCallback);
} catch (RemoteException e) {
- throw new RuntimeException("Remote exception");
+ Log.e(TAG, "Caught exception connecting to FaceLock: " + e.toString());
+ mFaceLockService = null;
+ mBoundToFaceLockService = false;
+ return;
}
if (mFaceLockAreaView != null) {
@@ -1116,6 +1291,7 @@
mFaceLockService = null;
mFaceLockServiceRunning = false;
}
+ mBoundToFaceLockService = false;
Log.w(TAG, "Unexpected disconnect from FaceLock service");
}
};
@@ -1131,7 +1307,8 @@
try {
mFaceLockService.startUi(windowToken, x, y, h, w);
} catch (RemoteException e) {
- throw new RuntimeException("Remote exception");
+ Log.e(TAG, "Caught exception starting FaceLock: " + e.toString());
+ return;
}
mFaceLockServiceRunning = true;
} else {
@@ -1155,7 +1332,7 @@
if (DEBUG) Log.d(TAG, "Stopping FaceLock");
mFaceLockService.stopUi();
} catch (RemoteException e) {
- throw new RuntimeException("Remote exception");
+ Log.e(TAG, "Caught exception stopping FaceLock: " + e.toString());
}
mFaceLockServiceRunning = false;
}
@@ -1170,7 +1347,7 @@
@Override
public void unlock() {
if (DEBUG) Log.d(TAG, "FaceLock unlock()");
- mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW); // Keep fallback covered
+ showFaceLockArea(); // Keep fallback covered
stopFaceLock();
mKeyguardScreenCallback.keyguardDone(true);
@@ -1178,12 +1355,24 @@
}
// Stops the FaceLock UI and exposes the backup method without unlocking
- // This means either the user has cancelled out or FaceLock failed to recognize them
+ // This means the user has cancelled out
@Override
public void cancel() {
if (DEBUG) Log.d(TAG, "FaceLock cancel()");
- mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW); // Expose fallback
+ hideFaceLockArea(); // Expose fallback
stopFaceLock();
+ mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT);
+ }
+
+ // Stops the FaceLock UI and exposes the backup method without unlocking
+ // This means FaceLock failed to recognize them
+ @Override
+ public void reportFailedAttempt() {
+ if (DEBUG) Log.d(TAG, "FaceLock reportFailedAttempt()");
+ mFailedFaceUnlockAttempts++;
+ hideFaceLockArea(); // Expose fallback
+ stopFaceLock();
+ mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT);
}
// Allows the Face Unlock service to poke the wake lock to keep the lockscreen alive
diff --git a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
index ec0072c..3ad716b 100644
--- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
@@ -28,6 +28,7 @@
import android.os.CountDownTimer;
import android.os.SystemClock;
+import android.provider.Settings;
import android.security.KeyStore;
import android.text.Editable;
import android.text.InputType;
@@ -109,6 +110,10 @@
mPasswordEntry.setOnEditorActionListener(this);
mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this, false);
+ mKeyboardHelper.setEnableHaptics(
+ Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED, 0)
+ != 0);
if (mIsAlpha) {
// We always use the system IME for alpha keyboard, so hide lockscreen's soft keyboard
mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA);
@@ -150,9 +155,6 @@
//KeyguardStatusViewManager.LOCK_ICON);
}
- mKeyboardHelper.setVibratePattern(mLockPatternUtils.isTactileFeedbackEnabled() ?
- com.android.internal.R.array.config_virtualKeyVibePattern : 0);
-
// Poke the wakelock any time the text is selected or modified
mPasswordEntry.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 2cd6eab..af86ae9 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -349,8 +349,9 @@
}
// Already prepared (isPrepared will be reset to false later)
- if (st.isPrepared)
+ if (st.isPrepared) {
return true;
+ }
if ((mPreparedPanel != null) && (mPreparedPanel != st)) {
// Another Panel is prepared and possibly open, so close it
@@ -800,14 +801,23 @@
closePanel(st, true);
} else if (st.isPrepared) {
+ boolean show = true;
+ if (st.refreshMenuContent) {
+ // Something may have invalidated the menu since we prepared it.
+ // Re-prepare it to refresh.
+ st.isPrepared = false;
+ show = preparePanel(st, event);
+ }
- // Write 'menu opened' to event log
- EventLog.writeEvent(50001, 0);
+ if (show) {
+ // Write 'menu opened' to event log
+ EventLog.writeEvent(50001, 0);
- // Show menu
- openPanel(st, event);
+ // Show menu
+ openPanel(st, event);
- playSoundEffect = true;
+ playSoundEffect = true;
+ }
}
}
@@ -1084,8 +1094,8 @@
}
MenuView menuView = st.isInListMode()
- ? st.getListMenuView(mPanelMenuPresenterCallback)
- : st.getIconMenuView(mPanelMenuPresenterCallback);
+ ? st.getListMenuView(getContext(), mPanelMenuPresenterCallback)
+ : st.getIconMenuView(getContext(), mPanelMenuPresenterCallback);
st.shownPanelView = (View) menuView;
@@ -3251,11 +3261,11 @@
}
}
- MenuView getListMenuView(MenuPresenter.Callback cb) {
+ MenuView getListMenuView(Context context, MenuPresenter.Callback cb) {
if (menu == null) return null;
if (!isCompact) {
- getIconMenuView(cb); // Need this initialized to know where our offset goes
+ getIconMenuView(context, cb); // Need this initialized to know where our offset goes
}
if (listMenuPresenter == null) {
@@ -3275,11 +3285,11 @@
return result;
}
- MenuView getIconMenuView(MenuPresenter.Callback cb) {
+ MenuView getIconMenuView(Context context, MenuPresenter.Callback cb) {
if (menu == null) return null;
if (iconMenuPresenter == null) {
- iconMenuPresenter = new IconMenuPresenter();
+ iconMenuPresenter = new IconMenuPresenter(context);
iconMenuPresenter.setCallback(cb);
iconMenuPresenter.setId(com.android.internal.R.id.icon_menu_presenter);
menu.addMenuPresenter(iconMenuPresenter);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 487063d..b9fe182 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -128,7 +128,6 @@
import android.view.WindowManagerImpl;
import android.view.WindowManagerPolicy;
import android.view.KeyCharacterMap.FallbackAction;
-import android.view.WindowManagerPolicy.WindowManagerFuncs;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
@@ -180,26 +179,26 @@
static final int PRIORITY_PHONE_LAYER = 7;
// like the ANR / app crashed dialogs
static final int SYSTEM_ALERT_LAYER = 8;
- // system-level error dialogs
- static final int SYSTEM_ERROR_LAYER = 9;
// on-screen keyboards and other such input method user interfaces go here.
- static final int INPUT_METHOD_LAYER = 10;
+ static final int INPUT_METHOD_LAYER = 9;
// on-screen keyboards and other such input method user interfaces go here.
- static final int INPUT_METHOD_DIALOG_LAYER = 11;
+ static final int INPUT_METHOD_DIALOG_LAYER = 10;
// the keyguard; nothing on top of these can take focus, since they are
// responsible for power management when displayed.
- static final int KEYGUARD_LAYER = 12;
- static final int KEYGUARD_DIALOG_LAYER = 13;
- static final int STATUS_BAR_SUB_PANEL_LAYER = 14;
- static final int STATUS_BAR_LAYER = 15;
- static final int STATUS_BAR_PANEL_LAYER = 16;
+ static final int KEYGUARD_LAYER = 11;
+ static final int KEYGUARD_DIALOG_LAYER = 12;
+ static final int STATUS_BAR_SUB_PANEL_LAYER = 13;
+ static final int STATUS_BAR_LAYER = 14;
+ static final int STATUS_BAR_PANEL_LAYER = 15;
// the on-screen volume indicator and controller shown when the user
// changes the device volume
- static final int VOLUME_OVERLAY_LAYER = 17;
+ static final int VOLUME_OVERLAY_LAYER = 16;
// things in here CAN NOT take focus, but are shown on top of everything else.
- static final int SYSTEM_OVERLAY_LAYER = 18;
+ static final int SYSTEM_OVERLAY_LAYER = 17;
// the navigation bar, if available, shows atop most things
- static final int NAVIGATION_BAR_LAYER = 19;
+ static final int NAVIGATION_BAR_LAYER = 18;
+ // system-level error dialogs
+ static final int SYSTEM_ERROR_LAYER = 19;
// the drag layer: input for drag-and-drop is associated with this window,
// which sits above all other focusable windows
static final int DRAG_LAYER = 20;
@@ -267,7 +266,8 @@
WindowState mKeyguard = null;
KeyguardViewMediator mKeyguardMediator;
GlobalActions mGlobalActions;
- volatile boolean mPowerKeyHandled;
+ volatile boolean mPowerKeyHandled; // accessed from input reader and handler thread
+ boolean mPendingPowerKeyUpCanceled;
RecentApplicationsDialog mRecentAppsDialog;
Handler mHandler;
@@ -353,8 +353,13 @@
int mDockLeft, mDockTop, mDockRight, mDockBottom;
// During layout, the layer at which the doc window is placed.
int mDockLayer;
- int mLastSystemUiVisibility;
- int mForceClearingStatusBarVisibility = 0;
+ int mLastSystemUiFlags;
+ // Bits that we are in the process of clearing, so we want to prevent
+ // them from being set by applications until everything has been updated
+ // to have them clear.
+ int mResettingSystemUiFlags = 0;
+ // Bits that we are currently always keeping cleared.
+ int mForceClearedSystemUiFlags = 0;
FakeWindow mHideNavFakeWindow = null;
@@ -403,8 +408,14 @@
private int mLongPressOnHomeBehavior = -1;
// Screenshot trigger states
- private boolean mVolumeDownTriggered;
- private boolean mPowerDownTriggered;
+ // Time to volume and power must be pressed within this interval of each other.
+ private static final long SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS = 150;
+ private boolean mVolumeDownKeyTriggered;
+ private long mVolumeDownKeyTime;
+ private boolean mVolumeDownKeyConsumedByScreenshotChord;
+ private boolean mVolumeUpKeyTriggered;
+ private boolean mPowerKeyTriggered;
+ private long mPowerKeyTime;
ShortcutManager mShortcutManager;
PowerManager.WakeLock mBroadcastWakeLock;
@@ -552,37 +563,64 @@
if (!mPowerKeyHandled) {
mHandler.removeCallbacks(mPowerLongPress);
return !canceled;
- } else {
- mPowerKeyHandled = true;
- return false;
}
+ return false;
+ }
+
+ private void cancelPendingPowerKeyAction() {
+ if (!mPowerKeyHandled) {
+ mHandler.removeCallbacks(mPowerLongPress);
+ }
+ mPendingPowerKeyUpCanceled = true;
+ }
+
+ private void interceptScreenshotChord() {
+ if (mVolumeDownKeyTriggered && mPowerKeyTriggered && !mVolumeUpKeyTriggered) {
+ final long now = SystemClock.uptimeMillis();
+ if (now <= mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS
+ && now <= mPowerKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) {
+ mVolumeDownKeyConsumedByScreenshotChord = true;
+ cancelPendingPowerKeyAction();
+
+ mHandler.postDelayed(mScreenshotChordLongPress,
+ ViewConfiguration.getGlobalActionKeyTimeout());
+ }
+ }
+ }
+
+ private void cancelPendingScreenshotChordAction() {
+ mHandler.removeCallbacks(mScreenshotChordLongPress);
}
private final Runnable mPowerLongPress = new Runnable() {
public void run() {
- if (!mPowerKeyHandled) {
- // The context isn't read
- if (mLongPressOnPowerBehavior < 0) {
- mLongPressOnPowerBehavior = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_longPressOnPowerBehavior);
- }
- switch (mLongPressOnPowerBehavior) {
- case LONG_PRESS_POWER_NOTHING:
- break;
- case LONG_PRESS_POWER_GLOBAL_ACTIONS:
- mPowerKeyHandled = true;
- performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
- sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
- showGlobalActionsDialog();
- break;
- case LONG_PRESS_POWER_SHUT_OFF:
- mPowerKeyHandled = true;
- performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
- sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
- ShutdownThread.shutdown(mContext, true);
- break;
- }
+ // The context isn't read
+ if (mLongPressOnPowerBehavior < 0) {
+ mLongPressOnPowerBehavior = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_longPressOnPowerBehavior);
}
+ switch (mLongPressOnPowerBehavior) {
+ case LONG_PRESS_POWER_NOTHING:
+ break;
+ case LONG_PRESS_POWER_GLOBAL_ACTIONS:
+ mPowerKeyHandled = true;
+ performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
+ sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
+ showGlobalActionsDialog();
+ break;
+ case LONG_PRESS_POWER_SHUT_OFF:
+ mPowerKeyHandled = true;
+ performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
+ sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
+ ShutdownThread.shutdown(mContext, true);
+ break;
+ }
+ }
+ };
+
+ private final Runnable mScreenshotChordLongPress = new Runnable() {
+ public void run() {
+ takeScreenshot();
}
};
@@ -1381,11 +1419,12 @@
/** {@inheritDoc} */
@Override
- public boolean interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
+ public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
final boolean keyguardOn = keyguardOn();
final int keyCode = event.getKeyCode();
final int repeatCount = event.getRepeatCount();
final int metaState = event.getMetaState();
+ final int flags = event.getFlags();
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
final boolean canceled = event.isCanceled();
@@ -1394,6 +1433,26 @@
+ repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed);
}
+ // If we think we might have a volume down & power key chord on the way
+ // but we're not sure, then tell the dispatcher to wait a little while and
+ // try again later before dispatching.
+ if ((flags & KeyEvent.FLAG_FALLBACK) == 0) {
+ if (mVolumeDownKeyTriggered && !mPowerKeyTriggered) {
+ final long now = SystemClock.uptimeMillis();
+ final long timeoutTime = mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS;
+ if (now < timeoutTime) {
+ return timeoutTime - now;
+ }
+ }
+ if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
+ && mVolumeDownKeyConsumedByScreenshotChord) {
+ if (!down) {
+ mVolumeDownKeyConsumedByScreenshotChord = false;
+ }
+ return -1;
+ }
+ }
+
// First we always handle the home key here, so applications
// can never break it, although if keyguard is on, we do let
// it handle it, because that gives us the correct 5 second
@@ -1425,7 +1484,7 @@
} else {
Log.i(TAG, "Ignoring HOME; event canceled.");
}
- return true;
+ return -1;
}
// If a system window has focus, then it doesn't make sense
@@ -1436,13 +1495,13 @@
if (type == WindowManager.LayoutParams.TYPE_KEYGUARD
|| type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {
// the "app" is keyguard, so give it the key
- return false;
+ return 0;
}
final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;
for (int i=0; i<typeCount; i++) {
if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {
// don't do anything, but also don't pass it to the app
- return true;
+ return -1;
}
}
}
@@ -1456,7 +1515,7 @@
}
}
}
- return true;
+ return -1;
} else if (keyCode == KeyEvent.KEYCODE_MENU) {
// Hijack modified menu keys for debugging features
final int chordBug = KeyEvent.META_SHIFT_ON;
@@ -1465,7 +1524,7 @@
if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) {
Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
mContext.sendOrderedBroadcast(intent, null);
- return true;
+ return -1;
} else if (SHOW_PROCESSES_ON_ALT_MENU &&
(metaState & KeyEvent.META_ALT_ON) == KeyEvent.META_ALT_ON) {
Intent service = new Intent();
@@ -1480,7 +1539,7 @@
}
Settings.System.putInt(
res, Settings.System.SHOW_PROCESSES, shown ? 0 : 1);
- return true;
+ return -1;
}
}
} else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
@@ -1493,15 +1552,15 @@
mShortcutKeyPressed = -1;
if (mConsumeShortcutKeyUp) {
mConsumeShortcutKeyUp = false;
- return true;
+ return -1;
}
}
- return false;
+ return 0;
} else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
if (down && repeatCount == 0) {
showOrHideRecentAppsDialog(0, true /*dismissIfShown*/);
}
- return true;
+ return -1;
}
// Shortcuts are invoked through Search+key, so intercept those here
@@ -1531,11 +1590,11 @@
+ "+" + KeyEvent.keyCodeToString(keyCode));
}
}
- return true;
+ return -1;
}
}
- return false;
+ return 0;
}
/** {@inheritDoc} */
@@ -1606,7 +1665,9 @@
flags, event.getSource(), null);
int actions = interceptKeyBeforeQueueing(fallbackEvent, policyFlags, true);
if ((actions & ACTION_PASS_TO_USER) != 0) {
- if (!interceptKeyBeforeDispatching(win, fallbackEvent, policyFlags)) {
+ long delayMillis = interceptKeyBeforeDispatching(
+ win, fallbackEvent, policyFlags);
+ if (delayMillis == 0) {
if (DEBUG_FALLBACK) {
Slog.d(TAG, "Performing fallback.");
}
@@ -1663,6 +1724,21 @@
}
}
+ /**
+ * A delayed callback use to determine when it is okay to re-allow applications
+ * to use certain system UI flags. This is used to prevent applications from
+ * spamming system UI changes that prevent the navigation bar from being shown.
+ */
+ final Runnable mAllowSystemUiDelay = new Runnable() {
+ @Override public void run() {
+ }
+ };
+
+ /**
+ * Input handler used while nav bar is hidden. Captures any touch on the screen,
+ * to determine when the nav bar should be shown and prevent applications from
+ * receiving those touches.
+ */
final InputHandler mHideNavInputHandler = new BaseInputHandler() {
@Override
public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
@@ -1675,12 +1751,30 @@
synchronized (mLock) {
// Any user activity always causes us to show the navigation controls,
// if they had been hidden.
- int newVal = mForceClearingStatusBarVisibility
+ int newVal = mResettingSystemUiFlags
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
- if (mForceClearingStatusBarVisibility != newVal) {
- mForceClearingStatusBarVisibility = newVal;
+ if (mResettingSystemUiFlags != newVal) {
+ mResettingSystemUiFlags = newVal;
changed = true;
}
+ // We don't allow the system's nav bar to be hidden
+ // again for 1 second, to prevent applications from
+ // spamming us and keeping it from being shown.
+ newVal = mForceClearedSystemUiFlags
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+ if (mForceClearedSystemUiFlags != newVal) {
+ mForceClearedSystemUiFlags = newVal;
+ changed = true;
+ mHandler.postDelayed(new Runnable() {
+ @Override public void run() {
+ synchronized (mLock) {
+ mForceClearedSystemUiFlags &=
+ ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+ }
+ mWindowManagerFuncs.reevaluateStatusBarVisibility();
+ }
+ }, 1000);
+ }
}
if (changed) {
mWindowManagerFuncs.reevaluateStatusBarVisibility();
@@ -1697,10 +1791,11 @@
public int adjustSystemUiVisibilityLw(int visibility) {
// Reset any bits in mForceClearingStatusBarVisibility that
// are now clear.
- mForceClearingStatusBarVisibility &= visibility;
+ mResettingSystemUiFlags &= visibility;
// Clear any bits in the new visibility that are currently being
// force cleared, before reporting it.
- return visibility & ~mForceClearingStatusBarVisibility;
+ return visibility & ~mResettingSystemUiFlags
+ & ~mForceClearedSystemUiFlags;
}
public void getContentInsetHintLw(WindowManager.LayoutParams attrs, Rect contentInset) {
@@ -1739,11 +1834,28 @@
pf.right = df.right = vf.right = mDockRight;
pf.bottom = df.bottom = vf.bottom = mDockBottom;
+ final boolean navVisible = (mNavigationBar == null || mNavigationBar.isVisibleLw()) &&
+ (mLastSystemUiFlags&View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
+
+ // When the navigation bar isn't visible, we put up a fake
+ // input window to catch all touch events. This way we can
+ // detect when the user presses anywhere to bring back the nav
+ // bar and ensure the application doesn't see the event.
+ if (navVisible) {
+ if (mHideNavFakeWindow != null) {
+ mHideNavFakeWindow.dismiss();
+ mHideNavFakeWindow = null;
+ }
+ } else if (mHideNavFakeWindow == null) {
+ mHideNavFakeWindow = mWindowManagerFuncs.addFakeWindow(
+ mHandler.getLooper(), mHideNavInputHandler,
+ "hidden nav", WindowManager.LayoutParams.TYPE_HIDDEN_NAV_CONSUMER,
+ 0, false, false, true);
+ }
+
// decide where the status bar goes ahead of time
if (mStatusBar != null) {
if (mNavigationBar != null) {
- final boolean navVisible = mNavigationBar.isVisibleLw() &&
- (mLastSystemUiVisibility&View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
// Force the navigation bar to its appropriate place and
// size. We need to do this directly, instead of relying on
// it to bubble up from the nav bar, because this needs to
@@ -1775,21 +1887,6 @@
mTmpNavigationFrame.offset(mNavigationBarWidth, 0);
}
}
- // When the navigation bar isn't visible, we put up a fake
- // input window to catch all touch events. This way we can
- // detect when the user presses anywhere to bring back the nav
- // bar and ensure the application doesn't see the event.
- if (navVisible) {
- if (mHideNavFakeWindow != null) {
- mHideNavFakeWindow.dismiss();
- mHideNavFakeWindow = null;
- }
- } else if (mHideNavFakeWindow == null) {
- mHideNavFakeWindow = mWindowManagerFuncs.addFakeWindow(
- mHandler.getLooper(), mHideNavInputHandler,
- "hidden nav", WindowManager.LayoutParams.TYPE_HIDDEN_NAV_CONSUMER,
- 0, false, false, true);
- }
// And compute the final frame.
mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
mTmpNavigationFrame, mTmpNavigationFrame);
@@ -2472,76 +2569,70 @@
final Object mScreenshotLock = new Object();
ServiceConnection mScreenshotConnection = null;
- Runnable mScreenshotTimeout = null;
- void finishScreenshotLSS(ServiceConnection conn) {
- if (mScreenshotConnection == conn) {
- mContext.unbindService(conn);
- mScreenshotConnection = null;
- if (mScreenshotTimeout != null) {
- mHandler.removeCallbacks(mScreenshotTimeout);
- mScreenshotTimeout = null;
- }
- }
- }
-
- private void takeScreenshot() {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- synchronized (mScreenshotLock) {
- if (mScreenshotConnection != null) {
- return;
- }
- ComponentName cn = new ComponentName("com.android.systemui",
- "com.android.systemui.screenshot.TakeScreenshotService");
- Intent intent = new Intent();
- intent.setComponent(cn);
- ServiceConnection conn = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- synchronized (mScreenshotLock) {
- if (mScreenshotConnection != this) {
- return;
- }
- Messenger messenger = new Messenger(service);
- Message msg = Message.obtain(null, 1);
- final ServiceConnection myConn = this;
- Handler h = new Handler(mHandler.getLooper()) {
- @Override
- public void handleMessage(Message msg) {
- synchronized (mScreenshotLock) {
- finishScreenshotLSS(myConn);
- }
- }
- };
- msg.replyTo = new Messenger(h);
- try {
- messenger.send(msg);
- } catch (RemoteException e) {
- }
- }
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {}
- };
- if (mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE)) {
- mScreenshotConnection = conn;
- mScreenshotTimeout = new Runnable() {
- @Override public void run() {
- synchronized (mScreenshotLock) {
- if (mScreenshotConnection != null) {
- finishScreenshotLSS(mScreenshotConnection);
- }
- }
- }
-
- };
- mHandler.postDelayed(mScreenshotTimeout, 10000);
- }
+ final Runnable mScreenshotTimeout = new Runnable() {
+ @Override public void run() {
+ synchronized (mScreenshotLock) {
+ if (mScreenshotConnection != null) {
+ mContext.unbindService(mScreenshotConnection);
+ mScreenshotConnection = null;
}
}
- });
+ }
+ };
+
+ // Assume this is called from the Handler thread.
+ private void takeScreenshot() {
+ synchronized (mScreenshotLock) {
+ if (mScreenshotConnection != null) {
+ return;
+ }
+ ComponentName cn = new ComponentName("com.android.systemui",
+ "com.android.systemui.screenshot.TakeScreenshotService");
+ Intent intent = new Intent();
+ intent.setComponent(cn);
+ ServiceConnection conn = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ synchronized (mScreenshotLock) {
+ if (mScreenshotConnection != this) {
+ return;
+ }
+ Messenger messenger = new Messenger(service);
+ Message msg = Message.obtain(null, 1);
+ final ServiceConnection myConn = this;
+ Handler h = new Handler(mHandler.getLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ synchronized (mScreenshotLock) {
+ if (mScreenshotConnection == myConn) {
+ mContext.unbindService(mScreenshotConnection);
+ mScreenshotConnection = null;
+ mHandler.removeCallbacks(mScreenshotTimeout);
+ }
+ }
+ }
+ };
+ msg.replyTo = new Messenger(h);
+ msg.arg1 = msg.arg2 = 0;
+ if (mStatusBar != null && mStatusBar.isVisibleLw())
+ msg.arg1 = 1;
+ if (mNavigationBar != null && mNavigationBar.isVisibleLw())
+ msg.arg2 = 1;
+ try {
+ messenger.send(msg);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ @Override
+ public void onServiceDisconnected(ComponentName name) {}
+ };
+ if (mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE)) {
+ mScreenshotConnection = conn;
+ mHandler.postDelayed(mScreenshotTimeout, 10000);
+ }
+ }
}
/** {@inheritDoc} */
@@ -2609,28 +2700,35 @@
// Handle special keys.
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_DOWN:
- if (down) {
- if (isScreenOn) {
- // If the power key down was already triggered, take the screenshot
- if (mPowerDownTriggered) {
- // Dismiss the power-key longpress
- mHandler.removeCallbacks(mPowerLongPress);
- mPowerKeyHandled = true;
-
- // Take the screenshot
- takeScreenshot();
-
- // Prevent the event from being passed through to the current activity
- result &= ~ACTION_PASS_TO_USER;
- break;
- }
- mVolumeDownTriggered = true;
- }
- } else {
- mVolumeDownTriggered = false;
- }
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_MUTE: {
+ if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
+ if (down) {
+ if (isScreenOn && !mVolumeDownKeyTriggered
+ && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
+ mVolumeDownKeyTriggered = true;
+ mVolumeDownKeyTime = event.getDownTime();
+ mVolumeDownKeyConsumedByScreenshotChord = false;
+ cancelPendingPowerKeyAction();
+ interceptScreenshotChord();
+ }
+ } else {
+ mVolumeDownKeyTriggered = false;
+ cancelPendingScreenshotChordAction();
+ }
+ } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
+ if (down) {
+ if (isScreenOn && !mVolumeUpKeyTriggered
+ && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
+ mVolumeUpKeyTriggered = true;
+ cancelPendingPowerKeyAction();
+ cancelPendingScreenshotChordAction();
+ }
+ } else {
+ mVolumeUpKeyTriggered = false;
+ cancelPendingScreenshotChordAction();
+ }
+ }
if (down) {
ITelephony telephonyService = getTelephonyService();
if (telephonyService != null) {
@@ -2709,17 +2807,11 @@
case KeyEvent.KEYCODE_POWER: {
result &= ~ACTION_PASS_TO_USER;
if (down) {
- if (isScreenOn) {
- // If the volume down key has been triggered, then just take the screenshot
- if (mVolumeDownTriggered) {
- // Take the screenshot
- takeScreenshot();
- mPowerKeyHandled = true;
-
- // Prevent the event from being passed through to the current activity
- break;
- }
- mPowerDownTriggered = true;
+ if (isScreenOn && !mPowerKeyTriggered
+ && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
+ mPowerKeyTriggered = true;
+ mPowerKeyTime = event.getDownTime();
+ interceptScreenshotChord();
}
ITelephony telephonyService = getTelephonyService();
@@ -2741,12 +2833,15 @@
Log.w(TAG, "ITelephony threw RemoteException", ex);
}
}
- interceptPowerKeyDown(!isScreenOn || hungUp);
+ interceptPowerKeyDown(!isScreenOn || hungUp
+ || mVolumeDownKeyTriggered || mVolumeUpKeyTriggered);
} else {
- mPowerDownTriggered = false;
- if (interceptPowerKeyUp(canceled)) {
+ mPowerKeyTriggered = false;
+ cancelPendingScreenshotChordAction();
+ if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) {
result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP;
}
+ mPendingPowerKeyUpCanceled = false;
}
break;
}
@@ -3604,12 +3699,13 @@
return 0;
}
final int visibility = mFocusedWindow.getSystemUiVisibility()
- & ~mForceClearingStatusBarVisibility;
- int diff = visibility ^ mLastSystemUiVisibility;
+ & ~mResettingSystemUiFlags
+ & ~mForceClearedSystemUiFlags;
+ int diff = visibility ^ mLastSystemUiFlags;
if (diff == 0) {
return 0;
}
- mLastSystemUiVisibility = visibility;
+ mLastSystemUiFlags = visibility;
mHandler.post(new Runnable() {
public void run() {
if (mStatusBarService == null) {
@@ -3636,11 +3732,14 @@
pw.print(prefix); pw.print("mLidOpen="); pw.print(mLidOpen);
pw.print(" mLidOpenRotation="); pw.print(mLidOpenRotation);
pw.print(" mHdmiPlugged="); pw.println(mHdmiPlugged);
- if (mLastSystemUiVisibility != 0 || mForceClearingStatusBarVisibility != 0) {
- pw.print(prefix); pw.print("mLastSystemUiVisibility=0x");
- pw.println(Integer.toHexString(mLastSystemUiVisibility));
- pw.print(" mForceClearingStatusBarVisibility=0x");
- pw.println(Integer.toHexString(mForceClearingStatusBarVisibility));
+ if (mLastSystemUiFlags != 0 || mResettingSystemUiFlags != 0
+ || mForceClearedSystemUiFlags != 0) {
+ pw.print(prefix); pw.print("mLastSystemUiFlags=0x");
+ pw.print(Integer.toHexString(mLastSystemUiFlags));
+ pw.print(" mResettingSystemUiFlags=0x");
+ pw.print(Integer.toHexString(mResettingSystemUiFlags));
+ pw.print(" mForceClearedSystemUiFlags=0x");
+ pw.println(Integer.toHexString(mForceClearedSystemUiFlags));
}
pw.print(prefix); pw.print("mUiMode="); pw.print(mUiMode);
pw.print(" mDockMode="); pw.print(mDockMode);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index ab49f93..3e0304f 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1832,7 +1832,9 @@
size_t mixBufferSize = mFrameCount * mFrameSize;
// FIXME: Relaxed timing because of a certain device that can't meet latency
// Should be reduced to 2x after the vendor fixes the driver issue
- nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 3;
+ // increase threshold again due to low power audio mode. The way this warning threshold is
+ // calculated and its usefulness should be reconsidered anyway.
+ nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
nsecs_t lastWarning = 0;
bool longStandbyExit = false;
uint32_t activeSleepTime = activeSleepTimeUs();
@@ -1886,7 +1888,9 @@
mixBufferSize = mFrameCount * mFrameSize;
// FIXME: Relaxed timing because of a certain device that can't meet latency
// Should be reduced to 2x after the vendor fixes the driver issue
- maxPeriod = seconds(mFrameCount) / mSampleRate * 3;
+ // increase threshold again due to low power audio mode. The way this warning
+ // threshold is calculated and its usefulness should be reconsidered anyway.
+ maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
activeSleepTime = activeSleepTimeUs();
idleSleepTime = idleSleepTimeUs();
}
@@ -1983,7 +1987,7 @@
mInWrite = false;
nsecs_t now = systemTime();
nsecs_t delta = now - mLastWriteTime;
- if (delta > maxPeriod) {
+ if (!mStandby && delta > maxPeriod) {
mNumDelayedWrites++;
if ((now - lastWarning) > kWarningThrottle) {
LOGW("write blocked for %llu msecs, %d delayed writes, thread %p",
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index f306e4a..171710a 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -97,6 +97,16 @@
setCameraFree(i);
}
}
+
+ // Read the system property to determine if we have to use the
+ // AUDIO_STREAM_ENFORCED_AUDIBLE type.
+ char value[PROPERTY_VALUE_MAX];
+ property_get("ro.camera.sound.forced", value, "0");
+ if (strcmp(value, "0") != 0) {
+ mAudioStreamType = AUDIO_STREAM_ENFORCED_AUDIBLE;
+ } else {
+ mAudioStreamType = AUDIO_STREAM_MUSIC;
+ }
}
CameraService::~CameraService() {
@@ -282,21 +292,10 @@
// A reference count is kept to determine when we will actually release the
// media players.
-static MediaPlayer* newMediaPlayer(const char *file) {
- // Read the system property to determine if we have need to use the
- // AUDIO_STREAM_ENFORCED_AUDIBLE type.
- char value[PROPERTY_VALUE_MAX];
- property_get("ro.camera.sound.forced", value, "0");
- int audioStreamType;
- if (strcmp(value, "0") != 0) {
- audioStreamType = AUDIO_STREAM_ENFORCED_AUDIBLE;
- } else {
- audioStreamType = AUDIO_STREAM_MUSIC;
- }
-
+MediaPlayer* CameraService::newMediaPlayer(const char *file) {
MediaPlayer* mp = new MediaPlayer();
if (mp->setDataSource(file, NULL) == NO_ERROR) {
- mp->setAudioStreamType(audioStreamType);
+ mp->setAudioStreamType(mAudioStreamType);
mp->prepare();
} else {
LOGE("Failed to load CameraService sounds: %s", file);
@@ -335,7 +334,7 @@
// do not play the sound if stream volume is 0
// (typically because ringer mode is silent).
int index;
- AudioSystem::getStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE, &index);
+ AudioSystem::getStreamVolumeIndex(mAudioStreamType, &index);
if (index != 0) {
player->seekTo(0);
player->start();
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 57abf83..cdfbc56 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -76,6 +76,9 @@
void setCameraFree(int cameraId);
// sounds
+ audio_stream_type_t mAudioStreamType;
+ MediaPlayer* newMediaPlayer(const char *file);
+
Mutex mSoundLock;
sp<MediaPlayer> mSoundPlayer[NUM_SOUNDS];
int mSoundRef; // reference count (release all MediaPlayer when 0)
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 1eb5f0e..04b4855 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -804,6 +804,18 @@
logOutboundKeyDetailsLocked("dispatchKey - ", entry);
}
+ // Handle case where the policy asked us to try again later last time.
+ if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
+ if (currentTime < entry->interceptKeyWakeupTime) {
+ if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
+ *nextWakeupTime = entry->interceptKeyWakeupTime;
+ }
+ return false; // wait until next wakeup
+ }
+ entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
+ entry->interceptKeyWakeupTime = 0;
+ }
+
// Give the policy a chance to intercept the key.
if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
@@ -3827,14 +3839,19 @@
mLock.unlock();
- bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
+ nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
&event, entry->policyFlags);
mLock.lock();
- entry->interceptKeyResult = consumed
- ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
- : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
+ if (delay < 0) {
+ entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
+ } else if (!delay) {
+ entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
+ } else {
+ entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
+ entry->interceptKeyWakeupTime = now() + delay;
+ }
entry->release();
}
@@ -4156,7 +4173,8 @@
deviceId(deviceId), source(source), action(action), flags(flags),
keyCode(keyCode), scanCode(scanCode), metaState(metaState),
repeatCount(repeatCount), downTime(downTime),
- syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
+ syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
+ interceptKeyWakeupTime(0) {
}
InputDispatcher::KeyEntry::~KeyEntry() {
@@ -4168,6 +4186,7 @@
dispatchInProgress = false;
syntheticRepeat = false;
interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
+ interceptKeyWakeupTime = 0;
}
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index e78f7bd..8ae5a56 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -242,7 +242,7 @@
virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0;
/* Allows the policy a chance to intercept a key before dispatching. */
- virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
+ virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
const KeyEvent* keyEvent, uint32_t policyFlags) = 0;
/* Allows the policy a chance to perform default processing for an unhandled key.
@@ -481,8 +481,10 @@
INTERCEPT_KEY_RESULT_UNKNOWN,
INTERCEPT_KEY_RESULT_SKIP,
INTERCEPT_KEY_RESULT_CONTINUE,
+ INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER,
};
InterceptKeyResult interceptKeyResult; // set based on the interception result
+ nsecs_t interceptKeyWakeupTime; // used with INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER
KeyEntry(nsecs_t eventTime,
int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
diff --git a/services/input/tests/InputDispatcher_test.cpp b/services/input/tests/InputDispatcher_test.cpp
index 8dfb44b..961566f 100644
--- a/services/input/tests/InputDispatcher_test.cpp
+++ b/services/input/tests/InputDispatcher_test.cpp
@@ -75,9 +75,9 @@
virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
}
- virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
+ virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
const KeyEvent* keyEvent, uint32_t policyFlags) {
- return false;
+ return 0;
}
virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index dd649e7..eb75ebc 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -16,24 +16,6 @@
package com.android.server;
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.commons.logging.impl.SimpleLog;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
@@ -42,9 +24,9 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.Intent.FilterComparison;
import android.content.IntentFilter;
import android.content.ServiceConnection;
+import android.content.Intent.FilterComparison;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
@@ -58,7 +40,6 @@
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
-import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.AttributeSet;
@@ -68,20 +49,37 @@
import android.util.TypedValue;
import android.util.Xml;
import android.widget.RemoteViews;
-import android.widget.RemoteViewsService;
import com.android.internal.appwidget.IAppWidgetHost;
import com.android.internal.appwidget.IAppWidgetService;
+import com.android.internal.os.AtomicFile;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.widget.IRemoteViewsAdapterConnection;
import com.android.internal.widget.IRemoteViewsFactory;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+
class AppWidgetService extends IAppWidgetService.Stub
{
private static final String TAG = "AppWidgetService";
private static final String SETTINGS_FILENAME = "appwidgets.xml";
- private static final String SETTINGS_TMP_FILENAME = SETTINGS_FILENAME + ".tmp";
private static final int MIN_UPDATE_PERIOD = 30 * 60 * 1000; // 30 minutes
/*
@@ -1159,70 +1157,46 @@
// only call from initialization -- it assumes that the data structures are all empty
void loadStateLocked() {
- File temp = savedStateTempFile();
- File real = savedStateRealFile();
+ AtomicFile file = savedStateFile();
+ try {
+ FileInputStream stream = file.openRead();
+ readStateFromFileLocked(stream);
- // prefer the real file. If it doesn't exist, use the temp one, and then copy it to the
- // real one. if there is both a real file and a temp one, assume that the temp one isn't
- // fully written and delete it.
- if (real.exists()) {
- readStateFromFileLocked(real);
- if (temp.exists()) {
- //noinspection ResultOfMethodCallIgnored
- temp.delete();
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ Slog.w(TAG, "Failed to close state FileInputStream " + e);
+ }
}
- } else if (temp.exists()) {
- readStateFromFileLocked(temp);
- //noinspection ResultOfMethodCallIgnored
- temp.renameTo(real);
+ } catch (FileNotFoundException e) {
+ Slog.w(TAG, "Failed to read state: " + e);
}
}
-
+
void saveStateLocked() {
- File temp = savedStateTempFile();
- File real = savedStateRealFile();
-
- if (!real.exists()) {
- // If the real one doesn't exist, it's either because this is the first time
- // or because something went wrong while copying them. In this case, we can't
- // trust anything that's in temp. In order to have the loadState code not
- // use the temporary one until it's fully written, create an empty file
- // for real, which will we'll shortly delete.
- try {
- //noinspection ResultOfMethodCallIgnored
- real.createNewFile();
- } catch (IOException e) {
- // Ignore
+ AtomicFile file = savedStateFile();
+ FileOutputStream stream;
+ try {
+ stream = file.startWrite();
+ if (writeStateToFileLocked(stream)) {
+ file.finishWrite(stream);
+ } else {
+ file.failWrite(stream);
+ Slog.w(TAG, "Failed to save state, restoring backup.");
}
+ } catch (IOException e) {
+ Slog.w(TAG, "Failed open state file for write: " + e);
}
-
- if (temp.exists()) {
- //noinspection ResultOfMethodCallIgnored
- temp.delete();
- }
-
- if (!writeStateToFileLocked(temp)) {
- Slog.w(TAG, "Failed to persist new settings");
- return;
- }
-
- //noinspection ResultOfMethodCallIgnored
- real.delete();
- //noinspection ResultOfMethodCallIgnored
- temp.renameTo(real);
}
- boolean writeStateToFileLocked(File file) {
- FileOutputStream stream = null;
+ boolean writeStateToFileLocked(FileOutputStream stream) {
int N;
try {
- stream = new FileOutputStream(file, false);
XmlSerializer out = new FastXmlSerializer();
out.setOutput(stream, "utf-8");
out.startDocument(null, true);
-
-
out.startTag(null, "gs");
int providerIndex = 0;
@@ -1264,31 +1238,17 @@
out.endTag(null, "gs");
out.endDocument();
- stream.close();
return true;
} catch (IOException e) {
- try {
- if (stream != null) {
- stream.close();
- }
- } catch (IOException ex) {
- // Ignore
- }
- if (file.exists()) {
- //noinspection ResultOfMethodCallIgnored
- file.delete();
- }
+ Slog.w(TAG, "Failed to write state: " + e);
return false;
}
}
- void readStateFromFileLocked(File file) {
- FileInputStream stream = null;
-
+ void readStateFromFileLocked(FileInputStream stream) {
boolean success = false;
try {
- stream = new FileInputStream(file);
XmlPullParser parser = Xml.newPullParser();
parser.setInput(stream, null);
@@ -1390,22 +1350,15 @@
} while (type != XmlPullParser.END_DOCUMENT);
success = true;
} catch (NullPointerException e) {
- Slog.w(TAG, "failed parsing " + file, e);
+ Slog.w(TAG, "failed parsing " + e);
} catch (NumberFormatException e) {
- Slog.w(TAG, "failed parsing " + file, e);
+ Slog.w(TAG, "failed parsing " + e);
} catch (XmlPullParserException e) {
- Slog.w(TAG, "failed parsing " + file, e);
+ Slog.w(TAG, "failed parsing " + e);
} catch (IOException e) {
- Slog.w(TAG, "failed parsing " + file, e);
+ Slog.w(TAG, "failed parsing " + e);
} catch (IndexOutOfBoundsException e) {
- Slog.w(TAG, "failed parsing " + file, e);
- }
- try {
- if (stream != null) {
- stream.close();
- }
- } catch (IOException e) {
- // Ignore
+ Slog.w(TAG, "failed parsing " + e);
}
if (success) {
@@ -1416,6 +1369,8 @@
}
} else {
// failed reading, clean up
+ Slog.w(TAG, "Failed to read state, clearing widgets and hosts.");
+
mAppWidgetIds.clear();
mHosts.clear();
final int N = mInstalledProviders.size();
@@ -1425,14 +1380,8 @@
}
}
- File savedStateTempFile() {
- return new File("/data/system/" + SETTINGS_TMP_FILENAME);
- //return new File(mContext.getFilesDir(), SETTINGS_FILENAME);
- }
-
- File savedStateRealFile() {
- return new File("/data/system/" + SETTINGS_FILENAME);
- //return new File(mContext.getFilesDir(), SETTINGS_TMP_FILENAME);
+ AtomicFile savedStateFile() {
+ return new AtomicFile(new File("/data/system/" + SETTINGS_FILENAME));
}
BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 5758954..4ef8837 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -62,14 +62,15 @@
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.WorkSource;
+import android.os.storage.IMountService;
import android.provider.Settings;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.SparseIntArray;
import android.util.StringBuilderPrinter;
import com.android.internal.backup.BackupConstants;
@@ -187,6 +188,7 @@
private IActivityManager mActivityManager;
private PowerManager mPowerManager;
private AlarmManager mAlarmManager;
+ private IMountService mMountService;
IBackupManager mBackupManagerBinder;
boolean mEnabled; // access to this is synchronized on 'this'
@@ -660,6 +662,7 @@
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
mBackupManagerBinder = asInterface(asBinder());
@@ -1037,6 +1040,40 @@
// Backup password management
boolean passwordMatchesSaved(String candidatePw, int rounds) {
+ // First, on an encrypted device we require matching the device pw
+ final boolean isEncrypted;
+ try {
+ isEncrypted = (mMountService.getEncryptionState() != MountService.ENCRYPTION_STATE_NONE);
+ if (isEncrypted) {
+ if (DEBUG) {
+ Slog.i(TAG, "Device encrypted; verifying against device data pw");
+ }
+ // 0 means the password validated
+ // -2 means device not encrypted
+ // Any other result is either password failure or an error condition,
+ // so we refuse the match
+ final int result = mMountService.verifyEncryptionPassword(candidatePw);
+ if (result == 0) {
+ if (MORE_DEBUG) Slog.d(TAG, "Pw verifies");
+ return true;
+ } else if (result != -2) {
+ if (MORE_DEBUG) Slog.d(TAG, "Pw mismatch");
+ return false;
+ } else {
+ // ...else the device is supposedly not encrypted. HOWEVER, the
+ // query about the encryption state said that the device *is*
+ // encrypted, so ... we may have a problem. Log it and refuse
+ // the backup.
+ Slog.e(TAG, "verified encryption state mismatch against query; no match allowed");
+ return false;
+ }
+ }
+ } catch (Exception e) {
+ // Something went wrong talking to the mount service. This is very bad;
+ // assume that we fail password validation.
+ return false;
+ }
+
if (mPasswordHash == null) {
// no current password case -- require that 'currentPw' be null or empty
if (candidatePw == null || "".equals(candidatePw)) {
@@ -1114,7 +1151,15 @@
public boolean hasBackupPassword() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"hasBackupPassword");
- return (mPasswordHash != null && mPasswordHash.length() > 0);
+
+ try {
+ return (mMountService.getEncryptionState() != IMountService.ENCRYPTION_STATE_NONE)
+ || (mPasswordHash != null && mPasswordHash.length() > 0);
+ } catch (Exception e) {
+ // If we can't talk to the mount service we have a serious problem; fail
+ // "secure" i.e. assuming that we require a password
+ return true;
+ }
}
// Maintain persistent state around whether need to do an initialize operation.
@@ -1966,6 +2011,9 @@
synchronized (mQueueLock) {
mBackupRunning = false;
if (mStatus == BackupConstants.TRANSPORT_NOT_INITIALIZED) {
+ // Make sure we back up everything and perform the one-time init
+ clearMetadata();
+ if (DEBUG) Slog.d(TAG, "Server requires init; rerunning");
backupNow();
}
}
@@ -1975,6 +2023,12 @@
mWakelock.release();
}
+ // Remove the PM metadata state. This will generate an init on the next pass.
+ void clearMetadata() {
+ final File pmState = new File(mStateDir, PACKAGE_MANAGER_SENTINEL);
+ if (pmState.exists()) pmState.delete();
+ }
+
// Invoke an agent's doBackup() and start a timeout message spinning on the main
// handler in case it doesn't get back to us.
int invokeAgentForBackup(String packageName, IBackupAgent agent,
@@ -4998,7 +5052,17 @@
params.observer = observer;
params.curPassword = curPassword;
- params.encryptPassword = encPpassword;
+
+ boolean isEncrypted;
+ try {
+ isEncrypted = (mMountService.getEncryptionState() != MountService.ENCRYPTION_STATE_NONE);
+ if (isEncrypted) Slog.w(TAG, "Device is encrypted; forcing enc password");
+ } catch (RemoteException e) {
+ // couldn't contact the mount service; fail "safe" and assume encryption
+ Slog.e(TAG, "Unable to contact mount service!");
+ isEncrypted = true;
+ }
+ params.encryptPassword = (isEncrypted) ? curPassword : encPpassword;
if (DEBUG) Slog.d(TAG, "Sending conf message with verb " + verb);
mWakelock.acquire();
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 582f0ed..5425813 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1897,6 +1897,53 @@
}
}
+ /**
+ * Validate a user-supplied password string with cryptfs
+ */
+ @Override
+ public int verifyEncryptionPassword(String password) throws RemoteException {
+ // Only the system process is permitted to validate passwords
+ if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
+ throw new SecurityException("no permission to access the crypt keeper");
+ }
+
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
+ "no permission to access the crypt keeper");
+
+ if (TextUtils.isEmpty(password)) {
+ throw new IllegalArgumentException("password cannot be empty");
+ }
+
+ waitForReady();
+
+ if (DEBUG_EVENTS) {
+ Slog.i(TAG, "validating encryption password...");
+ }
+
+ try {
+ ArrayList<String> response = mConnector.doCommand("cryptfs verifypw " + password);
+ String[] tokens = response.get(0).split(" ");
+
+ if (tokens == null || tokens.length != 2) {
+ String msg = "Unexpected result from cryptfs verifypw: {";
+ if (tokens == null) msg += "null";
+ else for (int i = 0; i < tokens.length; i++) {
+ if (i != 0) msg += ',';
+ msg += tokens[i];
+ }
+ msg += '}';
+ Slog.e(TAG, msg);
+ return -1;
+ }
+
+ Slog.i(TAG, "cryptfs verifypw => " + tokens[1]);
+ return Integer.parseInt(tokens[1]);
+ } catch (NativeDaemonConnectorException e) {
+ // Encryption failed
+ return e.getCode();
+ }
+ }
+
public Parcelable[] getVolumeList() {
synchronized(mVolumes) {
int size = mVolumes.size();
diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java
index 43d938c..28013bd 100644
--- a/services/java/com/android/server/NativeDaemonConnector.java
+++ b/services/java/com/android/server/NativeDaemonConnector.java
@@ -207,6 +207,13 @@
*/
private void sendCommandLocked(String command, String argument)
throws NativeDaemonConnectorException {
+ if (command != null && command.indexOf('\0') >= 0) {
+ throw new IllegalArgumentException("unexpected command: " + command);
+ }
+ if (argument != null && argument.indexOf('\0') >= 0) {
+ throw new IllegalArgumentException("unexpected argument: " + argument);
+ }
+
if (LOCAL_LOGD) Slog.d(TAG, String.format("SND -> {%s} {%s}", command, argument));
if (mOutputStream == null) {
Slog.e(TAG, "No connection to daemon", new IllegalStateException());
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index b05705e..4e4fe4a 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -16,6 +16,8 @@
package com.android.server;
+import static android.Manifest.permission.ACCESS_NETWORK_STATE;
+import static android.Manifest.permission.CHANGE_NETWORK_STATE;
import static android.Manifest.permission.DUMP;
import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
import static android.net.NetworkStats.SET_DEFAULT;
@@ -238,6 +240,11 @@
* Notify our observers of an interface removal.
*/
private void notifyInterfaceRemoved(String iface) {
+ // netd already clears out quota and alerts for removed ifaces; update
+ // our sanity-checking state.
+ mActiveAlertIfaces.remove(iface);
+ mActiveQuotaIfaces.remove(iface);
+
for (INetworkManagementEventObserver obs : mObservers) {
try {
obs.interfaceRemoved(iface);
@@ -350,6 +357,7 @@
}
public InterfaceConfiguration getInterfaceConfig(String iface) throws IllegalStateException {
+ mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
String rsp;
try {
rsp = mConnector.doCommand("interface getcfg " + iface).get(0);
@@ -404,6 +412,7 @@
public void setInterfaceConfig(
String iface, InterfaceConfiguration cfg) throws IllegalStateException {
+ mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
LinkAddress linkAddr = cfg.addr;
if (linkAddr == null || linkAddr.getAddress() == null) {
throw new IllegalStateException("Null LinkAddress given");
@@ -421,6 +430,7 @@
}
public void setInterfaceDown(String iface) throws IllegalStateException {
+ mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
try {
InterfaceConfiguration ifcg = getInterfaceConfig(iface);
ifcg.interfaceFlags = ifcg.interfaceFlags.replace("up", "down");
@@ -432,6 +442,7 @@
}
public void setInterfaceUp(String iface) throws IllegalStateException {
+ mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
try {
InterfaceConfiguration ifcg = getInterfaceConfig(iface);
ifcg.interfaceFlags = ifcg.interfaceFlags.replace("down", "up");
@@ -444,6 +455,7 @@
public void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable)
throws IllegalStateException {
+ mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
String cmd = String.format("interface ipv6privacyextensions %s %s", iface,
enable ? "enable" : "disable");
try {
@@ -459,7 +471,8 @@
/* TODO: This is right now a IPv4 only function. Works for wifi which loses its
IPv6 addresses on interface down, but we need to do full clean up here */
public void clearInterfaceAddresses(String iface) throws IllegalStateException {
- String cmd = String.format("interface clearaddrs %s", iface);
+ mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
+ String cmd = String.format("interface clearaddrs %s", iface);
try {
mConnector.doCommand(cmd);
} catch (NativeDaemonConnectorException e) {
@@ -491,10 +504,12 @@
}
public void addRoute(String interfaceName, RouteInfo route) {
+ mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
modifyRoute(interfaceName, ADD, route);
}
public void removeRoute(String interfaceName, RouteInfo route) {
+ mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
modifyRoute(interfaceName, REMOVE, route);
}
@@ -578,6 +593,7 @@
}
public RouteInfo[] getRoutes(String interfaceName) {
+ mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
ArrayList<RouteInfo> routes = new ArrayList<RouteInfo>();
// v4 routes listed as:
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 78dbbd6..994201b 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -1677,6 +1677,18 @@
e.fillInStackTrace();
Slog.i(TAG, "Set screen state: " + on, e);
}
+ if (on) {
+ if ((mPowerState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
+ // If we are turning the screen state on, but the screen
+ // light is currently off, then make sure that we set the
+ // light at this point to 0. This is the case where we are
+ // turning on the screen and waiting for the UI to be drawn
+ // before showing it to the user. We want the light off
+ // until it is ready to be shown to the user, not it using
+ // whatever the last value it had.
+ mScreenBrightness.forceValueLocked(Power.BRIGHTNESS_OFF);
+ }
+ }
int err = Power.setScreenState(on);
if (err == 0) {
mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0);
@@ -1686,11 +1698,6 @@
// make sure button and key backlights are off too
mButtonLight.turnOff();
mKeyboardLight.turnOff();
- // clear current value so we will update based on the new conditions
- // when the sensor is reenabled.
- mLightSensorValue = -1;
- // reset our highest light sensor value when the screen turns off
- mHighestLightSensorValue = -1;
}
}
}
@@ -2029,8 +2036,6 @@
RuntimeException e = new RuntimeException("here");
e.fillInStackTrace();
Slog.i(TAG, "Setting screen brightness: " + brightness, e);
- mScreenBrightness.setTargetLocked(brightness, steps,
- INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue);
}
}
@@ -2103,6 +2108,15 @@
+ " delta=" + delta);
}
+ void forceValueLocked(int value) {
+ targetValue = -1;
+ curValue = value;
+ setLightBrightness(mask, value);
+ if (animating) {
+ finishAnimationLocked(false, value);
+ }
+ }
+
void setTargetLocked(int target, int stepsToTarget, int initialValue,
int nominalCurrentValue) {
if (!initialized) {
@@ -2453,6 +2467,7 @@
synchronized (mLocks) {
mIsDocked = (state != Intent.EXTRA_DOCK_STATE_UNDOCKED);
if (mIsDocked) {
+ // allow brightness to decrease when docked
mHighestLightSensorValue = -1;
}
if ((mPowerState & SCREEN_ON_BIT) != 0) {
@@ -3028,11 +3043,21 @@
long identity = Binder.clearCallingIdentity();
try {
if (enable) {
+ // reset our highest value when reenabling
+ mHighestLightSensorValue = -1;
+ // force recompute of backlight values
+ if (mLightSensorValue >= 0) {
+ int value = (int)mLightSensorValue;
+ mLightSensorValue = -1;
+ handleLightSensorValue(value);
+ }
mSensorManager.registerListener(mLightListener, mLightSensor,
SensorManager.SENSOR_DELAY_NORMAL);
} else {
mSensorManager.unregisterListener(mLightListener);
mHandler.removeCallbacks(mAutoBrightnessTask);
+ mLightSensorPendingDecrease = false;
+ mLightSensorPendingIncrease = false;
}
} finally {
Binder.restoreCallingIdentity(identity);
@@ -3084,43 +3109,45 @@
}
};
+ private void handleLightSensorValue(int value) {
+ long milliseconds = SystemClock.elapsedRealtime();
+ if (mLightSensorValue == -1 ||
+ milliseconds < mLastScreenOnTime + mLightSensorWarmupTime) {
+ // process the value immediately if screen has just turned on
+ mHandler.removeCallbacks(mAutoBrightnessTask);
+ mLightSensorPendingDecrease = false;
+ mLightSensorPendingIncrease = false;
+ lightSensorChangedLocked(value);
+ } else {
+ if ((value > mLightSensorValue && mLightSensorPendingDecrease) ||
+ (value < mLightSensorValue && mLightSensorPendingIncrease) ||
+ (value == mLightSensorValue) ||
+ (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) {
+ // delay processing to debounce the sensor
+ mHandler.removeCallbacks(mAutoBrightnessTask);
+ mLightSensorPendingDecrease = (value < mLightSensorValue);
+ mLightSensorPendingIncrease = (value > mLightSensorValue);
+ if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
+ mLightSensorPendingValue = value;
+ mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY);
+ }
+ } else {
+ mLightSensorPendingValue = value;
+ }
+ }
+ }
+
SensorEventListener mLightListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent event) {
+ if (mDebugLightSensor) {
+ Slog.d(TAG, "onSensorChanged: light value: " + event.values[0]);
+ }
synchronized (mLocks) {
// ignore light sensor while screen is turning off
if (isScreenTurningOffLocked()) {
return;
}
-
- int value = (int)event.values[0];
- long milliseconds = SystemClock.elapsedRealtime();
- if (mDebugLightSensor) {
- Slog.d(TAG, "onSensorChanged: light value: " + value);
- }
- if (mLightSensorValue == -1 ||
- milliseconds < mLastScreenOnTime + mLightSensorWarmupTime) {
- // process the value immediately if screen has just turned on
- mHandler.removeCallbacks(mAutoBrightnessTask);
- mLightSensorPendingDecrease = false;
- mLightSensorPendingIncrease = false;
- lightSensorChangedLocked(value);
- } else {
- if ((value > mLightSensorValue && mLightSensorPendingDecrease) ||
- (value < mLightSensorValue && mLightSensorPendingIncrease) ||
- (value == mLightSensorValue) ||
- (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) {
- // delay processing to debounce the sensor
- mHandler.removeCallbacks(mAutoBrightnessTask);
- mLightSensorPendingDecrease = (value < mLightSensorValue);
- mLightSensorPendingIncrease = (value > mLightSensorValue);
- if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
- mLightSensorPendingValue = value;
- mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY);
- }
- } else {
- mLightSensorPendingValue = value;
- }
- }
+ handleLightSensorValue((int)event.values[0]);
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 5006de7..3ae62ad 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -163,6 +163,11 @@
pm = PackageManagerService.main(context,
factoryTest != SystemServer.FACTORY_TEST_OFF,
onlyCore);
+ boolean firstBoot = false;
+ try {
+ firstBoot = pm.isFirstBoot();
+ } catch (RemoteException e) {
+ }
ActivityManagerService.setSystemProcess();
@@ -208,7 +213,8 @@
Slog.i(TAG, "Window Manager");
wm = WindowManagerService.main(context, power,
- factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL);
+ factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
+ !firstBoot);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ActivityManagerService.self().setWindowManager(wm);
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index ef48b9e..788ecda 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -43,10 +43,13 @@
import android.view.textservice.SpellCheckerInfo;
import android.view.textservice.SpellCheckerSubtype;
+import java.io.FileDescriptor;
import java.io.IOException;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
public class TextServicesManagerService extends ITextServicesManager.Stub {
private static final String TAG = TextServicesManagerService.class.getSimpleName();
@@ -480,6 +483,66 @@
}
}
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+
+ pw.println("Permission Denial: can't dump TextServicesManagerService from from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid());
+ return;
+ }
+
+ synchronized(mSpellCheckerMap) {
+ pw.println("Current Text Services Manager state:");
+ pw.println(" Spell Checker Map:");
+ for (Map.Entry<String, SpellCheckerInfo> ent : mSpellCheckerMap.entrySet()) {
+ pw.print(" "); pw.print(ent.getKey()); pw.println(":");
+ SpellCheckerInfo info = ent.getValue();
+ pw.print(" "); pw.print("id="); pw.println(info.getId());
+ pw.print(" "); pw.print("comp=");
+ pw.println(info.getComponent().toShortString());
+ int NS = info.getSubtypeCount();
+ for (int i=0; i<NS; i++) {
+ SpellCheckerSubtype st = info.getSubtypeAt(i);
+ pw.print(" "); pw.print("Subtype #"); pw.print(i); pw.println(":");
+ pw.print(" "); pw.print("locale="); pw.println(st.getLocale());
+ pw.print(" "); pw.print("extraValue=");
+ pw.println(st.getExtraValue());
+ }
+ }
+ pw.println("");
+ pw.println(" Spell Checker Bind Groups:");
+ for (Map.Entry<String, SpellCheckerBindGroup> ent
+ : mSpellCheckerBindGroups.entrySet()) {
+ SpellCheckerBindGroup grp = ent.getValue();
+ pw.print(" "); pw.print(ent.getKey()); pw.print(" ");
+ pw.print(grp); pw.println(":");
+ pw.print(" "); pw.print("mInternalConnection=");
+ pw.println(grp.mInternalConnection);
+ pw.print(" "); pw.print("mSpellChecker=");
+ pw.println(grp.mSpellChecker);
+ pw.print(" "); pw.print("mBound="); pw.print(grp.mBound);
+ pw.print(" mConnected="); pw.println(grp.mConnected);
+ int NL = grp.mListeners.size();
+ for (int i=0; i<NL; i++) {
+ InternalDeathRecipient listener = grp.mListeners.get(i);
+ pw.print(" "); pw.print("Listener #"); pw.print(i); pw.println(":");
+ pw.print(" "); pw.print("mTsListener=");
+ pw.println(listener.mTsListener);
+ pw.print(" "); pw.print("mScListener=");
+ pw.println(listener.mScListener);
+ pw.print(" "); pw.print("mGroup=");
+ pw.println(listener.mGroup);
+ pw.print(" "); pw.print("mScLocale=");
+ pw.print(listener.mScLocale);
+ pw.print(" mUid="); pw.println(listener.mUid);
+ }
+ }
+ }
+ }
+
// SpellCheckerBindGroup contains active text service session listeners.
// If there are no listeners anymore, the SpellCheckerBindGroup instance will be removed from
// mSpellCheckerBindGroups
@@ -488,6 +551,7 @@
private final InternalServiceConnection mInternalConnection;
private final ArrayList<InternalDeathRecipient> mListeners =
new ArrayList<InternalDeathRecipient>();
+ public boolean mBound;
public ISpellCheckerService mSpellChecker;
public boolean mConnected;
@@ -495,6 +559,7 @@
ITextServicesSessionListener listener, String locale,
ISpellCheckerSessionListener scListener, int uid, Bundle bundle) {
mInternalConnection = connection;
+ mBound = true;
mConnected = false;
addListener(listener, locale, scListener, uid, bundle);
}
@@ -580,15 +645,18 @@
if (DBG) {
Slog.d(TAG, "cleanLocked");
}
- if (mListeners.isEmpty()) {
+ // If there are no more active listeners, clean up. Only do this
+ // once.
+ if (mBound && mListeners.isEmpty()) {
+ mBound = false;
final String sciId = mInternalConnection.mSciId;
- if (mSpellCheckerBindGroups.containsKey(sciId)) {
+ SpellCheckerBindGroup cur = mSpellCheckerBindGroups.get(sciId);
+ if (cur == this) {
if (DBG) {
Slog.d(TAG, "Remove bind group.");
}
mSpellCheckerBindGroups.remove(sciId);
}
- // Unbind service when there is no active clients.
mContext.unbindService(mInternalConnection);
}
}
@@ -623,7 +691,7 @@
}
ISpellCheckerService spellChecker = ISpellCheckerService.Stub.asInterface(service);
final SpellCheckerBindGroup group = mSpellCheckerBindGroups.get(mSciId);
- if (group != null) {
+ if (this == group.mInternalConnection) {
group.onServiceConnected(spellChecker);
}
}
@@ -631,7 +699,12 @@
@Override
public void onServiceDisconnected(ComponentName name) {
- mSpellCheckerBindGroups.remove(mSciId);
+ synchronized(mSpellCheckerMap) {
+ final SpellCheckerBindGroup group = mSpellCheckerBindGroups.get(mSciId);
+ if (this == group.mInternalConnection) {
+ mSpellCheckerBindGroups.remove(mSciId);
+ }
+ }
}
}
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 660681b..5bfe6f8 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -1402,7 +1402,7 @@
long ident = Binder.clearCallingIdentity();
try {
if (hadLock) {
- noteAcquireWifiLock(wifiLock);
+ noteReleaseWifiLock(wifiLock);
switch(wifiLock.mMode) {
case WifiManager.WIFI_MODE_FULL:
++mFullLocksReleased;
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index 5875ee3..41cf9a6 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -457,6 +457,9 @@
case MotionEvent.ACTION_MOVE: {
final int activePointerCount = mPointerTracker.getActivePointerCount();
switch (activePointerCount) {
+ case 1: {
+ // do nothing
+ } break;
case 2: {
if (isDraggingGesture(event)) {
// If still dragging send a drag event.
@@ -484,10 +487,20 @@
}
} break;
case MotionEvent.ACTION_POINTER_UP: {
- mCurrentState = STATE_TOUCH_EXPLORING;
- // Send an event to the end of the drag gesture.
- sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags);
+ final int activePointerCount = mPointerTracker.getActivePointerCount();
+ switch (activePointerCount) {
+ case 1: {
+ // Send an event to the end of the drag gesture.
+ sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags);
+ } break;
+ default: {
+ mCurrentState = STATE_TOUCH_EXPLORING;
+ }
+ }
} break;
+ case MotionEvent.ACTION_UP: {
+ mCurrentState = STATE_TOUCH_EXPLORING;
+ } break;
case MotionEvent.ACTION_CANCEL: {
clear();
} break;
@@ -500,7 +513,7 @@
* @param event The event to be handled.
* @param policyFlags The policy flags associated with the event.
*/
- public void handleMotionEventStateDelegating(MotionEvent event, int policyFlags) {
+ private void handleMotionEventStateDelegating(MotionEvent event, int policyFlags) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
throw new IllegalStateException("Delegating state can only be reached if "
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d038d76..0d6f405 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -165,7 +165,7 @@
static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
static final boolean DEBUG_USER_LEAVING = localLOGV || false;
static final boolean DEBUG_RESULTS = localLOGV || false;
- static final boolean DEBUG_BACKUP = localLOGV || true;
+ static final boolean DEBUG_BACKUP = localLOGV || false;
static final boolean DEBUG_CONFIGURATION = localLOGV || false;
static final boolean DEBUG_POWER = localLOGV || false;
static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
@@ -2607,9 +2607,18 @@
TAG, "Record #" + i + " " + r + ": app=" + r.app);
if (r.app == app) {
if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
- if (localLOGV) Slog.v(
- TAG, "Removing this entry! frozen=" + r.haveState
- + " finishing=" + r.finishing);
+ if (ActivityStack.DEBUG_ADD_REMOVE) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "Removing activity " + r + " from stack at " + i
+ + ": haveState=" + r.haveState
+ + " stateNotNeeded=" + r.stateNotNeeded
+ + " finishing=" + r.finishing
+ + " state=" + r.state, here);
+ }
+ if (!r.finishing) {
+ Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
+ }
r.makeFinishing();
mMainStack.mHistory.remove(i);
r.takeFromHistory();
@@ -2630,6 +2639,8 @@
r.app = null;
r.nowVisible = false;
if (!r.haveState) {
+ if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
+ "App died, clearing saved state of " + r);
r.icicle = null;
}
}
@@ -3427,8 +3438,10 @@
ac.removePackage(name);
}
}
- mMainStack.resumeTopActivityLocked(null);
- mMainStack.scheduleIdleLocked();
+ if (mBooted) {
+ mMainStack.resumeTopActivityLocked(null);
+ mMainStack.scheduleIdleLocked();
+ }
}
return didSomething;
@@ -4477,7 +4490,7 @@
}
}
if (pi == null) {
- Slog.w(TAG, "No content provider found for: " + name);
+ Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
return -1;
}
@@ -4733,7 +4746,7 @@
}
}
if (pi == null) {
- Slog.w(TAG, "No content provider found for: " + authority);
+ Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
return;
}
@@ -4827,7 +4840,8 @@
}
}
if (pi == null) {
- Slog.w(TAG, "No content provider found for: " + authority);
+ Slog.w(TAG, "No content provider found for permission revoke: "
+ + uri.toSafeString());
return;
}
@@ -13052,11 +13066,13 @@
if (app.foregroundServices) {
// The user is aware of this app, so make it visible.
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
+ app.hidden = false;
app.adjType = "foreground-service";
schedGroup = Process.THREAD_GROUP_DEFAULT;
} else if (app.forcingToForeground != null) {
// The user is aware of this app, so make it visible.
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
+ app.hidden = false;
app.adjType = "force-foreground";
app.adjSource = app.forcingToForeground;
schedGroup = Process.THREAD_GROUP_DEFAULT;
@@ -13067,6 +13083,7 @@
// We don't want to kill the current heavy-weight process.
adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
+ app.hidden = false;
app.adjType = "heavy";
}
@@ -13075,11 +13092,13 @@
// home app, so we don't want to let it go into the background.
adj = ProcessList.HOME_APP_ADJ;
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
+ app.hidden = false;
app.adjType = "home";
}
-
- //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
-
+
+ if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
+ + " reason=" + app.adjType);
+
// By default, we use the computed adjustment. It may be changed if
// there are applications dependent on our services or providers, but
// this gives us a baseline and makes sure we don't get into an
@@ -13106,7 +13125,7 @@
while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
ServiceRecord s = jt.next();
if (s.startRequested) {
- if (app.hasShownUi) {
+ if (app.hasShownUi && app != mHomeProcess) {
// If this process has shown some UI, let it immediately
// go to the LRU list because it may be pretty heavy with
// UI stuff. We'll tag it with a label just to help
@@ -13167,7 +13186,7 @@
if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
// Not doing bind OOM management, so treat
// this guy more like a started service.
- if (app.hasShownUi) {
+ if (app.hasShownUi && app != mHomeProcess) {
// If this process has shown some UI, let it immediately
// go to the LRU list because it may be pretty heavy with
// UI stuff. We'll tag it with a label just to help
@@ -13175,6 +13194,7 @@
if (adj > clientAdj) {
adjType = "bound-bg-ui-services";
}
+ app.hidden = false;
clientAdj = adj;
} else {
if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
@@ -13198,7 +13218,8 @@
// about letting this process get into the LRU
// list to be killed and restarted if needed for
// memory.
- if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
+ if (app.hasShownUi && app != mHomeProcess
+ && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
adjType = "bound-bg-ui-services";
} else {
if ((cr.flags&(Context.BIND_ABOVE_CLIENT
@@ -13292,7 +13313,8 @@
int clientAdj = computeOomAdjLocked(
client, myHiddenAdj, TOP_APP, true);
if (adj > clientAdj) {
- if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
+ if (app.hasShownUi && app != mHomeProcess
+ && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
app.adjType = "bg-ui-provider";
} else {
adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 7bc19ab4..28c3bae 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -87,6 +87,8 @@
static final boolean DEBUG_TASKS = ActivityManagerService.DEBUG_TASKS;
static final boolean DEBUG_STATES = false;
+ static final boolean DEBUG_ADD_REMOVE = false;
+ static final boolean DEBUG_SAVED_STATE = false;
static final boolean VALIDATE_TOKENS = ActivityManagerService.VALIDATE_TOKENS;
@@ -589,8 +591,8 @@
}
}
app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
- System.identityHashCode(r),
- r.info, r.compat, r.icicle, results, newIntents, !andResume,
+ System.identityHashCode(r), r.info, mService.mConfiguration,
+ r.compat, r.icicle, results, newIntents, !andResume,
mService.isNextTransitionForward(), profileFile, profileFd,
profileAutoStop);
@@ -653,6 +655,9 @@
}
completeResumeLocked(r);
checkReadyForSleepLocked();
+ if (DEBUG_SAVED_STATE) Slog.i(TAG, "Launch completed; removing icicle of " + r.icicle);
+ r.icicle = null;
+ r.haveState = false;
} else {
// This activity is not starting in the resumed state... which
// should look like we asked it to pause+stop (but remain visible),
@@ -664,9 +669,6 @@
r.stopped = true;
}
- r.icicle = null;
- r.haveState = false;
-
// Launch the new version setup screen if needed. We do this -after-
// launching the initial activity (that is, home), so that it can have
// a chance to initialize itself while in the background, making the
@@ -936,6 +938,7 @@
final void activityStoppedLocked(ActivityRecord r, Bundle icicle, Bitmap thumbnail,
CharSequence description) {
+ if (DEBUG_SAVED_STATE) Slog.i(TAG, "Saving icicle of " + r + ": " + icicle);
r.icicle = icicle;
r.haveState = true;
r.updateThumbnail(thumbnail, description);
@@ -1544,6 +1547,7 @@
}
// Didn't need to use the icicle, and it is now out of date.
+ if (DEBUG_SAVED_STATE) Slog.i(TAG, "Resumed activity; didn't need icicle of: " + next);
next.icicle = null;
next.haveState = false;
next.stopped = false;
@@ -1590,6 +1594,12 @@
// get started when the user navigates back to it.
addPos = i+1;
if (!startIt) {
+ if (DEBUG_ADD_REMOVE) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "Adding activity " + r + " to stack at " + addPos,
+ here);
+ }
mHistory.add(addPos, r);
r.putInHistory();
mService.mWindowManager.addAppToken(addPos, r, r.task.taskId,
@@ -1622,6 +1632,11 @@
}
// Slot the activity into the history stack and proceed
+ if (DEBUG_ADD_REMOVE) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "Adding activity " + r + " to stack at " + addPos, here);
+ }
mHistory.add(addPos, r);
r.putInHistory();
r.frontOfTask = newTask;
@@ -1818,6 +1833,12 @@
+ " out to target's task " + target.task);
p.setTask(target.task, curThumbHolder, false);
curThumbHolder = p.thumbHolder;
+ if (DEBUG_ADD_REMOVE) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "Removing and adding activity " + p + " to stack at "
+ + dstPos, here);
+ }
mHistory.remove(srcPos);
mHistory.add(dstPos, p);
mService.mWindowManager.moveAppToken(dstPos, p);
@@ -1945,6 +1966,12 @@
} else {
lastReparentPos--;
}
+ if (DEBUG_ADD_REMOVE) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "Removing and adding activity " + p + " to stack at "
+ + lastReparentPos, here);
+ }
mHistory.remove(srcPos);
p.setTask(task, null, false);
mHistory.add(lastReparentPos, p);
@@ -2067,7 +2094,7 @@
* task starting at a specified index.
*/
private final void performClearTaskAtIndexLocked(int taskId, int i) {
- while (i < (mHistory.size()-1)) {
+ while (i < mHistory.size()) {
ActivityRecord r = mHistory.get(i);
if (r.task.taskId != taskId) {
// Whoops hit the end.
@@ -2143,6 +2170,12 @@
ActivityRecord newTop = mHistory.remove(where);
int top = mHistory.size();
ActivityRecord oldTop = mHistory.get(top-1);
+ if (DEBUG_ADD_REMOVE) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "Removing and adding activity " + newTop + " to stack at "
+ + top, here);
+ }
mHistory.add(top, newTop);
oldTop.frontOfTask = false;
newTop.frontOfTask = true;
@@ -2183,7 +2216,7 @@
if (resultTo != null) {
int index = indexOfTokenLocked(resultTo);
if (DEBUG_RESULTS) Slog.v(
- TAG, "Sending result to " + resultTo + " (index " + index + ")");
+ TAG, "Will send result to " + resultTo + " (index " + index + ")");
if (index >= 0) {
sourceRecord = mHistory.get(index);
if (requestCode >= 0 && !sourceRecord.finishing) {
@@ -3279,34 +3312,15 @@
*/
final boolean requestFinishActivityLocked(IBinder token, int resultCode,
Intent resultData, String reason) {
- if (DEBUG_RESULTS) Slog.v(
- TAG, "Finishing activity: token=" + token
- + ", result=" + resultCode + ", data=" + resultData);
-
int index = indexOfTokenLocked(token);
+ if (DEBUG_RESULTS) Slog.v(
+ TAG, "Finishing activity @" + index + ": token=" + token
+ + ", result=" + resultCode + ", data=" + resultData);
if (index < 0) {
return false;
}
ActivityRecord r = mHistory.get(index);
- // Is this the last activity left?
- boolean lastActivity = true;
- for (int i=mHistory.size()-1; i>=0; i--) {
- ActivityRecord p = mHistory.get(i);
- if (!p.finishing && p != r) {
- lastActivity = false;
- break;
- }
- }
-
- // If this is the last activity, but it is the home activity, then
- // just don't finish it.
- if (lastActivity) {
- if (r.intent.hasCategory(Intent.CATEGORY_HOME)) {
- return false;
- }
- }
-
finishActivityLocked(r, index, resultCode, resultData, reason);
return true;
}
@@ -3538,6 +3552,11 @@
private final void removeActivityFromHistoryLocked(ActivityRecord r) {
if (r.state != ActivityState.DESTROYED) {
r.makeFinishing();
+ if (DEBUG_ADD_REMOVE) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "Removing activity " + r + " from stack");
+ }
mHistory.remove(r);
r.takeFromHistory();
if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
@@ -3769,6 +3788,11 @@
TAG, "At " + pos + " ckp " + r.task + ": " + r);
if (r.task.taskId == task) {
if (localLOGV) Slog.v(TAG, "Removing and adding at " + top);
+ if (DEBUG_ADD_REMOVE) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "Removing and adding activity " + r + " to stack at " + top, here);
+ }
mHistory.remove(pos);
mHistory.add(top, r);
moved.add(0, r);
@@ -3858,6 +3882,12 @@
TAG, "At " + pos + " ckp " + r.task + ": " + r);
if (r.task.taskId == task) {
if (localLOGV) Slog.v(TAG, "Removing and adding at " + (N-1));
+ if (DEBUG_ADD_REMOVE) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "Removing and adding activity " + r + " to stack at "
+ + bottom, here);
+ }
mHistory.remove(pos);
mHistory.add(bottom, r);
moved.add(r);
@@ -4035,7 +4065,18 @@
// But then we need to figure out how it needs to deal with that.
Configuration oldConfig = r.configuration;
r.configuration = newConfig;
-
+
+ // Determine what has changed. May be nothing, if this is a config
+ // that has come back from the app after going idle. In that case
+ // we just want to leave the official config object now in the
+ // activity and do nothing else.
+ final int changes = oldConfig.diff(newConfig);
+ if (changes == 0 && !r.forceNewConfig) {
+ if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+ "Configuration no differences in " + r);
+ return true;
+ }
+
// If the activity isn't currently running, just leave the new
// configuration and it will pick that up next time it starts.
if (r.app == null || r.app.thread == null) {
@@ -4046,8 +4087,7 @@
return true;
}
- // Figure out what has changed between the two configurations.
- int changes = oldConfig.diff(newConfig);
+ // Figure out how to handle the changes between the configurations.
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Slog.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
+ Integer.toHexString(changes) + ", handles=0x"
diff --git a/services/java/com/android/server/am/AppErrorDialog.java b/services/java/com/android/server/am/AppErrorDialog.java
index a769c05..57e11cf 100644
--- a/services/java/com/android/server/am/AppErrorDialog.java
+++ b/services/java/com/android/server/am/AppErrorDialog.java
@@ -24,6 +24,7 @@
import android.os.Handler;
import android.os.Message;
import android.util.Slog;
+import android.view.WindowManager;
class AppErrorDialog extends BaseErrorDialog {
private final static String TAG = "AppErrorDialog";
@@ -73,6 +74,9 @@
setTitle(res.getText(com.android.internal.R.string.aerr_title));
getWindow().addFlags(FLAG_SYSTEM_ERROR);
getWindow().setTitle("Application Error: " + app.info.processName);
+ if (app.persistent) {
+ getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+ }
// After the timeout, pretend the user clicked the quit button
mHandler.sendMessageDelayed(
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 0da5cc6..e610782 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -85,7 +85,6 @@
import android.net.NetworkPolicy;
import android.net.NetworkQuotaInfo;
import android.net.NetworkState;
-import android.net.NetworkStats;
import android.net.NetworkTemplate;
import android.os.Binder;
import android.os.Environment;
@@ -489,7 +488,7 @@
final long end = currentTime;
final long totalBytes = getTotalBytes(policy.template, start, end);
- if (policy.limitBytes != LIMIT_DISABLED && totalBytes >= policy.limitBytes) {
+ if (policy.isOverLimit(totalBytes)) {
if (policy.lastSnooze >= start) {
enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes);
} else {
@@ -574,7 +573,7 @@
final CharSequence title = res.getText(R.string.data_usage_warning_title);
final CharSequence body = res.getString(R.string.data_usage_warning_body);
- builder.setSmallIcon(R.drawable.ic_menu_info_details);
+ builder.setSmallIcon(R.drawable.stat_notify_error);
builder.setTicker(title);
builder.setContentTitle(title);
builder.setContentText(body);
@@ -606,7 +605,7 @@
break;
}
- builder.setSmallIcon(com.android.internal.R.drawable.ic_menu_block);
+ builder.setSmallIcon(R.drawable.stat_notify_disabled);
builder.setTicker(title);
builder.setContentTitle(title);
builder.setContentText(body);
@@ -640,7 +639,7 @@
break;
}
- builder.setSmallIcon(R.drawable.ic_menu_info_details);
+ builder.setSmallIcon(R.drawable.stat_notify_error);
builder.setTicker(title);
builder.setContentTitle(title);
builder.setContentText(body);
@@ -677,7 +676,7 @@
builder.setOnlyAlertOnce(true);
builder.setOngoing(true);
- builder.setSmallIcon(R.drawable.ic_menu_info_details);
+ builder.setSmallIcon(R.drawable.stat_notify_error);
builder.setTicker(title);
builder.setContentTitle(title);
builder.setContentText(body);
@@ -750,8 +749,7 @@
final long totalBytes = getTotalBytes(policy.template, start, end);
// disable data connection when over limit and not snoozed
- final boolean overLimit = policy.limitBytes != LIMIT_DISABLED
- && totalBytes > policy.limitBytes && policy.lastSnooze < start;
+ final boolean overLimit = policy.isOverLimit(totalBytes) && policy.lastSnooze < start;
final boolean enabled = !overLimit;
setNetworkTemplateEnabled(policy.template, enabled);
@@ -1535,10 +1533,7 @@
private long getTotalBytes(NetworkTemplate template, long start, long end) {
try {
- final NetworkStats stats = mNetworkStats.getSummaryForNetwork(
- template, start, end);
- final NetworkStats.Entry entry = stats.getValues(0, null);
- return entry.rxBytes + entry.txBytes;
+ return mNetworkStats.getSummaryForNetwork(template, start, end).getTotalBytes();
} catch (RemoteException e) {
// ignored; service lives in system_server
return 0;
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 19dd606..0e9f64c 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1157,6 +1157,10 @@
} // synchronized (mInstallLock)
}
+ public boolean isFirstBoot() {
+ return !mRestoredSettings;
+ }
+
private String getRequiredVerifierLPr() {
final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
@@ -2983,12 +2987,14 @@
}
if (pkgs != null) {
for (int i=0; i<pkgs.size(); i++) {
- try {
- ActivityManagerNative.getDefault().showBootMessage(
- mContext.getResources().getString(
- com.android.internal.R.string.android_upgrading_apk,
- i+1, pkgs.size()), true);
- } catch (RemoteException e) {
+ if (!isFirstBoot()) {
+ try {
+ ActivityManagerNative.getDefault().showBootMessage(
+ mContext.getResources().getString(
+ com.android.internal.R.string.android_upgrading_apk,
+ i+1, pkgs.size()), true);
+ } catch (RemoteException e) {
+ }
}
PackageParser.Package p = pkgs.get(i);
synchronized (mInstallLock) {
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 7cdb5b1..bfe6613 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -1238,9 +1238,8 @@
mReadMessages.append("No start tag found in settings file\n");
PackageManagerService.reportSettingsProblem(Log.WARN,
"No start tag found in package manager settings");
- Log
- .wtf(PackageManagerService.TAG,
- "No start tag found in package manager settings");
+ Log.wtf(PackageManagerService.TAG,
+ "No start tag found in package manager settings");
return false;
}
diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java
index 25cc259..73cd64e 100644
--- a/services/java/com/android/server/wm/DragState.java
+++ b/services/java/com/android/server/wm/DragState.java
@@ -274,7 +274,8 @@
final int myPid = Process.myPid();
// Move the surface to the given touch
- if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION notifyMoveLw");
+ if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(
+ WindowManagerService.TAG, ">>> OPEN TRANSACTION notifyMoveLw");
Surface.openTransaction();
try {
mSurface.setPosition(x - mThumbOffsetX, y - mThumbOffsetY);
@@ -283,7 +284,8 @@
(int)(x - mThumbOffsetX) + "," + (int)(y - mThumbOffsetY) + ")");
} finally {
Surface.closeTransaction();
- if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION notifyMoveLw");
+ if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(
+ WindowManagerService.TAG, "<<< CLOSE TRANSACTION notifyMoveLw");
}
// Tell the affected window
diff --git a/services/java/com/android/server/wm/InputManager.java b/services/java/com/android/server/wm/InputManager.java
index 60333a3..df7e0e1 100644
--- a/services/java/com/android/server/wm/InputManager.java
+++ b/services/java/com/android/server/wm/InputManager.java
@@ -575,7 +575,7 @@
}
@SuppressWarnings("unused")
- public boolean interceptKeyBeforeDispatching(InputWindowHandle focus,
+ public long interceptKeyBeforeDispatching(InputWindowHandle focus,
KeyEvent event, int policyFlags) {
return mWindowManagerService.mInputMonitor.interceptKeyBeforeDispatching(
focus, event, policyFlags);
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index 9a559e0..fb74d27 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -288,7 +288,7 @@
/* Provides an opportunity for the window manager policy to process a key before
* ordinary dispatch. */
- public boolean interceptKeyBeforeDispatching(
+ public long interceptKeyBeforeDispatching(
InputWindowHandle focus, KeyEvent event, int policyFlags) {
WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
return mService.mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);
diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java
index e25638f..131f11c 100644
--- a/services/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -64,24 +64,23 @@
boolean inTransaction, int originalWidth, int originalHeight, int originalRotation) {
mContext = context;
- Bitmap screenshot = Surface.screenshot(0, 0);
-
- if (screenshot == null) {
- // Device is not capable of screenshots... we can't do an animation.
- return;
- }
-
// Screenshot does NOT include rotation!
mSnapshotRotation = 0;
- mWidth = screenshot.getWidth();
- mHeight = screenshot.getHeight();
+ if (originalRotation == Surface.ROTATION_90
+ || originalRotation == Surface.ROTATION_270) {
+ mWidth = originalHeight;
+ mHeight = originalWidth;
+ } else {
+ mWidth = originalWidth;
+ mHeight = originalHeight;
+ }
mOriginalRotation = originalRotation;
mOriginalWidth = originalWidth;
mOriginalHeight = originalHeight;
if (!inTransaction) {
- if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
+ if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
">>> OPEN TRANSACTION ScreenRotationAnimation");
Surface.openTransaction();
}
@@ -89,7 +88,12 @@
try {
try {
mSurface = new Surface(session, 0, "FreezeSurface",
- -1, mWidth, mHeight, PixelFormat.OPAQUE, 0);
+ -1, mWidth, mHeight, PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT);
+ if (mSurface == null || !mSurface.isValid()) {
+ // Screenshot failed, punt.
+ mSurface = null;
+ return;
+ }
mSurface.setLayer(FREEZE_LAYER + 1);
} catch (Surface.OutOfResourcesException e) {
Slog.w(TAG, "Unable to allocate freeze surface", e);
@@ -100,38 +104,12 @@
" FREEZE " + mSurface + ": CREATE");
setRotation(originalRotation);
-
- if (mSurface != null) {
- Rect dirty = new Rect(0, 0, mWidth, mHeight);
- Canvas c = null;
- try {
- c = mSurface.lockCanvas(dirty);
- } catch (IllegalArgumentException e) {
- Slog.w(TAG, "Unable to lock surface", e);
- } catch (Surface.OutOfResourcesException e) {
- Slog.w(TAG, "Unable to lock surface", e);
- }
- if (c == null) {
- Slog.w(TAG, "Null surface canvas");
- mSurface.destroy();
- mSurface = null;
- return;
- }
-
- Paint paint = new Paint(0);
- paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
- c.drawBitmap(screenshot, 0, 0, paint);
-
- mSurface.unlockCanvasAndPost(c);
- }
} finally {
if (!inTransaction) {
Surface.closeTransaction();
- if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
+ if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
"<<< CLOSE TRANSACTION ScreenRotationAnimation");
}
-
- screenshot.recycle();
}
}
@@ -254,7 +232,7 @@
mEnterAnimation.restrictDuration(maxAnimationDuration);
mEnterAnimation.scaleCurrentDuration(animationScale);
- if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
+ if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
">>> OPEN TRANSACTION ScreenRotationAnimation.dismiss");
Surface.openTransaction();
@@ -266,7 +244,7 @@
Slog.w(TAG, "Unable to allocate black surface", e);
} finally {
Surface.closeTransaction();
- if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
+ if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
"<<< CLOSE TRANSACTION ScreenRotationAnimation.dismiss");
}
diff --git a/services/java/com/android/server/wm/Session.java b/services/java/com/android/server/wm/Session.java
index 10882f9..03b7546 100644
--- a/services/java/com/android/server/wm/Session.java
+++ b/services/java/com/android/server/wm/Session.java
@@ -278,7 +278,8 @@
// Make the surface visible at the proper location
final Surface surface = mService.mDragState.mSurface;
- if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION performDrag");
+ if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(
+ WindowManagerService.TAG, ">>> OPEN TRANSACTION performDrag");
Surface.openTransaction();
try {
surface.setPosition(touchX - thumbCenterX,
@@ -288,7 +289,8 @@
surface.show();
} finally {
Surface.closeTransaction();
- if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION performDrag");
+ if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(
+ WindowManagerService.TAG, "<<< CLOSE TRANSACTION performDrag");
}
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 73a9601..68f0e66 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -167,8 +167,10 @@
static final boolean DEBUG_DRAG = false;
static final boolean DEBUG_SCREEN_ON = false;
static final boolean DEBUG_SCREENSHOT = false;
+ static final boolean DEBUG_BOOT = false;
static final boolean SHOW_SURFACE_ALLOC = false;
static final boolean SHOW_TRANSACTIONS = false;
+ static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
static final boolean HIDE_STACK_CRAWLS = true;
static final boolean PROFILE_ORIENTATION = false;
@@ -297,6 +299,8 @@
final boolean mHaveInputMethods;
+ final boolean mAllowBootMessages;
+
final boolean mLimitedAlphaCompositing;
final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
@@ -633,8 +637,8 @@
float mCompatibleScreenScale;
public static WindowManagerService main(Context context,
- PowerManagerService pm, boolean haveInputMethods) {
- WMThread thr = new WMThread(context, pm, haveInputMethods);
+ PowerManagerService pm, boolean haveInputMethods, boolean allowBootMsgs) {
+ WMThread thr = new WMThread(context, pm, haveInputMethods, allowBootMsgs);
thr.start();
synchronized (thr) {
@@ -654,19 +658,21 @@
private final Context mContext;
private final PowerManagerService mPM;
private final boolean mHaveInputMethods;
+ private final boolean mAllowBootMessages;
public WMThread(Context context, PowerManagerService pm,
- boolean haveInputMethods) {
+ boolean haveInputMethods, boolean allowBootMsgs) {
super("WindowManager");
mContext = context;
mPM = pm;
mHaveInputMethods = haveInputMethods;
+ mAllowBootMessages = allowBootMsgs;
}
public void run() {
Looper.prepare();
WindowManagerService s = new WindowManagerService(mContext, mPM,
- mHaveInputMethods);
+ mHaveInputMethods, mAllowBootMessages);
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_DISPLAY);
android.os.Process.setCanSelfBackground(false);
@@ -728,9 +734,10 @@
}
private WindowManagerService(Context context, PowerManagerService pm,
- boolean haveInputMethods) {
+ boolean haveInputMethods, boolean showBootMsgs) {
mContext = context;
mHaveInputMethods = haveInputMethods;
+ mAllowBootMessages = showBootMsgs;
mLimitedAlphaCompositing = context.getResources().getBoolean(
com.android.internal.R.bool.config_sf_limitedAlpha);
@@ -2364,7 +2371,7 @@
synchronized (mWindowMap) {
WindowState w = windowForClientLocked(session, client, false);
if ((w != null) && (w.mSurface != null)) {
- if (SHOW_TRANSACTIONS) Slog.i(TAG,
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
">>> OPEN TRANSACTION setTransparentRegion");
Surface.openTransaction();
try {
@@ -2373,7 +2380,7 @@
w.mSurface.setTransparentRegionHint(region);
} finally {
Surface.closeTransaction();
- if (SHOW_TRANSACTIONS) Slog.i(TAG,
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
"<<< CLOSE TRANSACTION setTransparentRegion");
}
}
@@ -4722,6 +4729,14 @@
public void enableScreenAfterBoot() {
synchronized(mWindowMap) {
+ if (DEBUG_BOOT) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
+ + " mForceDisplayEnabled=" + mForceDisplayEnabled
+ + " mShowingBootMessages=" + mShowingBootMessages
+ + " mSystemBooted=" + mSystemBooted, here);
+ }
if (mSystemBooted) {
return;
}
@@ -4739,6 +4754,14 @@
}
void enableScreenIfNeededLocked() {
+ if (DEBUG_BOOT) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
+ + " mForceDisplayEnabled=" + mForceDisplayEnabled
+ + " mShowingBootMessages=" + mShowingBootMessages
+ + " mSystemBooted=" + mSystemBooted, here);
+ }
if (mDisplayEnabled) {
return;
}
@@ -4761,6 +4784,14 @@
public void performEnableScreen() {
synchronized(mWindowMap) {
+ if (DEBUG_BOOT) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
+ + " mForceDisplayEnabled=" + mForceDisplayEnabled
+ + " mShowingBootMessages=" + mShowingBootMessages
+ + " mSystemBooted=" + mSystemBooted, here);
+ }
if (mDisplayEnabled) {
return;
}
@@ -4774,10 +4805,22 @@
boolean haveBootMsg = false;
boolean haveApp = false;
boolean haveWallpaper = false;
- boolean haveKeyguard = false;
+ boolean haveKeyguard = true;
final int N = mWindows.size();
for (int i=0; i<N; i++) {
WindowState w = mWindows.get(i);
+ if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD) {
+ // Only if there is a keyguard attached to the window manager
+ // will we consider ourselves as having a keyguard. If it
+ // isn't attached, we don't know if it wants to be shown or
+ // hidden. If it is attached, we will say we have a keyguard
+ // if the window doesn't want to be visible, because in that
+ // case it explicitly doesn't want to be shown so we should
+ // not delay turning the screen on for it.
+ boolean vis = w.mViewVisibility == View.VISIBLE
+ && w.mPolicyVisibility;
+ haveKeyguard = !vis;
+ }
if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
return;
}
@@ -4794,7 +4837,7 @@
}
}
- if (DEBUG_SCREEN_ON) {
+ if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
+ " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
+ " haveWall=" + haveWallpaper + " haveKeyguard=" + haveKeyguard);
@@ -4815,7 +4858,7 @@
}
mDisplayEnabled = true;
- if (DEBUG_SCREEN_ON) Slog.i(TAG, "******************** ENABLING SCREEN!");
+ if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
if (false) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
@@ -4846,6 +4889,17 @@
public void showBootMessage(final CharSequence msg, final boolean always) {
boolean first = false;
synchronized(mWindowMap) {
+ if (DEBUG_BOOT) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
+ + " mAllowBootMessages=" + mAllowBootMessages
+ + " mShowingBootMessages=" + mShowingBootMessages
+ + " mSystemBooted=" + mSystemBooted, here);
+ }
+ if (!mAllowBootMessages) {
+ return;
+ }
if (!mShowingBootMessages) {
if (!always) {
return;
@@ -4864,6 +4918,14 @@
}
public void hideBootMessagesLocked() {
+ if (DEBUG_BOOT) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
+ + " mForceDisplayEnabled=" + mForceDisplayEnabled
+ + " mShowingBootMessages=" + mShowingBootMessages
+ + " mSystemBooted=" + mSystemBooted, here);
+ }
if (mShowingBootMessages) {
mShowingBootMessages = false;
mPolicy.hideBootMessages();
@@ -4897,7 +4959,8 @@
}
}
- if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION showStrictModeViolation");
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+ ">>> OPEN TRANSACTION showStrictModeViolation");
Surface.openTransaction();
try {
if (mStrictModeFlash == null) {
@@ -4906,7 +4969,8 @@
mStrictModeFlash.setVisibility(on);
} finally {
Surface.closeTransaction();
- if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION showStrictModeViolation");
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+ "<<< CLOSE TRANSACTION showStrictModeViolation");
}
}
}
@@ -5222,32 +5286,27 @@
startFreezingDisplayLocked(inTransaction);
mInputManager.setDisplayOrientation(0, rotation);
- // NOTE: We disable the rotation in the emulator because
- // it doesn't support hardware OpenGL emulation yet.
- if (CUSTOM_SCREEN_ROTATION && mScreenRotationAnimation != null
- && mScreenRotationAnimation.hasScreenshot()) {
- Surface.freezeDisplay(0);
- if (!inTransaction) {
- if (SHOW_TRANSACTIONS) Slog.i(TAG,
- ">>> OPEN TRANSACTION setRotationUnchecked");
- Surface.openTransaction();
- }
- try {
- if (mScreenRotationAnimation != null) {
- mScreenRotationAnimation.setRotation(rotation);
- }
- } finally {
- if (!inTransaction) {
- Surface.closeTransaction();
- if (SHOW_TRANSACTIONS) Slog.i(TAG,
- "<<< CLOSE TRANSACTION setRotationUnchecked");
- }
- }
- Surface.setOrientation(0, rotation);
- Surface.unfreezeDisplay(0);
- } else {
- Surface.setOrientation(0, rotation);
+ if (!inTransaction) {
+ if (SHOW_TRANSACTIONS) Slog.i(TAG,
+ ">>> OPEN TRANSACTION setRotationUnchecked");
+ Surface.openTransaction();
}
+ try {
+ // NOTE: We disable the rotation in the emulator because
+ // it doesn't support hardware OpenGL emulation yet.
+ if (CUSTOM_SCREEN_ROTATION && mScreenRotationAnimation != null
+ && mScreenRotationAnimation.hasScreenshot()) {
+ mScreenRotationAnimation.setRotation(rotation);
+ }
+ Surface.setOrientation(0, rotation);
+ } finally {
+ if (!inTransaction) {
+ Surface.closeTransaction();
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+ "<<< CLOSE TRANSACTION setRotationUnchecked");
+ }
+ }
+
rebuildBlackFrame(inTransaction);
for (int i=mWindows.size()-1; i>=0; i--) {
@@ -5840,6 +5899,10 @@
final DisplayMetrics dm = mDisplayMetrics;
mAppDisplayWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
mAppDisplayHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
+ if (false) {
+ Slog.i(TAG, "Set app display size: " + mAppDisplayWidth
+ + " x " + mAppDisplayHeight);
+ }
mDisplay.getMetricsWithSize(dm, mAppDisplayWidth, mAppDisplayHeight);
mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,
@@ -5857,8 +5920,8 @@
// Compute the screen layout size class.
int screenLayout;
- int longSize = dw;
- int shortSize = dh;
+ int longSize = mAppDisplayWidth;
+ int shortSize = mAppDisplayHeight;
if (longSize < shortSize) {
int tmp = longSize;
longSize = shortSize;
@@ -6844,7 +6907,7 @@
private void rebuildBlackFrame(boolean inTransaction) {
if (!inTransaction) {
- if (SHOW_TRANSACTIONS) Slog.i(TAG,
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
">>> OPEN TRANSACTION rebuildBlackFrame");
Surface.openTransaction();
}
@@ -6879,7 +6942,7 @@
} finally {
if (!inTransaction) {
Surface.closeTransaction();
- if (SHOW_TRANSACTIONS) Slog.i(TAG,
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
"<<< CLOSE TRANSACTION rebuildBlackFrame");
}
}
@@ -7351,7 +7414,8 @@
createWatermark = true;
}
- if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+ ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
Surface.openTransaction();
@@ -8460,7 +8524,8 @@
Surface.closeTransaction();
- if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+ "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
if (mWatermark != null) {
mWatermark.drawIfNeeded();
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 47f74fb..eeffb02 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -57,6 +57,7 @@
final class WindowState implements WindowManagerPolicy.WindowState {
static final boolean DEBUG_VISIBILITY = WindowManagerService.DEBUG_VISIBILITY;
static final boolean SHOW_TRANSACTIONS = WindowManagerService.SHOW_TRANSACTIONS;
+ static final boolean SHOW_LIGHT_TRANSACTIONS = WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
static final boolean SHOW_SURFACE_ALLOC = WindowManagerService.SHOW_SURFACE_ALLOC;
final WindowManagerService mService;
@@ -671,7 +672,7 @@
WindowManagerService.TAG, "Got surface: " + mSurface
+ ", set left=" + mFrame.left + " top=" + mFrame.top
+ ", animLayer=" + mAnimLayer);
- if (SHOW_TRANSACTIONS) {
+ if (SHOW_LIGHT_TRANSACTIONS) {
Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
WindowManagerService.logSurface(this, "CREATE pos=(" + mFrame.left
+ "," + mFrame.top + ") (" +
@@ -700,7 +701,8 @@
mLastHidden = true;
} finally {
Surface.closeTransaction();
- if (SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION createSurfaceLocked");
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
+ "<<< CLOSE TRANSACTION createSurfaceLocked");
}
if (WindowManagerService.localLOGV) Slog.v(
WindowManagerService.TAG, "Created surface " + this);
@@ -1118,7 +1120,11 @@
// window's center).
final float w = frame.width();
final float h = frame.height();
- tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
+ if (w>=1 && h>=1) {
+ tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
+ } else {
+ tmpMatrix.reset();
+ }
} else {
tmpMatrix.reset();
}
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index f976301..7e9fba8 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -149,6 +149,12 @@
}
}
+enum {
+ WM_ACTION_PASS_TO_USER = 1,
+ WM_ACTION_POKE_USER_ACTIVITY = 2,
+ WM_ACTION_GO_TO_SLEEP = 4,
+};
+
// --- NativeInputManager ---
@@ -199,7 +205,8 @@
virtual bool isKeyRepeatEnabled();
virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
- virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
+ virtual nsecs_t interceptKeyBeforeDispatching(
+ const sp<InputWindowHandle>& inputWindowHandle,
const KeyEvent* keyEvent, uint32_t policyFlags);
virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
@@ -819,12 +826,6 @@
void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
uint32_t& policyFlags) {
- enum {
- WM_ACTION_PASS_TO_USER = 1,
- WM_ACTION_POKE_USER_ACTIVITY = 2,
- WM_ACTION_GO_TO_SLEEP = 4,
- };
-
if (wmActions & WM_ACTION_GO_TO_SLEEP) {
#if DEBUG_INPUT_DISPATCHER_POLICY
LOGD("handleInterceptActions: Going to sleep.");
@@ -848,14 +849,14 @@
}
}
-bool NativeInputManager::interceptKeyBeforeDispatching(
+nsecs_t NativeInputManager::interceptKeyBeforeDispatching(
const sp<InputWindowHandle>& inputWindowHandle,
const KeyEvent* keyEvent, uint32_t policyFlags) {
// Policy:
// - Ignore untrusted events and pass them along.
// - Filter normal events and trusted injected events through the window manager policy to
// handle the HOME key and the like.
- bool result = false;
+ nsecs_t result = 0;
if (policyFlags & POLICY_FLAG_TRUSTED) {
JNIEnv* env = jniEnv();
@@ -863,13 +864,19 @@
jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
if (keyEventObj) {
- jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
+ jlong delayMillis = env->CallLongMethod(mCallbacksObj,
gCallbacksClassInfo.interceptKeyBeforeDispatching,
inputWindowHandleObj, keyEventObj, policyFlags);
bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
android_view_KeyEvent_recycle(env, keyEventObj);
env->DeleteLocalRef(keyEventObj);
- result = consumed && !error;
+ if (!error) {
+ if (delayMillis < 0) {
+ result = -1;
+ } else if (delayMillis > 0) {
+ result = milliseconds_to_nanoseconds(delayMillis);
+ }
+ }
} else {
LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
}
@@ -1433,7 +1440,7 @@
GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
"interceptKeyBeforeDispatching",
- "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
+ "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)J");
GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
"dispatchUnhandledKey",
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 51eb0a3..61a8358 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -5,6 +5,7 @@
Layer.cpp \
LayerBase.cpp \
LayerDim.cpp \
+ LayerScreenshot.cpp \
DdmConnection.cpp \
DisplayHardware/DisplayHardware.cpp \
DisplayHardware/DisplayHardwareBase.cpp \
@@ -22,6 +23,9 @@
ifeq ($(TARGET_BOARD_PLATFORM), omap3)
LOCAL_CFLAGS += -DNO_RGBX_8888
endif
+ifeq ($(TARGET_BOARD_PLATFORM), omap4)
+ LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
+endif
ifeq ($(TARGET_BOARD_PLATFORM), s5pc110)
LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -DNEVER_DEFAULT_TO_ASYNC_MODE
endif
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
index 59b7e5a..3b7c09e 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
@@ -122,7 +122,7 @@
DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger,
uint32_t displayIndex)
- : mCanDraw(true), mScreenAcquired(true)
+ : mScreenAcquired(true)
{
mDisplayEventThread = new DisplayEventThread(flinger);
}
@@ -133,14 +133,9 @@
mDisplayEventThread->requestExitAndWait();
}
-void DisplayHardwareBase::setCanDraw(bool canDraw)
-{
- mCanDraw = canDraw;
-}
-
bool DisplayHardwareBase::canDraw() const
{
- return mCanDraw && mScreenAcquired;
+ return mScreenAcquired;
}
void DisplayHardwareBase::releaseScreen() const
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
index 3ebc7b6..ef2df43 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
@@ -43,7 +43,6 @@
bool isScreenAcquired() const;
bool canDraw() const;
- void setCanDraw(bool canDraw);
private:
@@ -74,7 +73,6 @@
};
sp<DisplayEventThreadBase> mDisplayEventThread;
- mutable int mCanDraw;
mutable int mScreenAcquired;
};
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index feb2c52..28552f6 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -88,16 +88,8 @@
Layer::~Layer()
{
- class MessageDestroyGLState : public MessageBase {
- GLuint texture;
- public:
- MessageDestroyGLState(GLuint texture) : texture(texture) { }
- virtual bool handler() {
- glDeleteTextures(1, &texture);
- return true;
- }
- };
- mFlinger->postMessageAsync( new MessageDestroyGLState(mTextureName) );
+ mFlinger->postMessageAsync(
+ new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) );
}
void Layer::onFrameQueued() {
@@ -280,33 +272,33 @@
return;
}
- GLenum target = GL_TEXTURE_EXTERNAL_OES;
if (!isProtected()) {
- glBindTexture(target, mTextureName);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
+ GLenum filter = GL_NEAREST;
if (getFiltering() || needsFiltering() || isFixedSize() || isCropped()) {
// TODO: we could be more subtle with isFixedSize()
- glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- } else {
- glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ filter = GL_LINEAR;
}
- glEnable(target);
+ glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
+ glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
glMatrixMode(GL_TEXTURE);
glLoadMatrixf(mTextureMatrix);
glMatrixMode(GL_MODELVIEW);
+ glEnable(GL_TEXTURE_EXTERNAL_OES);
+ glDisable(GL_TEXTURE_2D);
} else {
- target = GL_TEXTURE_2D;
- glBindTexture(target, mFlinger->getProtectedTexName());
- glEnable(target);
+ glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
+ glDisable(GL_TEXTURE_EXTERNAL_OES);
+ glEnable(GL_TEXTURE_2D);
}
drawWithOpenGL(clip);
- glDisable(target);
+ glDisable(GL_TEXTURE_EXTERNAL_OES);
+ glDisable(GL_TEXTURE_2D);
}
// As documented in libhardware header, formats in the range
@@ -368,18 +360,6 @@
mCurrentScalingMode);
if (!isFixedSize()) {
- // we're being resized and there is a freeze display request,
- // acquire a freeze lock, so that the screen stays put
- // until we've redrawn at the new size; this is to avoid
- // glitches upon orientation changes.
- if (mFlinger->hasFreezeRequest()) {
- // if the surface is hidden, don't try to acquire the
- // freeze lock, since hidden surfaces may never redraw
- if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
- mFreezeLock = mFlinger->getFreezeLock();
- }
- }
-
// this will make sure LayerBase::doTransaction doesn't update
// the drawing state's size
Layer::State& editDraw(mDrawingState);
@@ -393,14 +373,6 @@
temp.requested_h);
}
- if (temp.sequence != front.sequence) {
- if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
- // this surface is now hidden, so it shouldn't hold a freeze lock
- // (it may never redraw, which is fine if it is hidden)
- mFreezeLock.clear();
- }
- }
-
return LayerBase::doTransaction(flags);
}
@@ -474,7 +446,7 @@
glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- // update the layer size and release freeze-lock
+ // update the layer size if needed
const Layer::State& front(drawingState());
// FIXME: mPostedDirtyRegion = dirty & bounds
@@ -511,9 +483,6 @@
// recompute visible region
recomputeVisibleRegions = true;
-
- // we now have the correct size, unfreeze the screen
- mFreezeLock.clear();
}
LOGD_IF(DEBUG_RESIZE,
@@ -546,11 +515,6 @@
dirtyRegion.andSelf(visibleRegionScreen);
outDirtyRegion.orSelf(dirtyRegion);
}
- if (visibleRegionScreen.isEmpty()) {
- // an invisible layer should not hold a freeze-lock
- // (because it may never be updated and therefore never release it)
- mFreezeLock.clear();
- }
}
void Layer::dump(String8& result, char* buffer, size_t SIZE) const
@@ -568,9 +532,9 @@
snprintf(buffer, SIZE,
" "
"format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
- " freezeLock=%p, transform-hint=0x%02x, queued-frames=%d\n",
+ " transform-hint=0x%02x, queued-frames=%d\n",
mFormat, w0, h0, s0,f0,
- getFreezeLock().get(), getTransformHint(), mQueuedFrames);
+ getTransformHint(), mQueuedFrames);
result.append(buffer);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 82e3521..2b9471b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -39,7 +39,6 @@
// ---------------------------------------------------------------------------
-class FreezeLock;
class Client;
class GLExtensions;
@@ -80,7 +79,6 @@
virtual wp<IBinder> getSurfaceTextureBinder() const;
// only for debugging
- inline const sp<FreezeLock>& getFreezeLock() const { return mFreezeLock; }
inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
protected:
@@ -124,9 +122,6 @@
bool mProtectedByApp; // application requires protected path to external sink
Region mPostedDirtyRegion;
- // page-flip thread and transaction thread (currently main thread)
- sp<FreezeLock> mFreezeLock;
-
// binder thread, transaction thread
mutable Mutex mLock;
};
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 7a47f62..f04add1 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -388,14 +388,9 @@
const uint32_t fbHeight = hw.getHeight();
glColor4f(red,green,blue,alpha);
-#if defined(GL_OES_EGL_image_external)
- if (GLExtensions::getInstance().haveTextureExternal()) {
- glDisable(GL_TEXTURE_EXTERNAL_OES);
- }
-#endif
+ glDisable(GL_TEXTURE_EXTERNAL_OES);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
- glDisable(GL_DITHER);
Region::const_iterator it = clip.begin();
Region::const_iterator const end = clip.end();
@@ -457,12 +452,6 @@
texCoords[3].u = 1;
texCoords[3].v = 1;
- if (needsDithering()) {
- glEnable(GL_DITHER);
- } else {
- glDisable(GL_DITHER);
- }
-
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, mVertices);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
@@ -476,6 +465,7 @@
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisable(GL_BLEND);
}
void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
index 654817d..e665d7a 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -49,7 +49,8 @@
const DisplayHardware& hw(graphicPlane(0).displayHardware());
const GLfloat alpha = s.alpha/255.0f;
const uint32_t fbHeight = hw.getHeight();
- glDisable(GL_DITHER);
+ glDisable(GL_TEXTURE_EXTERNAL_OES);
+ glDisable(GL_TEXTURE_2D);
if (s.alpha == 0xFF) {
glDisable(GL_BLEND);
@@ -60,11 +61,6 @@
glColor4f(0, 0, 0, alpha);
-#if defined(GL_OES_EGL_image_external)
- if (GLExtensions::getInstance().haveTextureExternal()) {
- glDisable(GL_TEXTURE_EXTERNAL_OES);
- }
-#endif
glVertexPointer(2, GL_FLOAT, 0, mVertices);
while (it != end) {
@@ -73,8 +69,9 @@
glScissor(r.left, sy, r.width(), r.height());
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
+ glDisable(GL_BLEND);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp
new file mode 100644
index 0000000..e30ccbf
--- /dev/null
+++ b/services/surfaceflinger/LayerScreenshot.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <ui/GraphicBuffer.h>
+
+#include "LayerScreenshot.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, DisplayID display,
+ const sp<Client>& client)
+ : LayerBaseClient(flinger, display, client),
+ mTextureName(0), mFlinger(flinger)
+{
+}
+
+LayerScreenshot::~LayerScreenshot()
+{
+ if (mTextureName) {
+ mFlinger->postMessageAsync(
+ new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) );
+ }
+}
+
+status_t LayerScreenshot::capture() {
+ GLfloat u, v;
+ status_t result = mFlinger->renderScreenToTexture(0, &mTextureName, &u, &v);
+ if (result != NO_ERROR) {
+ return result;
+ }
+
+ glBindTexture(GL_TEXTURE_2D, mTextureName);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ mTexCoords[0] = 0; mTexCoords[1] = v;
+ mTexCoords[2] = 0; mTexCoords[3] = 0;
+ mTexCoords[4] = u; mTexCoords[5] = 0;
+ mTexCoords[6] = u; mTexCoords[7] = v;
+
+ return NO_ERROR;
+}
+
+void LayerScreenshot::onDraw(const Region& clip) const
+{
+ const State& s(drawingState());
+ Region::const_iterator it = clip.begin();
+ Region::const_iterator const end = clip.end();
+ if (s.alpha>0 && (it != end)) {
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ const GLfloat alpha = s.alpha/255.0f;
+ const uint32_t fbHeight = hw.getHeight();
+
+ if (s.alpha == 0xFF) {
+ glDisable(GL_BLEND);
+ } else {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ glColor4f(0, 0, 0, alpha);
+
+ glDisable(GL_TEXTURE_EXTERNAL_OES);
+ glEnable(GL_TEXTURE_2D);
+
+ glBindTexture(GL_TEXTURE_2D, mTextureName);
+ glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords);
+ glVertexPointer(2, GL_FLOAT, 0, mVertices);
+
+ while (it != end) {
+ const Rect& r = *it++;
+ const GLint sy = fbHeight - (r.top + r.height());
+ glScissor(r.left, sy, r.width(), r.height());
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ }
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/services/surfaceflinger/LayerScreenshot.h b/services/surfaceflinger/LayerScreenshot.h
new file mode 100644
index 0000000..e3a2b19
--- /dev/null
+++ b/services/surfaceflinger/LayerScreenshot.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_LAYER_SCREENSHOT_H
+#define ANDROID_LAYER_SCREENSHOT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "LayerBase.h"
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class LayerScreenshot : public LayerBaseClient
+{
+ GLuint mTextureName;
+ GLfloat mTexCoords[8];
+ sp<SurfaceFlinger> mFlinger;
+public:
+ LayerScreenshot(SurfaceFlinger* flinger, DisplayID display,
+ const sp<Client>& client);
+ virtual ~LayerScreenshot();
+
+ status_t capture();
+
+ virtual void onDraw(const Region& clip) const;
+ virtual bool isOpaque() const { return false; }
+ virtual bool isSecure() const { return false; }
+ virtual bool isProtectedByApp() const { return false; }
+ virtual bool isProtectedByDRM() const { return false; }
+ virtual const char* getTypeId() const { return "LayerScreenshot"; }
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_SCREENSHOT_H
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b01a6a3..1905a68 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -50,6 +50,7 @@
#include "DdmConnection.h"
#include "Layer.h"
#include "LayerDim.h"
+#include "LayerScreenshot.h"
#include "SurfaceFlinger.h"
#include "DisplayHardware/DisplayHardware.h"
@@ -79,16 +80,12 @@
SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(), Thread(false),
mTransactionFlags(0),
- mResizeTransationPending(false),
+ mTransationPending(false),
mLayersRemoved(false),
mBootTime(systemTime()),
mVisibleRegionsDirty(false),
mHwWorkListDirty(false),
- mDeferReleaseConsole(false),
- mFreezeDisplay(false),
mElectronBeamAnimationMode(0),
- mFreezeCount(0),
- mFreezeDisplayTime(0),
mDebugRegion(0),
mDebugBackground(0),
mDebugDDMS(0),
@@ -191,11 +188,6 @@
{
// the window manager died on us. prepare its eulogy.
- // unfreeze the screen in case it was... frozen
- mFreezeDisplayTime = 0;
- mFreezeCount = 0;
- mFreezeDisplay = false;
-
// reset screen orientation
setOrientation(0, eOrientationDefault, 0);
@@ -323,33 +315,7 @@
{
while (true) {
nsecs_t timeout = -1;
- const nsecs_t freezeDisplayTimeout = ms2ns(5000);
- if (UNLIKELY(isFrozen())) {
- // wait 5 seconds
- const nsecs_t now = systemTime();
- if (mFreezeDisplayTime == 0) {
- mFreezeDisplayTime = now;
- }
- nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
- timeout = waitTime>0 ? waitTime : 0;
- }
-
sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
-
- // see if we timed out
- if (isFrozen()) {
- const nsecs_t now = systemTime();
- nsecs_t frozenTime = (now - mFreezeDisplayTime);
- if (frozenTime >= freezeDisplayTimeout) {
- // we timed out and are still frozen
- LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
- mFreezeDisplay, mFreezeCount);
- mFreezeDisplayTime = 0;
- mFreezeCount = 0;
- mFreezeDisplay = false;
- }
- }
-
if (msg != 0) {
switch (msg->what) {
case MessageQueue::INVALIDATE:
@@ -446,13 +412,18 @@
// post surfaces (if needed)
handlePageFlip();
+ if (mDirtyRegion.isEmpty()) {
+ // nothing new to do.
+ return true;
+ }
+
if (UNLIKELY(mHwWorkListDirty)) {
// build the h/w work list
handleWorkList();
}
const DisplayHardware& hw(graphicPlane(0).displayHardware());
- if (LIKELY(hw.canDraw() && !isFrozen())) {
+ if (LIKELY(hw.canDraw())) {
// repaint the framebuffer (if needed)
const int index = hw.getCurrentBufferIndex();
@@ -479,15 +450,16 @@
void SurfaceFlinger::postFramebuffer()
{
- if (!mSwapRegion.isEmpty()) {
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- const nsecs_t now = systemTime();
- mDebugInSwapBuffers = now;
- hw.flip(mSwapRegion);
- mLastSwapBufferTime = systemTime() - now;
- mDebugInSwapBuffers = 0;
- mSwapRegion.clear();
- }
+ // this should never happen. we do the flip anyways so we don't
+ // risk to cause a deadlock with hwc
+ LOGW_IF(mSwapRegion.isEmpty(), "mSwapRegion is empty");
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ const nsecs_t now = systemTime();
+ mDebugInSwapBuffers = now;
+ hw.flip(mSwapRegion);
+ mLastSwapBufferTime = systemTime() - now;
+ mDebugInSwapBuffers = 0;
+ mSwapRegion.clear();
}
void SurfaceFlinger::handleConsoleEvents()
@@ -503,17 +475,9 @@
SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
}
- if (mDeferReleaseConsole && hw.isScreenAcquired()) {
- // We got the release signal before the acquire signal
- mDeferReleaseConsole = false;
- hw.releaseScreen();
- }
-
if (what & eConsoleReleased) {
if (hw.isScreenAcquired()) {
hw.releaseScreen();
- } else {
- mDeferReleaseConsole = true;
}
}
@@ -591,13 +555,6 @@
mDirtyRegion.set(hw.bounds());
}
- if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
- // freezing or unfreezing the display -> trigger animation if needed
- mFreezeDisplay = mCurrentState.freezeDisplay;
- if (mFreezeDisplay)
- mFreezeDisplayTime = 0;
- }
-
if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
// layers have been added
mVisibleRegionsDirty = true;
@@ -623,11 +580,6 @@
commitTransaction();
}
-sp<FreezeLock> SurfaceFlinger::getFreezeLock() const
-{
- return new FreezeLock(const_cast<SurfaceFlinger *>(this));
-}
-
void SurfaceFlinger::computeVisibleRegions(
const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
{
@@ -757,7 +709,7 @@
void SurfaceFlinger::commitTransaction()
{
mDrawingState = mCurrentState;
- mResizeTransationPending = false;
+ mTransationPending = false;
mTransactionCV.broadcast();
}
@@ -949,7 +901,7 @@
// data.
//
// Also we want to make sure to not clear areas that belong to
- // layers above that won't redraw (we would just erasing them),
+ // layers above that won't redraw (we would just be erasing them),
// that is, we can't erase anything outside the dirty region.
Region transparent;
@@ -1040,8 +992,9 @@
composeSurfaces(repaint);
}
+ glDisable(GL_TEXTURE_EXTERNAL_OES);
+ glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
- glDisable(GL_DITHER);
glDisable(GL_SCISSOR_TEST);
static int toggle = 0;
@@ -1084,9 +1037,6 @@
const int32_t width = hw.getWidth();
const int32_t height = hw.getHeight();
- glDisable(GL_BLEND);
- glDisable(GL_DITHER);
-
if (LIKELY(!mDebugBackground)) {
glClearColor(0,0,0,0);
Region::const_iterator it = region.begin();
@@ -1101,19 +1051,20 @@
const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
{ width, height }, { 0, height } };
const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } };
+
glVertexPointer(2, GL_SHORT, 0, vertices);
glTexCoordPointer(2, GL_SHORT, 0, tcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-#if defined(GL_OES_EGL_image_external)
- if (GLExtensions::getInstance().haveTextureExternal()) {
- glDisable(GL_TEXTURE_EXTERNAL_OES);
- }
-#endif
+
+ glDisable(GL_TEXTURE_EXTERNAL_OES);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
+
+ glDisable(GL_BLEND);
+
glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
Region::const_iterator it = region.begin();
Region::const_iterator const end = region.end();
@@ -1243,64 +1194,48 @@
}
-void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state) {
+void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
+ int orientation, uint32_t flags) {
Mutex::Autolock _l(mStateLock);
- uint32_t flags = 0;
+ uint32_t transactionFlags = 0;
+ if (mCurrentState.orientation != orientation) {
+ if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
+ mCurrentState.orientation = orientation;
+ transactionFlags |= eTransactionNeeded;
+ } else if (orientation != eOrientationUnchanged) {
+ LOGW("setTransactionState: ignoring unrecognized orientation: %d",
+ orientation);
+ }
+ }
+
const size_t count = state.size();
for (size_t i=0 ; i<count ; i++) {
const ComposerState& s(state[i]);
sp<Client> client( static_cast<Client *>(s.client.get()) );
- flags |= setClientStateLocked(client, s.state);
+ transactionFlags |= setClientStateLocked(client, s.state);
}
- if (flags) {
- setTransactionFlags(flags);
+ if (transactionFlags) {
+ setTransactionFlags(transactionFlags);
}
- signalEvent();
-
- // if there is a transaction with a resize, wait for it to
- // take effect before returning.
- while (mResizeTransationPending) {
+ // if this is a synchronous transaction, wait for it to take effect before
+ // returning.
+ if (flags & eSynchronous) {
+ mTransationPending = true;
+ }
+ while (mTransationPending) {
status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
if (CC_UNLIKELY(err != NO_ERROR)) {
// just in case something goes wrong in SF, return to the
// called after a few seconds.
LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
- mResizeTransationPending = false;
+ mTransationPending = false;
break;
}
}
}
-status_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
-{
- if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
- return BAD_VALUE;
-
- Mutex::Autolock _l(mStateLock);
- mCurrentState.freezeDisplay = 1;
- setTransactionFlags(eTransactionNeeded);
-
- // flags is intended to communicate some sort of animation behavior
- // (for instance fading)
- return NO_ERROR;
-}
-
-status_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
-{
- if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
- return BAD_VALUE;
-
- Mutex::Autolock _l(mStateLock);
- mCurrentState.freezeDisplay = 0;
- setTransactionFlags(eTransactionNeeded);
-
- // flags is intended to communicate some sort of animation behavior
- // (for instance fading)
- return NO_ERROR;
-}
-
int SurfaceFlinger::setOrientation(DisplayID dpy,
int orientation, uint32_t flags)
{
@@ -1350,6 +1285,9 @@
case eFXSurfaceDim:
layer = createDimSurface(client, d, w, h, flags);
break;
+ case eFXSurfaceScreenshot:
+ layer = createScreenshotSurface(client, d, w, h, flags);
+ break;
}
if (layer != 0) {
@@ -1412,7 +1350,19 @@
uint32_t w, uint32_t h, uint32_t flags)
{
sp<LayerDim> layer = new LayerDim(this, display, client);
- layer->initStates(w, h, flags);
+ return layer;
+}
+
+sp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
+ const sp<Client>& client, DisplayID display,
+ uint32_t w, uint32_t h, uint32_t flags)
+{
+ sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
+ status_t err = layer->capture();
+ if (err != NO_ERROR) {
+ layer.clear();
+ LOGW("createScreenshotSurface failed (%s)", strerror(-err));
+ }
return layer;
}
@@ -1486,7 +1436,6 @@
if (what & eSizeChanged) {
if (layer->setSize(s.w, s.h)) {
flags |= eTraversalNeeded;
- mResizeTransationPending = true;
}
}
if (what & eAlphaChanged) {
@@ -1606,8 +1555,7 @@
mWormholeRegion.dump(result, "WormholeRegion");
const DisplayHardware& hw(graphicPlane(0).displayHardware());
snprintf(buffer, SIZE,
- " display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
- mFreezeDisplay?"yes":"no", mFreezeCount,
+ " orientation=%d, canDraw=%d\n",
mCurrentState.orientation, hw.canDraw());
result.append(buffer);
snprintf(buffer, SIZE,
@@ -1660,8 +1608,6 @@
case CREATE_CONNECTION:
case SET_TRANSACTION_STATE:
case SET_ORIENTATION:
- case FREEZE_DISPLAY:
- case UNFREEZE_DISPLAY:
case BOOT_FINISHED:
case TURN_ELECTRON_BEAM_OFF:
case TURN_ELECTRON_BEAM_ON:
@@ -1733,10 +1679,6 @@
GraphicLog::getInstance().setEnabled(enabled);
return NO_ERROR;
}
- case 1007: // set mFreezeCount
- mFreezeCount = data.readInt32();
- mFreezeDisplayTime = 0;
- return NO_ERROR;
case 1008: // toggle use of hw composer
n = data.readInt32();
mDebugDisableHWC = n ? 1 : 0;
@@ -1769,12 +1711,19 @@
void SurfaceFlinger::repaintEverything() {
Mutex::Autolock _l(mStateLock);
const DisplayHardware& hw(graphicPlane(0).displayHardware());
- mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
+ mDirtyRegion.set(hw.bounds());
signalEvent();
}
// ---------------------------------------------------------------------------
+status_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
+ GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
+{
+ Mutex::Autolock _l(mStateLock);
+ return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
+}
+
status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
{
@@ -1812,8 +1761,12 @@
GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
// redraw the screen entirely...
+ glDisable(GL_TEXTURE_EXTERNAL_OES);
+ glDisable(GL_TEXTURE_2D);
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
const size_t count = layers.size();
for (size_t i=0 ; i<count ; ++i) {
@@ -1821,6 +1774,8 @@
layer->drawForSreenShot();
}
+ hw.compositionComplete();
+
// back to main framebuffer
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
glDisable(GL_SCISSOR_TEST);
@@ -1836,26 +1791,21 @@
status_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
{
- status_t result = PERMISSION_DENIED;
-
- if (!GLExtensions::getInstance().haveFramebufferObject())
- return INVALID_OPERATION;
-
// get screen geometry
const DisplayHardware& hw(graphicPlane(0).displayHardware());
const uint32_t hw_w = hw.getWidth();
const uint32_t hw_h = hw.getHeight();
- const Region screenBounds(hw.bounds());
+ const Region screenBounds(hw.getBounds());
GLfloat u, v;
GLuint tname;
- result = renderScreenToTextureLocked(0, &tname, &u, &v);
+ status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
if (result != NO_ERROR) {
return result;
}
GLfloat vtx[8];
- const GLfloat texCoords[4][2] = { {0,1}, {0,1-v}, {u,1-v}, {u,1} };
+ const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
glBindTexture(GL_TEXTURE_2D, tname);
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -1941,6 +1891,12 @@
s_curve_interpolator itb(nbFrames, 8.5f);
v_stretch vverts(hw_w, hw_h);
+
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
for (int i=0 ; i<nbFrames ; i++) {
@@ -1995,6 +1951,7 @@
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDeleteTextures(1, &tname);
glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
return NO_ERROR;
}
@@ -2019,10 +1976,6 @@
return result;
}
- // back to main framebuffer
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
- glDisable(GL_SCISSOR_TEST);
-
GLfloat vtx[8];
const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
glBindTexture(GL_TEXTURE_2D, tname);
@@ -2139,6 +2092,7 @@
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDeleteTextures(1, &tname);
glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
return NO_ERROR;
}
@@ -2169,7 +2123,6 @@
glEnable(GL_SCISSOR_TEST);
hw.flip( Region(hw.bounds()) );
- hw.setCanDraw(false);
return NO_ERROR;
}
@@ -2218,7 +2171,6 @@
if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
electronBeamOnAnimationImplLocked();
}
- hw.setCanDraw(true);
// make sure to redraw the whole screen when the animation is done
mDirtyRegion.set(hw.bounds());
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 92b265e..1490dec 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -46,9 +46,9 @@
class Client;
class DisplayHardware;
-class FreezeLock;
class Layer;
class LayerDim;
+class LayerScreenshot;
struct surface_flinger_cblk_t;
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
@@ -167,9 +167,8 @@
virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc();
virtual sp<IMemoryHeap> getCblk() const;
virtual void bootFinished();
- virtual void setTransactionState(const Vector<ComposerState>& state);
- virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags);
- virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags);
+ virtual void setTransactionState(const Vector<ComposerState>& state,
+ int orientation, uint32_t flags);
virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags);
virtual bool authenticateSurfaceTexture(const sp<ISurfaceTexture>& surface) const;
@@ -185,6 +184,15 @@
void screenReleased(DisplayID dpy);
void screenAcquired(DisplayID dpy);
+ status_t renderScreenToTexture(DisplayID dpy,
+ GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
+
+ status_t postMessageAsync(const sp<MessageBase>& msg,
+ nsecs_t reltime=0, uint32_t flags = 0);
+
+ status_t postMessageSync(const sp<MessageBase>& msg,
+ nsecs_t reltime=0, uint32_t flags = 0);
+
status_t removeLayer(const sp<LayerBase>& layer);
status_t addLayer(const sp<LayerBase>& layer);
status_t invalidateLayerVisibility(const sp<LayerBase>& layer);
@@ -194,6 +202,18 @@
GLuint getProtectedTexName() const { return mProtectedTexName; }
+
+ class MessageDestroyGLTexture : public MessageBase {
+ GLuint texture;
+ public:
+ MessageDestroyGLTexture(GLuint texture) : texture(texture) { }
+ virtual bool handler() {
+ glDeleteTextures(1, &texture);
+ return true;
+ }
+ };
+
+
private:
// DeathRecipient interface
virtual void binderDied(const wp<IBinder>& who);
@@ -203,7 +223,6 @@
friend class LayerBase;
friend class LayerBaseClient;
friend class Layer;
- friend class LayerDim;
sp<ISurface> createSurface(
ISurfaceComposerClient::surface_data_t* params,
@@ -221,6 +240,10 @@
const sp<Client>& client, DisplayID display,
uint32_t w, uint32_t h, uint32_t flags);
+ sp<LayerScreenshot> createScreenshotSurface(
+ const sp<Client>& client, DisplayID display,
+ uint32_t w, uint32_t h, uint32_t flags);
+
status_t removeSurface(const sp<Client>& client, SurfaceID sid);
status_t destroySurface(const wp<LayerBaseClient>& layer);
uint32_t setClientStateLocked(const sp<Client>& client, const layer_state_t& s);
@@ -243,12 +266,10 @@
struct State {
State() {
orientation = ISurfaceComposer::eOrientationDefault;
- freezeDisplay = 0;
}
LayerVector layersSortedByZ;
uint8_t orientation;
uint8_t orientationFlags;
- uint8_t freezeDisplay;
};
virtual bool threadLoop();
@@ -307,20 +328,6 @@
status_t renderScreenToTextureLocked(DisplayID dpy,
GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
- friend class FreezeLock;
- sp<FreezeLock> getFreezeLock() const;
- inline void incFreezeCount() {
- if (mFreezeCount == 0)
- mFreezeDisplayTime = 0;
- mFreezeCount++;
- }
- inline void decFreezeCount() { if (mFreezeCount > 0) mFreezeCount--; }
- inline bool hasFreezeRequest() const { return mFreezeDisplay; }
- inline bool isFrozen() const {
- return (mFreezeDisplay || mFreezeCount>0) && mBootFinished;
- }
-
-
void debugFlashRegions();
void debugShowFPS() const;
void drawWormhole() const;
@@ -328,19 +335,13 @@
mutable MessageQueue mEventQueue;
- status_t postMessageAsync(const sp<MessageBase>& msg,
- nsecs_t reltime=0, uint32_t flags = 0);
-
- status_t postMessageSync(const sp<MessageBase>& msg,
- nsecs_t reltime=0, uint32_t flags = 0);
-
// access must be protected by mStateLock
mutable Mutex mStateLock;
State mCurrentState;
volatile int32_t mTransactionFlags;
Condition mTransactionCV;
SortedVector< sp<LayerBase> > mLayerPurgatory;
- bool mResizeTransationPending;
+ bool mTransationPending;
// protected by mStateLock (but we could use another lock)
GraphicPlane mGraphicPlanes[1];
@@ -363,11 +364,7 @@
Region mWormholeRegion;
bool mVisibleRegionsDirty;
bool mHwWorkListDirty;
- bool mDeferReleaseConsole;
- bool mFreezeDisplay;
int32_t mElectronBeamAnimationMode;
- int32_t mFreezeCount;
- nsecs_t mFreezeDisplayTime;
Vector< sp<LayerBase> > mVisibleLayersSortedByZ;
@@ -403,20 +400,6 @@
};
// ---------------------------------------------------------------------------
-
-class FreezeLock : public LightRefBase<FreezeLock> {
- SurfaceFlinger* mFlinger;
-public:
- FreezeLock(SurfaceFlinger* flinger)
- : mFlinger(flinger) {
- mFlinger->incFreezeCount();
- }
- ~FreezeLock() {
- mFlinger->decFreezeCount();
- }
-};
-
-// ---------------------------------------------------------------------------
}; // namespace android
#endif // ANDROID_SURFACE_FLINGER_H
diff --git a/services/surfaceflinger/tests/Android.mk b/services/surfaceflinger/tests/Android.mk
index 5053e7d..b655648 100644
--- a/services/surfaceflinger/tests/Android.mk
+++ b/services/surfaceflinger/tests/Android.mk
@@ -1 +1,40 @@
-include $(call all-subdir-makefiles)
+# Build the unit tests,
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := SurfaceFlinger_test
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := \
+ Transaction_test.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ libEGL \
+ libGLESv2 \
+ libandroid \
+ libbinder \
+ libcutils \
+ libgui \
+ libstlport \
+ libui \
+ libutils \
+
+LOCAL_C_INCLUDES := \
+ bionic \
+ bionic/libstdc++/include \
+ external/gtest/include \
+ external/stlport/stlport \
+
+# Build the binary to $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
+# to integrate with auto-test framework.
+include $(BUILD_NATIVE_TEST)
+
+# Include subdirectory makefiles
+# ============================================================
+
+# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
+# team really wants is to build the stuff defined by this makefile.
+ifeq (,$(ONE_SHOT_MAKEFILE))
+include $(call first-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
new file mode 100644
index 0000000..afafd8a
--- /dev/null
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <binder/IMemory.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/Surface.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+#include <utils/String8.h>
+
+namespace android {
+
+// Fill an RGBA_8888 formatted surface with a single color.
+static void fillSurfaceRGBA8(const sp<SurfaceControl>& sc,
+ uint8_t r, uint8_t g, uint8_t b) {
+ Surface::SurfaceInfo info;
+ sp<Surface> s = sc->getSurface();
+ ASSERT_TRUE(s != NULL);
+ ASSERT_EQ(NO_ERROR, s->lock(&info));
+ uint8_t* img = reinterpret_cast<uint8_t*>(info.bits);
+ for (uint32_t y = 0; y < info.h; y++) {
+ for (uint32_t x = 0; x < info.w; x++) {
+ uint8_t* pixel = img + (4 * (y*info.s + x));
+ pixel[0] = r;
+ pixel[1] = g;
+ pixel[2] = b;
+ pixel[3] = 255;
+ }
+ }
+ ASSERT_EQ(NO_ERROR, s->unlockAndPost());
+}
+
+// A ScreenCapture is a screenshot from SurfaceFlinger that can be used to check
+// individual pixel values for testing purposes.
+class ScreenCapture : public RefBase {
+public:
+ static void captureScreen(sp<ScreenCapture>* sc) {
+ sp<IMemoryHeap> heap;
+ uint32_t w=0, h=0;
+ PixelFormat fmt=0;
+ sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+ ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 0, 0,
+ 0, INT_MAX));
+ ASSERT_TRUE(heap != NULL);
+ ASSERT_EQ(PIXEL_FORMAT_RGBA_8888, fmt);
+ *sc = new ScreenCapture(w, h, heap);
+ }
+
+ void checkPixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t b) {
+ const uint8_t* img = reinterpret_cast<const uint8_t*>(mHeap->base());
+ const uint8_t* pixel = img + (4 * (y*mWidth + x));
+ if (r != pixel[0] || g != pixel[1] || b != pixel[2]) {
+ String8 err(String8::format("pixel @ (%3d, %3d): "
+ "expected [%3d, %3d, %3d], got [%3d, %3d, %3d]",
+ x, y, r, g, b, pixel[0], pixel[1], pixel[2]));
+ EXPECT_EQ(String8(), err);
+ }
+ }
+
+private:
+ ScreenCapture(uint32_t w, uint32_t h, const sp<IMemoryHeap>& heap) :
+ mWidth(w),
+ mHeight(h),
+ mHeap(heap)
+ {}
+
+ const uint32_t mWidth;
+ const uint32_t mHeight;
+ sp<IMemoryHeap> mHeap;
+};
+
+class LayerUpdateTest : public ::testing::Test {
+protected:
+ virtual void SetUp() {
+ mComposerClient = new SurfaceComposerClient;
+ ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
+
+ ssize_t displayWidth = mComposerClient->getDisplayWidth(0);
+ ssize_t displayHeight = mComposerClient->getDisplayHeight(0);
+
+ // Background surface
+ mBGSurfaceControl = mComposerClient->createSurface(
+ String8("BG Test Surface"), 0, displayWidth, displayHeight,
+ PIXEL_FORMAT_RGBA_8888, 0);
+ ASSERT_TRUE(mBGSurfaceControl != NULL);
+ ASSERT_TRUE(mBGSurfaceControl->isValid());
+ fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
+
+ // Foreground surface
+ mFGSurfaceControl = mComposerClient->createSurface(
+ String8("FG Test Surface"), 0, 64, 64, PIXEL_FORMAT_RGBA_8888, 0);
+ ASSERT_TRUE(mFGSurfaceControl != NULL);
+ ASSERT_TRUE(mFGSurfaceControl->isValid());
+
+ fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
+
+ // Synchronization surface
+ mSyncSurfaceControl = mComposerClient->createSurface(
+ String8("Sync Test Surface"), 0, 1, 1, PIXEL_FORMAT_RGBA_8888, 0);
+ ASSERT_TRUE(mSyncSurfaceControl != NULL);
+ ASSERT_TRUE(mSyncSurfaceControl->isValid());
+
+ fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
+
+ SurfaceComposerClient::openGlobalTransaction();
+
+ ASSERT_EQ(NO_ERROR, mBGSurfaceControl->setLayer(INT_MAX-2));
+ ASSERT_EQ(NO_ERROR, mBGSurfaceControl->show());
+
+ ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayer(INT_MAX-1));
+ ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(64, 64));
+ ASSERT_EQ(NO_ERROR, mFGSurfaceControl->show());
+
+ ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->setLayer(INT_MAX-1));
+ ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->setPosition(displayWidth-2,
+ displayHeight-2));
+ ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->show());
+
+ SurfaceComposerClient::closeGlobalTransaction(true);
+ }
+
+ virtual void TearDown() {
+ mComposerClient->dispose();
+ mBGSurfaceControl = 0;
+ mFGSurfaceControl = 0;
+ mSyncSurfaceControl = 0;
+ mComposerClient = 0;
+ }
+
+ void waitForPostedBuffers() {
+ // Since the sync surface is in synchronous mode (i.e. double buffered)
+ // posting three buffers to it should ensure that at least two
+ // SurfaceFlinger::handlePageFlip calls have been made, which should
+ // guaranteed that a buffer posted to another Surface has been retired.
+ fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
+ fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
+ fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
+ }
+
+ sp<SurfaceComposerClient> mComposerClient;
+ sp<SurfaceControl> mBGSurfaceControl;
+ sp<SurfaceControl> mFGSurfaceControl;
+
+ // This surface is used to ensure that the buffers posted to
+ // mFGSurfaceControl have been picked up by SurfaceFlinger.
+ sp<SurfaceControl> mSyncSurfaceControl;
+};
+
+TEST_F(LayerUpdateTest, LayerMoveWorks) {
+ sp<ScreenCapture> sc;
+ {
+ SCOPED_TRACE("before move");
+ ScreenCapture::captureScreen(&sc);
+ sc->checkPixel( 0, 12, 63, 63, 195);
+ sc->checkPixel( 75, 75, 195, 63, 63);
+ sc->checkPixel(145, 145, 63, 63, 195);
+ }
+
+ SurfaceComposerClient::openGlobalTransaction();
+ ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(128, 128));
+ SurfaceComposerClient::closeGlobalTransaction(true);
+ {
+ // This should reflect the new position, but not the new color.
+ SCOPED_TRACE("after move, before redraw");
+ ScreenCapture::captureScreen(&sc);
+ sc->checkPixel( 24, 24, 63, 63, 195);
+ sc->checkPixel( 75, 75, 63, 63, 195);
+ sc->checkPixel(145, 145, 195, 63, 63);
+ }
+
+ fillSurfaceRGBA8(mFGSurfaceControl, 63, 195, 63);
+ waitForPostedBuffers();
+ {
+ // This should reflect the new position and the new color.
+ SCOPED_TRACE("after redraw");
+ ScreenCapture::captureScreen(&sc);
+ sc->checkPixel( 24, 24, 63, 63, 195);
+ sc->checkPixel( 75, 75, 63, 63, 195);
+ sc->checkPixel(145, 145, 63, 195, 63);
+ }
+}
+
+TEST_F(LayerUpdateTest, LayerResizeWorks) {
+ sp<ScreenCapture> sc;
+ {
+ SCOPED_TRACE("before resize");
+ ScreenCapture::captureScreen(&sc);
+ sc->checkPixel( 0, 12, 63, 63, 195);
+ sc->checkPixel( 75, 75, 195, 63, 63);
+ sc->checkPixel(145, 145, 63, 63, 195);
+ }
+
+ LOGD("resizing");
+ SurfaceComposerClient::openGlobalTransaction();
+ ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setSize(128, 128));
+ SurfaceComposerClient::closeGlobalTransaction(true);
+ LOGD("resized");
+ {
+ // This should not reflect the new size or color because SurfaceFlinger
+ // has not yet received a buffer of the correct size.
+ SCOPED_TRACE("after resize, before redraw");
+ ScreenCapture::captureScreen(&sc);
+ sc->checkPixel( 0, 12, 63, 63, 195);
+ sc->checkPixel( 75, 75, 195, 63, 63);
+ sc->checkPixel(145, 145, 63, 63, 195);
+ }
+
+ LOGD("drawing");
+ fillSurfaceRGBA8(mFGSurfaceControl, 63, 195, 63);
+ waitForPostedBuffers();
+ LOGD("drawn");
+ {
+ // This should reflect the new size and the new color.
+ SCOPED_TRACE("after redraw");
+ ScreenCapture::captureScreen(&sc);
+ sc->checkPixel( 24, 24, 63, 63, 195);
+ sc->checkPixel( 75, 75, 63, 195, 63);
+ sc->checkPixel(145, 145, 63, 195, 63);
+ }
+}
+
+}
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index ae152fb..97e7aa3 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -254,9 +254,6 @@
/** CID of active data connection */
protected int mCidActive;
- /** indication of our availability (preconditions to trysetupData are met) **/
- protected boolean mAvailability = false;
-
// When false we will not auto attach and manually attaching is required.
protected boolean mAutoAttachOnCreation = false;
@@ -679,6 +676,15 @@
return result;
}
+ protected boolean isEmergency() {
+ final boolean result;
+ synchronized (mDataEnabledLock) {
+ result = mPhone.isInEcm() || mPhone.isInEmergencyCall();
+ }
+ log("isEmergency: result=" + result);
+ return result;
+ }
+
protected int apnTypeToId(String type) {
if (TextUtils.equals(type, Phone.APN_TYPE_DEFAULT)) {
return APN_DEFAULT_ID;
@@ -755,7 +761,7 @@
mPhone.notifyDataConnection(reason, apnIdToType(id));
}
}
- notifyDataAvailability(reason);
+ notifyOffApnsOfAvailability(reason);
}
// a new APN has gone active and needs to send events to catch up with the
@@ -783,15 +789,8 @@
}
// disabled apn's still need avail/unavail notificiations - send them out
- protected void notifyOffApnsOfAvailability(String reason, boolean availability) {
- if (mAvailability == availability) {
- if (DBG) {
- log("notifyOffApnsOfAvailability: no change in availability, " +
- "not nofitying about reason='" + reason + "' availability=" + availability);
- }
- return;
- }
- mAvailability = availability;
+ protected void notifyOffApnsOfAvailability(String reason) {
+ if (DBG) log("notifyOffApnsOfAvailability - reason= " + reason);
for (int id = 0; id < APN_NUM_TYPES; id++) {
if (!isApnIdEnabled(id)) {
notifyApnIdDisconnected(reason, id);
@@ -799,13 +798,6 @@
}
}
- // we had an availability change - tell the listeners
- protected void notifyDataAvailability(String reason) {
- // note that we either just turned all off because we lost availability
- // or all were off and could now go on, so only have off apns to worry about
- notifyOffApnsOfAvailability(reason, isDataPossible(Phone.APN_TYPE_DEFAULT));
- }
-
public boolean isApnTypeEnabled(String apnType) {
if (apnType == null) {
return false;
@@ -998,17 +990,14 @@
protected void onSetInternalDataEnabled(boolean enabled) {
synchronized (mDataEnabledLock) {
- final boolean prevEnabled = getAnyDataEnabled();
- if (mInternalDataEnabled != enabled) {
- mInternalDataEnabled = enabled;
- if (prevEnabled != getAnyDataEnabled()) {
- if (!prevEnabled) {
- resetAllRetryCounts();
- onTrySetupData(Phone.REASON_DATA_ENABLED);
- } else {
- cleanUpAllConnections(null);
- }
- }
+ mInternalDataEnabled = enabled;
+ if (enabled) {
+ log("onSetInternalDataEnabled: changed to enabled, try to setup data call");
+ resetAllRetryCounts();
+ onTrySetupData(Phone.REASON_DATA_ENABLED);
+ } else {
+ log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections");
+ cleanUpAllConnections(null);
}
}
}
diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
index a3f4f1f..2e99849 100644
--- a/telephony/java/com/android/internal/telephony/GsmAlphabet.java
+++ b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
@@ -208,6 +208,24 @@
* Converts a String into a byte array containing the 7-bit packed
* GSM Alphabet representation of the string. If a header is provided,
* this is included in the returned byte array and padded to a septet
+ * boundary. This method is used by OEM code.
+ *
+ * @param data The text string to encode.
+ * @param header Optional header (including length byte) that precedes
+ * the encoded data, padded to septet boundary.
+ * @return Byte array containing header and encoded data.
+ * @throws EncodeException if String is too large to encode
+ * @see #stringToGsm7BitPackedWithHeader(String, byte[], int, int)
+ */
+ public static byte[] stringToGsm7BitPackedWithHeader(String data, byte[] header)
+ throws EncodeException {
+ return stringToGsm7BitPackedWithHeader(data, header, 0, 0);
+ }
+
+ /**
+ * Converts a String into a byte array containing the 7-bit packed
+ * GSM Alphabet representation of the string. If a header is provided,
+ * this is included in the returned byte array and padded to a septet
* boundary.
*
* Unencodable chars are encoded as spaces
diff --git a/telephony/java/com/android/internal/telephony/IccProvider.java b/telephony/java/com/android/internal/telephony/IccProvider.java
index 3471ec2..a66e19d 100644
--- a/telephony/java/com/android/internal/telephony/IccProvider.java
+++ b/telephony/java/com/android/internal/telephony/IccProvider.java
@@ -19,166 +19,20 @@
import android.content.ContentProvider;
import android.content.UriMatcher;
import android.content.ContentValues;
-import android.database.AbstractCursor;
import android.database.Cursor;
-import android.database.CursorWindow;
+import android.database.MatrixCursor;
import android.net.Uri;
-import android.os.SystemProperties;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
import android.util.Log;
-import java.util.ArrayList;
import java.util.List;
import com.android.internal.telephony.IccConstants;
import com.android.internal.telephony.AdnRecord;
import com.android.internal.telephony.IIccPhoneBook;
-/**
- * XXX old code -- should be replaced with MatrixCursor.
- * @deprecated This is has been replaced by MatrixCursor.
-*/
-class ArrayListCursor extends AbstractCursor {
- private String[] mColumnNames;
- private ArrayList<Object>[] mRows;
-
- @SuppressWarnings({"unchecked"})
- public ArrayListCursor(String[] columnNames, ArrayList<ArrayList> rows) {
- int colCount = columnNames.length;
- boolean foundID = false;
- // Add an _id column if not in columnNames
- for (int i = 0; i < colCount; ++i) {
- if (columnNames[i].compareToIgnoreCase("_id") == 0) {
- mColumnNames = columnNames;
- foundID = true;
- break;
- }
- }
-
- if (!foundID) {
- mColumnNames = new String[colCount + 1];
- System.arraycopy(columnNames, 0, mColumnNames, 0, columnNames.length);
- mColumnNames[colCount] = "_id";
- }
-
- int rowCount = rows.size();
- mRows = new ArrayList[rowCount];
-
- for (int i = 0; i < rowCount; ++i) {
- mRows[i] = rows.get(i);
- if (!foundID) {
- mRows[i].add(i);
- }
- }
- }
-
- @Override
- public void fillWindow(int position, CursorWindow window) {
- if (position < 0 || position > getCount()) {
- return;
- }
-
- window.acquireReference();
- try {
- int oldpos = mPos;
- mPos = position - 1;
- window.clear();
- window.setStartPosition(position);
- int columnNum = getColumnCount();
- window.setNumColumns(columnNum);
- while (moveToNext() && window.allocRow()) {
- for (int i = 0; i < columnNum; i++) {
- final Object data = mRows[mPos].get(i);
- if (data != null) {
- if (data instanceof byte[]) {
- byte[] field = (byte[]) data;
- if (!window.putBlob(field, mPos, i)) {
- window.freeLastRow();
- break;
- }
- } else {
- String field = data.toString();
- if (!window.putString(field, mPos, i)) {
- window.freeLastRow();
- break;
- }
- }
- } else {
- if (!window.putNull(mPos, i)) {
- window.freeLastRow();
- break;
- }
- }
- }
- }
-
- mPos = oldpos;
- } catch (IllegalStateException e){
- // simply ignore it
- } finally {
- window.releaseReference();
- }
- }
-
- @Override
- public int getCount() {
- return mRows.length;
- }
-
- @Override
- public String[] getColumnNames() {
- return mColumnNames;
- }
-
- @Override
- public byte[] getBlob(int columnIndex) {
- return (byte[]) mRows[mPos].get(columnIndex);
- }
-
- @Override
- public String getString(int columnIndex) {
- Object cell = mRows[mPos].get(columnIndex);
- return (cell == null) ? null : cell.toString();
- }
-
- @Override
- public short getShort(int columnIndex) {
- Number num = (Number) mRows[mPos].get(columnIndex);
- return num.shortValue();
- }
-
- @Override
- public int getInt(int columnIndex) {
- Number num = (Number) mRows[mPos].get(columnIndex);
- return num.intValue();
- }
-
- @Override
- public long getLong(int columnIndex) {
- Number num = (Number) mRows[mPos].get(columnIndex);
- return num.longValue();
- }
-
- @Override
- public float getFloat(int columnIndex) {
- Number num = (Number) mRows[mPos].get(columnIndex);
- return num.floatValue();
- }
-
- @Override
- public double getDouble(int columnIndex) {
- Number num = (Number) mRows[mPos].get(columnIndex);
- return num.doubleValue();
- }
-
- @Override
- public boolean isNull(int columnIndex) {
- return mRows[mPos].get(columnIndex) == null;
- }
-}
-
/**
* {@hide}
@@ -191,7 +45,8 @@
private static final String[] ADDRESS_BOOK_COLUMN_NAMES = new String[] {
"name",
"number",
- "emails"
+ "emails",
+ "_id"
};
private static final int ADN = 1;
@@ -213,70 +68,27 @@
}
- private boolean mSimulator;
-
@Override
public boolean onCreate() {
- String device = SystemProperties.get("ro.product.device");
- if (!TextUtils.isEmpty(device)) {
- mSimulator = false;
- } else {
- // simulator
- mSimulator = true;
- }
-
return true;
}
@Override
public Cursor query(Uri url, String[] projection, String selection,
String[] selectionArgs, String sort) {
- ArrayList<ArrayList> results;
+ switch (URL_MATCHER.match(url)) {
+ case ADN:
+ return loadFromEf(IccConstants.EF_ADN);
- if (!mSimulator) {
- switch (URL_MATCHER.match(url)) {
- case ADN:
- results = loadFromEf(IccConstants.EF_ADN);
- break;
+ case FDN:
+ return loadFromEf(IccConstants.EF_FDN);
- case FDN:
- results = loadFromEf(IccConstants.EF_FDN);
- break;
+ case SDN:
+ return loadFromEf(IccConstants.EF_SDN);
- case SDN:
- results = loadFromEf(IccConstants.EF_SDN);
- break;
-
- default:
- throw new IllegalArgumentException("Unknown URL " + url);
- }
- } else {
- // Fake up some data for the simulator
- results = new ArrayList<ArrayList>(4);
- ArrayList<String> contact;
-
- contact = new ArrayList<String>();
- contact.add("Ron Stevens/H");
- contact.add("512-555-5038");
- results.add(contact);
-
- contact = new ArrayList<String>();
- contact.add("Ron Stevens/M");
- contact.add("512-555-8305");
- results.add(contact);
-
- contact = new ArrayList<String>();
- contact.add("Melissa Owens");
- contact.add("512-555-8305");
- results.add(contact);
-
- contact = new ArrayList<String>();
- contact.add("Directory Assistence");
- contact.add("411");
- results.add(contact);
+ default:
+ throw new IllegalArgumentException("Unknown URL " + url);
}
-
- return new ArrayListCursor(ADDRESS_BOOK_COLUMN_NAMES, results);
}
@Override
@@ -473,12 +285,10 @@
return 1;
}
- private ArrayList<ArrayList> loadFromEf(int efType) {
- ArrayList<ArrayList> results = new ArrayList<ArrayList>();
- List<AdnRecord> adnRecords = null;
-
+ private MatrixCursor loadFromEf(int efType) {
if (DBG) log("loadFromEf: efType=" + efType);
+ List<AdnRecord> adnRecords = null;
try {
IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
ServiceManager.getService("simphonebook"));
@@ -490,21 +300,21 @@
} catch (SecurityException ex) {
if (DBG) log(ex.toString());
}
+
if (adnRecords != null) {
// Load the results
-
- int N = adnRecords.size();
+ final int N = adnRecords.size();
+ final MatrixCursor cursor = new MatrixCursor(ADDRESS_BOOK_COLUMN_NAMES, N);
if (DBG) log("adnRecords.size=" + N);
for (int i = 0; i < N ; i++) {
- loadRecord(adnRecords.get(i), results);
+ loadRecord(adnRecords.get(i), cursor, i);
}
+ return cursor;
} else {
// No results to load
Log.w(TAG, "Cannot load ADN records");
- results.clear();
+ return new MatrixCursor(ADDRESS_BOOK_COLUMN_NAMES);
}
- if (DBG) log("loadFromEf: return results");
- return results;
}
private boolean
@@ -584,35 +394,33 @@
}
/**
- * Loads an AdnRecord into an ArrayList. Must be called with mLock held.
+ * Loads an AdnRecord into a MatrixCursor. Must be called with mLock held.
*
* @param record the ADN record to load from
- * @param results the array list to put the results in
+ * @param cursor the cursor to receive the results
*/
- private void loadRecord(AdnRecord record,
- ArrayList<ArrayList> results) {
+ private void loadRecord(AdnRecord record, MatrixCursor cursor, int id) {
if (!record.isEmpty()) {
- ArrayList<String> contact = new ArrayList<String>();
+ Object[] contact = new Object[4];
String alphaTag = record.getAlphaTag();
String number = record.getNumber();
- String[] emails = record.getEmails();
if (DBG) log("loadRecord: " + alphaTag + ", " + number + ",");
- contact.add(alphaTag);
- contact.add(number);
- StringBuilder emailString = new StringBuilder();
+ contact[0] = alphaTag;
+ contact[1] = number;
+ String[] emails = record.getEmails();
if (emails != null) {
+ StringBuilder emailString = new StringBuilder();
for (String email: emails) {
if (DBG) log("Adding email:" + email);
emailString.append(email);
emailString.append(",");
}
- contact.add(emailString.toString());
- } else {
- contact.add(null);
+ contact[2] = emailString.toString();
}
- results.add(contact);
+ contact[3] = id;
+ cursor.addRow(contact);
}
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index a7a4908..10121dd 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -832,6 +832,22 @@
mNotifier.notifyOtaspChanged(this, otaspMode);
}
+ /**
+ * @return true if a mobile originating emergency call is active
+ */
+ public boolean isInEmergencyCall() {
+ return false;
+ }
+
+ /**
+ * @return true if we are in the emergency call back mode. This is a period where
+ * the phone should be using as little power as possible and be ready to receive an
+ * incoming call from the emergency operator.
+ */
+ public boolean isInEcm() {
+ return false;
+ }
+
public abstract String getPhoneName();
public abstract int getPhoneType();
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
index e4c6028..a42a267 100644
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -518,6 +518,7 @@
* @param address the originating address
* @param referenceNumber distinguishes concatenated messages from the same sender
* @param sequenceNumber the order of this segment in the message
+ * (starting at 0 for CDMA WDP datagrams and 1 for concatenated messages).
* @param messageCount the number of segments in the message
* @param timestamp the service center timestamp in millis
* @param destPort the destination port for the message, or -1 for no destination port
@@ -583,7 +584,11 @@
for (int i = 0; i < cursorCount; i++) {
cursor.moveToNext();
int cursorSequence = cursor.getInt(SEQUENCE_COLUMN);
- pdus[cursorSequence - 1] = HexDump.hexStringToByteArray(
+ // GSM sequence numbers start at 1; CDMA WDP datagram sequence numbers start at 0
+ if (!isCdmaWapPush) {
+ cursorSequence--;
+ }
+ pdus[cursorSequence] = HexDump.hexStringToByteArray(
cursor.getString(PDU_COLUMN));
// Read the destination port from the first segment (needed for CDMA WAP PDU).
@@ -593,7 +598,12 @@
}
}
// This one isn't in the DB, so add it
- pdus[sequenceNumber - 1] = pdu;
+ // GSM sequence numbers start at 1; CDMA WDP datagram sequence numbers start at 0
+ if (isCdmaWapPush) {
+ pdus[sequenceNumber] = pdu;
+ } else {
+ pdus[sequenceNumber - 1] = pdu;
+ }
// Remove the parts from the database
mResolver.delete(mRawUri, where, whereArgs);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
index c2b9e4f..4f50d24 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
@@ -18,13 +18,17 @@
import android.content.ContentValues;
import android.content.Context;
+import android.content.SharedPreferences;
import android.database.SQLException;
import android.net.Uri;
+import android.os.AsyncResult;
import android.os.Message;
+import android.preference.PreferenceManager;
import android.provider.Telephony;
import android.util.Log;
import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.OperatorInfo;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneNotifier;
import com.android.internal.telephony.PhoneProxy;
@@ -41,6 +45,18 @@
/** Secondary SMSDispatcher for 3GPP format messages. */
SMSDispatcher m3gppSMS;
+ /**
+ * Small container class used to hold information relevant to
+ * the carrier selection process. operatorNumeric can be ""
+ * if we are looking for automatic selection. operatorAlphaLong is the
+ * corresponding operator name.
+ */
+ private static class NetworkSelectMessage {
+ public Message message;
+ public String operatorNumeric;
+ public String operatorAlphaLong;
+ }
+
// Constructors
public CDMALTEPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
super(context, ci, notifier, false);
@@ -48,6 +64,20 @@
}
@Override
+ public void handleMessage (Message msg) {
+ AsyncResult ar;
+ Message onComplete;
+ switch (msg.what) {
+ // handle the select network completion callbacks.
+ case EVENT_SET_NETWORK_MANUAL_COMPLETE:
+ handleSetSelectNetwork((AsyncResult) msg.obj);
+ break;
+ default:
+ super.handleMessage(msg);
+ }
+ }
+
+ @Override
protected void initSstIcc() {
mSST = new CdmaLteServiceStateTracker(this);
mIccRecords = new CdmaLteUiccRecords(this);
@@ -109,6 +139,58 @@
}
@Override
+ public void
+ selectNetworkManually(OperatorInfo network,
+ Message response) {
+ // wrap the response message in our own message along with
+ // the operator's id.
+ NetworkSelectMessage nsm = new NetworkSelectMessage();
+ nsm.message = response;
+ nsm.operatorNumeric = network.getOperatorNumeric();
+ nsm.operatorAlphaLong = network.getOperatorAlphaLong();
+
+ // get the message
+ Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm);
+
+ mCM.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg);
+ }
+
+ /**
+ * Used to track the settings upon completion of the network change.
+ */
+ private void handleSetSelectNetwork(AsyncResult ar) {
+ // look for our wrapper within the asyncresult, skip the rest if it
+ // is null.
+ if (!(ar.userObj instanceof NetworkSelectMessage)) {
+ if (DBG) Log.d(LOG_TAG, "unexpected result from user object.");
+ return;
+ }
+
+ NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj;
+
+ // found the object, now we send off the message we had originally
+ // attached to the request.
+ if (nsm.message != null) {
+ if (DBG) Log.d(LOG_TAG, "sending original message to recipient");
+ AsyncResult.forMessage(nsm.message, ar.result, ar.exception);
+ nsm.message.sendToTarget();
+ }
+
+ // open the shared preferences editor, and write the value.
+ // nsm.operatorNumeric is "" if we're in automatic.selection.
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putString(NETWORK_SELECTION_KEY, nsm.operatorNumeric);
+ editor.putString(NETWORK_SELECTION_NAME_KEY, nsm.operatorAlphaLong);
+
+ // commit and log the result.
+ if (! editor.commit()) {
+ Log.e(LOG_TAG, "failed to commit network selection preference");
+ }
+
+ }
+
+ @Override
public boolean updateCurrentCarrierInProvider() {
if (mIccRecords != null) {
try {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 09ee28c..58e3e5f 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -848,6 +848,14 @@
mUnknownConnectionRegistrants.notifyResult(this);
}
+ public boolean isInEmergencyCall() {
+ return mCT.isInEmergencyCall();
+ }
+
+ public boolean isInEcm() {
+ return mIsPhoneInEcmState;
+ }
+
void sendEmergencyCallbackModeChange(){
//Send an Intent
Intent intent = new Intent(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 4dace82..f5d05a1 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -237,7 +237,7 @@
// FIXME this can be improved
setState(State.CONNECTED);
notifyDataConnection(reason);
- notifyOffApnsOfAvailability(reason, true);
+ notifyOffApnsOfAvailability(reason);
log("(fix?) We're on the simulator; assuming data is connected");
return true;
@@ -248,12 +248,12 @@
boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState();
if ((mState == State.IDLE || mState == State.SCANNING) &&
- isDataAllowed() && getAnyDataEnabled()) {
+ isDataAllowed() && getAnyDataEnabled() && !isEmergency()) {
boolean retValue = setupData(reason);
- notifyOffApnsOfAvailability(reason, retValue);
+ notifyOffApnsOfAvailability(reason);
return retValue;
} else {
- notifyOffApnsOfAvailability(reason, false);
+ notifyOffApnsOfAvailability(reason);
return false;
}
}
@@ -276,7 +276,7 @@
}
setState(State.DISCONNECTING);
- notifyDataAvailability(reason);
+ notifyOffApnsOfAvailability(reason);
boolean notificationDeferred = false;
for (DataConnection conn : mDataConnections.values()) {
@@ -536,7 +536,7 @@
private void notifyNoData(FailCause lastFailCauseCode) {
setState(State.FAILED);
- notifyDataAvailability(null);
+ notifyOffApnsOfAvailability(null);
}
protected void gotoIdleAndNotifyDataConnection(String reason) {
@@ -583,7 +583,7 @@
@Override
protected void onRoamingOff() {
if (getDataOnRoamingEnabled() == false) {
- notifyDataAvailability(Phone.REASON_ROAMING_OFF);
+ notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
trySetupData(Phone.REASON_ROAMING_OFF);
} else {
notifyDataConnection(Phone.REASON_ROAMING_OFF);
@@ -601,7 +601,7 @@
} else {
if (DBG) log("Tear down data connection on roaming.");
cleanUpAllConnections(null);
- notifyDataAvailability(Phone.REASON_ROAMING_ON);
+ notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
}
}
@@ -619,7 +619,7 @@
log("We're on the simulator; assuming data is connected");
}
- notifyDataAvailability(null);
+ notifyOffApnsOfAvailability(null);
if (mState != State.IDLE) {
cleanUpAllConnections(null);
@@ -710,7 +710,7 @@
if (mState == State.CONNECTED && !mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed()) {
stopNetStatPoll();
notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
- notifyDataAvailability(Phone.REASON_VOICE_CALL_STARTED);
+ notifyOffApnsOfAvailability(Phone.REASON_VOICE_CALL_STARTED);
}
}
@@ -727,7 +727,7 @@
// clean slate after call end.
resetPollStats();
}
- notifyDataAvailability(Phone.REASON_VOICE_CALL_ENDED);
+ notifyOffApnsOfAvailability(Phone.REASON_VOICE_CALL_ENDED);
} else {
mDataConnections.get(0).resetRetryCount();
// in case data setup was attempted when we were on a voice call
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index dded39e..ca8d9ae 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -88,6 +88,7 @@
PendingIntent intent = tracker.mDeliveryIntent;
Intent fillIn = new Intent();
fillIn.putExtra("pdu", sms.getPdu());
+ fillIn.putExtra("format", android.telephony.SmsMessage.FORMAT_3GPP2);
try {
intent.send(mContext, Activity.RESULT_OK, fillIn);
} catch (CanceledException ex) {}
@@ -197,13 +198,18 @@
protected int processCdmaWapPdu(byte[] pdu, int referenceNumber, String address) {
int index = 0;
- int msgType = pdu[index++];
+ int msgType = (0xFF & pdu[index++]);
if (msgType != 0) {
Log.w(TAG, "Received a WAP SMS which is not WDP. Discard.");
return Intents.RESULT_SMS_HANDLED;
}
- int totalSegments = pdu[index++]; // >= 1
- int segment = pdu[index++]; // >= 0
+ int totalSegments = (0xFF & pdu[index++]); // >= 1
+ int segment = (0xFF & pdu[index++]); // >= 0
+
+ if (segment >= totalSegments) {
+ Log.e(TAG, "WDP bad segment #" + segment + " expecting 0-" + (totalSegments - 1));
+ return Intents.RESULT_SMS_HANDLED;
+ }
// Only the first segment contains sourcePort and destination Port
int sourcePort = 0;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 8f5a2eb..3d6cd68 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -726,7 +726,7 @@
isPrlLoaded = false;
}
if (!isPrlLoaded) {
- newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_FLASH);
+ newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF);
} else if (!isSidsAllZeros()) {
if (!namMatch && !mIsInPrl) {
// Use default
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 78ba7dd..e166401 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -273,7 +273,14 @@
break;
case ConnectivityManager.TYPE_MOBILE_HIPRI:
apnContext = addApnContext(Phone.APN_TYPE_HIPRI);
- break;
+ ApnContext defaultContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
+ if (defaultContext != null) {
+ applyNewState(apnContext, apnContext.isEnabled(),
+ defaultContext.getDependencyMet());
+ } else {
+ // the default will set the hipri dep-met when it is created
+ }
+ continue;
case ConnectivityManager.TYPE_MOBILE_FOTA:
apnContext = addApnContext(Phone.APN_TYPE_FOTA);
break;
@@ -556,7 +563,7 @@
notifyDataConnection(Phone.REASON_DATA_ATTACHED);
} else {
// update APN availability so that APN can be enabled.
- notifyDataAvailability(Phone.REASON_DATA_ATTACHED);
+ notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
}
setupDataOnReadyApns(Phone.REASON_DATA_ATTACHED);
@@ -686,14 +693,14 @@
boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
if ((apnContext.getState() == State.IDLE || apnContext.getState() == State.SCANNING) &&
- isDataAllowed(apnContext) && getAnyDataEnabled()) {
+ isDataAllowed(apnContext) && getAnyDataEnabled() && !isEmergency()) {
if (apnContext.getState() == State.IDLE) {
ArrayList<ApnSetting> waitingApns = buildWaitingApns(apnContext.getApnType());
if (waitingApns.isEmpty()) {
if (DBG) log("trySetupData: No APN found");
notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN, apnContext);
- notifyOffApnsOfAvailability(apnContext.getReason(), false);
+ notifyOffApnsOfAvailability(apnContext.getReason());
return false;
} else {
apnContext.setWaitingApns(waitingApns);
@@ -708,7 +715,7 @@
}
// apnContext.setReason(apnContext.getReason());
boolean retValue = setupData(apnContext);
- notifyOffApnsOfAvailability(apnContext.getReason(), retValue);
+ notifyOffApnsOfAvailability(apnContext.getReason());
return retValue;
} else {
// TODO: check the condition.
@@ -716,23 +723,25 @@
&& (apnContext.getState() == State.IDLE
|| apnContext.getState() == State.SCANNING))
mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
- notifyOffApnsOfAvailability(apnContext.getReason(), false);
+ notifyOffApnsOfAvailability(apnContext.getReason());
return false;
}
}
@Override
// Disabled apn's still need avail/unavail notificiations - send them out
- protected void notifyOffApnsOfAvailability(String reason, boolean availability) {
- if (mAvailability == availability) return;
- mAvailability = availability;
-
+ protected void notifyOffApnsOfAvailability(String reason) {
for (ApnContext apnContext : mApnContexts.values()) {
if (!apnContext.isReady()) {
if (DBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
apnContext.getApnType(),
Phone.DataState.DISCONNECTED);
+ } else {
+ if (DBG) {
+ log("notifyOffApnsOfAvailability skipped apn due to isReady==false: " +
+ apnContext.toString());
+ }
}
}
}
@@ -1572,7 +1581,7 @@
createAllApnList();
if (mPhone.mCM.getRadioState().isOn()) {
if (DBG) log("onRecordsLoaded: notifying data availability");
- notifyDataAvailability(Phone.REASON_SIM_LOADED);
+ notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
}
setupDataOnReadyApns(Phone.REASON_SIM_LOADED);
}
@@ -1681,7 +1690,7 @@
if (DBG) log("onRoamingOff");
if (getDataOnRoamingEnabled() == false) {
- notifyDataAvailability(Phone.REASON_ROAMING_OFF);
+ notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
setupDataOnReadyApns(Phone.REASON_ROAMING_OFF);
} else {
notifyDataConnection(Phone.REASON_ROAMING_OFF);
@@ -1697,7 +1706,7 @@
} else {
if (DBG) log("onRoamingOn: Tear down data connection on roaming.");
cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
- notifyDataAvailability(Phone.REASON_ROAMING_ON);
+ notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
}
}
@@ -1714,7 +1723,7 @@
}
if (mPhone.mIccRecords.getRecordsLoaded()) {
- notifyDataAvailability(null);
+ notifyOffApnsOfAvailability(null);
}
if (getOverallState() != State.IDLE) {
@@ -1740,7 +1749,7 @@
if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
}
- notifyDataAvailability(null);
+ notifyOffApnsOfAvailability(null);
}
@Override
@@ -1985,7 +1994,7 @@
apnContext.getApnType());
}
}
- notifyDataAvailability(reason);
+ notifyOffApnsOfAvailability(reason);
}
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
index 4e1cc9a..c1553d8 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -122,6 +122,7 @@
PendingIntent intent = tracker.mDeliveryIntent;
Intent fillIn = new Intent();
fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString));
+ fillIn.putExtra("format", android.telephony.SmsMessage.FORMAT_3GPP);
try {
intent.send(mContext, Activity.RESULT_OK, fillIn);
} catch (CanceledException ex) {}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index ea030e6..2da9642 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -300,8 +300,8 @@
return null;
}
// TP-Data-Coding-Scheme
- // Class 3, UCS-2 encoding, uncompressed
- bo.write(0x0b);
+ // UCS-2 encoding, uncompressed
+ bo.write(0x08);
}
// (no TP-Validity-Period)
diff --git a/test-runner/src/android/test/mock/MockContentProvider.java b/test-runner/src/android/test/mock/MockContentProvider.java
index b63ff3d..e0ce322 100644
--- a/test-runner/src/android/test/mock/MockContentProvider.java
+++ b/test-runner/src/android/test/mock/MockContentProvider.java
@@ -21,16 +21,12 @@
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.Context;
-import android.content.EntityIterator;
import android.content.IContentProvider;
import android.content.OperationApplicationException;
import android.content.pm.PathPermission;
import android.content.pm.ProviderInfo;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
-import android.database.CursorWindow;
-import android.database.IBulkCursor;
-import android.database.IContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
@@ -55,84 +51,75 @@
* IContentProvider that directs all calls to this MockContentProvider.
*/
private class InversionIContentProvider implements IContentProvider {
- @SuppressWarnings("unused")
+ @Override
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
throws RemoteException, OperationApplicationException {
return MockContentProvider.this.applyBatch(operations);
}
- @SuppressWarnings("unused")
+ @Override
public int bulkInsert(Uri url, ContentValues[] initialValues) throws RemoteException {
return MockContentProvider.this.bulkInsert(url, initialValues);
}
- @SuppressWarnings("unused")
- public IBulkCursor bulkQuery(Uri url, String[] projection, String selection,
- String[] selectionArgs, String sortOrder, IContentObserver observer,
- CursorWindow window) throws RemoteException {
- throw new UnsupportedOperationException("Must not come here");
- }
-
- @SuppressWarnings("unused")
+ @Override
public int delete(Uri url, String selection, String[] selectionArgs)
throws RemoteException {
return MockContentProvider.this.delete(url, selection, selectionArgs);
}
- @SuppressWarnings("unused")
+ @Override
public String getType(Uri url) throws RemoteException {
return MockContentProvider.this.getType(url);
}
- @SuppressWarnings("unused")
+ @Override
public Uri insert(Uri url, ContentValues initialValues) throws RemoteException {
return MockContentProvider.this.insert(url, initialValues);
}
- @SuppressWarnings("unused")
+ @Override
public AssetFileDescriptor openAssetFile(Uri url, String mode) throws RemoteException,
FileNotFoundException {
return MockContentProvider.this.openAssetFile(url, mode);
}
- @SuppressWarnings("unused")
+ @Override
public ParcelFileDescriptor openFile(Uri url, String mode) throws RemoteException,
FileNotFoundException {
return MockContentProvider.this.openFile(url, mode);
}
- @SuppressWarnings("unused")
+ @Override
public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
String sortOrder) throws RemoteException {
return MockContentProvider.this.query(url, projection, selection,
selectionArgs, sortOrder);
}
- @SuppressWarnings("unused")
+ @Override
public int update(Uri url, ContentValues values, String selection, String[] selectionArgs)
throws RemoteException {
return MockContentProvider.this.update(url, values, selection, selectionArgs);
}
- /**
- * @hide
- */
- @SuppressWarnings("unused")
+ @Override
public Bundle call(String method, String request, Bundle args)
throws RemoteException {
return MockContentProvider.this.call(method, request, args);
}
+ @Override
public IBinder asBinder() {
throw new UnsupportedOperationException();
}
- @SuppressWarnings("unused")
+ @Override
public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException {
return MockContentProvider.this.getStreamTypes(url, mimeTypeFilter);
}
- @SuppressWarnings("unused")
+ @Override
public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts)
throws RemoteException, FileNotFoundException {
return MockContentProvider.this.openTypedAssetFile(url, mimeType, opts);
diff --git a/test-runner/src/android/test/mock/MockIContentProvider.java b/test-runner/src/android/test/mock/MockIContentProvider.java
index 183be41..b7733a4 100644
--- a/test-runner/src/android/test/mock/MockIContentProvider.java
+++ b/test-runner/src/android/test/mock/MockIContentProvider.java
@@ -23,9 +23,6 @@
import android.content.IContentProvider;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
-import android.database.CursorWindow;
-import android.database.IBulkCursor;
-import android.database.IContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
@@ -47,12 +44,6 @@
throw new UnsupportedOperationException("unimplemented mock method");
}
- public IBulkCursor bulkQuery(Uri url, String[] projection, String selection,
- String[] selectionArgs, String sortOrder, IContentObserver observer,
- CursorWindow window) {
- throw new UnsupportedOperationException("unimplemented mock method");
- }
-
@SuppressWarnings("unused")
public int delete(Uri url, String selection, String[] selectionArgs)
throws RemoteException {
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/GLTextureViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/GLTextureViewActivity.java
index 3232eedc..414ae0d 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/GLTextureViewActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/GLTextureViewActivity.java
@@ -22,9 +22,11 @@
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.opengl.GLUtils;
import android.os.Bundle;
+import android.os.Environment;
import android.util.Log;
import android.view.Gravity;
import android.view.TextureView;
@@ -39,6 +41,7 @@
import javax.microedition.khronos.egl.EGLSurface;
import javax.microedition.khronos.opengles.GL;
import java.io.BufferedOutputStream;
+import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -65,7 +68,8 @@
Bitmap b = mTextureView.getBitmap(800, 800);
BufferedOutputStream out = null;
try {
- out = new BufferedOutputStream(new FileOutputStream("/sdcard/out.png"));
+ File dump = new File(Environment.getExternalStorageDirectory(), "out.png");
+ out = new BufferedOutputStream(new FileOutputStream(dump));
b.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
@@ -168,10 +172,10 @@
private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
private final float[] mTriangleVerticesData = {
// X, Y, Z, U, V
- -1.0f, -1.0f, 0, 0.f, 0.f,
- 1.0f, -1.0f, 0, 1.f, 0.f,
- -1.0f, 1.0f, 0, 0.f, 1.f,
- 1.0f, 1.0f, 0, 1.f, 1.f,
+ -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
+ -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
};
@Override
@@ -212,8 +216,6 @@
while (!mFinished) {
checkCurrent();
- Log.d(LOG_TAG, "Rendering frame");
-
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
checkGlError();
@@ -237,7 +239,7 @@
checkEglError();
try {
- Thread.sleep(20);
+ Thread.sleep(2000);
} catch (InterruptedException e) {
// Ignore
}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TextureViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TextureViewActivity.java
index fcb57d9..0f4c668 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/TextureViewActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TextureViewActivity.java
@@ -17,16 +17,23 @@
package com.android.test.hwui;
import android.app.Activity;
+import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
+import android.os.Environment;
import android.view.Gravity;
+import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
@SuppressWarnings({"UnusedDeclaration"})
@@ -44,6 +51,26 @@
mTextureView = new TextureView(this);
mTextureView.setSurfaceTextureListener(this);
+ mTextureView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Bitmap b = mTextureView.getBitmap(800, 800);
+ BufferedOutputStream out = null;
+ try {
+ File dump = new File(Environment.getExternalStorageDirectory(), "out.png");
+ out = new BufferedOutputStream(new FileOutputStream(dump));
+ b.compress(Bitmap.CompressFormat.PNG, 100, out);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } finally {
+ if (out != null) try {
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ });
Button button = new Button(this);
button.setText("Remove/Add");
@@ -73,6 +100,8 @@
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mCamera = Camera.open();
+ mCamera.setDisplayOrientation(getCameraOrientation());
+
Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
mTextureView.setLayoutParams(new FrameLayout.LayoutParams(
previewSize.width, previewSize.height, Gravity.CENTER));
@@ -86,6 +115,34 @@
mCamera.startPreview();
}
+ private int getCameraOrientation() {
+ Camera.CameraInfo info = new Camera.CameraInfo();
+ for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
+ Camera.getCameraInfo(i, info);
+ if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) break;
+ }
+
+ int rotation = getWindowManager().getDefaultDisplay().getRotation();
+ int degrees = 0;
+
+ switch (rotation) {
+ case Surface.ROTATION_0:
+ degrees = 0;
+ break;
+ case Surface.ROTATION_90:
+ degrees = 90;
+ break;
+ case Surface.ROTATION_180:
+ degrees = 180;
+ break;
+ case Surface.ROTATION_270:
+ degrees = 270;
+ break;
+ }
+
+ return (info.orientation - degrees + 360) % 360;
+ }
+
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
// Ignored, the Camera does all the work for us
diff --git a/tests/RenderScriptTests/ComputePerf/Android.mk b/tests/RenderScriptTests/ComputePerf/Android.mk
new file mode 100644
index 0000000..1d67d29
--- /dev/null
+++ b/tests/RenderScriptTests/ComputePerf/Android.mk
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+ $(call all-renderscript-files-under, src)
+
+LOCAL_PACKAGE_NAME := RsComputePerf
+
+include $(BUILD_PACKAGE)
diff --git a/tests/RenderScriptTests/ComputePerf/AndroidManifest.xml b/tests/RenderScriptTests/ComputePerf/AndroidManifest.xml
new file mode 100644
index 0000000..a9193b5
--- /dev/null
+++ b/tests/RenderScriptTests/ComputePerf/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.rs.computeperf">
+
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-sdk android:minSdkVersion="14" />
+ <application android:label="Compute Perf">
+ <activity android:name="ComputePerf">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/tests/RenderScriptTests/ComputePerf/res/layout/main.xml b/tests/RenderScriptTests/ComputePerf/res/layout/main.xml
new file mode 100644
index 0000000..61cd24d
--- /dev/null
+++ b/tests/RenderScriptTests/ComputePerf/res/layout/main.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ImageView
+ android:id="@+id/displayin"
+ android:layout_width="320dip"
+ android:layout_height="266dip" />
+
+ <ImageView
+ android:id="@+id/displayout"
+ android:layout_width="320dip"
+ android:layout_height="266dip" />
+
+</LinearLayout>
diff --git a/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/ComputePerf.java b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/ComputePerf.java
new file mode 100644
index 0000000..f7abe8b
--- /dev/null
+++ b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/ComputePerf.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.rs.computeperf;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.graphics.BitmapFactory;
+import android.graphics.Bitmap;
+import android.renderscript.RenderScript;
+import android.renderscript.Allocation;
+import android.widget.ImageView;
+
+public class ComputePerf extends Activity {
+
+ private LaunchTest mLT;
+ private Mandelbrot mMandel;
+ private RenderScript mRS;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ mRS = RenderScript.create(this);
+ mLT = new LaunchTest(mRS, getResources());
+ mLT.run();
+ mLT.run();
+
+ mMandel = new Mandelbrot(mRS, getResources());
+ mMandel.run();
+
+ }
+
+}
diff --git a/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/LaunchTest.java b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/LaunchTest.java
new file mode 100644
index 0000000..0c29ce1
--- /dev/null
+++ b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/LaunchTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.rs.computeperf;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+
+public class LaunchTest implements Runnable {
+ private RenderScript mRS;
+ private Allocation mAllocationX;
+ private Allocation mAllocationXY;
+ private ScriptC_launchtestxlw mScript_xlw;
+ private ScriptC_launchtestxyw mScript_xyw;
+
+ LaunchTest(RenderScript rs, Resources res) {
+ mRS = rs;
+ mScript_xlw = new ScriptC_launchtestxlw(mRS, res, R.raw.launchtestxlw);
+ mScript_xyw = new ScriptC_launchtestxyw(mRS, res, R.raw.launchtestxyw);
+ final int dim = mScript_xlw.get_dim();
+
+ mAllocationX = Allocation.createSized(rs, Element.U8(rs), dim);
+ Type.Builder tb = new Type.Builder(rs, Element.U8(rs));
+ tb.setX(dim);
+ tb.setY(dim);
+ mAllocationXY = Allocation.createTyped(rs, tb.create());
+ mScript_xlw.bind_buf(mAllocationXY);
+ }
+
+ public void run() {
+ long t = java.lang.System.currentTimeMillis();
+ mScript_xlw.forEach_root(mAllocationX);
+ mRS.finish();
+ t = java.lang.System.currentTimeMillis() - t;
+ android.util.Log.v("ComputePerf", "xlw launch test ms " + t);
+
+ t = java.lang.System.currentTimeMillis();
+ mScript_xyw.forEach_root(mAllocationXY);
+ mRS.finish();
+ t = java.lang.System.currentTimeMillis() - t;
+ android.util.Log.v("ComputePerf", "xyw launch test ms " + t);
+ }
+
+}
diff --git a/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/Mandelbrot.java b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/Mandelbrot.java
new file mode 100644
index 0000000..ea1cd62
--- /dev/null
+++ b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/Mandelbrot.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.rs.computeperf;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+
+public class Mandelbrot implements Runnable {
+ private RenderScript mRS;
+ private Allocation mAllocationXY;
+ private ScriptC_mandelbrot mScript;
+
+ Mandelbrot(RenderScript rs, Resources res) {
+ mRS = rs;
+ mScript = new ScriptC_mandelbrot(mRS, res, R.raw.mandelbrot);
+
+ Type.Builder tb = new Type.Builder(rs, Element.U8_4(rs));
+ tb.setX(mScript.get_gDimX());
+ tb.setY(mScript.get_gDimY());
+ mAllocationXY = Allocation.createTyped(rs, tb.create());
+ }
+
+ public void run() {
+ long t = java.lang.System.currentTimeMillis();
+ mScript.forEach_root(mAllocationXY);
+ mRS.finish();
+ t = java.lang.System.currentTimeMillis() - t;
+ android.util.Log.v("ComputePerf", "mandelbrot ms " + t);
+ }
+
+}
diff --git a/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/launchtestxlw.rs b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/launchtestxlw.rs
new file mode 100644
index 0000000..7b81dfe
--- /dev/null
+++ b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/launchtestxlw.rs
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.example.android.rs.computeperf)
+
+const int dim = 2048;
+uint8_t *buf;
+
+void root(uchar *v_out, uint32_t x) {
+ uint8_t *p = buf;
+ p += x * dim;
+ for (int i=0; i<dim; i++) {
+ p[i] = 1;
+ }
+}
+
diff --git a/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/launchtestxyw.rs b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/launchtestxyw.rs
new file mode 100644
index 0000000..7f7aa95
--- /dev/null
+++ b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/launchtestxyw.rs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.example.android.rs.computeperf)
+
+void root(uchar *v_out, uint32_t x, uint32_t y) {
+ *v_out = 0;
+}
+
diff --git a/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rs b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rs
new file mode 100644
index 0000000..a7987b3
--- /dev/null
+++ b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rs
@@ -0,0 +1,42 @@
+// Copyright (C) 2011 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma version(1)
+#pragma rs java_package_name(com.example.android.rs.computeperf)
+
+const int gMaxIteration = 500;
+const int gDimX = 1024;
+const int gDimY = 1024;
+
+void root(uchar4 *v_out, uint32_t x, uint32_t y) {
+ float2 p;
+ p.x = -2.5f + ((float)x / gDimX) * 3.5f;
+ p.y = -1.f + ((float)y / gDimY) * 2.f;
+
+ float2 t = 0;
+ int iteration = 0;
+ while((t.x*t.x + t.y*t.y < 4.f) && (iteration < gMaxIteration)) {
+ float2 t2 = t * t;
+ float xtemp = t2.x - t2.y + p.x;
+ t.y = 2 * t.x * t.y + p.y;
+ t.x = xtemp;
+ iteration++;
+ }
+
+ if(iteration >= gMaxIteration) {
+ *v_out = 0;
+ } else {
+ *v_out = (uchar4){iteration & 0xff, (iteration >> 6) & 0xff, 0x8f, 0xff};
+ }
+}
diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs
index b77ccb4..42b1cf1 100644
--- a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs
+++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs
@@ -105,8 +105,8 @@
rsgMeshComputeBoundingBox(info->mMesh,
&minX, &minY, &minZ,
&maxX, &maxY, &maxZ);
- info->bBoxMin = (minX, minY, minZ);
- info->bBoxMax = (maxX, maxY, maxZ);
+ info->bBoxMin = (float3){minX, minY, minZ};
+ info->bBoxMax = (float3){maxX, maxY, maxZ};
gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f;
}
gLookAt = gLookAt / (float)size;
diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs
index d44fd2b..05ef3ac 100644
--- a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs
+++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs
@@ -104,8 +104,8 @@
rsgMeshComputeBoundingBox(info->mMesh,
&minX, &minY, &minZ,
&maxX, &maxY, &maxZ);
- info->bBoxMin = (minX, minY, minZ);
- info->bBoxMax = (maxX, maxY, maxZ);
+ info->bBoxMin = (float3){minX, minY, minZ};
+ info->bBoxMax = (float3){maxX, maxY, maxZ};
gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f;
}
gLookAt = gLookAt / (float)size;
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
index c038478..4466e59 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
@@ -64,6 +64,9 @@
unitTests = new ArrayList<UnitTest>();
+ unitTests.add(new UT_sampler(this, mRes, mCtx));
+ unitTests.add(new UT_program_store(this, mRes, mCtx));
+ unitTests.add(new UT_program_raster(this, mRes, mCtx));
unitTests.add(new UT_primitives(this, mRes, mCtx));
unitTests.add(new UT_vector(this, mRes, mCtx));
unitTests.add(new UT_rsdebug(this, mRes, mCtx));
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_raster.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_raster.java
new file mode 100644
index 0000000..1fbf97a
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_raster.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.ProgramRaster;
+import android.renderscript.ProgramRaster.CullMode;
+
+public class UT_program_raster extends UnitTest {
+ private Resources mRes;
+
+ protected UT_program_raster(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "ProgramRaster", ctx);
+ mRes = res;
+ }
+
+ private ProgramRaster.Builder getDefaultBuilder(RenderScript RS) {
+ ProgramRaster.Builder b = new ProgramRaster.Builder(RS);
+ b.setCullMode(CullMode.BACK);
+ b.setPointSpriteEnabled(false);
+ return b;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_program_raster s) {
+ ProgramRaster.Builder b = getDefaultBuilder(RS);
+ s.set_pointSpriteEnabled(b.setPointSpriteEnabled(true).create());
+ b = getDefaultBuilder(RS);
+ s.set_cullMode(b.setCullMode(CullMode.FRONT).create());
+ return;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_program_raster s = new ScriptC_program_raster(pRS, mRes, R.raw.program_raster);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.invoke_program_raster_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_store.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_store.java
new file mode 100644
index 0000000..e06112c
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_store.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.ProgramStore.BlendDstFunc;
+import android.renderscript.ProgramStore.BlendSrcFunc;
+import android.renderscript.ProgramStore.Builder;
+import android.renderscript.ProgramStore.DepthFunc;
+
+public class UT_program_store extends UnitTest {
+ private Resources mRes;
+
+ protected UT_program_store(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "ProgramStore", ctx);
+ mRes = res;
+ }
+
+ private ProgramStore.Builder getDefaultBuilder(RenderScript RS) {
+ ProgramStore.Builder b = new ProgramStore.Builder(RS);
+ b.setBlendFunc(ProgramStore.BlendSrcFunc.ZERO, ProgramStore.BlendDstFunc.ZERO);
+ b.setColorMaskEnabled(false, false, false, false);
+ b.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+ b.setDepthMaskEnabled(false);
+ b.setDitherEnabled(false);
+ return b;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_program_store s) {
+ ProgramStore.Builder b = getDefaultBuilder(RS);
+ s.set_ditherEnable(b.setDitherEnabled(true).create());
+
+ b = getDefaultBuilder(RS);
+ s.set_colorRWriteEnable(b.setColorMaskEnabled(true, false, false, false).create());
+
+ b = getDefaultBuilder(RS);
+ s.set_colorGWriteEnable(b.setColorMaskEnabled(false, true, false, false).create());
+
+ b = getDefaultBuilder(RS);
+ s.set_colorBWriteEnable(b.setColorMaskEnabled(false, false, true, false).create());
+
+ b = getDefaultBuilder(RS);
+ s.set_colorAWriteEnable(b.setColorMaskEnabled(false, false, false, true).create());
+
+ b = getDefaultBuilder(RS);
+ s.set_blendSrc(b.setBlendFunc(ProgramStore.BlendSrcFunc.DST_COLOR,
+ ProgramStore.BlendDstFunc.ZERO).create());
+
+ b = getDefaultBuilder(RS);
+ s.set_blendDst(b.setBlendFunc(ProgramStore.BlendSrcFunc.ZERO,
+ ProgramStore.BlendDstFunc.DST_ALPHA).create());
+
+ b = getDefaultBuilder(RS);
+ s.set_depthWriteEnable(b.setDepthMaskEnabled(true).create());
+
+ b = getDefaultBuilder(RS);
+ s.set_depthFunc(b.setDepthFunc(ProgramStore.DepthFunc.GREATER).create());
+ return;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_program_store s = new ScriptC_program_store(pRS, mRes, R.raw.program_store);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.invoke_program_store_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java
new file mode 100644
index 0000000..b0ccf9d
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.Sampler;
+import android.renderscript.Sampler.Value;
+
+public class UT_sampler extends UnitTest {
+ private Resources mRes;
+
+ protected UT_sampler(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Sampler", ctx);
+ mRes = res;
+ }
+
+ private Sampler.Builder getDefaultBuilder(RenderScript RS) {
+ Sampler.Builder b = new Sampler.Builder(RS);
+ b.setMinification(Value.NEAREST);
+ b.setMagnification(Value.NEAREST);
+ b.setWrapS(Value.CLAMP);
+ b.setWrapT(Value.CLAMP);
+ b.setAnisotropy(1.0f);
+ return b;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_sampler s) {
+ Sampler.Builder b = getDefaultBuilder(RS);
+ b.setMinification(Value.LINEAR_MIP_LINEAR);
+ s.set_minification(b.create());
+
+ b = getDefaultBuilder(RS);
+ b.setMagnification(Value.LINEAR);
+ s.set_magnification(b.create());
+
+ b = getDefaultBuilder(RS);
+ b.setWrapS(Value.WRAP);
+ s.set_wrapS(b.create());
+
+ b = getDefaultBuilder(RS);
+ b.setWrapT(Value.WRAP);
+ s.set_wrapT(b.create());
+
+ b = getDefaultBuilder(RS);
+ b.setAnisotropy(8.0f);
+ s.set_anisotropy(b.create());
+ return;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_sampler s = new ScriptC_sampler(pRS, mRes, R.raw.sampler);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.invoke_sampler_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/program_raster.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_raster.rs
new file mode 100644
index 0000000..11b8c30
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_raster.rs
@@ -0,0 +1,37 @@
+#include "shared.rsh"
+#include "rs_graphics.rsh"
+
+rs_program_raster pointSpriteEnabled;
+rs_program_raster cullMode;
+
+static bool test_program_raster_getters() {
+ bool failed = false;
+
+ _RS_ASSERT(rsgProgramRasterGetPointSpriteEnabled(pointSpriteEnabled) == true);
+ _RS_ASSERT(rsgProgramRasterGetCullMode(pointSpriteEnabled) == RS_CULL_BACK);
+
+ _RS_ASSERT(rsgProgramRasterGetPointSpriteEnabled(cullMode) == false);
+ _RS_ASSERT(rsgProgramRasterGetCullMode(cullMode) == RS_CULL_FRONT);
+
+ if (failed) {
+ rsDebug("test_program_raster_getters FAILED", 0);
+ }
+ else {
+ rsDebug("test_program_raster_getters PASSED", 0);
+ }
+
+ return failed;
+}
+
+void program_raster_test() {
+ bool failed = false;
+ failed |= test_program_raster_getters();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/program_store.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_store.rs
new file mode 100644
index 0000000..3cd8a20
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_store.rs
@@ -0,0 +1,128 @@
+#include "shared.rsh"
+#include "rs_graphics.rsh"
+
+rs_program_store ditherEnable;
+rs_program_store colorRWriteEnable;
+rs_program_store colorGWriteEnable;
+rs_program_store colorBWriteEnable;
+rs_program_store colorAWriteEnable;
+rs_program_store blendSrc;
+rs_program_store blendDst;
+rs_program_store depthWriteEnable;
+rs_program_store depthFunc;
+
+static bool test_program_store_getters() {
+ bool failed = false;
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(depthFunc) == RS_DEPTH_FUNC_GREATER);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(depthFunc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(depthFunc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(depthFunc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(depthFunc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(depthFunc) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(depthFunc) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(depthFunc) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(depthFunc) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(depthWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(depthWriteEnable) == true);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(depthWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(depthWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(depthWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(depthWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(depthWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(depthWriteEnable) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(depthWriteEnable) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorRWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(colorRWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorRWriteEnable) == true);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorRWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorRWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorRWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorRWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorRWriteEnable) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorRWriteEnable) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorGWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(colorGWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorGWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorGWriteEnable) == true);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorGWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorGWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorGWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorGWriteEnable) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorGWriteEnable) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorBWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(colorBWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorBWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorBWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorBWriteEnable) == true);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorBWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorBWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorBWriteEnable) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorBWriteEnable) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorAWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(colorAWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorAWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorAWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorAWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorAWriteEnable) == true);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorAWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorAWriteEnable) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorAWriteEnable) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(ditherEnable) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(ditherEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(ditherEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(ditherEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(ditherEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(ditherEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(ditherEnable) == true);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(ditherEnable) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(ditherEnable) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(blendSrc) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(blendSrc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(blendSrc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(blendSrc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(blendSrc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(blendSrc) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(blendSrc) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(blendSrc) == RS_BLEND_SRC_DST_COLOR);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(blendSrc) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(blendDst) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(blendDst) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(blendDst) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(blendDst) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(blendDst) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(blendDst) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(blendDst) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(blendDst) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(blendDst) == RS_BLEND_DST_DST_ALPHA);
+
+ if (failed) {
+ rsDebug("test_program_store_getters FAILED", 0);
+ }
+ else {
+ rsDebug("test_program_store_getters PASSED", 0);
+ }
+
+ return failed;
+}
+
+void program_store_test() {
+ bool failed = false;
+ failed |= test_program_store_getters();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/sampler.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/sampler.rs
new file mode 100644
index 0000000..ac9a549
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/sampler.rs
@@ -0,0 +1,63 @@
+#include "shared.rsh"
+#include "rs_graphics.rsh"
+rs_sampler minification;
+rs_sampler magnification;
+rs_sampler wrapS;
+rs_sampler wrapT;
+rs_sampler anisotropy;
+
+static bool test_sampler_getters() {
+ bool failed = false;
+
+ _RS_ASSERT(rsgSamplerGetMagnification(minification) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetMinification(minification) == RS_SAMPLER_LINEAR_MIP_LINEAR);
+ _RS_ASSERT(rsgSamplerGetWrapS(minification) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetWrapT(minification) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetAnisotropy(minification) == 1.0f);
+
+ _RS_ASSERT(rsgSamplerGetMagnification(magnification) == RS_SAMPLER_LINEAR);
+ _RS_ASSERT(rsgSamplerGetMinification(magnification) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetWrapS(magnification) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetWrapT(magnification) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetAnisotropy(magnification) == 1.0f);
+
+ _RS_ASSERT(rsgSamplerGetMagnification(wrapS) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetMinification(wrapS) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetWrapS(wrapS) == RS_SAMPLER_WRAP);
+ _RS_ASSERT(rsgSamplerGetWrapT(wrapS) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetAnisotropy(wrapS) == 1.0f);
+
+ _RS_ASSERT(rsgSamplerGetMagnification(wrapT) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetMinification(wrapT) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetWrapS(wrapT) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetWrapT(wrapT) == RS_SAMPLER_WRAP);
+ _RS_ASSERT(rsgSamplerGetAnisotropy(wrapT) == 1.0f);
+
+ _RS_ASSERT(rsgSamplerGetMagnification(anisotropy) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetMinification(anisotropy) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetWrapS(anisotropy) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetWrapT(anisotropy) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetAnisotropy(anisotropy) == 8.0f);
+
+ if (failed) {
+ rsDebug("test_sampler_getters FAILED", 0);
+ }
+ else {
+ rsDebug("test_sampler_getters PASSED", 0);
+ }
+
+ return failed;
+}
+
+void sampler_test() {
+ bool failed = false;
+ failed |= test_sampler_getters();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
index 7c94c2d..94ad620 100644
--- a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
@@ -114,9 +114,9 @@
// v.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
// }
// },
- new Test("systemUiVisibility: STATUS_BAR_DISABLE_NAVIGATION") {
+ new Test("systemUiVisibility: STATUS_BAR_DISABLE_HOME") {
public void run() {
- mListView.setSystemUiVisibility(View.STATUS_BAR_DISABLE_NAVIGATION);
+ mListView.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME);
}
},
new Test("Double Remove") {
@@ -227,16 +227,21 @@
}, 3000);
}
},
- new Test("Disable Navigation") {
+ new Test("Disable Home (StatusBarManager)") {
public void run() {
- mStatusBarManager.disable(StatusBarManager.DISABLE_NAVIGATION);
+ mStatusBarManager.disable(StatusBarManager.DISABLE_HOME);
}
},
- new Test("Disable Back") {
+ new Test("Disable Back (StatusBarManager)") {
public void run() {
mStatusBarManager.disable(StatusBarManager.DISABLE_BACK);
}
},
+ new Test("Disable Recent (StatusBarManager)") {
+ public void run() {
+ mStatusBarManager.disable(StatusBarManager.DISABLE_RECENT);
+ }
+ },
new Test("Disable Clock") {
public void run() {
mStatusBarManager.disable(StatusBarManager.DISABLE_CLOCK);
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index d66cdf0..3d6537a 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -3,6 +3,7 @@
//
#include "AaptAssets.h"
+#include "ResourceFilter.h"
#include "Main.h"
#include <utils/misc.h>
@@ -16,6 +17,8 @@
static const char* kWildcardName = "any";
static const char* kAssetDir = "assets";
static const char* kResourceDir = "res";
+static const char* kValuesDir = "values";
+static const char* kMipmapDir = "mipmap";
static const char* kInvalidChars = "/\\:";
static const size_t kMaxAssetFileName = 100;
@@ -257,9 +260,69 @@
return 1;
}
+uint32_t
+AaptGroupEntry::getConfigValueForAxis(const ResTable_config& config, int axis)
+{
+ switch (axis) {
+ case AXIS_MCC:
+ return config.mcc;
+ case AXIS_MNC:
+ return config.mnc;
+ case AXIS_LANGUAGE:
+ return (((uint32_t)config.country[1]) << 24) | (((uint32_t)config.country[0]) << 16)
+ | (((uint32_t)config.language[1]) << 8) | (config.language[0]);
+ case AXIS_SCREENLAYOUTSIZE:
+ return config.screenLayout&ResTable_config::MASK_SCREENSIZE;
+ case AXIS_ORIENTATION:
+ return config.orientation;
+ case AXIS_UIMODETYPE:
+ return (config.uiMode&ResTable_config::MASK_UI_MODE_TYPE);
+ case AXIS_UIMODENIGHT:
+ return (config.uiMode&ResTable_config::MASK_UI_MODE_NIGHT);
+ case AXIS_DENSITY:
+ return config.density;
+ case AXIS_TOUCHSCREEN:
+ return config.touchscreen;
+ case AXIS_KEYSHIDDEN:
+ return config.inputFlags;
+ case AXIS_KEYBOARD:
+ return config.keyboard;
+ case AXIS_NAVIGATION:
+ return config.navigation;
+ case AXIS_SCREENSIZE:
+ return config.screenSize;
+ case AXIS_SMALLESTSCREENWIDTHDP:
+ return config.smallestScreenWidthDp;
+ case AXIS_SCREENWIDTHDP:
+ return config.screenWidthDp;
+ case AXIS_SCREENHEIGHTDP:
+ return config.screenHeightDp;
+ case AXIS_VERSION:
+ return config.version;
+ }
+ return 0;
+}
+
+bool
+AaptGroupEntry::configSameExcept(const ResTable_config& config,
+ const ResTable_config& otherConfig, int axis)
+{
+ for (int i=AXIS_START; i<=AXIS_END; i++) {
+ if (i == axis) {
+ continue;
+ }
+ if (getConfigValueForAxis(config, i) != getConfigValueForAxis(otherConfig, i)) {
+ return false;
+ }
+ }
+ return true;
+}
+
bool
AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
{
+ mParamsChanged = true;
+
Vector<String8> parts;
String8 mcc, mnc, loc, layoutsize, layoutlong, orient, den;
@@ -629,79 +692,117 @@
{
String8 s = resType;
if (this->mcc != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += mcc;
}
if (this->mnc != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += mnc;
}
if (this->locale != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += locale;
}
if (this->smallestScreenWidthDp != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += smallestScreenWidthDp;
}
if (this->screenWidthDp != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += screenWidthDp;
}
if (this->screenHeightDp != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += screenHeightDp;
}
if (this->screenLayoutSize != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += screenLayoutSize;
}
if (this->screenLayoutLong != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += screenLayoutLong;
}
if (this->orientation != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += orientation;
}
if (this->uiModeType != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += uiModeType;
}
if (this->uiModeNight != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += uiModeNight;
}
if (this->density != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += density;
}
if (this->touchscreen != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += touchscreen;
}
if (this->keysHidden != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += keysHidden;
}
if (this->keyboard != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += keyboard;
}
if (this->navHidden != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += navHidden;
}
if (this->navigation != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += navigation;
}
if (this->screenSize != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += screenSize;
}
if (this->version != "") {
- s += "-";
+ if (s.length() > 0) {
+ s += "-";
+ }
s += version;
}
@@ -1286,9 +1387,14 @@
return v;
}
-ResTable_config AaptGroupEntry::toParams() const
+const ResTable_config& AaptGroupEntry::toParams() const
{
- ResTable_config params;
+ if (!mParamsChanged) {
+ return mParams;
+ }
+
+ mParamsChanged = false;
+ ResTable_config& params(mParams);
memset(¶ms, 0, sizeof(params));
getMccName(mcc.string(), ¶ms);
getMncName(mnc.string(), ¶ms);
@@ -1403,8 +1509,7 @@
String8 AaptFile::getPrintableSource() const
{
if (hasData()) {
- String8 name(mGroupEntry.locale.string());
- name.appendPath(mGroupEntry.vendor.string());
+ String8 name(mGroupEntry.toDirName(String8()));
name.appendPath(mPath);
name.append(" #generated");
return name;
@@ -1424,6 +1529,13 @@
return NO_ERROR;
}
+#if 0
+ printf("Error adding file %s: group %s already exists in leaf=%s path=%s\n",
+ file->getSourceFile().string(),
+ file->getGroupEntry().toDirName(String8()).string(),
+ mLeaf.string(), mPath.string());
+#endif
+
SourcePos(file->getSourceFile(), -1).error("Duplicate file.\n%s: Original is here.",
getPrintableSource().string());
return UNKNOWN_ERROR;
@@ -1434,20 +1546,23 @@
mFiles.removeItemsAt(index);
}
-void AaptGroup::print() const
+void AaptGroup::print(const String8& prefix) const
{
- printf(" %s\n", getPath().string());
+ printf("%s%s\n", prefix.string(), getPath().string());
const size_t N=mFiles.size();
size_t i;
for (i=0; i<N; i++) {
sp<AaptFile> file = mFiles.valueAt(i);
const AaptGroupEntry& e = file->getGroupEntry();
if (file->hasData()) {
- printf(" Gen: (%s) %d bytes\n", e.toString().string(),
+ printf("%s Gen: (%s) %d bytes\n", prefix.string(), e.toDirName(String8()).string(),
(int)file->getSize());
} else {
- printf(" Src: %s\n", file->getPrintableSource().string());
+ printf("%s Src: (%s) %s\n", prefix.string(), e.toDirName(String8()).string(),
+ file->getPrintableSource().string());
}
+ //printf("%s File Group Entry: %s\n", prefix.string(),
+ // file->getGroupEntry().toDirName(String8()).string());
}
}
@@ -1514,38 +1629,6 @@
mDirs.removeItem(name);
}
-status_t AaptDir::renameFile(const sp<AaptFile>& file, const String8& newName)
-{
- sp<AaptGroup> origGroup;
-
- // Find and remove the given file with shear, brute force!
- const size_t NG = mFiles.size();
- size_t i;
- for (i=0; origGroup == NULL && i<NG; i++) {
- sp<AaptGroup> g = mFiles.valueAt(i);
- const size_t NF = g->getFiles().size();
- for (size_t j=0; j<NF; j++) {
- if (g->getFiles().valueAt(j) == file) {
- origGroup = g;
- g->removeFile(j);
- if (NF == 1) {
- mFiles.removeItemsAt(i);
- }
- break;
- }
- }
- }
-
- //printf("Renaming %s to %s\n", file->getPath().getPathName(), newName.string());
-
- // Place the file under its new name.
- if (origGroup != NULL) {
- return addLeafFile(newName, file);
- }
-
- return NO_ERROR;
-}
-
status_t AaptDir::addLeafFile(const String8& leafName, const sp<AaptFile>& file)
{
sp<AaptGroup> group;
@@ -1710,17 +1793,17 @@
return NO_ERROR;
}
-void AaptDir::print() const
+void AaptDir::print(const String8& prefix) const
{
const size_t ND=getDirs().size();
size_t i;
for (i=0; i<ND; i++) {
- getDirs().valueAt(i)->print();
+ getDirs().valueAt(i)->print(prefix);
}
const size_t NF=getFiles().size();
for (i=0; i<NF; i++) {
- getFiles().valueAt(i)->print();
+ getFiles().valueAt(i)->print(prefix);
}
}
@@ -1744,6 +1827,24 @@
// =========================================================================
// =========================================================================
+AaptAssets::AaptAssets()
+ : AaptDir(String8(), String8()),
+ mChanged(false), mHaveIncludedAssets(false), mRes(NULL)
+{
+}
+
+const SortedVector<AaptGroupEntry>& AaptAssets::getGroupEntries() const {
+ if (mChanged) {
+ }
+ return mGroupEntries;
+}
+
+status_t AaptAssets::addFile(const String8& name, const sp<AaptGroup>& file)
+{
+ mChanged = true;
+ return AaptDir::addFile(name, file);
+}
+
sp<AaptFile> AaptAssets::addFile(
const String8& filePath, const AaptGroupEntry& entry,
const String8& srcDir, sp<AaptGroup>* outGroup,
@@ -1945,6 +2046,11 @@
goto bail;
}
+ count = filter(bundle);
+ if (count != NO_ERROR) {
+ totalCount = count;
+ goto bail;
+ }
bail:
return totalCount;
@@ -2002,9 +2108,9 @@
continue;
}
- if (bundle->getMaxResVersion() != NULL && group.version.length() != 0) {
+ if (bundle->getMaxResVersion() != NULL && group.getVersionString().length() != 0) {
int maxResInt = atoi(bundle->getMaxResVersion());
- const char *verString = group.version.string();
+ const char *verString = group.getVersionString().string();
int dirVersionInt = atoi(verString + 1); // skip 'v' in version name
if (dirVersionInt > maxResInt) {
fprintf(stderr, "max res %d, skipping %s\n", maxResInt, entry->d_name);
@@ -2015,7 +2121,7 @@
FileType type = getFileType(subdirName.string());
if (type == kFileTypeDirectory) {
- sp<AaptDir> dir = makeDir(String8(entry->d_name));
+ sp<AaptDir> dir = makeDir(resType);
ssize_t res = dir->slurpFullTree(bundle, subdirName, group,
resType, mFullResPaths);
if (res < 0) {
@@ -2027,7 +2133,13 @@
count += res;
}
- mDirs.add(dir);
+ // Only add this directory if we don't already have a resource dir
+ // for the current type. This ensures that we only add the dir once
+ // for all configs.
+ sp<AaptDir> rdir = resDir(resType);
+ if (rdir == NULL) {
+ mResDirs.add(dir);
+ }
} else {
if (bundle->getVerbose()) {
fprintf(stderr, " (ignoring file '%s')\n", subdirName.string());
@@ -2136,6 +2248,142 @@
return count;
}
+status_t AaptAssets::filter(Bundle* bundle)
+{
+ ResourceFilter reqFilter;
+ status_t err = reqFilter.parse(bundle->getConfigurations());
+ if (err != NO_ERROR) {
+ return err;
+ }
+
+ ResourceFilter prefFilter;
+ err = prefFilter.parse(bundle->getPreferredConfigurations());
+ if (err != NO_ERROR) {
+ return err;
+ }
+
+ if (reqFilter.isEmpty() && prefFilter.isEmpty()) {
+ return NO_ERROR;
+ }
+
+ if (bundle->getVerbose()) {
+ if (!reqFilter.isEmpty()) {
+ printf("Applying required filter: %s\n",
+ bundle->getConfigurations());
+ }
+ if (!prefFilter.isEmpty()) {
+ printf("Applying preferred filter: %s\n",
+ bundle->getPreferredConfigurations());
+ }
+ }
+
+ const Vector<sp<AaptDir> >& resdirs = mResDirs;
+ const size_t ND = resdirs.size();
+ for (size_t i=0; i<ND; i++) {
+ const sp<AaptDir>& dir = resdirs.itemAt(i);
+ if (dir->getLeaf() == kValuesDir) {
+ // The "value" dir is special since a single file defines
+ // multiple resources, so we can not do filtering on the
+ // files themselves.
+ continue;
+ }
+ if (dir->getLeaf() == kMipmapDir) {
+ // We also skip the "mipmap" directory, since the point of this
+ // is to include all densities without stripping. If you put
+ // other configurations in here as well they won't be stripped
+ // either... So don't do that. Seriously. What is wrong with you?
+ continue;
+ }
+
+ const size_t NG = dir->getFiles().size();
+ for (size_t j=0; j<NG; j++) {
+ sp<AaptGroup> grp = dir->getFiles().valueAt(j);
+
+ // First remove any configurations we know we don't need.
+ for (size_t k=0; k<grp->getFiles().size(); k++) {
+ sp<AaptFile> file = grp->getFiles().valueAt(k);
+ if (k == 0 && grp->getFiles().size() == 1) {
+ // If this is the only file left, we need to keep it.
+ // Otherwise the resource IDs we are using will be inconsistent
+ // with what we get when not stripping. Sucky, but at least
+ // for now we can rely on the back-end doing another filtering
+ // pass to take this out and leave us with this resource name
+ // containing no entries.
+ continue;
+ }
+ if (file->getPath().getPathExtension() == ".xml") {
+ // We can't remove .xml files at this point, because when
+ // we parse them they may add identifier resources, so
+ // removing them can cause our resource identifiers to
+ // become inconsistent.
+ continue;
+ }
+ const ResTable_config& config(file->getGroupEntry().toParams());
+ if (!reqFilter.match(config)) {
+ if (bundle->getVerbose()) {
+ printf("Pruning unneeded resource: %s\n",
+ file->getPrintableSource().string());
+ }
+ grp->removeFile(k);
+ k--;
+ }
+ }
+
+ // Quick check: no preferred filters, nothing more to do.
+ if (prefFilter.isEmpty()) {
+ continue;
+ }
+
+ // Now deal with preferred configurations.
+ for (int axis=AXIS_START; axis<=AXIS_END; axis++) {
+ for (size_t k=0; k<grp->getFiles().size(); k++) {
+ sp<AaptFile> file = grp->getFiles().valueAt(k);
+ if (k == 0 && grp->getFiles().size() == 1) {
+ // If this is the only file left, we need to keep it.
+ // Otherwise the resource IDs we are using will be inconsistent
+ // with what we get when not stripping. Sucky, but at least
+ // for now we can rely on the back-end doing another filtering
+ // pass to take this out and leave us with this resource name
+ // containing no entries.
+ continue;
+ }
+ if (file->getPath().getPathExtension() == ".xml") {
+ // We can't remove .xml files at this point, because when
+ // we parse them they may add identifier resources, so
+ // removing them can cause our resource identifiers to
+ // become inconsistent.
+ continue;
+ }
+ const ResTable_config& config(file->getGroupEntry().toParams());
+ if (!prefFilter.match(axis, config)) {
+ // This is a resource we would prefer not to have. Check
+ // to see if have a similar variation that we would like
+ // to have and, if so, we can drop it.
+ for (size_t m=0; m<grp->getFiles().size(); m++) {
+ if (m == k) continue;
+ sp<AaptFile> mfile = grp->getFiles().valueAt(m);
+ const ResTable_config& mconfig(mfile->getGroupEntry().toParams());
+ if (AaptGroupEntry::configSameExcept(config, mconfig, axis)) {
+ if (prefFilter.match(axis, mconfig)) {
+ if (bundle->getVerbose()) {
+ printf("Pruning unneeded resource: %s\n",
+ file->getPrintableSource().string());
+ }
+ grp->removeFile(k);
+ k--;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return NO_ERROR;
+}
+
sp<AaptSymbols> AaptAssets::getSymbolsFor(const String8& name)
{
sp<AaptSymbols> sym = mSymbols.valueFor(name);
@@ -2179,26 +2427,39 @@
return mIncludedAssets.getResources(false);
}
-void AaptAssets::print() const
+void AaptAssets::print(const String8& prefix) const
{
- printf("Locale/Vendor pairs:\n");
+ String8 innerPrefix(prefix);
+ innerPrefix.append(" ");
+ String8 innerInnerPrefix(innerPrefix);
+ innerInnerPrefix.append(" ");
+ printf("%sConfigurations:\n", prefix.string());
const size_t N=mGroupEntries.size();
for (size_t i=0; i<N; i++) {
- printf(" %s/%s\n",
- mGroupEntries.itemAt(i).locale.string(),
- mGroupEntries.itemAt(i).vendor.string());
+ String8 cname = mGroupEntries.itemAt(i).toDirName(String8());
+ printf("%s %s\n", prefix.string(),
+ cname != "" ? cname.string() : "(default)");
}
- printf("\nFiles:\n");
- AaptDir::print();
+ printf("\n%sFiles:\n", prefix.string());
+ AaptDir::print(innerPrefix);
+
+ printf("\n%sResource Dirs:\n", prefix.string());
+ const Vector<sp<AaptDir> >& resdirs = mResDirs;
+ const size_t NR = resdirs.size();
+ for (size_t i=0; i<NR; i++) {
+ const sp<AaptDir>& d = resdirs.itemAt(i);
+ printf("%s Type %s\n", prefix.string(), d->getLeaf().string());
+ d->print(innerInnerPrefix);
+ }
}
-sp<AaptDir> AaptAssets::resDir(const String8& name)
+sp<AaptDir> AaptAssets::resDir(const String8& name) const
{
- const Vector<sp<AaptDir> >& dirs = mDirs;
- const size_t N = dirs.size();
+ const Vector<sp<AaptDir> >& resdirs = mResDirs;
+ const size_t N = resdirs.size();
for (size_t i=0; i<N; i++) {
- const sp<AaptDir>& d = dirs.itemAt(i);
+ const sp<AaptDir>& d = resdirs.itemAt(i);
if (d->getLeaf() == name) {
return d;
}
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index 82dfd71..d5345b2 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -24,6 +24,8 @@
bool valid_symbol_name(const String8& str);
+class AaptAssets;
+
enum {
AXIS_NONE = 0,
AXIS_MCC = 1,
@@ -45,7 +47,10 @@
AXIS_SMALLESTSCREENWIDTHDP,
AXIS_SCREENWIDTHDP,
AXIS_SCREENHEIGHTDP,
- AXIS_VERSION
+ AXIS_VERSION,
+
+ AXIS_START = AXIS_MCC,
+ AXIS_END = AXIS_VERSION,
};
enum {
@@ -56,6 +61,7 @@
SDK_MR1 = 7,
SDK_FROYO = 8,
SDK_HONEYCOMB_MR2 = 13,
+ SDK_ICE_CREAM_SANDWICH = 14,
};
/**
@@ -65,35 +71,19 @@
struct AaptGroupEntry
{
public:
- AaptGroupEntry() { }
+ AaptGroupEntry() : mParamsChanged(true) { }
AaptGroupEntry(const String8& _locale, const String8& _vendor)
- : locale(_locale), vendor(_vendor) { }
-
- String8 mcc;
- String8 mnc;
- String8 locale;
- String8 vendor;
- String8 smallestScreenWidthDp;
- String8 screenWidthDp;
- String8 screenHeightDp;
- String8 screenLayoutSize;
- String8 screenLayoutLong;
- String8 orientation;
- String8 uiModeType;
- String8 uiModeNight;
- String8 density;
- String8 touchscreen;
- String8 keysHidden;
- String8 keyboard;
- String8 navHidden;
- String8 navigation;
- String8 screenSize;
- String8 version;
+ : locale(_locale), vendor(_vendor), mParamsChanged(true) { }
bool initFromDirName(const char* dir, String8* resType);
static status_t parseNamePart(const String8& part, int* axis, uint32_t* value);
-
+
+ static uint32_t getConfigValueForAxis(const ResTable_config& config, int axis);
+
+ static bool configSameExcept(const ResTable_config& config,
+ const ResTable_config& otherConfig, int axis);
+
static bool getMccName(const char* name, ResTable_config* out = NULL);
static bool getMncName(const char* name, ResTable_config* out = NULL);
static bool getLocaleName(const char* name, ResTable_config* out = NULL);
@@ -116,7 +106,7 @@
int compare(const AaptGroupEntry& o) const;
- ResTable_config toParams() const;
+ const ResTable_config& toParams() const;
inline bool operator<(const AaptGroupEntry& o) const { return compare(o) < 0; }
inline bool operator<=(const AaptGroupEntry& o) const { return compare(o) <= 0; }
@@ -127,6 +117,33 @@
String8 toString() const;
String8 toDirName(const String8& resType) const;
+
+ const String8& getVersionString() const { return version; }
+
+private:
+ String8 mcc;
+ String8 mnc;
+ String8 locale;
+ String8 vendor;
+ String8 smallestScreenWidthDp;
+ String8 screenWidthDp;
+ String8 screenHeightDp;
+ String8 screenLayoutSize;
+ String8 screenLayoutLong;
+ String8 orientation;
+ String8 uiModeType;
+ String8 uiModeNight;
+ String8 density;
+ String8 touchscreen;
+ String8 keysHidden;
+ String8 keyboard;
+ String8 navHidden;
+ String8 navigation;
+ String8 screenSize;
+ String8 version;
+
+ mutable bool mParamsChanged;
+ mutable ResTable_config mParams;
};
inline int compare_type(const AaptGroupEntry& lhs, const AaptGroupEntry& rhs)
@@ -225,7 +242,7 @@
status_t addFile(const sp<AaptFile>& file);
void removeFile(size_t index);
- void print() const;
+ void print(const String8& prefix) const;
String8 getPrintableSource() const;
@@ -237,7 +254,7 @@
};
/**
- * A single directory of assets, which can contain for files and other
+ * A single directory of assets, which can contain files and other
* sub-directories.
*/
class AaptDir : public RefBase
@@ -254,25 +271,11 @@
const DefaultKeyedVector<String8, sp<AaptGroup> >& getFiles() const { return mFiles; }
const DefaultKeyedVector<String8, sp<AaptDir> >& getDirs() const { return mDirs; }
- status_t addFile(const String8& name, const sp<AaptGroup>& file);
- status_t addDir(const String8& name, const sp<AaptDir>& dir);
-
- sp<AaptDir> makeDir(const String8& name);
+ virtual status_t addFile(const String8& name, const sp<AaptGroup>& file);
void removeFile(const String8& name);
void removeDir(const String8& name);
- status_t renameFile(const sp<AaptFile>& file, const String8& newName);
-
- status_t addLeafFile(const String8& leafName,
- const sp<AaptFile>& file);
-
- virtual ssize_t slurpFullTree(Bundle* bundle,
- const String8& srcDir,
- const AaptGroupEntry& kind,
- const String8& resType,
- sp<FilePathStore>& fullResPaths);
-
/*
* Perform some sanity checks on the names of files and directories here.
* In particular:
@@ -292,11 +295,23 @@
*/
status_t validate() const;
- void print() const;
+ void print(const String8& prefix) const;
String8 getPrintableSource() const;
private:
+ friend class AaptAssets;
+
+ status_t addDir(const String8& name, const sp<AaptDir>& dir);
+ sp<AaptDir> makeDir(const String8& name);
+ status_t addLeafFile(const String8& leafName,
+ const sp<AaptFile>& file);
+ virtual ssize_t slurpFullTree(Bundle* bundle,
+ const String8& srcDir,
+ const AaptGroupEntry& kind,
+ const String8& resType,
+ sp<FilePathStore>& fullResPaths);
+
String8 mLeaf;
String8 mPath;
@@ -501,13 +516,15 @@
class AaptAssets : public AaptDir
{
public:
- AaptAssets() : AaptDir(String8(), String8()), mHaveIncludedAssets(false), mRes(NULL) { }
+ AaptAssets();
virtual ~AaptAssets() { delete mRes; }
const String8& getPackage() const { return mPackage; }
void setPackage(const String8& package) { mPackage = package; mSymbolsPrivatePackage = package; }
- const SortedVector<AaptGroupEntry>& getGroupEntries() const { return mGroupEntries; }
+ const SortedVector<AaptGroupEntry>& getGroupEntries() const;
+
+ virtual status_t addFile(const String8& name, const sp<AaptGroup>& file);
sp<AaptFile> addFile(const String8& filePath,
const AaptGroupEntry& entry,
@@ -524,15 +541,6 @@
ssize_t slurpFromArgs(Bundle* bundle);
- virtual ssize_t slurpFullTree(Bundle* bundle,
- const String8& srcDir,
- const AaptGroupEntry& kind,
- const String8& resType,
- sp<FilePathStore>& fullResPaths);
-
- ssize_t slurpResourceTree(Bundle* bundle, const String8& srcDir);
- ssize_t slurpResourceZip(Bundle* bundle, const char* filename);
-
sp<AaptSymbols> getSymbolsFor(const String8& name);
const DefaultKeyedVector<String8, sp<AaptSymbols> >& getSymbols() const { return mSymbols; }
@@ -544,10 +552,10 @@
status_t addIncludedResources(const sp<AaptFile>& file);
const ResTable& getIncludedResources() const;
- void print() const;
+ void print(const String8& prefix) const;
- inline const Vector<sp<AaptDir> >& resDirs() { return mDirs; }
- sp<AaptDir> resDir(const String8& name);
+ inline const Vector<sp<AaptDir> >& resDirs() const { return mResDirs; }
+ sp<AaptDir> resDir(const String8& name) const;
inline sp<AaptAssets> getOverlay() { return mOverlay; }
inline void setOverlay(sp<AaptAssets>& overlay) { mOverlay = overlay; }
@@ -565,12 +573,25 @@
setFullAssetPaths(sp<FilePathStore>& res) { mFullAssetPaths = res; }
private:
+ virtual ssize_t slurpFullTree(Bundle* bundle,
+ const String8& srcDir,
+ const AaptGroupEntry& kind,
+ const String8& resType,
+ sp<FilePathStore>& fullResPaths);
+
+ ssize_t slurpResourceTree(Bundle* bundle, const String8& srcDir);
+ ssize_t slurpResourceZip(Bundle* bundle, const char* filename);
+
+ status_t filter(Bundle* bundle);
+
String8 mPackage;
SortedVector<AaptGroupEntry> mGroupEntries;
DefaultKeyedVector<String8, sp<AaptSymbols> > mSymbols;
String8 mSymbolsPrivatePackage;
- Vector<sp<AaptDir> > mDirs;
+ Vector<sp<AaptDir> > mResDirs;
+
+ bool mChanged;
bool mHaveIncludedAssets;
AssetManager mIncludedAssets;
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index e507fb9..a3e5d9a 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -19,6 +19,7 @@
Package.cpp \
StringPool.cpp \
XMLNode.cpp \
+ ResourceFilter.cpp \
ResourceTable.cpp \
Images.cpp \
Resource.cpp \
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 539c312..2d1060b 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -122,6 +122,8 @@
void setRClassDir(const char* dir) { mRClassDir = dir; }
const char* getConfigurations() const { return mConfigurations.size() > 0 ? mConfigurations.string() : NULL; }
void addConfigurations(const char* val) { if (mConfigurations.size() > 0) { mConfigurations.append(","); mConfigurations.append(val); } else { mConfigurations = val; } }
+ const char* getPreferredConfigurations() const { return mPreferredConfigurations.size() > 0 ? mPreferredConfigurations.string() : NULL; }
+ void addPreferredConfigurations(const char* val) { if (mPreferredConfigurations.size() > 0) { mPreferredConfigurations.append(","); mPreferredConfigurations.append(val); } else { mPreferredConfigurations = val; } }
const char* getResourceIntermediatesDir() const { return mResourceIntermediatesDir; }
void setResourceIntermediatesDir(const char* dir) { mResourceIntermediatesDir = dir; }
const android::Vector<const char*>& getPackageIncludes() const { return mPackageIncludes; }
@@ -244,6 +246,7 @@
const char* mRClassDir;
const char* mResourceIntermediatesDir;
android::String8 mConfigurations;
+ android::String8 mPreferredConfigurations;
android::Vector<const char*> mPackageIncludes;
android::Vector<const char*> mJarFiles;
android::Vector<const char*> mNoCompressExtensions;
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 413a2dc..637c27d 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -5,6 +5,7 @@
//
#include "Main.h"
#include "Bundle.h"
+#include "ResourceFilter.h"
#include "ResourceTable.h"
#include "XMLNode.h"
@@ -1572,7 +1573,7 @@
}
if (bundle->getVerbose()) {
- assets->print();
+ assets->print(String8());
}
// If they asked for any fileAs that need to be compiled, do so.
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
index 311ceea..ffbe875 100644
--- a/tools/aapt/Images.cpp
+++ b/tools/aapt/Images.cpp
@@ -980,6 +980,10 @@
String8 printableName(file->getPrintableSource());
+ if (bundle->getVerbose()) {
+ printf("Processing image: %s\n", printableName.string());
+ }
+
png_structp read_ptr = NULL;
png_infop read_info = NULL;
FILE* fp;
@@ -1094,6 +1098,10 @@
status_t error = UNKNOWN_ERROR;
+ if (bundle->getVerbose()) {
+ printf("Processing image to cache: %s => %s\n", source.string(), dest.string());
+ }
+
// Get a file handler to read from
fp = fopen(source.string(),"rb");
if (fp == NULL) {
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 5135787..50c828d 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -65,9 +65,10 @@
" [--max-res-version VAL] \\\n"
" [-I base-package [-I base-package ...]] \\\n"
" [-A asset-source-dir] [-G class-list-file] [-P public-definitions-file] \\\n"
- " [-S resource-sources [-S resource-sources ...]] "
+ " [-S resource-sources [-S resource-sources ...]] \\\n"
" [-F apk-file] [-J R-file-dir] \\\n"
" [--product product1,product2,...] \\\n"
+ " [-c CONFIGS] [--preferred-configurations CONFIGS] \\\n"
" [-o] \\\n"
" [raw-files-dir [raw-files-dir] ...]\n"
"\n"
@@ -154,6 +155,10 @@
" generate dependency files in the same directories for R.java and resource package\n"
" --auto-add-overlay\n"
" Automatically add resources that are only in overlays.\n"
+ " --preferred-configurations\n"
+ " Like the -c option for filtering out unneeded configurations, but\n"
+ " only expresses a preference. If there is no resource available with\n"
+ " the preferred configuration then it will not be stripped.\n"
" --rename-manifest-package\n"
" Rewrite the manifest so that its package name is the package name\n"
" given here. Relative class names (for example .Foo) will be\n"
@@ -509,6 +514,15 @@
bundle.setGenDependencies(true);
} else if (strcmp(cp, "-utf16") == 0) {
bundle.setWantUTF16(true);
+ } else if (strcmp(cp, "-preferred-configurations") == 0) {
+ argc--;
+ argv++;
+ if (!argc) {
+ fprintf(stderr, "ERROR: No argument supplied for '--preferred-configurations' option\n");
+ wantUsage = true;
+ goto bail;
+ }
+ bundle.addPreferredConfigurations(argv[0]);
} else if (strcmp(cp, "-rename-manifest-package") == 0) {
argc--;
argv++;
diff --git a/tools/aapt/Package.cpp b/tools/aapt/Package.cpp
index 1e3efde..3930117 100644
--- a/tools/aapt/Package.cpp
+++ b/tools/aapt/Package.cpp
@@ -6,6 +6,7 @@
#include "Main.h"
#include "AaptAssets.h"
#include "ResourceTable.h"
+#include "ResourceFilter.h"
#include <utils/Log.h>
#include <utils/threads.h>
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 2e796a2..887fa74 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -352,18 +352,27 @@
if (index < 0) {
sp<ResourceTypeSet> set = new ResourceTypeSet();
+ NOISY(printf("Creating new resource type set for leaf %s with group %s (%p)\n",
+ leafName.string(), group->getPath().string(), group.get()));
set->add(leafName, group);
resources->add(resType, set);
} else {
sp<ResourceTypeSet> set = resources->valueAt(index);
index = set->indexOfKey(leafName);
if (index < 0) {
+ NOISY(printf("Adding to resource type set for leaf %s group %s (%p)\n",
+ leafName.string(), group->getPath().string(), group.get()));
set->add(leafName, group);
} else {
sp<AaptGroup> existingGroup = set->valueAt(index);
- int M = files.size();
- for (int j=0; j<M; j++) {
- existingGroup->addFile(files.valueAt(j));
+ NOISY(printf("Extending to resource type set for leaf %s group %s (%p)\n",
+ leafName.string(), group->getPath().string(), group.get()));
+ for (size_t j=0; j<files.size(); j++) {
+ NOISY(printf("Adding file %s in group %s resType %s\n",
+ files.valueAt(j)->getSourceFile().string(),
+ files.keyAt(j).toDirName(String8()).string(),
+ resType.string()));
+ status_t err = existingGroup->addFile(files.valueAt(j));
}
}
}
@@ -378,9 +387,12 @@
for (int i=0; i<N; i++) {
sp<AaptDir> d = dirs.itemAt(i);
+ NOISY(printf("Collecting dir #%d %p: %s, leaf %s\n", i, d.get(), d->getPath().string(),
+ d->getLeaf().string()));
collect_files(d, resources);
// don't try to include the res dir
+ NOISY(printf("Removing dir leaf %s\n", d->getLeaf().string()));
ass->removeDir(d->getLeaf());
}
}
@@ -570,7 +582,7 @@
size_t baseFileIndex =
baseGroup->getFiles().indexOfKey(overlayFiles.
keyAt(overlayGroupIndex));
- if(baseFileIndex < UNKNOWN_ERROR) {
+ if (baseFileIndex < UNKNOWN_ERROR) {
if (bundle->getVerbose()) {
printf("found a match (%zd) for overlay file %s, for flavor %s\n",
baseFileIndex,
@@ -580,6 +592,11 @@
baseGroup->removeFile(baseFileIndex);
} else {
// didn't find a match fall through and add it..
+ if (true || bundle->getVerbose()) {
+ printf("nothing matches overlay file %s, for flavor %s\n",
+ overlayGroup->getLeaf().string(),
+ overlayFiles.keyAt(overlayGroupIndex).toString().string());
+ }
}
baseGroup->addFile(overlayFiles.valueAt(overlayGroupIndex));
assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));
diff --git a/tools/aapt/ResourceFilter.cpp b/tools/aapt/ResourceFilter.cpp
new file mode 100644
index 0000000..8cfd2a5
--- /dev/null
+++ b/tools/aapt/ResourceFilter.cpp
@@ -0,0 +1,112 @@
+//
+// Copyright 2011 The Android Open Source Project
+//
+// Build resource files from raw assets.
+//
+
+#include "ResourceFilter.h"
+
+status_t
+ResourceFilter::parse(const char* arg)
+{
+ if (arg == NULL) {
+ return 0;
+ }
+
+ const char* p = arg;
+ const char* q;
+
+ while (true) {
+ q = strchr(p, ',');
+ if (q == NULL) {
+ q = p + strlen(p);
+ }
+
+ String8 part(p, q-p);
+
+ if (part == "zz_ZZ") {
+ mContainsPseudo = true;
+ }
+ int axis;
+ uint32_t value;
+ if (AaptGroupEntry::parseNamePart(part, &axis, &value)) {
+ fprintf(stderr, "Invalid configuration: %s\n", arg);
+ fprintf(stderr, " ");
+ for (int i=0; i<p-arg; i++) {
+ fprintf(stderr, " ");
+ }
+ for (int i=0; i<q-p; i++) {
+ fprintf(stderr, "^");
+ }
+ fprintf(stderr, "\n");
+ return 1;
+ }
+
+ ssize_t index = mData.indexOfKey(axis);
+ if (index < 0) {
+ mData.add(axis, SortedVector<uint32_t>());
+ }
+ SortedVector<uint32_t>& sv = mData.editValueFor(axis);
+ sv.add(value);
+ // if it's a locale with a region, also match an unmodified locale of the
+ // same language
+ if (axis == AXIS_LANGUAGE) {
+ if (value & 0xffff0000) {
+ sv.add(value & 0x0000ffff);
+ }
+ }
+ p = q;
+ if (!*p) break;
+ p++;
+ }
+
+ return NO_ERROR;
+}
+
+bool
+ResourceFilter::isEmpty() const
+{
+ return mData.size() == 0;
+}
+
+bool
+ResourceFilter::match(int axis, uint32_t value) const
+{
+ if (value == 0) {
+ // they didn't specify anything so take everything
+ return true;
+ }
+ ssize_t index = mData.indexOfKey(axis);
+ if (index < 0) {
+ // we didn't request anything on this axis so take everything
+ return true;
+ }
+ const SortedVector<uint32_t>& sv = mData.valueAt(index);
+ return sv.indexOf(value) >= 0;
+}
+
+bool
+ResourceFilter::match(int axis, const ResTable_config& config) const
+{
+ return match(axis, AaptGroupEntry::getConfigValueForAxis(config, axis));
+}
+
+bool
+ResourceFilter::match(const ResTable_config& config) const
+{
+ for (int i=AXIS_START; i<=AXIS_END; i++) {
+ if (!match(i, AaptGroupEntry::getConfigValueForAxis(config, i))) {
+ return false;
+ }
+ }
+ return true;
+}
+
+const SortedVector<uint32_t>* ResourceFilter::configsForAxis(int axis) const
+{
+ ssize_t index = mData.indexOfKey(axis);
+ if (index < 0) {
+ return NULL;
+ }
+ return &mData.valueAt(index);
+}
diff --git a/tools/aapt/ResourceFilter.h b/tools/aapt/ResourceFilter.h
new file mode 100644
index 0000000..647b7bb
--- /dev/null
+++ b/tools/aapt/ResourceFilter.h
@@ -0,0 +1,33 @@
+//
+// Copyright 2011 The Android Open Source Project
+//
+// Build resource files from raw assets.
+//
+
+#ifndef RESOURCE_FILTER_H
+#define RESOURCE_FILTER_H
+
+#include "AaptAssets.h"
+
+/**
+ * Implements logic for parsing and handling "-c" and "--preferred-configurations"
+ * options.
+ */
+class ResourceFilter
+{
+public:
+ ResourceFilter() : mData(), mContainsPseudo(false) {}
+ status_t parse(const char* arg);
+ bool isEmpty() const;
+ bool match(int axis, uint32_t value) const;
+ bool match(int axis, const ResTable_config& config) const;
+ bool match(const ResTable_config& config) const;
+ const SortedVector<uint32_t>* configsForAxis(int axis) const;
+ inline bool containsPseudo() const { return mContainsPseudo; }
+
+private:
+ KeyedVector<int,SortedVector<uint32_t> > mData;
+ bool mContainsPseudo;
+};
+
+#endif
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 99f74c6..fdb39ca 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -7,6 +7,7 @@
#include "ResourceTable.h"
#include "XMLNode.h"
+#include "ResourceFilter.h"
#include <utils/ByteOrder.h>
#include <utils/ResourceTypes.h>
@@ -2528,135 +2529,6 @@
return err;
}
-
-status_t
-ResourceFilter::parse(const char* arg)
-{
- if (arg == NULL) {
- return 0;
- }
-
- const char* p = arg;
- const char* q;
-
- while (true) {
- q = strchr(p, ',');
- if (q == NULL) {
- q = p + strlen(p);
- }
-
- String8 part(p, q-p);
-
- if (part == "zz_ZZ") {
- mContainsPseudo = true;
- }
- int axis;
- uint32_t value;
- if (AaptGroupEntry::parseNamePart(part, &axis, &value)) {
- fprintf(stderr, "Invalid configuration: %s\n", arg);
- fprintf(stderr, " ");
- for (int i=0; i<p-arg; i++) {
- fprintf(stderr, " ");
- }
- for (int i=0; i<q-p; i++) {
- fprintf(stderr, "^");
- }
- fprintf(stderr, "\n");
- return 1;
- }
-
- ssize_t index = mData.indexOfKey(axis);
- if (index < 0) {
- mData.add(axis, SortedVector<uint32_t>());
- }
- SortedVector<uint32_t>& sv = mData.editValueFor(axis);
- sv.add(value);
- // if it's a locale with a region, also match an unmodified locale of the
- // same language
- if (axis == AXIS_LANGUAGE) {
- if (value & 0xffff0000) {
- sv.add(value & 0x0000ffff);
- }
- }
- p = q;
- if (!*p) break;
- p++;
- }
-
- return NO_ERROR;
-}
-
-bool
-ResourceFilter::match(int axis, uint32_t value) const
-{
- if (value == 0) {
- // they didn't specify anything so take everything
- return true;
- }
- ssize_t index = mData.indexOfKey(axis);
- if (index < 0) {
- // we didn't request anything on this axis so take everything
- return true;
- }
- const SortedVector<uint32_t>& sv = mData.valueAt(index);
- return sv.indexOf(value) >= 0;
-}
-
-bool
-ResourceFilter::match(const ResTable_config& config) const
-{
- if (config.locale) {
- uint32_t locale = (config.country[1] << 24) | (config.country[0] << 16)
- | (config.language[1] << 8) | (config.language[0]);
- if (!match(AXIS_LANGUAGE, locale)) {
- return false;
- }
- }
- if (!match(AXIS_ORIENTATION, config.orientation)) {
- return false;
- }
- if (!match(AXIS_UIMODETYPE, (config.uiMode&ResTable_config::MASK_UI_MODE_TYPE))) {
- return false;
- }
- if (!match(AXIS_UIMODENIGHT, (config.uiMode&ResTable_config::MASK_UI_MODE_NIGHT))) {
- return false;
- }
- if (!match(AXIS_DENSITY, config.density)) {
- return false;
- }
- if (!match(AXIS_TOUCHSCREEN, config.touchscreen)) {
- return false;
- }
- if (!match(AXIS_KEYSHIDDEN, config.inputFlags)) {
- return false;
- }
- if (!match(AXIS_KEYBOARD, config.keyboard)) {
- return false;
- }
- if (!match(AXIS_NAVIGATION, config.navigation)) {
- return false;
- }
- if (!match(AXIS_SCREENSIZE, config.screenSize)) {
- return false;
- }
- if (!match(AXIS_SMALLESTSCREENWIDTHDP, config.smallestScreenWidthDp)) {
- return false;
- }
- if (!match(AXIS_SCREENWIDTHDP, config.screenWidthDp)) {
- return false;
- }
- if (!match(AXIS_SCREENHEIGHTDP, config.screenHeightDp)) {
- return false;
- }
- if (!match(AXIS_SCREENLAYOUTSIZE, config.screenLayout&ResTable_config::MASK_SCREENSIZE)) {
- return false;
- }
- if (!match(AXIS_VERSION, config.version)) {
- return false;
- }
- return true;
-}
-
status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
{
ResourceFilter filter;
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
index 80f2192..8123bb3 100644
--- a/tools/aapt/ResourceTable.h
+++ b/tools/aapt/ResourceTable.h
@@ -549,19 +549,4 @@
map<String16, set<String8> > mLocalizations;
};
-class ResourceFilter
-{
-public:
- ResourceFilter() : mData(), mContainsPseudo(false) {}
- status_t parse(const char* arg);
- bool match(int axis, uint32_t value) const;
- bool match(const ResTable_config& config) const;
- inline bool containsPseudo() const { return mContainsPseudo; }
-
-private:
- KeyedVector<int,SortedVector<uint32_t> > mData;
- bool mContainsPseudo;
-};
-
-
#endif
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
index 3835378..c91a3bf 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
@@ -23,9 +23,6 @@
import android.content.OperationApplicationException;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
-import android.database.CursorWindow;
-import android.database.IBulkCursor;
-import android.database.IContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
@@ -41,78 +38,84 @@
* TODO: never return null when the method is not supposed to. Return fake data instead.
*/
public final class BridgeContentProvider implements IContentProvider {
-
+ @Override
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> arg0)
throws RemoteException, OperationApplicationException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public int bulkInsert(Uri arg0, ContentValues[] arg1) throws RemoteException {
// TODO Auto-generated method stub
return 0;
}
- public IBulkCursor bulkQuery(Uri arg0, String[] arg1, String arg2, String[] arg3,
- String arg4, IContentObserver arg5, CursorWindow arg6) throws RemoteException {
- // TODO Auto-generated method stub
- return null;
- }
-
+ @Override
public Bundle call(String arg0, String arg1, Bundle arg2) throws RemoteException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public int delete(Uri arg0, String arg1, String[] arg2) throws RemoteException {
// TODO Auto-generated method stub
return 0;
}
+ @Override
public String getType(Uri arg0) throws RemoteException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public Uri insert(Uri arg0, ContentValues arg1) throws RemoteException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public AssetFileDescriptor openAssetFile(Uri arg0, String arg1) throws RemoteException,
FileNotFoundException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public ParcelFileDescriptor openFile(Uri arg0, String arg1) throws RemoteException,
FileNotFoundException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4)
throws RemoteException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3)
throws RemoteException {
// TODO Auto-generated method stub
return 0;
}
+ @Override
public IBinder asBinder() {
// TODO Auto-generated method stub
return null;
}
+ @Override
public String[] getStreamTypes(Uri arg0, String arg1) throws RemoteException {
// TODO Auto-generated method stub
return null;
}
+ @Override
public AssetFileDescriptor openTypedAssetFile(Uri arg0, String arg1, Bundle arg2)
throws RemoteException, FileNotFoundException {
// TODO Auto-generated method stub
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 55e9587..b76f8b9 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -2698,6 +2698,19 @@
handleNetworkDisconnect();
}
transitionTo(mDriverStoppedState);
+ break;
+ }
+
+ // Supplicant can fail to report a NETWORK_DISCONNECTION_EVENT
+ // when authentication times out after a successful connection,
+ // we can figure this from the supplicant state. If supplicant
+ // state is DISCONNECTED, but the mNetworkInfo says we are not
+ // disconnected, we need to handle a disconnection
+ if (state == SupplicantState.DISCONNECTED &&
+ mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
+ if (DBG) log("Missed CTRL-EVENT-DISCONNECTED, disconnect");
+ handleNetworkDisconnect();
+ transitionTo(mDisconnectedState);
}
break;
/* Do a redundant disconnect without transition */