Merge "Invalidate text display list on scroll"
diff --git a/Android.mk b/Android.mk
index 79f6220..5572c50 100644
--- a/Android.mk
+++ b/Android.mk
@@ -127,6 +127,7 @@
core/java/android/os/IPermissionController.aidl \
core/java/android/os/IPowerManager.aidl \
core/java/android/os/IRemoteCallback.aidl \
+ core/java/android/os/IUpdateLock.aidl \
core/java/android/os/IVibratorService.aidl \
core/java/android/service/wallpaper/IWallpaperConnection.aidl \
core/java/android/service/wallpaper/IWallpaperEngine.aidl \
diff --git a/api/current.txt b/api/current.txt
index 8af75db..5babf23 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -15343,6 +15343,7 @@
method public abstract void acquired();
method public void cleanup(android.os.IBinder, boolean);
method public void dump();
+ method public void dump(java.io.PrintWriter);
method public boolean isAcquired();
method public void release(android.os.IBinder);
method public abstract void released();
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index 1dcba70..bd9eb9a 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -69,6 +69,7 @@
+ " <COLUMN_NAME>:<TYPE>:<COLUMN_VALUE> where:\n"
+ " <TYPE> specifies data type such as:\n"
+ " b - boolean, s - string, i - integer, l - long, f - float, d - double\n"
+ + " Note: Omit the value for passing an empty string, e.g column:s:\n"
+ " Example:\n"
+ " # Add \"new_setting\" secure setting with value \"new_value\".\n"
+ " adb shell content insert --uri content://settings/secure --bind name:s:new_setting"
@@ -245,13 +246,17 @@
if (TextUtils.isEmpty(argument)) {
throw new IllegalArgumentException("Binding not well formed: " + argument);
}
- String[] binding = argument.split(COLON);
- if (binding.length != 3) {
+ final int firstColonIndex = argument.indexOf(COLON);
+ if (firstColonIndex < 0) {
throw new IllegalArgumentException("Binding not well formed: " + argument);
}
- String column = binding[0];
- String type = binding[1];
- String value = binding[2];
+ final int secondColonIndex = argument.indexOf(COLON, firstColonIndex + 1);
+ if (secondColonIndex < 0) {
+ throw new IllegalArgumentException("Binding not well formed: " + argument);
+ }
+ String column = argument.substring(0, firstColonIndex);
+ String type = argument.substring(firstColonIndex + 1, secondColonIndex);
+ String value = argument.substring(secondColonIndex + 1);
if (TYPE_STRING.equals(type)) {
values.put(column, value);
} else if (TYPE_BOOLEAN.equalsIgnoreCase(type)) {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d4b9a36..1230c81 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3986,40 +3986,40 @@
dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
}
- // allow disk access during application and provider setup. this could
+ // Allow disk access during application and provider setup. This could
// block processing ordered broadcasts, but later processing would
- // probably end up doing the same disk access. restore not guarded with
- // finally block, since exceptions here will take down the application.
+ // probably end up doing the same disk access.
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
-
- // If the app is being launched for full backup or restore, bring it up in
- // a restricted environment with the base application class.
- Application app = data.info.makeApplication(data.restrictedBackupMode, null);
- mInitialApplication = app;
-
- // don't bring up providers in restricted mode; they may depend on the
- // app's custom Application class
- if (!data.restrictedBackupMode) {
- List<ProviderInfo> providers = data.providers;
- if (providers != null) {
- installContentProviders(app, providers);
- // For process that contains content providers, we want to
- // ensure that the JIT is enabled "at some point".
- mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
- }
- }
-
try {
- mInstrumentation.callApplicationOnCreate(app);
- } catch (Exception e) {
- if (!mInstrumentation.onException(app, e)) {
- throw new RuntimeException(
- "Unable to create application " + app.getClass().getName()
- + ": " + e.toString(), e);
- }
- }
+ // If the app is being launched for full backup or restore, bring it up in
+ // a restricted environment with the base application class.
+ Application app = data.info.makeApplication(data.restrictedBackupMode, null);
+ mInitialApplication = app;
- StrictMode.setThreadPolicy(savedPolicy);
+ // don't bring up providers in restricted mode; they may depend on the
+ // app's custom Application class
+ if (!data.restrictedBackupMode) {
+ List<ProviderInfo> providers = data.providers;
+ if (providers != null) {
+ installContentProviders(app, providers);
+ // For process that contains content providers, we want to
+ // ensure that the JIT is enabled "at some point".
+ mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
+ }
+ }
+
+ try {
+ mInstrumentation.callApplicationOnCreate(app);
+ } catch (Exception e) {
+ if (!mInstrumentation.onException(app, e)) {
+ throw new RuntimeException(
+ "Unable to create application " + app.getClass().getName()
+ + ": " + e.toString(), e);
+ }
+ }
+ } finally {
+ StrictMode.setThreadPolicy(savedPolicy);
+ }
}
/*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index a1198de..111f45e 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1646,6 +1646,17 @@
/**
* Use with {@link #getSystemService} to retrieve a {@link
+ * android.os.IUpdateLock} for managing runtime sequences that
+ * must not be interrupted by headless OTA application or similar.
+ *
+ * @hide
+ * @see #getSystemService
+ * @see android.os.UpdateLock
+ */
+ public static final String UPDATE_LOCK_SERVICE = "updatelock";
+
+ /**
+ * Use with {@link #getSystemService} to retrieve a {@link
* android.net.NetworkManagementService} for handling management of
* system network services
*
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index e04b2f7..079f739 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -20,6 +20,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.util.LocaleUtil;
+import android.view.View;
import java.util.Locale;
@@ -280,9 +281,9 @@
public int compatSmallestScreenWidthDp;
/**
- * @hide The text layout direction associated to the current Locale
+ * @hide The layout direction associated to the current Locale
*/
- public int textLayoutDirection;
+ public int layoutDirection;
/**
* @hide Internal book-keeping.
@@ -310,7 +311,7 @@
mnc = o.mnc;
if (o.locale != null) {
locale = (Locale) o.locale.clone();
- textLayoutDirection = o.textLayoutDirection;
+ layoutDirection = o.layoutDirection;
}
userSetLocale = o.userSetLocale;
touchscreen = o.touchscreen;
@@ -346,10 +347,10 @@
} else {
sb.append(" (no locale)");
}
- switch (textLayoutDirection) {
- case LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE: /* ltr not interesting */ break;
- case LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE: sb.append(" rtl"); break;
- default: sb.append(" layoutdir="); sb.append(textLayoutDirection); break;
+ switch (layoutDirection) {
+ case View.LAYOUT_DIRECTION_LTR: /* ltr not interesting */ break;
+ case View.LAYOUT_DIRECTION_RTL: sb.append(" rtl"); break;
+ default: sb.append(" layoutDir="); sb.append(layoutDirection); break;
}
if (smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
sb.append(" sw"); sb.append(smallestScreenWidthDp); sb.append("dp");
@@ -472,7 +473,7 @@
screenWidthDp = compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
screenHeightDp = compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
- textLayoutDirection = LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE;
+ layoutDirection = View.LAYOUT_DIRECTION_LTR;
seq = 0;
}
@@ -508,7 +509,7 @@
changed |= ActivityInfo.CONFIG_LOCALE;
locale = delta.locale != null
? (Locale) delta.locale.clone() : null;
- textLayoutDirection = LocaleUtil.getLayoutDirectionFromLocale(locale);
+ layoutDirection = LocaleUtil.getLayoutDirectionFromLocale(locale);
}
if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0)))
{
@@ -776,7 +777,7 @@
dest.writeInt(compatScreenWidthDp);
dest.writeInt(compatScreenHeightDp);
dest.writeInt(compatSmallestScreenWidthDp);
- dest.writeInt(textLayoutDirection);
+ dest.writeInt(layoutDirection);
dest.writeInt(seq);
}
@@ -804,7 +805,7 @@
compatScreenWidthDp = source.readInt();
compatScreenHeightDp = source.readInt();
compatSmallestScreenWidthDp = source.readInt();
- textLayoutDirection = source.readInt();
+ layoutDirection = source.readInt();
seq = source.readInt();
}
diff --git a/core/java/android/database/sqlite/SQLiteConnectionPool.java b/core/java/android/database/sqlite/SQLiteConnectionPool.java
index 236948e..3562e89 100644
--- a/core/java/android/database/sqlite/SQLiteConnectionPool.java
+++ b/core/java/android/database/sqlite/SQLiteConnectionPool.java
@@ -92,13 +92,25 @@
new ArrayList<SQLiteConnection>();
private SQLiteConnection mAvailablePrimaryConnection;
+ // Describes what should happen to an acquired connection when it is returned to the pool.
+ enum AcquiredConnectionStatus {
+ // The connection should be returned to the pool as usual.
+ NORMAL,
+
+ // The connection must be reconfigured before being returned.
+ RECONFIGURE,
+
+ // The connection must be closed and discarded.
+ DISCARD,
+ }
+
// Weak references to all acquired connections. The associated value
- // is a boolean that indicates whether the connection must be reconfigured
- // before being returned to the available connection list.
+ // indicates whether the connection must be reconfigured before being
+ // returned to the available connection list or discarded.
// For example, the prepared statement cache size may have changed and
- // need to be updated.
- private final WeakHashMap<SQLiteConnection, Boolean> mAcquiredConnections =
- new WeakHashMap<SQLiteConnection, Boolean>();
+ // need to be updated in preparation for the next client.
+ private final WeakHashMap<SQLiteConnection, AcquiredConnectionStatus> mAcquiredConnections =
+ new WeakHashMap<SQLiteConnection, AcquiredConnectionStatus>();
/**
* Connection flag: Read-only.
@@ -168,7 +180,7 @@
private void open() {
// Open the primary connection.
// This might throw if the database is corrupt.
- mAvailablePrimaryConnection = openConnectionLocked(
+ mAvailablePrimaryConnection = openConnectionLocked(mConfiguration,
true /*primaryConnection*/); // might throw
// Mark the pool as being open for business.
@@ -209,16 +221,7 @@
mIsOpen = false;
- final int count = mAvailableNonPrimaryConnections.size();
- for (int i = 0; i < count; i++) {
- closeConnectionAndLogExceptionsLocked(mAvailableNonPrimaryConnections.get(i));
- }
- mAvailableNonPrimaryConnections.clear();
-
- if (mAvailablePrimaryConnection != null) {
- closeConnectionAndLogExceptionsLocked(mAvailablePrimaryConnection);
- mAvailablePrimaryConnection = null;
- }
+ closeAvailableConnectionsAndLogExceptionsLocked();
final int pendingCount = mAcquiredConnections.size();
if (pendingCount != 0) {
@@ -254,21 +257,27 @@
synchronized (mLock) {
throwIfClosedLocked();
- final boolean poolSizeChanged = mConfiguration.maxConnectionPoolSize
- != configuration.maxConnectionPoolSize;
- mConfiguration.updateParametersFrom(configuration);
+ if (mConfiguration.openFlags != configuration.openFlags) {
+ // Try to reopen the primary connection using the new open flags then
+ // close and discard all existing connections.
+ // This might throw if the database is corrupt or cannot be opened in
+ // the new mode in which case existing connections will remain untouched.
+ SQLiteConnection newPrimaryConnection = openConnectionLocked(configuration,
+ true /*primaryConnection*/); // might throw
- if (poolSizeChanged) {
- int availableCount = mAvailableNonPrimaryConnections.size();
- while (availableCount-- > mConfiguration.maxConnectionPoolSize - 1) {
- SQLiteConnection connection =
- mAvailableNonPrimaryConnections.remove(availableCount);
- closeConnectionAndLogExceptionsLocked(connection);
- }
+ closeAvailableConnectionsAndLogExceptionsLocked();
+ discardAcquiredConnectionsLocked();
+
+ mAvailablePrimaryConnection = newPrimaryConnection;
+ mConfiguration.updateParametersFrom(configuration);
+ } else {
+ // Reconfigure the database connections in place.
+ mConfiguration.updateParametersFrom(configuration);
+
+ closeExcessConnectionsAndLogExceptionsLocked();
+ reconfigureAllConnectionsLocked();
}
- reconfigureAllConnectionsLocked();
-
wakeConnectionWaitersLocked();
}
}
@@ -310,8 +319,8 @@
*/
public void releaseConnection(SQLiteConnection connection) {
synchronized (mLock) {
- Boolean mustReconfigure = mAcquiredConnections.remove(connection);
- if (mustReconfigure == null) {
+ AcquiredConnectionStatus status = mAcquiredConnections.remove(connection);
+ if (status == null) {
throw new IllegalStateException("Cannot perform this operation "
+ "because the specified connection was not acquired "
+ "from this pool or has already been released.");
@@ -320,18 +329,8 @@
if (!mIsOpen) {
closeConnectionAndLogExceptionsLocked(connection);
} else if (connection.isPrimaryConnection()) {
- assert mAvailablePrimaryConnection == null;
- try {
- if (mustReconfigure == Boolean.TRUE) {
- connection.reconfigure(mConfiguration); // might throw
- }
- } catch (RuntimeException ex) {
- Log.e(TAG, "Failed to reconfigure released primary connection, closing it: "
- + connection, ex);
- closeConnectionAndLogExceptionsLocked(connection);
- connection = null;
- }
- if (connection != null) {
+ if (recycleConnectionLocked(connection, status)) {
+ assert mAvailablePrimaryConnection == null;
mAvailablePrimaryConnection = connection;
}
wakeConnectionWaitersLocked();
@@ -339,17 +338,7 @@
mConfiguration.maxConnectionPoolSize - 1) {
closeConnectionAndLogExceptionsLocked(connection);
} else {
- try {
- if (mustReconfigure == Boolean.TRUE) {
- connection.reconfigure(mConfiguration); // might throw
- }
- } catch (RuntimeException ex) {
- Log.e(TAG, "Failed to reconfigure released non-primary connection, "
- + "closing it: " + connection, ex);
- closeConnectionAndLogExceptionsLocked(connection);
- connection = null;
- }
- if (connection != null) {
+ if (recycleConnectionLocked(connection, status)) {
mAvailableNonPrimaryConnections.add(connection);
}
wakeConnectionWaitersLocked();
@@ -357,6 +346,25 @@
}
}
+ // Can't throw.
+ private boolean recycleConnectionLocked(SQLiteConnection connection,
+ AcquiredConnectionStatus status) {
+ if (status == AcquiredConnectionStatus.RECONFIGURE) {
+ try {
+ connection.reconfigure(mConfiguration); // might throw
+ } catch (RuntimeException ex) {
+ Log.e(TAG, "Failed to reconfigure released connection, closing it: "
+ + connection, ex);
+ status = AcquiredConnectionStatus.DISCARD;
+ }
+ }
+ if (status == AcquiredConnectionStatus.DISCARD) {
+ closeConnectionAndLogExceptionsLocked(connection);
+ return false;
+ }
+ return true;
+ }
+
/**
* Returns true if the session should yield the connection due to
* contention over available database connections.
@@ -407,9 +415,10 @@
}
// Might throw.
- private SQLiteConnection openConnectionLocked(boolean primaryConnection) {
+ private SQLiteConnection openConnectionLocked(SQLiteDatabaseConfiguration configuration,
+ boolean primaryConnection) {
final int connectionId = mNextConnectionId++;
- return SQLiteConnection.open(this, mConfiguration,
+ return SQLiteConnection.open(this, configuration,
connectionId, primaryConnection); // might throw
}
@@ -443,6 +452,30 @@
}
// Can't throw.
+ private void closeAvailableConnectionsAndLogExceptionsLocked() {
+ final int count = mAvailableNonPrimaryConnections.size();
+ for (int i = 0; i < count; i++) {
+ closeConnectionAndLogExceptionsLocked(mAvailableNonPrimaryConnections.get(i));
+ }
+ mAvailableNonPrimaryConnections.clear();
+
+ if (mAvailablePrimaryConnection != null) {
+ closeConnectionAndLogExceptionsLocked(mAvailablePrimaryConnection);
+ mAvailablePrimaryConnection = null;
+ }
+ }
+
+ // Can't throw.
+ private void closeExcessConnectionsAndLogExceptionsLocked() {
+ int availableCount = mAvailableNonPrimaryConnections.size();
+ while (availableCount-- > mConfiguration.maxConnectionPoolSize - 1) {
+ SQLiteConnection connection =
+ mAvailableNonPrimaryConnections.remove(availableCount);
+ closeConnectionAndLogExceptionsLocked(connection);
+ }
+ }
+
+ // Can't throw.
private void closeConnectionAndLogExceptionsLocked(SQLiteConnection connection) {
try {
connection.close(); // might throw
@@ -453,8 +486,12 @@
}
// Can't throw.
+ private void discardAcquiredConnectionsLocked() {
+ markAcquiredConnectionsLocked(AcquiredConnectionStatus.DISCARD);
+ }
+
+ // Can't throw.
private void reconfigureAllConnectionsLocked() {
- boolean wake = false;
if (mAvailablePrimaryConnection != null) {
try {
mAvailablePrimaryConnection.reconfigure(mConfiguration); // might throw
@@ -463,7 +500,6 @@
+ mAvailablePrimaryConnection, ex);
closeConnectionAndLogExceptionsLocked(mAvailablePrimaryConnection);
mAvailablePrimaryConnection = null;
- wake = true;
}
}
@@ -478,27 +514,30 @@
closeConnectionAndLogExceptionsLocked(connection);
mAvailableNonPrimaryConnections.remove(i--);
count -= 1;
- wake = true;
}
}
+ markAcquiredConnectionsLocked(AcquiredConnectionStatus.RECONFIGURE);
+ }
+
+ // Can't throw.
+ private void markAcquiredConnectionsLocked(AcquiredConnectionStatus status) {
if (!mAcquiredConnections.isEmpty()) {
ArrayList<SQLiteConnection> keysToUpdate = new ArrayList<SQLiteConnection>(
mAcquiredConnections.size());
- for (Map.Entry<SQLiteConnection, Boolean> entry : mAcquiredConnections.entrySet()) {
- if (entry.getValue() != Boolean.TRUE) {
+ for (Map.Entry<SQLiteConnection, AcquiredConnectionStatus> entry
+ : mAcquiredConnections.entrySet()) {
+ AcquiredConnectionStatus oldStatus = entry.getValue();
+ if (status != oldStatus
+ && oldStatus != AcquiredConnectionStatus.DISCARD) {
keysToUpdate.add(entry.getKey());
}
}
final int updateCount = keysToUpdate.size();
for (int i = 0; i < updateCount; i++) {
- mAcquiredConnections.put(keysToUpdate.get(i), Boolean.TRUE);
+ mAcquiredConnections.put(keysToUpdate.get(i), status);
}
}
-
- if (wake) {
- wakeConnectionWaitersLocked();
- }
}
// Might throw.
@@ -658,8 +697,7 @@
int activeConnections = 0;
int idleConnections = 0;
if (!mAcquiredConnections.isEmpty()) {
- for (Map.Entry<SQLiteConnection, Boolean> entry : mAcquiredConnections.entrySet()) {
- final SQLiteConnection connection = entry.getKey();
+ for (SQLiteConnection connection : mAcquiredConnections.keySet()) {
String description = connection.describeCurrentOperationUnsafe();
if (description != null) {
requests.add(description);
@@ -769,7 +807,8 @@
// Uhoh. No primary connection! Either this is the first time we asked
// for it, or maybe it leaked?
- connection = openConnectionLocked(true /*primaryConnection*/); // might throw
+ connection = openConnectionLocked(mConfiguration,
+ true /*primaryConnection*/); // might throw
finishAcquireConnectionLocked(connection, connectionFlags); // might throw
return connection;
}
@@ -807,7 +846,8 @@
if (openConnections >= mConfiguration.maxConnectionPoolSize) {
return null;
}
- connection = openConnectionLocked(false /*primaryConnection*/); // might throw
+ connection = openConnectionLocked(mConfiguration,
+ false /*primaryConnection*/); // might throw
finishAcquireConnectionLocked(connection, connectionFlags); // might throw
return connection;
}
@@ -818,7 +858,7 @@
final boolean readOnly = (connectionFlags & CONNECTION_FLAG_READ_ONLY) != 0;
connection.setOnlyAllowReadOnlyOperations(readOnly);
- mAcquiredConnections.put(connection, Boolean.FALSE);
+ mAcquiredConnections.put(connection, AcquiredConnectionStatus.NORMAL);
} catch (RuntimeException ex) {
Log.e(TAG, "Failed to prepare acquired connection for session, closing it: "
+ connection +", connectionFlags=" + connectionFlags);
@@ -858,7 +898,7 @@
private void throwIfClosedLocked() {
if (!mIsOpen) {
throw new IllegalStateException("Cannot perform this operation "
- + "because the connection pool have been closed.");
+ + "because the connection pool has been closed.");
}
}
@@ -922,11 +962,11 @@
printer.println(" Acquired connections:");
if (!mAcquiredConnections.isEmpty()) {
- for (Map.Entry<SQLiteConnection, Boolean> entry :
+ for (Map.Entry<SQLiteConnection, AcquiredConnectionStatus> entry :
mAcquiredConnections.entrySet()) {
final SQLiteConnection connection = entry.getKey();
connection.dumpUnsafe(indentedPrinter, verbose);
- indentedPrinter.println(" Pending reconfiguration: " + entry.getValue());
+ indentedPrinter.println(" Status: " + entry.getValue());
}
} else {
indentedPrinter.println("<none>");
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 505f83e..36f678d 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -677,6 +677,38 @@
return openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler);
}
+ /**
+ * Reopens the database in read-write mode.
+ * If the database is already read-write, does nothing.
+ *
+ * @throws SQLiteException if the database could not be reopened as requested, in which
+ * case it remains open in read only mode.
+ * @throws IllegalStateException if the database is not open.
+ *
+ * @see #isReadOnly()
+ * @hide
+ */
+ public void reopenReadWrite() {
+ synchronized (mLock) {
+ throwIfNotOpenLocked();
+
+ if (!isReadOnlyLocked()) {
+ return; // nothing to do
+ }
+
+ // Reopen the database in read-write mode.
+ final int oldOpenFlags = mConfigurationLocked.openFlags;
+ mConfigurationLocked.openFlags = (mConfigurationLocked.openFlags & ~OPEN_READ_MASK)
+ | OPEN_READWRITE;
+ try {
+ mConnectionPoolLocked.reconfigure(mConfigurationLocked);
+ } catch (RuntimeException ex) {
+ mConfigurationLocked.openFlags = oldOpenFlags;
+ throw ex;
+ }
+ }
+ }
+
private void open() {
try {
try {
@@ -1902,28 +1934,6 @@
return true;
}
- /**
- * Prevent other threads from using the database's primary connection.
- *
- * This method is only used by {@link SQLiteOpenHelper} when transitioning from
- * a readable to a writable database. It should not be used in any other way.
- *
- * @see #unlockPrimaryConnection()
- */
- void lockPrimaryConnection() {
- getThreadSession().beginTransaction(SQLiteSession.TRANSACTION_MODE_DEFERRED,
- null, SQLiteConnectionPool.CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY, null);
- }
-
- /**
- * Allow other threads to use the database's primary connection.
- *
- * @see #lockPrimaryConnection()
- */
- void unlockPrimaryConnection() {
- getThreadSession().endTransaction(null);
- }
-
@Override
public String toString() {
return "SQLiteDatabase: " + getPath();
diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
index bc79ad3..02ef671 100644
--- a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
+++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
@@ -51,17 +51,17 @@
public final String path;
/**
- * The flags used to open the database.
- */
- public final int openFlags;
-
- /**
* The label to use to describe the database when it appears in logs.
* This is derived from the path but is stripped to remove PII.
*/
public final String label;
/**
+ * The flags used to open the database.
+ */
+ public int openFlags;
+
+ /**
* The maximum number of connections to retain in the connection pool.
* Must be at least 1.
*
@@ -103,8 +103,8 @@
}
this.path = path;
- this.openFlags = openFlags;
label = stripPathForLogs(path);
+ this.openFlags = openFlags;
// Set default values for optional parameters.
maxConnectionPoolSize = 1;
@@ -123,7 +123,6 @@
}
this.path = other.path;
- this.openFlags = other.openFlags;
this.label = other.label;
updateParametersFrom(other);
}
@@ -138,11 +137,12 @@
if (other == null) {
throw new IllegalArgumentException("other must not be null.");
}
- if (!path.equals(other.path) || openFlags != other.openFlags) {
+ if (!path.equals(other.path)) {
throw new IllegalArgumentException("other configuration must refer to "
+ "the same database.");
}
+ openFlags = other.openFlags;
maxConnectionPoolSize = other.maxConnectionPoolSize;
maxSqlCacheSize = other.maxSqlCacheSize;
locale = other.locale;
diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java
index 46d9369..ffa4663 100644
--- a/core/java/android/database/sqlite/SQLiteOpenHelper.java
+++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java
@@ -43,13 +43,21 @@
public abstract class SQLiteOpenHelper {
private static final String TAG = SQLiteOpenHelper.class.getSimpleName();
+ // When true, getReadableDatabase returns a read-only database if it is just being opened.
+ // The database handle is reopened in read/write mode when getWritableDatabase is called.
+ // We leave this behavior disabled in production because it is inefficient and breaks
+ // many applications. For debugging purposes it can be useful to turn on strict
+ // read-only semantics to catch applications that call getReadableDatabase when they really
+ // wanted getWritableDatabase.
+ private static final boolean DEBUG_STRICT_READONLY = false;
+
private final Context mContext;
private final String mName;
private final CursorFactory mFactory;
private final int mNewVersion;
- private SQLiteDatabase mDatabase = null;
- private boolean mIsInitializing = false;
+ private SQLiteDatabase mDatabase;
+ private boolean mIsInitializing;
private final DatabaseErrorHandler mErrorHandler;
/**
@@ -127,76 +135,9 @@
* @throws SQLiteException if the database cannot be opened for writing
* @return a read/write database object valid until {@link #close} is called
*/
- public synchronized SQLiteDatabase getWritableDatabase() {
- if (mDatabase != null) {
- if (!mDatabase.isOpen()) {
- // darn! the user closed the database by calling mDatabase.close()
- mDatabase = null;
- } else if (!mDatabase.isReadOnly()) {
- return mDatabase; // The database is already open for business
- }
- }
-
- if (mIsInitializing) {
- throw new IllegalStateException("getWritableDatabase called recursively");
- }
-
- // If we have a read-only database open, someone could be using it
- // (though they shouldn't), which would cause a lock to be held on
- // the file, and our attempts to open the database read-write would
- // fail waiting for the file lock. To prevent that, we acquire a lock
- // on the read-only database, which shuts out other users.
-
- boolean success = false;
- SQLiteDatabase db = null;
- if (mDatabase != null) {
- mDatabase.lockPrimaryConnection();
- }
- try {
- mIsInitializing = true;
- if (mName == null) {
- db = SQLiteDatabase.create(null);
- } else {
- db = mContext.openOrCreateDatabase(mName, 0, mFactory, mErrorHandler);
- }
-
- int version = db.getVersion();
- if (version != mNewVersion) {
- db.beginTransaction();
- try {
- if (version == 0) {
- onCreate(db);
- } else {
- if (version > mNewVersion) {
- onDowngrade(db, version, mNewVersion);
- } else {
- onUpgrade(db, version, mNewVersion);
- }
- }
- db.setVersion(mNewVersion);
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
- }
-
- onOpen(db);
- success = true;
- return db;
- } finally {
- mIsInitializing = false;
- if (success) {
- if (mDatabase != null) {
- try { mDatabase.close(); } catch (Exception e) { }
- mDatabase.unlockPrimaryConnection();
- }
- mDatabase = db;
- } else {
- if (mDatabase != null) {
- mDatabase.unlockPrimaryConnection();
- }
- if (db != null) db.close();
- }
+ public SQLiteDatabase getWritableDatabase() {
+ synchronized (this) {
+ return getDatabaseLocked(true);
}
}
@@ -218,45 +159,95 @@
* @return a database object valid until {@link #getWritableDatabase}
* or {@link #close} is called.
*/
- public synchronized SQLiteDatabase getReadableDatabase() {
+ public SQLiteDatabase getReadableDatabase() {
+ synchronized (this) {
+ return getDatabaseLocked(false);
+ }
+ }
+
+ private SQLiteDatabase getDatabaseLocked(boolean writable) {
if (mDatabase != null) {
if (!mDatabase.isOpen()) {
- // darn! the user closed the database by calling mDatabase.close()
+ // Darn! The user closed the database by calling mDatabase.close().
mDatabase = null;
- } else {
- return mDatabase; // The database is already open for business
+ } else if (!writable || !mDatabase.isReadOnly()) {
+ // The database is already open for business.
+ return mDatabase;
}
}
if (mIsInitializing) {
- throw new IllegalStateException("getReadableDatabase called recursively");
+ throw new IllegalStateException("getDatabase called recursively");
}
- try {
- return getWritableDatabase();
- } catch (SQLiteException e) {
- if (mName == null) throw e; // Can't open a temp database read-only!
- Log.e(TAG, "Couldn't open " + mName + " for writing (will try read-only):", e);
- }
-
- SQLiteDatabase db = null;
+ SQLiteDatabase db = mDatabase;
try {
mIsInitializing = true;
- String path = mContext.getDatabasePath(mName).getPath();
- db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY,
- mErrorHandler);
- if (db.getVersion() != mNewVersion) {
- throw new SQLiteException("Can't upgrade read-only database from version " +
- db.getVersion() + " to " + mNewVersion + ": " + path);
+
+ if (db != null) {
+ if (writable && db.isReadOnly()) {
+ db.reopenReadWrite();
+ }
+ } else if (mName == null) {
+ db = SQLiteDatabase.create(null);
+ } else {
+ try {
+ if (DEBUG_STRICT_READONLY && !writable) {
+ final String path = mContext.getDatabasePath(mName).getPath();
+ db = SQLiteDatabase.openDatabase(path, mFactory,
+ SQLiteDatabase.OPEN_READONLY, mErrorHandler);
+ } else {
+ db = mContext.openOrCreateDatabase(mName, 0, mFactory, mErrorHandler);
+ }
+ } catch (SQLiteException ex) {
+ if (writable) {
+ throw ex;
+ }
+ Log.e(TAG, "Couldn't open " + mName
+ + " for writing (will try read-only):", ex);
+ final String path = mContext.getDatabasePath(mName).getPath();
+ db = SQLiteDatabase.openDatabase(path, mFactory,
+ SQLiteDatabase.OPEN_READONLY, mErrorHandler);
+ }
}
+ final int version = db.getVersion();
+ if (version != mNewVersion) {
+ if (db.isReadOnly()) {
+ throw new SQLiteException("Can't upgrade read-only database from version " +
+ db.getVersion() + " to " + mNewVersion + ": " + mName);
+ }
+
+ db.beginTransaction();
+ try {
+ if (version == 0) {
+ onCreate(db);
+ } else {
+ if (version > mNewVersion) {
+ onDowngrade(db, version, mNewVersion);
+ } else {
+ onUpgrade(db, version, mNewVersion);
+ }
+ }
+ db.setVersion(mNewVersion);
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+ }
onOpen(db);
- Log.w(TAG, "Opened " + mName + " in read-only mode");
+
+ if (db.isReadOnly()) {
+ Log.w(TAG, "Opened " + mName + " in read-only mode");
+ }
+
mDatabase = db;
- return mDatabase;
+ return db;
} finally {
mIsInitializing = false;
- if (db != null && db != mDatabase) db.close();
+ if (db != null && db != mDatabase) {
+ db.close();
+ }
}
}
diff --git a/core/java/android/os/IUpdateLock.aidl b/core/java/android/os/IUpdateLock.aidl
new file mode 100644
index 0000000..4492fb8
--- /dev/null
+++ b/core/java/android/os/IUpdateLock.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 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.os;
+
+/**
+ * Direct interface to the UpdateLockService's functionality
+ *
+ * {@hide}
+ */
+interface IUpdateLock {
+ void acquireUpdateLock(IBinder token, String tag);
+ void releaseUpdateLock(IBinder token);
+}
diff --git a/core/java/android/os/TokenWatcher.java b/core/java/android/os/TokenWatcher.java
index ac3cc92..9b3a2d6 100755
--- a/core/java/android/os/TokenWatcher.java
+++ b/core/java/android/os/TokenWatcher.java
@@ -16,6 +16,8 @@
package android.os;
+import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.WeakHashMap;
import java.util.Set;
import android.util.Log;
@@ -115,15 +117,31 @@
public void dump()
{
+ ArrayList<String> a = dumpInternal();
+ for (String s : a) {
+ Log.i(mTag, s);
+ }
+ }
+
+ public void dump(PrintWriter pw) {
+ ArrayList<String> a = dumpInternal();
+ for (String s : a) {
+ pw.println(s);
+ }
+ }
+
+ private ArrayList<String> dumpInternal() {
+ ArrayList<String> a = new ArrayList<String>();
synchronized (mTokens) {
Set<IBinder> keys = mTokens.keySet();
- Log.i(mTag, "Token count: " + mTokens.size());
+ a.add("Token count: " + mTokens.size());
int i = 0;
for (IBinder b: keys) {
- Log.i(mTag, "[" + i + "] " + mTokens.get(b).tag + " - " + b);
+ a.add("[" + i + "] " + mTokens.get(b).tag + " - " + b);
i++;
}
}
+ return a;
}
private Runnable mNotificationTask = new Runnable() {
diff --git a/core/java/android/os/UpdateLock.java b/core/java/android/os/UpdateLock.java
new file mode 100644
index 0000000..4060326
--- /dev/null
+++ b/core/java/android/os/UpdateLock.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2012 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.os;
+
+import android.content.Context;
+import android.util.Log;
+
+/**
+ * Advisory wakelock-like mechanism by which processes that should not be interrupted for
+ * OTA/update purposes can so advise the OS. This is particularly relevant for headless
+ * or kiosk-like operation.
+ *
+ * @hide
+ */
+public class UpdateLock {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "UpdateLock";
+
+ private static IUpdateLock sService;
+ private static void checkService() {
+ if (sService == null) {
+ sService = IUpdateLock.Stub.asInterface(
+ ServiceManager.getService(Context.UPDATE_LOCK_SERVICE));
+ }
+ }
+
+ IBinder mToken;
+ int mCount = 0;
+ boolean mRefCounted = true;
+ boolean mHeld = false;
+ final String mTag;
+
+ /**
+ * Broadcast Intent action sent when the global update lock state changes,
+ * i.e. when the first locker acquires an update lock, or when the last
+ * locker releases theirs. The broadcast is sticky but is sent only to
+ * registered receivers.
+ */
+ public static final String UPDATE_LOCK_CHANGED = "android.os.UpdateLock.UPDATE_LOCK_CHANGED";
+
+ /**
+ * Boolean Intent extra on the UPDATE_LOCK_CHANGED sticky broadcast, indicating
+ * whether now is an appropriate time to interrupt device activity with an
+ * update operation. True means that updates are okay right now; false indicates
+ * that perhaps later would be a better time.
+ */
+ public static final String NOW_IS_CONVENIENT = "nowisconvenient";
+
+ /**
+ * Long Intent extra on the UPDATE_LOCK_CHANGED sticky broadcast, marking the
+ * wall-clock time [in UTC] at which the broadcast was sent. Note that this is
+ * in the System.currentTimeMillis() time base, which may be non-monotonic especially
+ * around reboots.
+ */
+ public static final String TIMESTAMP = "timestamp";
+
+ /**
+ * Construct an UpdateLock instance.
+ * @param tag An arbitrary string used to identify this lock instance in dump output.
+ */
+ public UpdateLock(String tag) {
+ mTag = tag;
+ mToken = new Binder();
+ }
+
+ /**
+ * Change the refcount behavior of this update lock.
+ */
+ public void setReferenceCounted(boolean isRefCounted) {
+ if (DEBUG) {
+ Log.v(TAG, "setting refcounted=" + isRefCounted + " : " + this);
+ }
+ mRefCounted = isRefCounted;
+ }
+
+ /**
+ * Is this lock currently held?
+ */
+ public boolean isHeld() {
+ synchronized (mToken) {
+ return mHeld;
+ }
+ }
+
+ /**
+ * Acquire an update lock.
+ */
+ public void acquire() {
+ if (DEBUG) {
+ Log.v(TAG, "acquire() : " + this, new RuntimeException("here"));
+ }
+ checkService();
+ synchronized (mToken) {
+ acquireLocked();
+ }
+ }
+
+ private void acquireLocked() {
+ if (!mRefCounted || mCount++ == 0) {
+ if (sService != null) {
+ try {
+ sService.acquireUpdateLock(mToken, mTag);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to contact service to acquire");
+ }
+ }
+ mHeld = true;
+ }
+ }
+
+ /**
+ * Release this update lock.
+ */
+ public void release() {
+ if (DEBUG) Log.v(TAG, "release() : " + this, new RuntimeException("here"));
+ checkService();
+ synchronized (mToken) {
+ releaseLocked();
+ }
+ }
+
+ private void releaseLocked() {
+ if (!mRefCounted || --mCount == 0) {
+ if (sService != null) {
+ try {
+ sService.releaseUpdateLock(mToken);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to contact service to release");
+ }
+ }
+ mHeld = false;
+ }
+ if (mCount < 0) {
+ throw new RuntimeException("UpdateLock under-locked");
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ synchronized (mToken) {
+ // if mHeld is true, sService must be non-null
+ if (mHeld) {
+ Log.wtf(TAG, "UpdateLock finalized while still held");
+ try {
+ sService.releaseUpdateLock(mToken);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to contact service to release");
+ }
+ }
+ }
+ }
+}
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index ca7263c..8c97293 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -16,6 +16,7 @@
package android.text;
+import com.android.internal.util.ArrayUtils;
import org.ccil.cowan.tagsoup.HTMLSchema;
import org.ccil.cowan.tagsoup.Parser;
import org.xml.sax.Attributes;
@@ -45,13 +46,11 @@
import android.text.style.TypefaceSpan;
import android.text.style.URLSpan;
import android.text.style.UnderlineSpan;
-import android.util.Log;
import com.android.internal.util.XmlUtils;
import java.io.IOException;
import java.io.StringReader;
-import java.nio.CharBuffer;
import java.util.HashMap;
/**
@@ -203,9 +202,26 @@
}
}
+ private static String getOpenParaTagWithDirection(Spanned text, int start, int end) {
+ final int len = end - start;
+ final byte[] levels = new byte[ArrayUtils.idealByteArraySize(len)];
+ final char[] buffer = TextUtils.obtain(len);
+ TextUtils.getChars(text, start, end, buffer, 0);
+
+ int paraDir = AndroidBidi.bidi(Layout.DIR_REQUEST_DEFAULT_LTR, buffer, levels, len,
+ false /* no info */);
+ switch(paraDir) {
+ case Layout.DIR_RIGHT_TO_LEFT:
+ return "<p dir=rtl>";
+ case Layout.DIR_LEFT_TO_RIGHT:
+ default:
+ return "<p dir=ltr>";
+ }
+ }
+
private static void withinBlockquote(StringBuilder out, Spanned text,
int start, int end) {
- out.append("<p>");
+ out.append(getOpenParaTagWithDirection(text, start, end));
int next;
for (int i = start; i < end; i = next) {
@@ -340,7 +356,7 @@
}
}
- String p = last ? "" : "</p>\n<p>";
+ String p = last ? "" : "</p>\n" + getOpenParaTagWithDirection(text, start, end);
if (nl == 1) {
out.append("<br>\n");
@@ -350,7 +366,6 @@
for (int i = 2; i < nl; i++) {
out.append("<br>");
}
-
out.append(p);
}
}
diff --git a/core/java/android/text/TextDirectionHeuristics.java b/core/java/android/text/TextDirectionHeuristics.java
index ae41eab..6ca6161 100644
--- a/core/java/android/text/TextDirectionHeuristics.java
+++ b/core/java/android/text/TextDirectionHeuristics.java
@@ -18,6 +18,7 @@
import android.util.LocaleUtil;
+import android.view.View;
/**
* Some objects that implement TextDirectionHeuristic.
@@ -240,7 +241,7 @@
@Override
protected boolean defaultIsRtl() {
final int dir = LocaleUtil.getLayoutDirectionFromLocale(java.util.Locale.getDefault());
- return (dir == LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE);
+ return (dir == View.LAYOUT_DIRECTION_RTL);
}
public static final TextDirectionHeuristicLocale INSTANCE =
diff --git a/core/java/android/util/LocaleUtil.java b/core/java/android/util/LocaleUtil.java
index 4d773f6..9953252 100644
--- a/core/java/android/util/LocaleUtil.java
+++ b/core/java/android/util/LocaleUtil.java
@@ -18,6 +18,7 @@
import java.util.Locale;
+import android.view.View;
import libcore.icu.ICU;
/**
@@ -29,16 +30,6 @@
private LocaleUtil() { /* cannot be instantiated */ }
- /**
- * @hide Do not use. Implementation not finished.
- */
- public static final int TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE = 0;
-
- /**
- * @hide Do not use. Implementation not finished.
- */
- public static final int TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE = 1;
-
private static String ARAB_SCRIPT_SUBTAG = "Arab";
private static String HEBR_SCRIPT_SUBTAG = "Hebr";
@@ -47,8 +38,8 @@
*
* @param locale the Locale for which we want the layout direction. Can be null.
* @return the layout direction. This may be one of:
- * {@link #TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE} or
- * {@link #TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE}.
+ * {@link View#LAYOUT_DIRECTION_LTR} or
+ * {@link View#LAYOUT_DIRECTION_RTL}.
*
* Be careful: this code will need to be changed when vertical scripts will be supported
*
@@ -61,11 +52,11 @@
if (scriptSubtag.equalsIgnoreCase(ARAB_SCRIPT_SUBTAG) ||
scriptSubtag.equalsIgnoreCase(HEBR_SCRIPT_SUBTAG)) {
- return TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE;
+ return View.LAYOUT_DIRECTION_RTL;
}
}
- return TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE;
+ return View.LAYOUT_DIRECTION_LTR;
}
/**
@@ -75,8 +66,8 @@
*
* @param locale
* @return the layout direction. This may be one of:
- * {@link #TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE} or
- * {@link #TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE}.
+ * {@link View#LAYOUT_DIRECTION_LTR} or
+ * {@link View#LAYOUT_DIRECTION_RTL}.
*
* Be careful: this code will need to be changed when vertical scripts will be supported
*
@@ -86,11 +77,11 @@
switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) {
case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
- return TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE;
+ return View.LAYOUT_DIRECTION_RTL;
case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
default:
- return TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE;
+ return View.LAYOUT_DIRECTION_LTR;
}
}
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e6b41da..5cf0459 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -40,7 +40,6 @@
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
@@ -9711,8 +9710,7 @@
* @hide
*/
protected static boolean isLayoutDirectionRtl(Locale locale) {
- return (LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE ==
- LocaleUtil.getLayoutDirectionFromLocale(locale));
+ return (LAYOUT_DIRECTION_RTL == LocaleUtil.getLayoutDirectionFromLocale(locale));
}
/**
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 97d90b4..385c7c7 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -5996,7 +5996,6 @@
if (des < 0) {
des = (int) FloatMath.ceil(Layout.getDesiredWidth(mTransformed, mTextPaint));
}
-
width = des;
} else {
width = boring.width;
@@ -6017,7 +6016,7 @@
}
if (hintDes < 0) {
- hintBoring = BoringLayout.isBoring(mHint, mTextPaint, mHintBoring);
+ hintBoring = BoringLayout.isBoring(mHint, mTextPaint, mTextDir, mHintBoring);
if (hintBoring != null) {
mHintBoring = hintBoring;
}
@@ -6025,10 +6024,8 @@
if (hintBoring == null || hintBoring == UNKNOWN_BORING) {
if (hintDes < 0) {
- hintDes = (int) FloatMath.ceil(
- Layout.getDesiredWidth(mHint, mTextPaint));
+ hintDes = (int) FloatMath.ceil(Layout.getDesiredWidth(mHint, mTextPaint));
}
-
hintWidth = hintDes;
} else {
hintWidth = hintBoring.width;
@@ -6292,20 +6289,25 @@
if (changed && mEditor != null) getEditor().mTextDisplayListIsValid = false;
}
+ private boolean isShowingHint() {
+ return TextUtils.isEmpty(mText) && !TextUtils.isEmpty(mHint);
+ }
+
/**
* Returns true if anything changed.
*/
private boolean bringTextIntoView() {
+ Layout layout = isShowingHint() ? mHintLayout : mLayout;
int line = 0;
if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
- line = mLayout.getLineCount() - 1;
+ line = layout.getLineCount() - 1;
}
- Layout.Alignment a = mLayout.getParagraphAlignment(line);
- int dir = mLayout.getParagraphDirection(line);
+ Layout.Alignment a = layout.getParagraphAlignment(line);
+ int dir = layout.getParagraphDirection(line);
int hspace = mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight();
int vspace = mBottom - mTop - getExtendedPaddingTop() - getExtendedPaddingBottom();
- int ht = mLayout.getHeight();
+ int ht = layout.getHeight();
int scrollx, scrolly;
@@ -6324,8 +6326,8 @@
* keep leading edge in view.
*/
- int left = (int) FloatMath.floor(mLayout.getLineLeft(line));
- int right = (int) FloatMath.ceil(mLayout.getLineRight(line));
+ int left = (int) FloatMath.floor(layout.getLineLeft(line));
+ int right = (int) FloatMath.ceil(layout.getLineRight(line));
if (right - left < hspace) {
scrollx = (right + left) / 2 - hspace / 2;
@@ -6337,10 +6339,10 @@
}
}
} else if (a == Layout.Alignment.ALIGN_RIGHT) {
- int right = (int) FloatMath.ceil(mLayout.getLineRight(line));
+ int right = (int) FloatMath.ceil(layout.getLineRight(line));
scrollx = right - hspace;
} else { // a == Layout.Alignment.ALIGN_LEFT (will also be the default)
- scrollx = (int) FloatMath.floor(mLayout.getLineLeft(line));
+ scrollx = (int) FloatMath.floor(layout.getLineLeft(line));
}
if (ht < vspace) {
@@ -6368,22 +6370,24 @@
public boolean bringPointIntoView(int offset) {
boolean changed = false;
- if (mLayout == null) return changed;
+ Layout layout = isShowingHint() ? mHintLayout: mLayout;
- int line = mLayout.getLineForOffset(offset);
+ if (layout == null) return changed;
+
+ int line = layout.getLineForOffset(offset);
// FIXME: Is it okay to truncate this, or should we round?
- final int x = (int)mLayout.getPrimaryHorizontal(offset);
- final int top = mLayout.getLineTop(line);
- final int bottom = mLayout.getLineTop(line + 1);
+ final int x = (int)layout.getPrimaryHorizontal(offset);
+ final int top = layout.getLineTop(line);
+ final int bottom = layout.getLineTop(line + 1);
- int left = (int) FloatMath.floor(mLayout.getLineLeft(line));
- int right = (int) FloatMath.ceil(mLayout.getLineRight(line));
- int ht = mLayout.getHeight();
+ int left = (int) FloatMath.floor(layout.getLineLeft(line));
+ int right = (int) FloatMath.ceil(layout.getLineRight(line));
+ int ht = layout.getHeight();
int grav;
- switch (mLayout.getParagraphAlignment(line)) {
+ switch (layout.getParagraphAlignment(line)) {
case ALIGN_LEFT:
grav = 1;
break;
@@ -6391,10 +6395,10 @@
grav = -1;
break;
case ALIGN_NORMAL:
- grav = mLayout.getParagraphDirection(line);
+ grav = layout.getParagraphDirection(line);
break;
case ALIGN_OPPOSITE:
- grav = -mLayout.getParagraphDirection(line);
+ grav = -layout.getParagraphDirection(line);
break;
case ALIGN_CENTER:
default:
@@ -8713,6 +8717,8 @@
@Override
public void onResolveTextDirection() {
if (hasPasswordTransformationMethod()) {
+ // TODO: take care of the content direction to show the password text and dots justified
+ // to the left or to the right
mTextDir = TextDirectionHeuristics.LOCALE;
return;
}
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 7f5d54d..efeba5c 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -36,6 +36,8 @@
#define TYPE_FACE_HEBREW_REGULAR "/system/fonts/DroidSansHebrew-Regular.ttf"
#define TYPE_FACE_HEBREW_BOLD "/system/fonts/DroidSansHebrew-Bold.ttf"
#define TYPEFACE_BENGALI "/system/fonts/Lohit-Bengali.ttf"
+#define TYPEFACE_DEVANAGARI "/system/fonts/Lohit-Devanagari.ttf"
+#define TYPEFACE_TAMIL "/system/fonts/Lohit-Tamil.ttf"
#define TYPEFACE_THAI "/system/fonts/DroidSansThai.ttf"
ANDROID_SINGLETON_STATIC_INSTANCE(TextLayoutEngine);
@@ -828,6 +830,20 @@
#endif
break;
+ case HB_Script_Devanagari:
+ typeface = getCachedTypeface(&mDevanagariTypeface, TYPEFACE_DEVANAGARI);
+#if DEBUG_GLYPHS
+ ALOGD("Using Devanagari Typeface");
+#endif
+ break;
+
+ case HB_Script_Tamil:
+ typeface = getCachedTypeface(&mTamilTypeface, TYPEFACE_TAMIL);
+#if DEBUG_GLYPHS
+ ALOGD("Using Tamil Typeface");
+#endif
+ break;
+
default:
if (!typeface) {
typeface = mDefaultTypeface;
@@ -859,6 +875,8 @@
case HB_Script_Arabic:
case HB_Script_Hebrew:
case HB_Script_Bengali:
+ case HB_Script_Devanagari:
+ case HB_Script_Tamil:
case HB_Script_Thai:{
const uint16_t* text16 = (const uint16_t*)(mShaperItem.string + mShaperItem.item.pos);
SkUnichar firstUnichar = SkUTF16_NextUnichar(&text16);
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 7ac2f18..3c834a4 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -194,6 +194,8 @@
SkTypeface* mHebrewBoldTypeface;
SkTypeface* mBengaliTypeface;
SkTypeface* mThaiTypeface;
+ SkTypeface* mDevanagariTypeface;
+ SkTypeface* mTamilTypeface;
/**
* Cache of Harfbuzz faces
diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp
index 80ecf2f..f47dc8a 100644
--- a/core/jni/android_database_SQLiteConnection.cpp
+++ b/core/jni/android_database_SQLiteConnection.cpp
@@ -426,11 +426,11 @@
SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+ // We ignore the result of sqlite3_finalize because it is really telling us about
+ // whether any errors occurred while executing the statement. The statement itself
+ // is always finalized regardless.
ALOGV("Finalized statement %p on connection %p", statement, connection->db);
- int err = sqlite3_finalize(statement);
- if (err != SQLITE_OK) {
- throw_sqlite3_exception(env, connection->db, NULL);
- }
+ sqlite3_finalize(statement);
}
static jint nativeGetParameterCount(JNIEnv* env, jclass clazz, jint connectionPtr,
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d4d29ae..17d2212 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -121,6 +121,7 @@
<protected-broadcast android:name="android.intent.action.CLEAR_DNS_CACHE" />
<protected-broadcast android:name="android.intent.action.PROXY_CHANGE" />
+ <protected-broadcast android:name="android.os.UpdateLock.UPDATE_LOCK_CHANGED" />
<!-- ====================================== -->
<!-- Permissions for things that cost money -->
@@ -1538,6 +1539,13 @@
android:label="@string/permlab_accessContentProvidersExternally"
android:description="@string/permdesc_accessContentProvidersExternally"
android:protectionLevel="signature" />
+ <!-- Allows an application to hold an UpdateLock, recommending that a headless
+ OTA reboot *not* occur while the lock is held.
+ @hide -->
+ <permission android:name="android.permission.UPDATE_LOCK"
+ android:label="@string/permlab_updateLock"
+ android:description="@string/permdesc_updateLock"
+ android:protectionLevel="signatureOrSystem" />
<!-- The system process is explicitly the only one allowed to launch the
confirmation UI for full backup/restore -->
diff --git a/core/res/res/layout/simple_list_item_multiple_choice.xml b/core/res/res/layout/simple_list_item_multiple_choice.xml
index 0305427..cb23dfd 100644
--- a/core/res/res/layout/simple_list_item_multiple_choice.xml
+++ b/core/res/res/layout/simple_list_item_multiple_choice.xml
@@ -17,10 +17,10 @@
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:textAppearance="?android:attr/textAppearanceListItem"
+ android:layout_height="?android:attr/listPreferredItemHeightSmall"
+ android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
/>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 49e0fd5..1de0390 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -315,10 +315,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"aktiveer of deaktiveer programkomponente"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Laat die program toe om te verander of \'n komponent van ander program geaktiveer is of nie. Kwaadwillige programme kan dit dalk gebruik om belangrike tabletvermoëns te deaktiveer. Wees versigtig met hierdie toestemming, want dit kan programkomponente tot \'n onbruikbare, inkonsekwente of onstabiele toestand bring."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Laat die program toe om te verander of \'n komponent van ander program geaktiveer is of nie. Kwaadwillige programme kan dit gebruik om belangrike foonvermoëns te deaktiveer. Wees versigtig met hierdie toestemming, want dit kan programkomponente tot \'n onbruikbare, inkonsekwente of onstabiele toestand bring."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"toestemmings te verleen of te herroep"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Laat \'n program toe om spesifieke toestemmings te verleen of te herroep vir die betrokke program of ander programme. Skadelike programme kan dit gebruik om toegang te verkry tot kenmerke waarvoor jy nie toestemming verleen het nie."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"stel voorkeurprogramme"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Laat die program toe om jou voorkeur-programme te verander. Kwaadwillige programme kan stilweg die programme wat loop, verander, wat jou bestaande programme bedrieg om private data oor jou in te samel."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"verander globale stelselinstellings"</string>
@@ -1010,8 +1008,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Stel datum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Stel"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Verstek"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NUUT: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Geen toestemmings benodig nie"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Versteek"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Wys alle"</b></string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 7300fa5..abdda71 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"تمكين مكونات التطبيق أو تعطيلها"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"للسماح للتطبيق بتغيير ما إذا كان سيتم تمكين مكون لتطبيق آخر أم لا. يمكن أن تستخدم التطبيقات الضارة ذلك لتعطيل قدرات الجهاز اللوحي المهمة. يجب توخي الحذر عند استخدام هذا الإذن، وذلك لأنه من الممكن أن يؤدي ذلك إلى جعل حالة مكونات التطبيق غير قابلة للاستخدام أو غير متناسقة أو غير مستقرة."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"للسماح للتطبيق بتغيير ما إذا كان سيتم تمكين مكون لتطبيق آخر أم لا. يمكن أن تستخدم التطبيقات الضارة ذلك لتعطيل قدرات الهاتف المهمة. يجب توخي الحذر عند استخدام هذا الإذن، وذلك لأنه من الممكن أن يؤدي ذلك إلى جعل حالة مكونات التطبيق غير قابلة للاستخدام أو غير متناسقة أو غير مستقرة."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"منح الأذونات أو إلغائها"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"للسماح لأحد التطبيقات بمنح أذونات محددة أو إلغائها لنفسه أو لتطبيقات أخرى. قد تستخدم التطبيقات الضارة هذا للدخول إلى ميزات لم تمنحها إذنًا لدخولها."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"تعيين التطبيقات المفضلة"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"للسماح للتطبيق بتعديل التطبيقات المفضلة. يمكن أن تغيّر التطبيقات الضارة التطبيقات قيد التشغيل بشكل غير ملحوظ، وانتحال صفة التطبيقات الحالية لجمع بيانات خاصة منك."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"تعديل إعدادات النظام العمومية"</string>
@@ -1008,8 +1006,7 @@
<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>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"جديد: "</font></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>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 9a578da..5cfa349 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"уключыць або адключыць кампаненты прыкладання"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Дазваляе прыкладанням змяняць вызначэнне таго, будзе ўключаны кампанент іншага прыкладання ці не. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта для адключэння важных магчымасцяў планшэта. З гэтым дазволам трэба быць уважлівым, бо можна прывесці кампаненты прыкладання ў непрыдатны, супярэчлівы або няўстойлівы стан."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Дазваляе прыкладанням змяняць вызначэнне таго, будзе ўключаны кампанент іншага прыкладання ці не. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта для адключэння важных магчымасцяў тэлефона. З гэтым дазволам трэба быць уважлівым, бо можна прывесці кампаненты прыкладання ў непрыдатны, супярэчлівы або няўстойлівы стан."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"прадаставiць або адмяніць дазвол"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Дазваляе прыкладанню прадастаўляць або адмяняць пэўныя дазволы для гэтага або іншых прыкладанняў. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб атрымаць доступ да функцый, якiя вы iм не прадаставiлi."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"усталяваць пажаданыя прыкладанні"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Дазваляе прыкладанням змяняць вашы пажаданыя прыкладанні. Шкоднасныя прыкладанні могуць непрыкметна змяняць запушчаныя прыкладанні, падмяняючы існуючыя прыкладанні, каб збiраць вашы асабістыя дадзеныя."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"змена глабальных параметраў сістэмы"</string>
@@ -1008,8 +1006,7 @@
<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>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"НОВАЕ: "</font></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>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 907392a..c66451a 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"activa o desactiva els components de l\'aplicació"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permet que l\'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 de l\'aplicació esdevinguin inutilitzables, incoherents o inestables."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permet que l\'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, perquè és possible que els components de l\'aplicació esdevinguin inutilitzables, incoherents o inestables."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"concedeix o denega permisos"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Permet que una aplicació concedeixi o denegui permisos específics per a aquesta o per a altres aplicacions. És possible que les aplicacions malicioses ho facin servir per accedir a funcions a les quals no heu concedit accés."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"defineix les aplicacions preferides"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permet que l\'aplicació modifiqui les aplicacions preferides. Les aplicacions malicioses poden 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>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Establiment de data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Defineix"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predeterminat"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOU: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"No cal cap permís"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Amaga"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mostra\'ls tots"</b></string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index f889c3b..89ff9cff3 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivace či deaktivace komponent aplikací"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Umožňuje aplikaci změnit, zda je komponenta jiné aplikace povolena nebo ne. Škodlivé aplikace mohou toto oprávnění použít k vypnutí důležitých funkcí tabletu. Toto oprávnění je třeba používat opatrně, protože může dojít k nepoužitelnosti, nekonzistenci nebo nestabilitě komponent aplikací."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Umožňuje aplikaci změnit, zda je komponenta jiné aplikace povolena nebo ne. Škodlivé aplikace mohou toto oprávnění použít k vypnutí důležitých funkcí telefonu. Toto oprávnění je třeba používat opatrně, protože může dojít k nepoužitelnosti, nekonzistenci nebo nestabilitě komponent aplikací."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"udělení nebo odebrání oprávnění"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Umožňuje aplikaci udělit nebo odebrat sobě samotné nebo jiným aplikacím určitá oprávnění. Škodlivé aplikace pomocí tohoto oprávnění mohou získat přístup k funkcím, které jste jim nepovolili."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"nastavení upřednostňovaných aplikací"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Umožňuje aplikaci upravit preferované aplikace. Škodlivé aplikace mohou tajně měnit běžící aplikace a přinutit stávající aplikace, aby shromažďovaly vaše soukromé údaje."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"změna globálních nastavení systému"</string>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastavení data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Nastavit"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Výchozí"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVÉ: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Nejsou vyžadována žádná oprávnění"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Skrýt"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Zobrazit vše"</b></string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index b432d46..91da279 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"ενεργοποίηση ή απενεργοποίηση στοιχείων εφαρμογής"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Επιτρέπει στην εφαρμογή την αλλαγή της κατάστασης ενεργοποίησης κάποιου στοιχείου. Τυχόν κακόβουλες εφαρμογές μπορούν να χρησιμοποιήσουν αυτήν τη δυνατότητα για την απενεργοποίηση σημαντικών δυνατοτήτων του tablet. Αυτή η άδεια θα πρέπει να χρησιμοποιείται προσεκτικά, καθώς είναι πιθανό να θέσει τα στοιχεία εφαρμογών σε κατάσταση αχρηστίας, μη συνοχής και αστάθειας."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Επιτρέπει στην εφαρμογή την αλλαγή της κατάστασης ενεργοποίησης κάποιου στοιχείου. Τυχόν κακόβουλες εφαρμογές μπορούν να χρησιμοποιήσουν αυτήν τη δυνατότητα για την απενεργοποίηση σημαντικών δυνατοτήτων του τηλεφώνου. Αυτή η άδεια θα πρέπει να χρησιμοποιείται προσεκτικά, καθώς είναι πιθανό να θέσει τα στοιχεία εφαρμογών σε κατάσταση αχρηστίας, μη συνοχής και αστάθειας."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"εκχώρηση ή ανάκληση δικαιωμάτων"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Επιτρέπει σε μια εφαρμογή να εκχωρήσει ή να ανακαλέσει ειδικά δικαιώματα για αυτήν ή για άλλες εφαρμογές. Οι κακόβουλες εφαρμογές μπορεί να το χρησιμοποιήσουν αυτό ώστε να αποκτήσουν πρόσβαση σε λειτουργίες για τις οποίες δεν τους έχει εκχωρηθεί δικαίωμα."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ορισμός προτιμώμενων εφαρμογών"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Επιτρέπει στην εφαρμογή την τροποποίηση των εφαρμογών της προτίμησής σας. Τυχόν κακόβουλες εφαρμογές ενδέχεται να να αλλάξουν χωρίς ειδοποίηση τις εφαρμογές που εκτελούνται, \"ξεγελώντας\" τις υπάρχουσες εφαρμογές ώστε να συλλέξουν ιδιωτικά δεδομένα από εσάς."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"τροποποίηση καθολικών ρυθμίσεων συστήματος"</string>
@@ -1008,8 +1006,7 @@
<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>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"ΝΕΟ: "</font></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>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 1013b11..cfd9965 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"enable or disable app components"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Allows the app to change whether a component of another app is enabled or not. Malicious apps may use this to disable important tablet capabilities. Care must be taken with this permission, as it is possible to get app components into an unusable, inconsistent or unstable state."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Allows the app to change whether a component of another app is enabled or not. Malicious apps may use this to disable important phone capabilities. Care must be taken with this permission, as it is possible to get app components into an unusable, inconsistent or unstable state."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"grant or revoke permissions"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Allows an application to grant or revoke specific permissions for it or other applications. Malicious applications may use this to access features for which you have not granted them permission."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"set preferred apps"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Allows the app to modify your preferred apps. Malicious apps may silently change the apps that are run, spoofing your existing apps to collect private data from you."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modify global system settings"</string>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Set date"</string>
<string name="date_time_set" msgid="5777075614321087758">"Set"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Default"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NEW: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"No permission required"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Hide"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Show all"</b></string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index a019c65..fe292e6 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"activar o desactivar componentes de la aplicación"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permite que la aplicación determine si un componente de otra aplicación está habilitado o no. Las aplicaciones maliciosas pueden utilizar este permiso para desactivar funciones importantes de la tableta. Es necesario ser precavido con este permiso, ya que es posible que los componentes de la aplicación queden inservibles, incoherentes o inestables."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permite que la aplicación determine si un componente de otra aplicación está habilitado o no. Las aplicaciones maliciosas pueden utilizar este permiso para desactivar funciones importantes del dispositivo. Es necesario ser precavido con este permiso, ya que es posible que los componentes de la aplicación queden inservibles, incoherentes o inestables."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"Otorgar o revocar permisos"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Permite a una aplicación otorgar permisos específicos a otras aplicaciones, autoconcedérselos o revocarlos. Las aplicaciones maliciosas pueden así acceder a funciones para las que no les otorgaste permiso."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"establecer aplicaciones preferidas"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permite que la aplicación modifique tus aplicaciones preferidas. Las aplicaciones maliciosas pueden modificar sin aviso las aplicaciones que se ejecutan y así engañar a tus aplicaciones existentes para que recopilen tu información privada."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modificar la configuración global del sistema"</string>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Configurar fecha"</string>
<string name="date_time_set" msgid="5777075614321087758">"Establecer"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predeterminado"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NUEVO: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"No se requieren permisos"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Ocultar"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mostrar todos"</b></string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index a159eb6..ee7efc8 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"sovelluskomponenttien ottaminen käyttöön tai pois käytöstä"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Antaa sovelluksen muuttaa, onko toisen sovelluksen komponentti käytössä vai ei. Haitalliset sovellukset voivat käyttää tätä tablet-laitteen tärkeiden ominaisuuksien poistamiseen käytöstä. Tämän luvan käyttöönotto edellyttää varovaisuutta, sillä sen avulla sovelluskomponentit on mahdollista saada epäkäytettävään, epäyhtenäiseen tai epävakaaseen tilaan."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Antaa sovelluksen muuttaa sitä, onko toisen sovelluksen komponentti käytössä vai ei. Haitalliset sovellukset voivat käyttää tätä puhelimen tärkeiden ominaisuuksien poistamiseen käytöstä. Tämän luvan käyttöönotto edellyttää varovaisuutta, sillä sen avulla sovelluskomponentit on mahdollista saada epäkäytettävään, epäyhtenäiseen tai epävakaaseen tilaan."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"myönnä tai kiellä käyttöluvat"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Antaa sovelluksen myöntää tai kieltää tiettyjä käyttööoikeuksia itselleen tai muille sovelluksille. Haittaohjelmat voivat käyttää tämän ominaisuuden avulla toimintoja, joiden käyttöön et ole antanut lupaa."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ensisijaisten sovellusten asettaminen"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Antaa sovelluksen muokata ensisijaisia sovelluksia. Haitalliset sovellukset voivat muuttaa käynnistettäviä sovelluksia huomaamattomasti ja kerätä henkilökohtaisia tietoja matkimalla nykyisiä sovelluksia."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"muokkaa yleisiä järjestelmän asetuksia"</string>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Aseta päivämäärä"</string>
<string name="date_time_set" msgid="5777075614321087758">"Aseta"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Oletus"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"UUTTA: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Lupia ei tarvita"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Piilota"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Näytä kaikki"</b></string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index e9b3b28..bca5701 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -767,7 +767,7 @@
<string name="permlab_serialPort" msgid="546083327654631076">"accéder aux ports série"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Permet à l\'application autorisée d\'accéder aux ports série avec l\'API SerialManager."</string>
<string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"accès externe fournisseurs de contenu"</string>
- <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Permettre à l\'application titulaire d\'accéder à des fournisseurs de contenu depuis l\'interface. Les applications standards ne devraient jamais avoir recours à cette autorisation."</string>
+ <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Permettre à l\'application titulaire d\'accéder à des fournisseurs de contenu depuis la commande shell. Les applications standards ne devraient jamais avoir recours à cette autorisation."</string>
<string name="save_password_message" msgid="767344687139195790">"Voulez-vous que le navigateur se souvienne de ce mot de passe ?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Pas maintenant"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Mémoriser"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index f32322e..1454253 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"एप्लिकेशन घटकों को सक्षम या अक्षम करें"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"एप्लिकेशन को यह बदलने देता है कि किसी अन्य एप्लिकेशन का घटक सक्षम है या नहीं. दुर्भावनापूर्ण एप्लिकेशन महत्वपूर्ण फ़ोन क्षमताओं को अक्षम करने में इसका उपयोग कर सकते हैं. इस अनुमति का उपयोग सावधानी के साथ करना चाहिए, क्योंकि इससे एप्लिकेशन घटकों के अनुपयोगी, असंगत, या अस्थिर स्थिति में जाने की संभावना है."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"एप्लिकेशन को यह बदलने देता है कि किसी अन्य एप्लिकेशन का घटक सक्षम है या नहीं. दुर्भावनापूर्ण एप्लिकेशन महत्वपूर्ण फ़ोन क्षमताओं को अक्षम करने में इसका उपयोग कर सकते हैं. इस अनुमति का उपयोग सावधानी के साथ करना चाहिए, क्योंकि इससे एप्लिकेशन घटकों के अनुपयोगी, असंगत, या अस्थिर स्थिति में जाने की संभावना है."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"अनुमति दें या रद्द करें"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"एप्लिकेशन को उसके या अन्य एप्लिकेशन के लिए विशेष अनुमतियां देने या रद्द करने देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग उन विशेषताओं तक पहुंचने के लिए कर सकते हैं जो आपने उन्हें नहीं दी हैं."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"पसंदीदा एप्लिकेशन सेट करें"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"एप्लिकेशन को आपके पसंदीदा एप्लिकेशन को संशोधित करने देता है. दुर्भावनापूर्ण एप्लिकेशन आपसे निजी डेटा एकत्रित करने के लिए आपके मौजूदा एप्लिकेशन को स्पूफ़ करके, चलाए जाने वाले एप्लिकेशन को चुपचाप बदल सकते हैं."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"वैश्विक सिस्टम सेटिंग संशोधित करें"</string>
@@ -1008,8 +1006,7 @@
<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>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"नया: "</font></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>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 8b8a51f..1908840 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"omogućavanje ili onemogućavanje komponenti aplikacije"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Omogućuje aplikaciji da promijeni hoće li komponenta neke druge aplikacije biti omogućena ili neće. Zlonamjerne aplikacije mogu to upotrijebiti da bi onemogućile važne mogućnosti tabletnog računala. Treba biti oprezan s tom dozvolom jer je moguće dovesti komponente aplikacija u neupotrebljivo, nedosljedno ili nestabilno stanje."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Omogućuje aplikaciji da promijeni hoće li komponenta neke druge aplikacije biti omogućena. Zlonamjerne aplikacije mogu to upotrijebiti da bi onemogućile važne mogućnosti telefona. Treba biti oprezan s tom dozvolom jer je moguće dovesti komponente aplikacija u neupotrebljivo, nedosljedno ili nestabilno stanje."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"dati ili oduzeti dopuštenja"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Aplikaciji omogućuje da odobri ili odbije određena dopuštenja za sebe ili druge aplikacije. Zlonamjerne aplikacije to mogu upotrijebiti za pristup značajkama za koje im niste odobrili pristup."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"postavljanje željenih aplikacija"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Omogućuje aplikaciji promjenu vaših željenih aplikacija. Zlonamjerne aplikacije mogu potajno promijeniti aplikacije koje su pokrenute, zavaravajući vaše postojeće aplikacije kako bi prikupljale privatne podatke od vas."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"izmjena postavki globalnog sustava"</string>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Postavi datum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Postavi"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Zadano"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVO: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Nije potrebno dopuštenje"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Sakrij"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Pokaži sve"</b></string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 7f89990..81f697b 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"alkalmazáskomponensek be- és kikapcsolása"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Lehetővé teszi az alkalmazás számára annak módosítását, hogy más alkalmazások komponensei engedélyezve vannak-e vagy sem. A rosszindulatú alkalmazások ezt a táblagép fontos funkcióinak kikapcsolására használhatják. Óvatosan kell eljárni az engedély megadásával, mert lehetséges, hogy a komponensek használhatatlanok, inkonzisztensek vagy instabilak lesznek."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Lehetővé teszi az alkalmazás számára annak módosítását, hogy más alkalmazások komponensei engedélyezve vannak-e vagy sem. A rosszindulatú alkalmazások ezt a telefon fontos funkcióinak kikapcsolására használhatják. Óvatosan kell eljárni az engedély megadásával, mert lehetséges, hogy a komponensek használhatatlanok, inkonzisztensek vagy instabilak lesznek."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"engedélyek megadása vagy visszavonása"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Lehetővé teszi, hogy egy alkalmazás engedélyeket adjon vagy vonjon vissza saját maga vagy más alkalmazás számára. A rosszindulatú alkalmazások olyan funkciókhoz való hozzáféréshez használhatják ezt, amelyeket nem engedélyezett számukra."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"előnyben részesített alkalmazások beállítása"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Lehetővé teszi az alkalmazás számára a preferált alkalmazások módosítását. A rosszindulatú alkalmazások ezáltal észrevétlenül megváltoztathatják a futó alkalmazásokat, személyes adatokat gyűjtve Öntől."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"rendszer globális beállításainak módosítása"</string>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Dátum beállítása"</string>
<string name="date_time_set" msgid="5777075614321087758">"Beállítás"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Alapértelmezett"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"ÚJ: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Nincs szükség engedélyre"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Elrejtés"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Az összes megjelenítése"</b></string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 5245306..08b0f60 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"mengaktifkan atau menonaktifkan komponen apl"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Mengizinkan apl mengubah apakah komponen apl lain diaktifkan atau tidak. Apl berbahaya dapat menggunakan ini untuk menonaktifkan kemampuan tablet yang penting. Izin ini harus digunakan dengan hati-hati karena dapat menjadikan komponen apl tidak dapat digunakan, tidak konsisten, atau tidak stabil."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Mengizinkan apl mengubah apakah komponen apl lain diaktifkan atau tidak. Apl berbahaya dapat menggunakan izin ini untuk menonaktifkan kemampuan ponsel yang penting. Izin ini harus digunakan dengan hati-hati, karena mungkin saja menjadikan komponen apl tidak dapat digunakan, tidak konsisten, atau tidak stabil."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"memberi atau mencabut izin"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Memungkinkan aplikasi memberikan atau mencabut izin khusus untuk aplikasi tersebut atau aplikasi lainnya. Aplikasi berbahaya dapat menggunakannya untuk mengakses fitur yang tidak Anda beri izin."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"menyetel apl yang disukai"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Mengizinkan apl memodifikasi apl pilihan Anda. Apl berbahaya dapat diam-diam mengubah apl yang berjalan, menipu apl yang ada untuk mengumpulkan data pribadi dari Anda."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"ubah setelan sistem global"</string>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Setel tanggal"</string>
<string name="date_time_set" msgid="5777075614321087758">"Setel"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Bawaan"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"BARU: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Tidak perlu izin"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Sembunyikan"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Tampilkan semua"</b></string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 4e4a1aa..9898734 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"アプリのコンポーネントの有効/無効化"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"別のアプリのコンポーネントの有効/無効を変更することをアプリに許可します。この許可を悪意のあるアプリに利用されると、タブレットの重要な機能が無効にされる恐れがあります。アプリのコンポーネントが利用できなくなったり、整合性が取れなくなったり、不安定な状態になったりする恐れがあるので許可には注意が必要です。"</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"別のアプリのコンポーネントの有効/無効を変更することをアプリに許可します。この許可を悪意のあるアプリに利用されると、携帯端末の重要な機能が無効にされる恐れがあります。アプリのコンポーネントが利用できなくなったり、整合性が取れなくなったり、不安定な状態になったりする恐れがあるので許可には注意が必要です。"</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"権限の許可または取り消し"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"このアプリケーションや他のアプリケーションに対して特定の権限を許可したり取り消したりすることをアプリケーションに許可します。悪意のあるアプリケーションがユーザーの許可なく複数の機能にアクセスする恐れがあります。"</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"優先アプリの設定"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"優先アプリを変更することをアプリに許可します。この許可を悪意のあるアプリに利用されると、実行中のアプリが密かに変更され、既存のアプリへのなりすましにより非公開データがだまし取られる恐れがあります。"</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"システムの全般設定の変更"</string>
@@ -1008,8 +1006,7 @@
<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>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NEW: "</font></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>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index f3cc2fe..5eea0ba 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"앱 구성요소 사용 또는 사용 안함"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"앱이 다른 앱 구성요소 사용 여부를 변경할 수 있도록 허용합니다. 이 경우 악성 앱이 이 기능을 이용하여 중요한 태블릿 기능을 중지시킬 수 있습니다. 이 권한을 허용할 경우 앱 구성요소가 사용 불가능하게 되거나 일관성이 맞지 않거나 불안정해질 수 있으므로 주의해야 합니다."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"앱이 다른 앱 구성요소 사용 여부를 변경할 수 있도록 허용합니다. 이 경우 악성 앱이 이 기능을 이용하여 중요한 휴대전화 기능을 중지시킬 수 있습니다. 이 권한을 허용할 경우 앱 구성요소가 사용 불가능하게 되거나 일관성이 맞지 않거나 불안정해질 수 있으므로 주의해야 합니다."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"권한 승인 또는 취소"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"애플리케이션이 해당 애플리케이션 및 기타 애플리케이션에 대한 특정 권한을 승인 또는 취소하도록 허용합니다. 이 경우 악성 애플리케이션이 승인되지 않은 기능에 액세스할 수 있습니다."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"기본 앱 설정"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"앱이 기본 앱을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 실행되는 앱을 몰래 변경하고 기존 앱으로 위장하여 사용자의 개인 정보를 수집할 수 있습니다."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"전체 시스템 설정 수정"</string>
@@ -1008,8 +1006,7 @@
<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>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"신규: "</font></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>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index c99d9ba..7ea172f 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"įgalinti programos komponentus arba jų neleisti"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Leidžiama programai pakeisti, ar įgalintas kitos programos komponentas, ar ne. Kenkėjiškos programos gali tai naudoti, kad neleistų svarbių planšetinio kompiuterio funkcijų. Šį leidimą reikia naudoti atsargiai, nes programos komponentai gali tapti nenaudojami, nenuoseklūs ar nestabilūs."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Leidžiama programai pakeisti nustatymą, ar įgalintas kitos programos komponentas, ar ne. Kenkėjiškos programos gali tai naudoti, kad neleistų svarbių telefono funkcijų. Šį leidimą reikia naudoti atsargiai, nes programos komponentai gali tapti nenaudojami, nenuoseklūs ar nestabilūs."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"suteikti arba panaikinti leidimus"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Programai leidžiama suteikti arba panaikinti konkrečius savo arba kitų programų leidimus. Tuo pasinaudoję kenkėjiškos programos gali pasiekti funkcijas, kurių pasiekti joms neleidote."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"nustatyti pageidaujamas programas"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Leidžiama programai keisti jūsų pageidaujamas programas. Kenkėjiškos programos gali nepastebimai pakeisti vykdomas programas, klastodama esamas programas, kad rinktų jūsų privačius duomenis."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"keisti visuotinius sistemos nustatymus"</string>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Nustatyti datą"</string>
<string name="date_time_set" msgid="5777075614321087758">"Nustatyti"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Numatytasis"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NAUJAS: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Nereikia leidimų"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Slėpti"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Rodyti viską"</b></string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index d2233e3..1581341 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"iespējot vai atspējot lietotnes komponentus"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Ļauj lietotnei mainīt to, vai tiek iespējots citas lietotnes komponents. Ļaunprātīgas lietotnes to var izmantot, lai atspējotu svarīgas planšetdatora iespējas. Izmantojiet šo atļauju uzmanīgi, jo pastāv iespēja, ka lietotnes komponenti var kļūt neizmantojami, neatbilstīgi vai nestabili."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Ļauj lietotnei mainīt to, vai tiek iespējots citas lietotnes komponents. Ļaunprātīgas lietotnes to var izmantot, lai atspējotu svarīgas tālruņa iespējas. Izmantojiet šo atļauju uzmanīgi, jo pastāv iespēja, ka lietotnes komponenti var kļūt neizmantojami, neatbilstīgi vai nestabili."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"atļauju piešķiršana vai atsaukšana"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Ļauj lietojumprogrammai piešķirt sev vai citām lietojumprogrammām noteiktas atļaujas un atsaukt tās. Ļaunprātīgas lietojumprogrammas var izmantot šo iespēju, lai piekļūtu funkcijām, kuras neesat atļāvis."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"iestatīt vēlamās lietotnes"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Ļauj lietotnei modificēt jūsu vēlamās lietotnes. Ļaunprātīgas lietotnes var nemanāmi mainīt izmantotās lietotnes, atveidojot esošās lietotnes, lai no jums iegūtu privātus datus."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"pārveidot globālos sistēmas iestatījumus"</string>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Datuma iestatīšana"</string>
<string name="date_time_set" msgid="5777075614321087758">"Iestatīt"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Noklusējums"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"JAUNA: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Atļaujas nav nepieciešamas."</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Slēpt"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Rādīt visu"</b></string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index bef0b20..ee58558 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivere eller deaktivere appkomponenter"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Lar appen endre hvorvidt en komponent i en annen app er aktivert eller ikke. Ondsinnede apper kan bruke dette til å deaktivere viktige nettbrettfunksjoner. Denne tillatelsen må brukes med forsiktighet, ettersom det er mulig å få appkomponenter inn i en ubrukelig, inkonsistent eller ustabil tilstand."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Lar appen endre hvorvidt en komponent i en annen app er aktivert eller ikke. Ondsinnede apper kan bruke dette til å deaktivere viktige telefonfunksjoner. Denne tillatelsen må brukes med forsiktighet, ettersom det er mulig å få appkomponenter inn i en ubrukelig, inkonsistent eller ustabil tilstand."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"gi eller trekke tilbake tillatelser"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Lar et program gi eller trekke tilbake spesielle tillatelser for eget bruk eller for andre programmer. Skadelige programmer kan bruke dette for å få tilgang til funksjoner de ikke skal ha tilgang til."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"angi foretrukne apper"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Lar appen endre de foretrukne appene dine. Ondsinnede apper kan ubemerket endre apper som kjøres, og forfalske eksisterende apper til å samle private data fra deg."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"endre globale systeminnstillinger"</string>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Angi dato"</string>
<string name="date_time_set" msgid="5777075614321087758">"Lagre"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NY: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Trenger ingen rettigheter"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Skjul"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Vis alle"</b></string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 25833aa..4d0e0fa 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"włączanie lub wyłączanie składników aplikacji"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Pozwala aplikacji na włączenie lub wyłączenie składnika innej aplikacji. Złośliwe aplikacje mogą wykorzystać to uprawnienie do wyłączenia ważnych funkcji tabletu. W przypadku tego uprawnienia należy zachować ostrożność, ponieważ istnieje możliwość wprowadzenia składników aplikacji w stan nieużywalności, niespójności lub niestabilności."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Pozwala aplikacji na włączenie lub wyłączenie składnika innej aplikacji. Złośliwe aplikacje mogą wykorzystać to uprawnienie do wyłączenia ważnych funkcji telefonu. W przypadku tego uprawnienia należy zachować ostrożność, ponieważ istnieje możliwość wprowadzenia składników aplikacji w stan nieużywalności, niespójności lub niestabilności."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"przyznaj lub cofnij uprawnienia"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Pozwala aplikacji na przyznanie lub cofnięcie określonych uprawnień do niej lub do innych aplikacji. Złośliwe aplikacje mogą to wykorzystać, by uzyskać dostęp do nieprzyznanych im funkcji."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ustawianie preferowanych aplikacji"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Pozwala aplikacji na zmianę Twoich preferowanych aplikacji. Złośliwe aplikacje mogą dyskretnie zmienić uruchamiane aplikacje, podszywając się pod dotychczasowe aplikacje w celu zebrania od Ciebie prywatnych danych."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modyfikowanie ogólnych ustawień systemu"</string>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Ustaw datę"</string>
<string name="date_time_set" msgid="5777075614321087758">"Ustaw"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Domyślne"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOWE: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Nie są wymagane żadne uprawnienia"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Ukryj"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Pokaż wszystko"</b></string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 374102c..4826ddf 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"ativar ou desativar os componentes do aplicativo"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permite que o aplicativo ative ou desative um componente de outro aplicativo. Aplicativos maliciosos podem usar esse recurso para desativar recursos importantes do tablet. Tenha cuidado com essa permissão, pois é possível fazer com que os componentes do aplicativo fiquem inutilizáveis, inconsistentes ou instáveis."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permite que o aplicativo altere se um componente de outro aplicativo está ativado ou não. Aplicativos maliciosos podem usar esse recurso para desativar recursos importantes do telefone. Deve-se tomar cuidado com essa permissão, uma vez que isso pode deixar os componentes do aplicativo inutilizáveis, inconsistentes ou instáveis."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"conceder ou revogar permissões"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Permite que um aplicativo conceda ou revogue permissões específicas para ele ou outros aplicativos. Aplicativos maliciosos podem usar isso para acessar recursos aos quais você não concedeu permissão."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"definir aplicativos preferidos"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permite que o aplicativo modifique seus aplicativos preferidos. Aplicativos maliciosos podem alterar os aplicativos que são executados, falsificando seus aplicativos existentes para coletar seus dados particulares."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modificar configurações globais do sistema"</string>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Definir data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Padrão"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVO: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Nenhuma permissão necessária"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Ocultar"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mostrar todas"</b></string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 5dfa648..662a54e 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"включение и отключение компонентов приложения"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Приложение сможет включать и отключать компоненты других программ. Вредоносные программы смогут таким образом отключать важные функции планшетного ПК. Используйте это разрешение с особой осторожностью, чтобы случайно не нарушить работу компонентов приложения."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Приложение сможет включать и отключать компоненты других программ. Вредоносные программы смогут таким образом отключать важные функции телефона. Используйте это разрешение с особой осторожностью, чтобы случайно не нарушить работу компонентов приложения."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"предоставление и отзыв разрешений"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Позволяет приложению предоставлять и отзывать разрешения самому себе и другим программам. Вредоносные приложения могут использовать эту функцию для получения прав, которых вы им не предоставляли."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"настройка предпочтительных приложений"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Приложение сможет изменять предпочтительные приложения. Вредоносные программы смогут незаметно изменять запускаемые вами программы и собирать ваши личные данные от имени существующих приложений."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"изменять общие настройки системы"</string>
@@ -1008,8 +1006,7 @@
<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>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"НОВОЕ: "</font></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>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index b65f535..98b829f 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"povoliť alebo zakázať súčasti aplikácie"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Umožňuje aplikácii zmeniť to, či je súčasť inej aplikácie povolená alebo zakázaná. Škodlivé aplikácie môžu pomocou tohto nastavenia zakázať dôležité funkcie tabletu. S týmto povolením musíte zaobchádzať opatrne, pretože súčasti aplikácie môžete dostať do nepoužiteľného, nekonzistentného alebo nestabilného stavu."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Umožňuje aplikácii zmeniť to, či je súčasť inej aplikácie povolená alebo zakázaná. Škodlivé aplikácie môžu pomocou tohto nastavenia zakázať dôležité funkcie telefónu. S týmto povolením musíte zaobchádzať opatrne, pretože súčasti aplikácie môžete dostať do nepoužiteľného, nekonzistentného alebo nestabilného stavu."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"povoliť alebo zakázať povolenia"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Umožňuje aplikácii povoliť alebo zakázať konkrétne povolenia pre seba alebo iné aplikácie. Škodlivé aplikácie môžu použiť túto možnosť na pristupovanie k funkciám, ktoré ste im nepovolili."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"nastaviť preferované aplikácie"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Umožňuje aplikácii zmeniť vaše preferované aplikácie. Škodlivé aplikácie môžu v tichosti zmeniť spustené aplikácie a oklamať existujúce aplikácie, aby zhromažďovali vaše súkromné údaje."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"zmeny globálnych nastavení systému"</string>
@@ -1010,8 +1008,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastaviť dátum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Nastaviť"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predvolené"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVINKA: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Nevyžadujú sa žiadne oprávnenia."</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Skryť"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Zobraziť všetky"</b></string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 83515dd..9d99013 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"omogočanje ali onemogočanje komponent programa"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Programu omogoča, da spremeni, ali je komponenta drugega programa omogočena ali ne. Zlonamerni programi lahko to uporabijo za onemogočanje pomembnih zmožnosti tabličnega računalnika. Pri dodeljevanju dovoljenja je treba biti previden, saj lahko komponente programa nastavite tako, da jih ni mogoče uporabiti, da niso dosledne ali da niso stabilne."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Programu omogoča, da spremeni, ali je komponenta drugega programa omogočena ali ne. Zlonamerni programi lahko to uporabijo za onemogočanje pomembnih zmožnosti telefona. Pri dodeljevanju dovoljenja je treba biti previden, saj lahko komponente programa nastavite tako, da jih ni mogoče uporabiti, da niso dosledne ali da niso stabilne."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"dodeljevanje ali preklic dovoljenj"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Programu omogoča dodeljevanje ali preklic posebnih dovoljenj zanj ali za druge programe. Zlonamerni programi lahko to uporabijo za dostop do funkcij, za katere jim niste dodelili pravic."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"nastavitev prednostnih programov"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Programu omogoča spreminjanje priljubljenih programov. Zlonamerni programi lahko s tem neopazno spremenijo programe, ki se izvajajo, tako da se izdajajo za obstoječe programe in zbirajo osebne podatke."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"spreminjanje splošnih nastavitev sistema"</string>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastavi datum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Nastavi"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Privzeto"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVO: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Ni zahtevanih dovoljenj"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Skrij"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Pokaži vse"</b></string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 2992fbe..a9e7b9b 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"омогућавање или онемогућавање компоненти апликације"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Дозвољава апликацији да промени да ли је компонента друге апликације омогућена или онемогућена. Злонамерне апликације могу то да искористе да онемогуће важне функције таблета. Треба бити опрезан при додељивању ове дозволе, јер компоненте апликација могу постати неупотребљиве, непоуздане или нестабилне."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Дозвољава апликацији да промени да ли је компонента друге апликације омогућена или онемогућена. Злонамерне апликације могу то да искористе да онемогуће важне функције телефона. Треба бити опрезан при додељивању ове дозволе, јер компоненте апликација могу да постану неупотребљиве, непоуздане или нестабилне."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"додела или опозив дозвола"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Омогућава апликацији да додели или опозове посебне дозволе за њу или друге апликације. Злонамерне апликације могу то да користе да би приступале функцијама које им нисте одобрили."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"подешавање жељених апликација"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Дозвољава апликацији да мења омиљене апликације. Злонамерне апликације могу без обавештења да промене апликације које су покренуте и да преко њих прикупљају ваше приватне податке."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"измена глобалних подешавања система"</string>
@@ -1008,8 +1006,7 @@
<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>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"НОВО: "</font></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>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 329a807..a787a2a 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"เปิดหรือปิดใช้งานคอมโพเนนต์ของแอปพลิเคชัน"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"อนุญาตให้แอปพลิเคชันเปลี่ยนแปลงการเปิดใช้งานส่วนประกอบของแอปพลิเคชันอื่น แอปพลิเคชันที่เป็นอันตรายอาจใช้การอนุญาตนี้ปิดใช้งานความสามารถของแท็บเล็ตที่สำคัญ ต้องใช้ความระมัดระวังสำหรับการอนุญาตนี้ เนื่องจากอาจทำให้ส่วนประกอบต่างๆ ของแอปพลิเคชันไม่สามารถใช้งาน ไม่สอดคล้อง หรือมีสถานะที่ไม่เสถียร"</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"อนุญาตให้แอปพลิเคชันเปลี่ยนแปลงการเปิดใช้งานส่วนประกอบของแอปพลิเคชันอื่น แอปพลิเคชันที่เป็นอันตรายอาจใช้การอนุญาตนี้ปิดใช้งานความสามารถที่สำคัญของโทรศัพท์ ต้องใช้ความระมัดระวังสำหรับการอนุญาตนี้เนื่องจากอาจทำให้ส่วนประกอบต่างๆ ของแอปพลิเคชันไม่สามารถใช้งาน ไม่สอดคล้อง หรือมีสถานะที่ไม่เสถียร"</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"อนุญาตหรือยกเลิกการอนุญาต"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"อนุญาตให้แอปพลิเคชันให้หรือยกเลิกการอนุญาตบางอย่างของตัวเองหรือแอปพลิเคชันอื่น แอปพลิเคชันที่เป็นอันตรายอาจใช้การทำงานนี้ในการเข้าถึงคุณลักษณะที่คุณไม่อนุญาต"</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ตั้งค่าแอปพลิเคชันที่ต้องการ"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"อนุญาตให้แอปพลิเคชันแก้ไขแอปพลิเคชันต่างๆ ที่คุณชอบใช้ แอปพลิเคชันที่เป็นอันตรายอาจจะแอบเปลี่ยนแอปพลิเคชันที่กำลังทำงาน ปลอมแปลงเป็นแอปพลิเคชันที่มีอยู่ของคุณเพื่อรวบรวมข้อมูลส่วนบุคคลจากคุณ"</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"แก้ไขการตั้งค่าระบบสากล"</string>
@@ -1008,8 +1006,7 @@
<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>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"ใหม่: "</font></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>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 40e8cc5..99731af 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"paganahin o huwag paganahin ang mga bahagi ng app"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Pinapayagan ang app na baguhin kung ang bahagi ng isa pang app ay pinagana o hindi. Maaari itong gamitin ng nakakahamak na apps upang huwag paganahin ang mahahalagang kakayahan ng tablet. Dapat na mayroong pag-iingat sa pahintulot na ito, dahil posibleng mailagay ng mga bahagi ng app sa isang hindi nagagamit, pabagu-bago, o hindi matatag na katayuan."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Pinapayagan ang app na baguhin kung ang isang bahagi ng isa pang app ay pinapagana o hindi. Maaari itong gamitin ng nakakahamak na apps upang huwag paganahin ang mga mahalagang kakayahan ng telepono. Dapat na mayroong pag-iingat sa pahintulot na ito, dahil posibleng mailagay ang mga bahagi ng app sa isang hindi nagagamit, pabagu-bago, o hindi matatag na katayuan."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"ibigay o bawiin ang mga pahintulot"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Binibigyang-daan ang isang application na ibigay o bawiin ang mga tukoy na pahintulot para dito o sa iba pang mga application. Maaari itong gamitin ng mga nakakapahamak na application upang i-access ang mga tampok na hindi mo ibinigay sa mga ito."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"itakda ang gustong apps"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Pinapayagan ang app na baguhin ang iyong gustong apps. Maaaring tahimik na baguhin ng nakakahamak na apps ang apps na tumatakbo, na dinadaya ang iyong umiiral nang apps upang mangolekta ng pribadong data mula sa iyo."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"baguhin ang mga setting ng global system"</string>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Itakda ang petsa"</string>
<string name="date_time_set" msgid="5777075614321087758">"Itakda"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Default"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"BAGO: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Walang mga kinakailangang pahintulot"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Itago"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Ipakita lahat"</b></string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index fd0beaf..4d3c8537 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"вмикати чи вимикати компоненти програми"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Дозволяє програмі змінювати статус ввімкнення чи вимкнення компонента іншої програми. Шкідливі програми можуть використовувати це для вимкнення важливих характеристик планшетного ПК. З цим типом дозволу треба поводитися обережно, оскільки компоненти програми можуть стати непридатними, невідповідними чи нестабільними."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Дозволяє програмі змінювати статус ввімкнення чи вимкнення компонента іншої програми. Шкідливі програми можуть використовувати це для вимкнення важливих характеристик телефону. З цим типом дозволу треба поводитися обережно, оскільки компоненти програми можуть стати непридатними, невідповідними чи нестабільними."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"надавати або скасовувати дозволи"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Дозволяє програмі надавати або скасовувати певні дозволи для себе чи інших програм. Шкідливі програми можуть використовувати це для доступу до функцій, якого ви їм не надавали."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"установлювати потрібні програми"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Дозволяє програмі змінювати ваші вибрані програми. Шкідливі програми можуть непомітно змінювати запущені програми, примушуючи існуючі програми оманливим шляхом збирати ваші особисті дані."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"змін. загальні налашт-ня сист."</string>
@@ -1008,8 +1006,7 @@
<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>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"НОВИЙ: "</font></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>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 37af091..c9b200d 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -313,10 +313,8 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"bật hoặc tắt cấu phần ứng dụng"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Cho phép ứng dụng thay đổi việc có bật cấu phần của ứng dụng khác hay không. Ứng dụng độc hại có thể sử dụng quyền này để vô hiệu hóa những tính năng quan trọng của máy tính bảng. Phải cẩn trọng khi sử dụng quyền này vì quyền này có thể khiến các cấu phần rơi vào trạng thái không sử dụng được, không đồng nhất hoặc không ổn định."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Cho phép ứng dụng thay đổi việc có bật cấu phần của một ứng dụng khác hay không. Ứng dụng độc hại có thể sử dụng quyền này để tắt những tính năng quan trọng của điện thoại. Phải sử dụng quyền này thận trọng vì có thể khiến các cấu phần của ứng dụng rơi vào trạng thái không thể sử dụng được, không đồng nhất hoặc không ổn định."</string>
- <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
- <skip />
- <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
- <skip />
+ <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"cấp hoặc thu hồi quyền"</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Cho phép ứng dụng cấp hoặc thu hồi quyền cụ thể đối với ứng dụng đó hoặc các ứng dụng khác. Các ứng dụng độc hại có thể lợi dụng điều này để truy cập các tính năng mà bạn không cấp."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"đặt ứng dụng ưa thích"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Cho phép ứng dụng sửa đổi ứng dụng ưa thích của bạn. Ứng dụng độc hại có thể ngầm thay đổi các ứng dụng đã được chạy, giả mạo các ứng dụng hiện có để thu thập dữ liệu cá nhân của bạn."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"sửa đổi cài đặt hệ thống chung"</string>
@@ -1008,8 +1006,7 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Đặt ngày"</string>
<string name="date_time_set" msgid="5777075614321087758">"Đặt"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Mặc định"</string>
- <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
- <skip />
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"MỚI: "</font></string>
<string name="no_permissions" msgid="7283357728219338112">"Không yêu cầu quyền"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Ẩn"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Hiển thị tất cả"</b></string>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f548165..c8df649 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2263,6 +2263,10 @@
content providers from outside an ApplicationThread. [CHAR LIMIT=NONE] -->
<string name="permdesc_accessContentProvidersExternally">Allows the holder to access content
providers from the shell. Should never be needed for normal apps.</string>
+ <!-- Title of an application permission which allows the application to suggest that now is a bad time to reboot the device in order to apply an OTA. [CHAR LIMIT=40] -->
+ <string name="permlab_updateLock">discourage automatic device updates</string>
+ <!-- Description of an application permission which allows the application to suggest that now is a bad time to reboot the device in order to apply an OTA. [CHAR LIMIT=NONE] -->
+ <string name="permdesc_updateLock">Allows the holder to offer information to the system about when would be a good time for a noninteractive reboot to upgrade the device.</string>
<!-- If the user enters a password in a form on a website, a dialog will come up asking if they want to save the password. Text in the save password dialog, asking if the browser should remember a password. -->
<string name="save_password_message">Do you want the browser to remember this password?</string>
diff --git a/core/tests/coretests/src/android/util/LocaleUtilTest.java b/core/tests/coretests/src/android/util/LocaleUtilTest.java
index ff3d539..0ca6043 100644
--- a/core/tests/coretests/src/android/util/LocaleUtilTest.java
+++ b/core/tests/coretests/src/android/util/LocaleUtilTest.java
@@ -22,7 +22,8 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
-import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE;
+import static android.view.View.LAYOUT_DIRECTION_LTR;
+import static android.view.View.LAYOUT_DIRECTION_RTL;
public class LocaleUtilTest extends AndroidTestCase {
@@ -32,168 +33,168 @@
args = {Locale.class}
)
public void testGetLayoutDirectionFromLocale() {
- assertEquals(TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(null));
- assertEquals(TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.ENGLISH));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.CANADA));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.CANADA_FRENCH));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.FRANCE));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.FRENCH));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.GERMAN));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.GERMANY));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.ITALIAN));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.ITALY));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.UK));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.US));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.ROOT));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.CHINA));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.CHINESE));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.JAPAN));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.JAPANESE));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.KOREA));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.KOREAN));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.PRC));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.SIMPLIFIED_CHINESE));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.TAIWAN));
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(Locale.TRADITIONAL_CHINESE));
Locale locale = new Locale("ar");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "AE");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "BH");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "DZ");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "EG");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "IQ");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "JO");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "KW");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "LB");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "LY");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "MA");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "OM");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "QA");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "SA");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "SD");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "SY");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "TN");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ar", "YE");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("fa");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("fa", "AF");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("fa", "IR");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("iw");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("iw", "IL");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("he");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("he", "IL");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("pa_Arab");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("pa_Arab", "PK");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ps");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ps", "AF");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ur");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ur", "IN");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("ur", "PK");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("uz_Arab");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
locale = new Locale("uz_Arab", "AF");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_RTL,
LocaleUtil.getLayoutDirectionFromLocale(locale));
// Locale without a real language
locale = new Locale("zz");
- assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+ assertEquals(LAYOUT_DIRECTION_LTR,
LocaleUtil.getLayoutDirectionFromLocale(locale));
}
}
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index caeb026..8ba0203 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -159,12 +159,18 @@
status_t DrmManagerService::consumeRights(
int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
ALOGV("Entering consumeRights");
+ if (!isProtectedCallAllowed()) {
+ return DRM_ERROR_NO_PERMISSION;
+ }
return mDrmManager->consumeRights(uniqueId, decryptHandle, action, reserve);
}
status_t DrmManagerService::setPlaybackStatus(
int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
ALOGV("Entering setPlaybackStatus");
+ if (!isProtectedCallAllowed()) {
+ return DRM_ERROR_NO_PERMISSION;
+ }
return mDrmManager->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
}
@@ -229,12 +235,18 @@
status_t DrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
ALOGV("Entering closeDecryptSession");
+ if (!isProtectedCallAllowed()) {
+ return DRM_ERROR_NO_PERMISSION;
+ }
return mDrmManager->closeDecryptSession(uniqueId, decryptHandle);
}
status_t DrmManagerService::initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
int decryptUnitId, const DrmBuffer* headerInfo) {
ALOGV("Entering initializeDecryptUnit");
+ if (!isProtectedCallAllowed()) {
+ return DRM_ERROR_NO_PERMISSION;
+ }
return mDrmManager->initializeDecryptUnit(uniqueId,decryptHandle, decryptUnitId, headerInfo);
}
@@ -242,18 +254,27 @@
int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
ALOGV("Entering decrypt");
+ if (!isProtectedCallAllowed()) {
+ return DRM_ERROR_NO_PERMISSION;
+ }
return mDrmManager->decrypt(uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
}
status_t DrmManagerService::finalizeDecryptUnit(
int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
ALOGV("Entering finalizeDecryptUnit");
+ if (!isProtectedCallAllowed()) {
+ return DRM_ERROR_NO_PERMISSION;
+ }
return mDrmManager->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
}
ssize_t DrmManagerService::pread(int uniqueId, DecryptHandle* decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset) {
ALOGV("Entering pread");
+ if (!isProtectedCallAllowed()) {
+ return DRM_ERROR_NO_PERMISSION;
+ }
return mDrmManager->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
}
diff --git a/include/binder/MemoryHeapPmem.h b/include/binder/MemoryHeapPmem.h
deleted file mode 100644
index e1660c4..0000000
--- a/include/binder/MemoryHeapPmem.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_MEMORY_HEAP_PMEM_H
-#define ANDROID_MEMORY_HEAP_PMEM_H
-
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <binder/MemoryHeapBase.h>
-#include <binder/IMemory.h>
-#include <utils/SortedVector.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class MemoryHeapBase;
-
-// ---------------------------------------------------------------------------
-
-class MemoryHeapPmem : public MemoryHeapBase
-{
-public:
- class MemoryPmem : public BnMemory {
- public:
- MemoryPmem(const sp<MemoryHeapPmem>& heap);
- ~MemoryPmem();
- protected:
- const sp<MemoryHeapPmem>& getHeap() const { return mClientHeap; }
- private:
- friend class MemoryHeapPmem;
- virtual void revoke() = 0;
- sp<MemoryHeapPmem> mClientHeap;
- };
-
- MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap, uint32_t flags = 0);
- ~MemoryHeapPmem();
-
- /* HeapInterface additions */
- virtual sp<IMemory> mapMemory(size_t offset, size_t size);
-
- /* make the whole heap visible (you know who you are) */
- virtual status_t slap();
-
- /* hide (revoke) the whole heap (the client will see the garbage page) */
- virtual status_t unslap();
-
- /* revoke all allocations made by this heap */
- virtual void revoke();
-
-private:
- /* use this to create your own IMemory for mapMemory */
- virtual sp<MemoryPmem> createMemory(size_t offset, size_t size);
- void remove(const wp<MemoryPmem>& memory);
-
-private:
- sp<MemoryHeapBase> mParentHeap;
- mutable Mutex mLock;
- SortedVector< wp<MemoryPmem> > mAllocations;
-};
-
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_MEMORY_HEAP_PMEM_H
diff --git a/include/drm/drm_framework_common.h b/include/drm/drm_framework_common.h
index 2632cbd..637409c 100644
--- a/include/drm/drm_framework_common.h
+++ b/include/drm/drm_framework_common.h
@@ -43,6 +43,7 @@
DRM_ERROR_DECRYPT = ERROR_BASE - 5,
DRM_ERROR_CANNOT_HANDLE = ERROR_BASE - 6,
DRM_ERROR_TAMPER_DETECTED = ERROR_BASE - 7,
+ DRM_ERROR_NO_PERMISSION = ERROR_BASE - 8,
DRM_NO_ERROR = NO_ERROR
};
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 437a89c..b0c581a 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -225,7 +225,7 @@
/* get sample rate for this record track
*/
- uint32_t getSampleRate();
+ uint32_t getSampleRate() const;
/* Sets marker position. When record reaches the number of frames specified,
* a callback with event type EVENT_MARKER is called. Calling setMarkerPosition
@@ -242,7 +242,7 @@
* - INVALID_OPERATION: the AudioRecord has no callback installed.
*/
status_t setMarkerPosition(uint32_t marker);
- status_t getMarkerPosition(uint32_t *marker);
+ status_t getMarkerPosition(uint32_t *marker) const;
/* Sets position update period. Every time the number of frames specified has been recorded,
@@ -261,7 +261,7 @@
* - INVALID_OPERATION: the AudioRecord has no callback installed.
*/
status_t setPositionUpdatePeriod(uint32_t updatePeriod);
- status_t getPositionUpdatePeriod(uint32_t *updatePeriod);
+ status_t getPositionUpdatePeriod(uint32_t *updatePeriod) const;
/* Gets record head position. The position is the total number of frames
@@ -275,7 +275,7 @@
* - NO_ERROR: successful operation
* - BAD_VALUE: position is NULL
*/
- status_t getPosition(uint32_t *position);
+ status_t getPosition(uint32_t *position) const;
/* returns a handle on the audio input used by this AudioRecord.
*
@@ -285,7 +285,7 @@
* Returned value:
* handle on audio hardware input
*/
- audio_io_handle_t getInput();
+ audio_io_handle_t getInput() const;
/* returns the audio session ID associated to this AudioRecord.
*
@@ -295,7 +295,7 @@
* Returned value:
* AudioRecord session ID.
*/
- int getSessionId();
+ int getSessionId() const;
/* obtains a buffer of "frameCount" frames. The buffer must be
* filled entirely. If the track is stopped, obtainBuffer() returns
@@ -326,7 +326,7 @@
* Such loss typically occurs when the user space process is blocked longer than the capacity of audio driver buffers.
* Unit: the number of input audio frames
*/
- unsigned int getInputFramesLost();
+ unsigned int getInputFramesLost() const;
private:
/* copying audio tracks is not allowed */
@@ -360,7 +360,7 @@
sp<IMemory> mCblkMemory;
sp<ClientRecordThread> mClientRecordThread;
status_t mReadyToRun;
- Mutex mLock;
+ mutable Mutex mLock;
Condition mCondition;
uint32_t mFrameCount;
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index fd116b7..d449298 100644
--- a/libs/binder/Android.mk
+++ b/libs/binder/Android.mk
@@ -24,7 +24,6 @@
MemoryDealer.cpp \
MemoryBase.cpp \
MemoryHeapBase.cpp \
- MemoryHeapPmem.cpp \
Parcel.cpp \
PermissionCache.cpp \
ProcessState.cpp \
diff --git a/libs/binder/MemoryHeapPmem.cpp b/libs/binder/MemoryHeapPmem.cpp
deleted file mode 100644
index 66bcf4d..0000000
--- a/libs/binder/MemoryHeapPmem.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "MemoryHeapPmem"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#include <cutils/log.h>
-
-#include <binder/MemoryHeapPmem.h>
-#include <binder/MemoryHeapBase.h>
-
-#ifdef HAVE_ANDROID_OS
-#include <linux/android_pmem.h>
-#endif
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-MemoryHeapPmem::MemoryPmem::MemoryPmem(const sp<MemoryHeapPmem>& heap)
- : BnMemory(), mClientHeap(heap)
-{
-}
-
-MemoryHeapPmem::MemoryPmem::~MemoryPmem() {
- if (mClientHeap != NULL) {
- mClientHeap->remove(this);
- }
-}
-
-// ---------------------------------------------------------------------------
-
-class SubRegionMemory : public MemoryHeapPmem::MemoryPmem {
-public:
- SubRegionMemory(const sp<MemoryHeapPmem>& heap, ssize_t offset, size_t size);
- virtual ~SubRegionMemory();
- virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const;
-private:
- friend class MemoryHeapPmem;
- void revoke();
- size_t mSize;
- ssize_t mOffset;
-};
-
-SubRegionMemory::SubRegionMemory(const sp<MemoryHeapPmem>& heap,
- ssize_t offset, size_t size)
- : MemoryHeapPmem::MemoryPmem(heap), mSize(size), mOffset(offset)
-{
-#ifndef NDEBUG
- void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + offset);
- memset(start_ptr, 0xda, size);
-#endif
-
-#ifdef HAVE_ANDROID_OS
- if (size > 0) {
- const size_t pagesize = getpagesize();
- size = (size + pagesize-1) & ~(pagesize-1);
- int our_fd = heap->heapID();
- struct pmem_region sub = { offset, size };
- int err = ioctl(our_fd, PMEM_MAP, &sub);
- ALOGE_IF(err<0, "PMEM_MAP failed (%s), "
- "mFD=%d, sub.offset=%lu, sub.size=%lu",
- strerror(errno), our_fd, sub.offset, sub.len);
-}
-#endif
-}
-
-sp<IMemoryHeap> SubRegionMemory::getMemory(ssize_t* offset, size_t* size) const
-{
- if (offset) *offset = mOffset;
- if (size) *size = mSize;
- return getHeap();
-}
-
-SubRegionMemory::~SubRegionMemory()
-{
- revoke();
-}
-
-
-void SubRegionMemory::revoke()
-{
- // NOTE: revoke() doesn't need to be protected by a lock because it
- // can only be called from MemoryHeapPmem::revoke(), which means
- // that we can't be in ~SubRegionMemory(), or in ~SubRegionMemory(),
- // which means MemoryHeapPmem::revoke() wouldn't have been able to
- // promote() it.
-
-#ifdef HAVE_ANDROID_OS
- if (mSize != 0) {
- const sp<MemoryHeapPmem>& heap(getHeap());
- int our_fd = heap->heapID();
- struct pmem_region sub;
- sub.offset = mOffset;
- sub.len = mSize;
- int err = ioctl(our_fd, PMEM_UNMAP, &sub);
- ALOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
- "mFD=%d, sub.offset=%lu, sub.size=%lu",
- strerror(errno), our_fd, sub.offset, sub.len);
- mSize = 0;
- }
-#endif
-}
-
-// ---------------------------------------------------------------------------
-
-MemoryHeapPmem::MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap,
- uint32_t flags)
- : MemoryHeapBase()
-{
- char const * const device = pmemHeap->getDevice();
-#ifdef HAVE_ANDROID_OS
- if (device) {
- int fd = open(device, O_RDWR | (flags & NO_CACHING ? O_SYNC : 0));
- ALOGE_IF(fd<0, "couldn't open %s (%s)", device, strerror(errno));
- if (fd >= 0) {
- int err = ioctl(fd, PMEM_CONNECT, pmemHeap->heapID());
- if (err < 0) {
- ALOGE("PMEM_CONNECT failed (%s), mFD=%d, sub-fd=%d",
- strerror(errno), fd, pmemHeap->heapID());
- close(fd);
- } else {
- // everything went well...
- mParentHeap = pmemHeap;
- MemoryHeapBase::init(fd,
- pmemHeap->getBase(),
- pmemHeap->getSize(),
- pmemHeap->getFlags() | flags,
- device);
- }
- }
- }
-#else
- mParentHeap = pmemHeap;
- MemoryHeapBase::init(
- dup(pmemHeap->heapID()),
- pmemHeap->getBase(),
- pmemHeap->getSize(),
- pmemHeap->getFlags() | flags,
- device);
-#endif
-}
-
-MemoryHeapPmem::~MemoryHeapPmem()
-{
-}
-
-sp<IMemory> MemoryHeapPmem::mapMemory(size_t offset, size_t size)
-{
- sp<MemoryPmem> memory = createMemory(offset, size);
- if (memory != 0) {
- Mutex::Autolock _l(mLock);
- mAllocations.add(memory);
- }
- return memory;
-}
-
-sp<MemoryHeapPmem::MemoryPmem> MemoryHeapPmem::createMemory(
- size_t offset, size_t size)
-{
- sp<SubRegionMemory> memory;
- if (heapID() > 0)
- memory = new SubRegionMemory(this, offset, size);
- return memory;
-}
-
-status_t MemoryHeapPmem::slap()
-{
-#ifdef HAVE_ANDROID_OS
- size_t size = getSize();
- const size_t pagesize = getpagesize();
- size = (size + pagesize-1) & ~(pagesize-1);
- int our_fd = getHeapID();
- struct pmem_region sub = { 0, size };
- int err = ioctl(our_fd, PMEM_MAP, &sub);
- ALOGE_IF(err<0, "PMEM_MAP failed (%s), "
- "mFD=%d, sub.offset=%lu, sub.size=%lu",
- strerror(errno), our_fd, sub.offset, sub.len);
- return -errno;
-#else
- return NO_ERROR;
-#endif
-}
-
-status_t MemoryHeapPmem::unslap()
-{
-#ifdef HAVE_ANDROID_OS
- size_t size = getSize();
- const size_t pagesize = getpagesize();
- size = (size + pagesize-1) & ~(pagesize-1);
- int our_fd = getHeapID();
- struct pmem_region sub = { 0, size };
- int err = ioctl(our_fd, PMEM_UNMAP, &sub);
- ALOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
- "mFD=%d, sub.offset=%lu, sub.size=%lu",
- strerror(errno), our_fd, sub.offset, sub.len);
- return -errno;
-#else
- return NO_ERROR;
-#endif
-}
-
-void MemoryHeapPmem::revoke()
-{
- SortedVector< wp<MemoryPmem> > allocations;
-
- { // scope for lock
- Mutex::Autolock _l(mLock);
- allocations = mAllocations;
- }
-
- ssize_t count = allocations.size();
- for (ssize_t i=0 ; i<count ; i++) {
- sp<MemoryPmem> memory(allocations[i].promote());
- if (memory != 0)
- memory->revoke();
- }
-}
-
-void MemoryHeapPmem::remove(const wp<MemoryPmem>& memory)
-{
- Mutex::Autolock _l(mLock);
- mAllocations.remove(memory);
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index f96fe50..9fa412c 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -286,8 +286,8 @@
{
if (mThreadPoolStarted) {
int32_t s = android_atomic_add(1, &mThreadPoolSeq);
- char buf[32];
- sprintf(buf, "Binder Thread #%d", s);
+ char buf[16];
+ snprintf(buf, sizeof(buf), "Binder_%X", s);
ALOGV("Spawning new pooled thread, name=%s\n", buf);
sp<Thread> t = new PoolThread(isMain);
t->run(buf);
diff --git a/libs/utils/BlobCache.cpp b/libs/utils/BlobCache.cpp
index e52cf2f..be398ee 100644
--- a/libs/utils/BlobCache.cpp
+++ b/libs/utils/BlobCache.cpp
@@ -183,7 +183,7 @@
status_t BlobCache::flatten(void* buffer, size_t size, int fds[], size_t count)
const {
if (count != 0) {
- ALOGE("flatten: nonzero fd count: %d", count);
+ ALOGE("flatten: nonzero fd count: %zu", count);
return BAD_VALUE;
}
@@ -234,7 +234,7 @@
mCacheEntries.clear();
if (count != 0) {
- ALOGE("unflatten: nonzero fd count: %d", count);
+ ALOGE("unflatten: nonzero fd count: %zu", count);
return BAD_VALUE;
}
diff --git a/libs/utils/Debug.cpp b/libs/utils/Debug.cpp
index f7988ec..e8ac983 100644
--- a/libs/utils/Debug.cpp
+++ b/libs/utils/Debug.cpp
@@ -199,7 +199,7 @@
if ((int32_t)length < 0) {
if (singleLineBytesCutoff < 0) func(cookie, "\n");
char buf[64];
- sprintf(buf, "(bad length: %d)", length);
+ sprintf(buf, "(bad length: %zu)", length);
func(cookie, buf);
return;
}
diff --git a/libs/utils/Static.cpp b/libs/utils/Static.cpp
index bfcb2da..624e917 100644
--- a/libs/utils/Static.cpp
+++ b/libs/utils/Static.cpp
@@ -57,8 +57,8 @@
virtual status_t writeLines(const struct iovec& vec, size_t N)
{
//android_writevLog(&vec, N); <-- this is now a no-op
- if (N != 1) ALOGI("WARNING: writeLines N=%d\n", N);
- ALOGI("%.*s", vec.iov_len, (const char*) vec.iov_base);
+ if (N != 1) ALOGI("WARNING: writeLines N=%zu\n", N);
+ ALOGI("%.*s", (int)vec.iov_len, (const char*) vec.iov_base);
return NO_ERROR;
}
};
diff --git a/libs/utils/StopWatch.cpp b/libs/utils/StopWatch.cpp
index 595aec3..b1708d62 100644
--- a/libs/utils/StopWatch.cpp
+++ b/libs/utils/StopWatch.cpp
@@ -20,6 +20,10 @@
#include <stdlib.h>
#include <stdio.h>
+/* for PRId64 */
+#define __STDC_FORMAT_MACROS 1
+#include <inttypes.h>
+
#include <utils/Log.h>
#include <utils/Errors.h>
#include <utils/StopWatch.h>
@@ -39,11 +43,11 @@
{
nsecs_t elapsed = elapsedTime();
const int n = mNumLaps;
- ALOGD("StopWatch %s (us): %lld ", mName, ns2us(elapsed));
+ ALOGD("StopWatch %s (us): %" PRId64 " ", mName, ns2us(elapsed));
for (int i=0 ; i<n ; i++) {
const nsecs_t soFar = mLaps[i].soFar;
const nsecs_t thisLap = mLaps[i].thisLap;
- ALOGD(" [%d: %lld, %lld]", i, ns2us(soFar), ns2us(thisLap));
+ ALOGD(" [%d: %" PRId64 ", %" PRId64, i, ns2us(soFar), ns2us(thisLap));
}
}
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index a4068ff..943f3af 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -307,7 +307,7 @@
pid_t tid;
if (t != 0) {
mReadyToRun = WOULD_BLOCK;
- t->run("ClientRecordThread", ANDROID_PRIORITY_AUDIO);
+ t->run("AudioRecord", ANDROID_PRIORITY_AUDIO);
tid = t->getTid(); // pid_t is unknown until run()
ALOGV("getTid=%d", tid);
if (tid == -1) {
@@ -386,7 +386,7 @@
return !mActive;
}
-uint32_t AudioRecord::getSampleRate()
+uint32_t AudioRecord::getSampleRate() const
{
AutoMutex lock(mLock);
return mCblk->sampleRate;
@@ -402,7 +402,7 @@
return NO_ERROR;
}
-status_t AudioRecord::getMarkerPosition(uint32_t *marker)
+status_t AudioRecord::getMarkerPosition(uint32_t *marker) const
{
if (marker == NULL) return BAD_VALUE;
@@ -423,7 +423,7 @@
return NO_ERROR;
}
-status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod)
+status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const
{
if (updatePeriod == NULL) return BAD_VALUE;
@@ -432,7 +432,7 @@
return NO_ERROR;
}
-status_t AudioRecord::getPosition(uint32_t *position)
+status_t AudioRecord::getPosition(uint32_t *position) const
{
if (position == NULL) return BAD_VALUE;
@@ -442,7 +442,7 @@
return NO_ERROR;
}
-unsigned int AudioRecord::getInputFramesLost()
+unsigned int AudioRecord::getInputFramesLost() const
{
if (mActive)
return AudioSystem::getInputFramesLost(mInput);
@@ -597,7 +597,7 @@
mCblk->stepUser(audioBuffer->frameCount);
}
-audio_io_handle_t AudioRecord::getInput()
+audio_io_handle_t AudioRecord::getInput() const
{
AutoMutex lock(mLock);
return mInput;
@@ -615,7 +615,7 @@
return mInput;
}
-int AudioRecord::getSessionId()
+int AudioRecord::getSessionId() const
{
return mSessionId;
}
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 74c97ed..4890f05 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -370,7 +370,7 @@
android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags);
pid_t tid;
if (t != 0) {
- t->run("AudioTrackThread", ANDROID_PRIORITY_AUDIO);
+ t->run("AudioTrack", ANDROID_PRIORITY_AUDIO);
tid = t->getTid(); // pid_t is unknown until run()
ALOGV("getTid=%d", tid);
if (tid == -1) {
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 14ce266..276ca21 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -53,6 +53,7 @@
// where fade starts
static final float ALPHA_FADE_END = 0.5f; // fraction of thumbnail width
// beyond which alpha->0
+ private float mMinAlpha = 0f;
private float mPagingTouchSlop;
private Callback mCallback;
@@ -120,6 +121,10 @@
v.getMeasuredHeight();
}
+ public void setMinAlpha(float minAlpha) {
+ mMinAlpha = minAlpha;
+ }
+
private float getAlphaForOffset(View view) {
float viewSize = getSize(view);
final float fadeSize = ALPHA_FADE_END * viewSize;
@@ -130,10 +135,7 @@
} else if (pos < viewSize * (1.0f - ALPHA_FADE_START)) {
result = 1.0f + (viewSize * ALPHA_FADE_START + pos) / fadeSize;
}
- // Make .03 alpha the minimum so you always see the item a bit-- slightly below
- // .03, the item disappears entirely (as if alpha = 0) and that discontinuity looks
- // a bit jarring
- return Math.max(0.03f, result);
+ return Math.max(mMinAlpha, result);
}
// invalidate the view's own bounds all the way up the view hierarchy
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index 76e6ee8..97c9553 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -44,7 +44,7 @@
import java.util.ArrayList;
public class RecentsHorizontalScrollView extends HorizontalScrollView
- implements SwipeHelper.Callback {
+ implements SwipeHelper.Callback, RecentsPanelView.RecentsScrollView {
private static final String TAG = RecentsPanelView.TAG;
private static final boolean DEBUG = RecentsPanelView.DEBUG;
private LinearLayout mLinearLayout;
@@ -65,6 +65,10 @@
mRecycledViews = new ArrayList<View>();
}
+ public void setMinSwipeAlpha(float minAlpha) {
+ mSwipeHelper.setMinAlpha(minAlpha);
+ }
+
private int scrollPositionOfMostRecent() {
return mLinearLayout.getWidth() - getWidth();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 18132ff..61aaa43 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -92,6 +92,13 @@
public void onRecentsPanelVisibilityChanged(boolean visible);
}
+ public static interface RecentsScrollView {
+ public int numItemsInOneScreenful();
+ public void setAdapter(TaskDescriptionAdapter adapter);
+ public void setCallback(RecentsCallback callback);
+ public void setMinSwipeAlpha(float minAlpha);
+ }
+
private final class OnLongClickDelegate implements View.OnLongClickListener {
View mOtherView;
OnLongClickDelegate(View other) {
@@ -196,16 +203,11 @@
}
public int numItemsInOneScreenful() {
- if (mRecentsContainer instanceof RecentsHorizontalScrollView){
- RecentsHorizontalScrollView scrollView
- = (RecentsHorizontalScrollView) mRecentsContainer;
+ if (mRecentsContainer instanceof RecentsScrollView){
+ RecentsScrollView scrollView
+ = (RecentsScrollView) mRecentsContainer;
return scrollView.numItemsInOneScreenful();
- } else if (mRecentsContainer instanceof RecentsVerticalScrollView){
- RecentsVerticalScrollView scrollView
- = (RecentsVerticalScrollView) mRecentsContainer;
- return scrollView.numItemsInOneScreenful();
- }
- else {
+ } else {
throw new IllegalArgumentException("missing Recents[Horizontal]ScrollView");
}
}
@@ -427,18 +429,12 @@
mRecentsContainer = (ViewGroup) findViewById(R.id.recents_container);
mStatusBarTouchProxy = (StatusBarTouchProxy) findViewById(R.id.status_bar_touch_proxy);
mListAdapter = new TaskDescriptionAdapter(mContext);
- if (mRecentsContainer instanceof RecentsHorizontalScrollView){
- RecentsHorizontalScrollView scrollView
- = (RecentsHorizontalScrollView) mRecentsContainer;
+ if (mRecentsContainer instanceof RecentsScrollView){
+ RecentsScrollView scrollView
+ = (RecentsScrollView) mRecentsContainer;
scrollView.setAdapter(mListAdapter);
scrollView.setCallback(this);
- } else if (mRecentsContainer instanceof RecentsVerticalScrollView){
- RecentsVerticalScrollView scrollView
- = (RecentsVerticalScrollView) mRecentsContainer;
- scrollView.setAdapter(mListAdapter);
- scrollView.setCallback(this);
- }
- else {
+ } else {
throw new IllegalArgumentException("missing Recents[Horizontal]ScrollView");
}
@@ -467,6 +463,14 @@
};
}
+ public void setMinSwipeAlpha(float minAlpha) {
+ if (mRecentsContainer instanceof RecentsScrollView){
+ RecentsScrollView scrollView
+ = (RecentsScrollView) mRecentsContainer;
+ scrollView.setMinSwipeAlpha(minAlpha);
+ }
+ }
+
private void createCustomAnimations(LayoutTransition transitioner) {
transitioner.setDuration(200);
transitioner.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);
@@ -523,8 +527,7 @@
synchronized (td) {
if (mRecentsContainer != null) {
ViewGroup container = mRecentsContainer;
- if (container instanceof HorizontalScrollView
- || container instanceof ScrollView) {
+ if (container instanceof RecentsScrollView) {
container = (ViewGroup) container.findViewById(
R.id.recents_linear_layout);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 1bfd000..f4e516c 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -43,7 +43,8 @@
import java.util.ArrayList;
-public class RecentsVerticalScrollView extends ScrollView implements SwipeHelper.Callback {
+public class RecentsVerticalScrollView extends ScrollView
+ implements SwipeHelper.Callback, RecentsPanelView.RecentsScrollView {
private static final String TAG = RecentsPanelView.TAG;
private static final boolean DEBUG = RecentsPanelView.DEBUG;
private LinearLayout mLinearLayout;
@@ -65,6 +66,10 @@
mRecycledViews = new ArrayList<View>();
}
+ public void setMinSwipeAlpha(float minAlpha) {
+ mSwipeHelper.setMinAlpha(minAlpha);
+ }
+
private int scrollPositionOfMostRecent() {
return mLinearLayout.getHeight() - getHeight();
}
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 b2d9e64..2e1f120 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -432,6 +432,11 @@
mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL,
mRecentsPanel));
mRecentsPanel.setVisibility(View.GONE);
+
+ // Make .03 alpha the minimum so you always see the item a bit-- slightly below
+ // .03, the item disappears entirely (as if alpha = 0) and that discontinuity looks
+ // a bit jarring
+ mRecentsPanel.setMinSwipeAlpha(0.03f);
WindowManager.LayoutParams lp = getRecentsLayoutParams(mRecentsPanel.getLayoutParams());
WindowManagerImpl.getDefault().addView(mRecentsPanel, lp);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 462c2fa..8f7b35c 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1464,7 +1464,7 @@
mMasterVolume(audioFlinger->masterVolumeSW_l()),
mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false)
{
- snprintf(mName, kNameLength, "AudioOut_%d", id);
+ snprintf(mName, kNameLength, "AudioOut_%X", id);
readOutputParameters();
@@ -1993,9 +1993,12 @@
bool AudioFlinger::MixerThread::threadLoop()
{
+ // DirectOutputThread has single trackToRemove instead of Vector
Vector< sp<Track> > tracksToRemove;
+ // DirectOutputThread has activeTrack here
nsecs_t standbyTime = systemTime();
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
// increase threshold again due to low power audio mode. The way this warning threshold is
@@ -2003,18 +2006,26 @@
nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
nsecs_t lastWarning = 0;
bool longStandbyExit = false;
+
uint32_t activeSleepTime = activeSleepTimeUs();
uint32_t idleSleepTime = idleSleepTimeUs();
uint32_t sleepTime = idleSleepTime;
+
uint32_t sleepTimeShift = 0;
- Vector< sp<EffectChain> > effectChains;
CpuStats cpuStats;
+ // DirectOutputThread has shorter standbyDelay
+
acquireWakeLock();
while (!exitPending())
{
cpuStats.sample();
+
+ // DirectOutputThread has rampVolume, leftVol, rightVol
+
+ Vector< sp<EffectChain> > effectChains;
+
processConfigEvents();
mixer_state mixerStatus = MIXER_IDLE;
@@ -2024,28 +2035,29 @@
if (checkForNewParameters_l()) {
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
// 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();
+ // DirectOutputThread updates standbyDelay also
}
- const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
-
// put audio hardware into standby after short delay
- if (CC_UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) ||
- mSuspended)) {
+ if (CC_UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) ||
+ mSuspended > 0)) {
if (!mStandby) {
- ALOGV("Audio hardware entering standby, mixer %p, mSuspended %d", this, mSuspended);
+ ALOGV("Audio hardware entering standby, mixer %p, suspend count %u", this, mSuspended);
mOutput->stream->common.standby(&mOutput->stream->common);
mStandby = true;
mBytesWritten = 0;
}
- if (!activeTracks.size() && mConfigEvents.isEmpty()) {
+ if (!mActiveTracks.size() && mConfigEvents.isEmpty()) {
// we're about to wait, flush the binder command buffer
IPCThreadState::self()->flushCommands();
@@ -2068,7 +2080,7 @@
}
}
- mixerStatus = prepareTracks_l(activeTracks, &tracksToRemove);
+ mixerStatus = prepareTracks_l(&tracksToRemove);
// prevent any changes in effect chain list and in each effect chain
// during mixing and effect process as the audio buffers could be deleted
@@ -2130,12 +2142,15 @@
// TODO add standby time extension fct of effect tail
}
- if (mSuspended) {
+ if (mSuspended > 0) {
sleepTime = suspendSleepTimeUs();
}
// only process effects if we're going to write
if (sleepTime == 0) {
+
+ // DirectOutputThread adds applyVolume here
+
for (size_t i = 0; i < effectChains.size(); i ++) {
effectChains[i]->process_l();
}
@@ -2146,14 +2161,16 @@
// sleepTime == 0 means we must write to audio hardware
if (sleepTime == 0) {
+ // FIXME Only in MixerThread, and rewrite to reduce number of system calls
mLastWriteTime = systemTime();
mInWrite = true;
mBytesWritten += mixBufferSize;
-
int bytesWritten = (int)mOutput->stream->write(mOutput->stream, mMixBuffer, mixBufferSize);
if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
mNumWrites++;
mInWrite = false;
+
+ // Only in MixerThread: start of write blocked detection
nsecs_t now = systemTime();
nsecs_t delta = now - mLastWriteTime;
if (!mStandby && delta > maxPeriod) {
@@ -2167,12 +2184,14 @@
longStandbyExit = true;
}
}
+ // end of write blocked detection
+
mStandby = false;
} else {
usleep(sleepTime);
}
- // finally let go of all our tracks, without the lock held
+ // finally let go of removed track(s), without the lock held
// since we can't guarantee the destructors won't acquire that
// same lock.
tracksToRemove.clear();
@@ -2180,8 +2199,12 @@
// Effect chains will be actually deleted here if they were removed from
// mEffectChains list during mixing or effects processing
effectChains.clear();
+
+ // FIXME Note that the above .clear() is no longer necessary since effectChains
+ // is now local to this block, but will keep it for now (at least until merge done).
}
+ // put output stream into standby mode
if (!mStandby) {
mOutput->stream->common.standby(&mOutput->stream->common);
}
@@ -2194,12 +2217,12 @@
// prepareTracks_l() must be called with ThreadBase::mLock held
AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTracks_l(
- const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove)
+ Vector< sp<Track> > *tracksToRemove)
{
mixer_state mixerStatus = MIXER_IDLE;
// find out which tracks need to be processed
- size_t count = activeTracks.size();
+ size_t count = mActiveTracks.size();
size_t mixedTracks = 0;
size_t tracksWithEffect = 0;
@@ -2219,7 +2242,7 @@
}
for (size_t i=0 ; i<count ; i++) {
- sp<Track> t = activeTracks[i].promote();
+ sp<Track> t = mActiveTracks[i].promote();
if (t == 0) continue;
// this const just means the local variable doesn't change
@@ -2706,13 +2729,20 @@
bool AudioFlinger::DirectOutputThread::threadLoop()
{
+ // MixerThread has Vector instead of single trackToRemove
sp<Track> trackToRemove;
- sp<Track> activeTrack;
+
nsecs_t standbyTime = systemTime();
- size_t mixBufferSize = mFrameCount*mFrameSize;
+ size_t mixBufferSize = mFrameCount * mFrameSize;
+
+ // MixerThread has relaxed timing: maxPeriod, lastWarning, longStandbyExit
+
uint32_t activeSleepTime = activeSleepTimeUs();
uint32_t idleSleepTime = idleSleepTimeUs();
uint32_t sleepTime = idleSleepTime;
+
+ // MixerThread has sleepTimeShift and cpuStats
+
// use shorter standby delay as on normal output to release
// hardware resources as soon as possible
nsecs_t standbyDelay = microseconds(activeSleepTime*2);
@@ -2721,20 +2751,30 @@
while (!exitPending())
{
+ // MixerThread has cpuStats.sample()
+
bool rampVolume;
uint16_t leftVol;
uint16_t rightVol;
+
Vector< sp<EffectChain> > effectChains;
processConfigEvents();
+ // MixerThread does not have activeTrack here
+ sp<Track> activeTrack;
+
mixer_state mixerStatus = MIXER_IDLE;
{ // scope for the mLock
Mutex::Autolock _l(mLock);
if (checkForNewParameters_l()) {
- mixBufferSize = mFrameCount*mFrameSize;
+ mixBufferSize = mFrameCount * mFrameSize;
+
+ // different calculations here
+ standbyDelay = microseconds(activeSleepTime*2);
+
activeSleepTime = activeSleepTimeUs();
idleSleepTime = idleSleepTimeUs();
standbyDelay = microseconds(activeSleepTime*2);
@@ -2742,10 +2782,9 @@
// put audio hardware into standby after short delay
if (CC_UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) ||
- mSuspended)) {
- // wait until we have something to do...
+ mSuspended > 0)) {
if (!mStandby) {
- ALOGV("Audio hardware entering standby, mixer %p, mSuspended %d", this, mSuspended);
+ ALOGV("Audio hardware entering standby, mixer %p, suspend count %u", this, mSuspended);
mOutput->stream->common.standby(&mOutput->stream->common);
mStandby = true;
mBytesWritten = 0;
@@ -2758,19 +2797,27 @@
if (exitPending()) break;
releaseWakeLock_l();
+ // wait until we have something to do...
ALOGV("Thread %p type %d TID %d going to sleep", this, mType, gettid());
mWaitWorkCV.wait(mLock);
ALOGV("Thread %p type %d TID %d waking up", this, mType, gettid());
acquireWakeLock_l();
+ // MixerThread has "mPrevMixerStatus = MIXER_IDLE"
checkSilentMode_l();
+ // MixerThread has different standbyDelay
standbyTime = systemTime() + standbyDelay;
sleepTime = idleSleepTime;
+ // MixerThread has "sleepTimeShift = 0"
continue;
}
}
+ // MixerThread has "mixerStatus = prepareTracks_l(...)"
+
+ // equivalent to MixerThread's lockEffectChains_l, but without the lock
+ // FIXME - is it OK to omit the lock here?
effectChains = mEffectChains;
// find out which tracks need to be processed
@@ -2901,6 +2948,7 @@
lockEffectChains_l(effectChains);
}
+ // For DirectOutputThread, this test is equivalent to "activeTrack != 0"
if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
AudioBufferProvider::Buffer buffer;
size_t frameCount = mFrameCount;
@@ -2933,15 +2981,18 @@
}
}
- if (mSuspended) {
+ if (mSuspended > 0) {
sleepTime = suspendSleepTimeUs();
}
// only process effects if we're going to write
if (sleepTime == 0) {
+
+ // MixerThread does not have applyVolume
if (mixerStatus == MIXER_TRACKS_READY) {
applyVolume(leftVol, rightVol, rampVolume);
}
+
for (size_t i = 0; i < effectChains.size(); i ++) {
effectChains[i]->process_l();
}
@@ -2959,12 +3010,15 @@
if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
mNumWrites++;
mInWrite = false;
+
+ // MixerThread has write blocked detection here
+
mStandby = false;
} else {
usleep(sleepTime);
}
- // finally let go of removed track, without the lock held
+ // finally let go of removed track(s), without the lock held
// since we can't guarantee the destructors won't acquire that
// same lock.
trackToRemove.clear();
@@ -2973,8 +3027,12 @@
// Effect chains will be actually deleted here if they were removed from
// mEffectChains list during mixing or effects processing
effectChains.clear();
+
+ // FIXME Note that the above .clear() is no longer necessary since effectChains
+ // is now local to this block, but will keep it for now (at least until merge done).
}
+ // put output stream into standby mode
if (!mStandby) {
mOutput->stream->common.standby(&mOutput->stream->common);
}
@@ -3099,18 +3157,24 @@
{
Vector< sp<Track> > tracksToRemove;
nsecs_t standbyTime = systemTime();
- size_t mixBufferSize = mFrameCount*mFrameSize;
+ size_t mixBufferSize = mFrameCount * mFrameSize;
+
+ // Only in DuplicatingThread
SortedVector< sp<OutputTrack> > outputTracks;
uint32_t writeFrames = 0;
+
uint32_t activeSleepTime = activeSleepTimeUs();
uint32_t idleSleepTime = idleSleepTimeUs();
uint32_t sleepTime = idleSleepTime;
- Vector< sp<EffectChain> > effectChains;
acquireWakeLock();
while (!exitPending())
{
+ // MixerThread has cpuStats.sample
+
+ Vector< sp<EffectChain> > effectChains;
+
processConfigEvents();
mixer_state mixerStatus = MIXER_IDLE;
@@ -3119,22 +3183,25 @@
Mutex::Autolock _l(mLock);
if (checkForNewParameters_l()) {
- mixBufferSize = mFrameCount*mFrameSize;
+ mixBufferSize = mFrameCount * mFrameSize;
+
+ // Only in DuplicatingThread
updateWaitTime();
+
activeSleepTime = activeSleepTimeUs();
idleSleepTime = idleSleepTimeUs();
}
- const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
-
+ // Only in DuplicatingThread
for (size_t i = 0; i < mOutputTracks.size(); i++) {
outputTracks.add(mOutputTracks[i]);
}
// put audio hardware into standby after short delay
- if (CC_UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) ||
- mSuspended)) {
+ if (CC_UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) ||
+ mSuspended > 0)) {
if (!mStandby) {
+ // DuplicatingThread implements standby by stopping all tracks
for (size_t i = 0; i < outputTracks.size(); i++) {
outputTracks[i]->stop();
}
@@ -3142,7 +3209,7 @@
mBytesWritten = 0;
}
- if (!activeTracks.size() && mConfigEvents.isEmpty()) {
+ if (!mActiveTracks.size() && mConfigEvents.isEmpty()) {
// we're about to wait, flush the binder command buffer
IPCThreadState::self()->flushCommands();
outputTracks.clear();
@@ -3156,15 +3223,17 @@
ALOGV("Thread %p type %d TID %d waking up", this, mType, gettid());
acquireWakeLock_l();
+ // MixerThread has "mPrevMixerStatus = MIXER_IDLE"
checkSilentMode_l();
standbyTime = systemTime() + mStandbyTimeInNsecs;
sleepTime = idleSleepTime;
+ // MixerThread has sleepTimeShift
continue;
}
}
- mixerStatus = prepareTracks_l(activeTracks, &tracksToRemove);
+ mixerStatus = prepareTracks_l(&tracksToRemove);
// prevent any changes in effect chain list and in each effect chain
// during mixing and effect process as the audio buffers could be deleted
@@ -3172,6 +3241,7 @@
lockEffectChains_l(effectChains);
}
+ // Duplicating Thread is completely different here
if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
// mix buffers...
if (outputsReady(outputTracks)) {
@@ -3201,7 +3271,7 @@
}
}
- if (mSuspended) {
+ if (mSuspended > 0) {
sleepTime = suspendSleepTimeUs();
}
@@ -3223,11 +3293,14 @@
}
mStandby = false;
mBytesWritten += mixBufferSize;
+
+ // MixerThread has write blocked detection here
+
} else {
usleep(sleepTime);
}
- // finally let go of all our tracks, without the lock held
+ // finally let go of removed track(s), without the lock held
// since we can't guarantee the destructors won't acquire that
// same lock.
tracksToRemove.clear();
@@ -3236,8 +3309,14 @@
// Effect chains will be actually deleted here if they were removed from
// mEffectChains list during mixing or effects processing
effectChains.clear();
+
+ // FIXME Note that the above .clear() is no longer necessary since effectChains
+ // is now local to this block, but will keep it for now (at least until merge done).
}
+ // MixerThread and DirectOutpuThread have standby here,
+ // but for DuplicatingThread this is handled by the outputTracks
+
releaseWakeLock();
ALOGV("Thread %p type %d exiting", this, mType);
@@ -4791,7 +4870,7 @@
// mBytesRead is only meaningful while active, and so is cleared in start()
// (but might be better to also clear here for dump?)
{
- snprintf(mName, kNameLength, "AudioIn_%d", id);
+ snprintf(mName, kNameLength, "AudioIn_%X", id);
readInputParameters();
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index e908d3f..bdaf97c 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -455,9 +455,10 @@
virtual status_t addEffectChain_l(const sp<EffectChain>& chain) = 0;
// remove an effect chain from the chain list (mEffectChains)
virtual size_t removeEffectChain_l(const sp<EffectChain>& chain) = 0;
- // lock mall effect chains Mutexes. Must be called before releasing the
+ // lock all effect chains Mutexes. Must be called before releasing the
// ThreadBase mutex before processing the mixer and effects. This guarantees the
// integrity of the chains during the process.
+ // Also sets the parameter 'effectChains' to current value of mEffectChains.
void lockEffectChains_l(Vector<sp <EffectChain> >& effectChains);
// unlock effect chains after process
void unlockEffectChains(const Vector<sp<EffectChain> >& effectChains);
@@ -548,7 +549,7 @@
Vector< sp<EffectChain> > mEffectChains;
uint32_t mDevice; // output device for PlaybackThread
// input + output devices for RecordThread
- static const int kNameLength = 32;
+ static const int kNameLength = 16; // prctl(PR_SET_NAME) limit
char mName[kNameLength];
sp<IPowerManager> mPowerManager;
sp<IBinder> mWakeLockToken;
@@ -575,9 +576,11 @@
public:
enum mixer_state {
- MIXER_IDLE,
- MIXER_TRACKS_ENABLED,
- MIXER_TRACKS_READY
+ MIXER_IDLE, // no active tracks
+ MIXER_TRACKS_ENABLED, // at least one active track, but no track has any data ready
+ MIXER_TRACKS_READY // at least one active track, and at least one track has data
+ // standby mode does not have an enum value
+ // suspend by audio policy manager is orthogonal to mixer state
};
// playback track
@@ -821,8 +824,8 @@
virtual audio_stream_t* stream();
void suspend() { mSuspended++; }
- void restore() { if (mSuspended) mSuspended--; }
- bool isSuspended() const { return (mSuspended != 0); }
+ void restore() { if (mSuspended > 0) mSuspended--; }
+ bool isSuspended() const { return (mSuspended > 0); }
virtual String8 getParameters(const String8& keys);
virtual void audioConfigChanged_l(int event, int param = 0);
virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
@@ -843,7 +846,7 @@
protected:
int16_t* mMixBuffer;
- int mSuspended;
+ uint32_t mSuspended; // suspend count, > 0 means suspended
int mBytesWritten;
private:
// mMasterMute is in both PlaybackThread and in AudioFlinger. When a
@@ -913,8 +916,11 @@
virtual status_t dumpInternals(int fd, const Vector<String16>& args);
protected:
- mixer_state prepareTracks_l(const SortedVector< wp<Track> >& activeTracks,
- Vector< sp<Track> > *tracksToRemove);
+ // prepareTracks_l reads and writes mActiveTracks, and also returns the
+ // pending set of tracks to remove via Vector 'tracksToRemove'. The caller is
+ // responsible for clearing or destroying this Vector later on, when it
+ // is safe to do so. That will drop the final ref count and destroy the tracks.
+ mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
virtual int getTrackName_l();
virtual void deleteTrackName_l(int name);
virtual uint32_t idleSleepTimeUs();
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 987b039..753b1d2 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -69,7 +69,7 @@
// start tone playback thread
mTonePlaybackThread = new AudioCommandThread(String8(""));
// start audio commands thread
- mAudioCommandThread = new AudioCommandThread(String8("ApmCommandThread"));
+ mAudioCommandThread = new AudioCommandThread(String8("ApmCommand"));
/* instantiate the audio policy manager */
rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
@@ -638,7 +638,7 @@
if (mName != "") {
run(mName.string(), ANDROID_PRIORITY_AUDIO);
} else {
- run("AudioCommandThread", ANDROID_PRIORITY_AUDIO);
+ run("AudioCommand", ANDROID_PRIORITY_AUDIO);
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index c9b5997..423dad6 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -402,6 +402,14 @@
reportWtf("starting ThrottleService", e);
}
+ try {
+ Slog.i(TAG, "UpdateLock Service");
+ ServiceManager.addService(Context.UPDATE_LOCK_SERVICE,
+ new UpdateLockService(context));
+ } catch (Throwable e) {
+ reportWtf("starting UpdateLockService", e);
+ }
+
if (!"0".equals(SystemProperties.get("system_init.startmountservice"))) {
try {
/*
diff --git a/services/java/com/android/server/UpdateLockService.java b/services/java/com/android/server/UpdateLockService.java
new file mode 100644
index 0000000..5df1928
--- /dev/null
+++ b/services/java/com/android/server/UpdateLockService.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2012 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.server;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IUpdateLock;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.TokenWatcher;
+import android.os.UpdateLock;
+import android.util.Slog;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+public class UpdateLockService extends IUpdateLock.Stub {
+ static final boolean DEBUG = false;
+ static final String TAG = "UpdateLockService";
+
+ // signatureOrSystem required to use update locks
+ static final String PERMISSION = "android.permission.UPDATE_LOCK";
+
+ Context mContext;
+ LockWatcher mLocks;
+
+ class LockWatcher extends TokenWatcher {
+ LockWatcher(Handler h, String tag) {
+ super(h, tag);
+ }
+
+ public void acquired() {
+ if (DEBUG) {
+ Slog.d(TAG, "first acquire; broadcasting convenient=false");
+ }
+ sendLockChangedBroadcast(false);
+ }
+ public void released() {
+ if (DEBUG) {
+ Slog.d(TAG, "last release; broadcasting convenient=true");
+ }
+ sendLockChangedBroadcast(true);
+ }
+ }
+
+ UpdateLockService(Context context) {
+ mContext = context;
+ mLocks = new LockWatcher(new Handler(), "UpdateLocks");
+
+ // Consider just-booting to be a reasonable time to allow
+ // interruptions for update installation etc.
+ sendLockChangedBroadcast(true);
+ }
+
+ void sendLockChangedBroadcast(boolean state) {
+ // Safe early during boot because this broadcast only goes to registered receivers.
+ long oldIdent = Binder.clearCallingIdentity();
+ try {
+ Intent intent = new Intent(UpdateLock.UPDATE_LOCK_CHANGED)
+ .putExtra(UpdateLock.NOW_IS_CONVENIENT, state)
+ .putExtra(UpdateLock.TIMESTAMP, System.currentTimeMillis())
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ mContext.sendStickyBroadcast(intent);
+ } finally {
+ Binder.restoreCallingIdentity(oldIdent);
+ }
+ }
+
+ @Override
+ public void acquireUpdateLock(IBinder token, String tag) throws RemoteException {
+ if (DEBUG) {
+ Slog.d(TAG, "acquire(" + token + ") by " + makeTag(tag));
+ }
+
+ mContext.enforceCallingOrSelfPermission(PERMISSION, "acquireUpdateLock");
+ mLocks.acquire(token, makeTag(tag));
+ }
+
+ @Override
+ public void releaseUpdateLock(IBinder token) throws RemoteException {
+ if (DEBUG) {
+ Slog.d(TAG, "release(" + token + ')');
+ }
+
+ mContext.enforceCallingOrSelfPermission(PERMISSION, "releaseUpdateLock");
+ mLocks.release(token);
+ };
+
+ private String makeTag(String tag) {
+ return "{tag=" + tag
+ + " uid=" + Binder.getCallingUid()
+ + " pid=" + Binder.getCallingPid() + '}';
+ }
+
+ @Override
+ public 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 update lock service from from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid());
+ return;
+ }
+
+ mLocks.dump(pw);
+ }
+}