diff options
Diffstat (limited to 'core')
161 files changed, 3275 insertions, 2473 deletions
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index ffa36d6..fd40d99 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -16,6 +16,8 @@ package android.accounts; +import android.annotation.RequiresPermission; +import android.annotation.Size; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -49,6 +51,11 @@ import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import static android.Manifest.permission.AUTHENTICATE_ACCOUNTS; +import static android.Manifest.permission.GET_ACCOUNTS; +import static android.Manifest.permission.MANAGE_ACCOUNTS; +import static android.Manifest.permission.USE_CREDENTIALS; + /** * This class provides access to a centralized registry of the user's * online accounts. The user enters credentials (username and password) once @@ -319,6 +326,7 @@ public class AccountManager { * @param account The account to query for a password * @return The account's password, null if none or if the account doesn't exist */ + @RequiresPermission(AUTHENTICATE_ACCOUNTS) public String getPassword(final Account account) { if (account == null) throw new IllegalArgumentException("account is null"); try { @@ -344,6 +352,7 @@ public class AccountManager { * @param account The account to query for user data * @return The user data, null if the account or key doesn't exist */ + @RequiresPermission(AUTHENTICATE_ACCOUNTS) public String getUserData(final Account account, final String key) { if (account == null) throw new IllegalArgumentException("account is null"); if (key == null) throw new IllegalArgumentException("key is null"); @@ -409,6 +418,7 @@ public class AccountManager { * @return An array of {@link Account}, one for each account. Empty * (never null) if no accounts have been added. */ + @RequiresPermission(GET_ACCOUNTS) public Account[] getAccounts() { try { return mService.getAccounts(null); @@ -431,6 +441,7 @@ public class AccountManager { * @return An array of {@link Account}, one for each account. Empty * (never null) if no accounts have been added. */ + @RequiresPermission(GET_ACCOUNTS) public Account[] getAccountsAsUser(int userId) { try { return mService.getAccountsAsUser(null, userId); @@ -490,6 +501,7 @@ public class AccountManager { * @return An array of {@link Account}, one per matching account. Empty * (never null) if no accounts of the specified type have been added. */ + @RequiresPermission(GET_ACCOUNTS) public Account[] getAccountsByType(String type) { return getAccountsByTypeAsUser(type, Process.myUserHandle()); } @@ -576,6 +588,7 @@ public class AccountManager { * @return An {@link AccountManagerFuture} which resolves to a Boolean, * true if the account exists and has all of the specified features. */ + @RequiresPermission(GET_ACCOUNTS) public AccountManagerFuture<Boolean> hasFeatures(final Account account, final String[] features, AccountManagerCallback<Boolean> callback, Handler handler) { @@ -621,6 +634,7 @@ public class AccountManager { * {@link Account}, one per account of the specified type which * matches the requested features. */ + @RequiresPermission(GET_ACCOUNTS) public AccountManagerFuture<Account[]> getAccountsByTypeAndFeatures( final String type, final String[] features, AccountManagerCallback<Account[]> callback, Handler handler) { @@ -659,6 +673,7 @@ public class AccountManager { * @return True if the account was successfully added, false if the account * already exists, the account is null, or another error occurs. */ + @RequiresPermission(AUTHENTICATE_ACCOUNTS) public boolean addAccountExplicitly(Account account, String password, Bundle userdata) { if (account == null) throw new IllegalArgumentException("account is null"); try { @@ -684,6 +699,7 @@ public class AccountManager { * * @param account The {@link Account} to be updated. */ + @RequiresPermission(AUTHENTICATE_ACCOUNTS) public boolean notifyAccountAuthenticated(Account account) { if (account == null) throw new IllegalArgumentException("account is null"); @@ -715,9 +731,10 @@ public class AccountManager { * after the name change. If successful the account's name will be the * specified new name. */ + @RequiresPermission(AUTHENTICATE_ACCOUNTS) public AccountManagerFuture<Account> renameAccount( final Account account, - final String newName, + @Size(min = 1) final String newName, AccountManagerCallback<Account> callback, Handler handler) { if (account == null) throw new IllegalArgumentException("account is null."); @@ -783,6 +800,7 @@ public class AccountManager { * {@link #removeAccount(Account, Activity, AccountManagerCallback, Handler)} * instead */ + @RequiresPermission(MANAGE_ACCOUNTS) @Deprecated public AccountManagerFuture<Boolean> removeAccount(final Account account, AccountManagerCallback<Boolean> callback, Handler handler) { @@ -837,6 +855,7 @@ public class AccountManager { * adding accounts (of this type) has been disabled by policy * </ul> */ + @RequiresPermission(MANAGE_ACCOUNTS) public AccountManagerFuture<Bundle> removeAccount(final Account account, final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) { if (account == null) throw new IllegalArgumentException("account is null"); @@ -909,6 +928,7 @@ public class AccountManager { * account did not exist, the account is null, or another error * occurs. */ + @RequiresPermission(AUTHENTICATE_ACCOUNTS) public boolean removeAccountExplicitly(Account account) { if (account == null) throw new IllegalArgumentException("account is null"); try { @@ -935,6 +955,7 @@ public class AccountManager { * @param accountType The account type of the auth token to invalidate, must not be null * @param authToken The auth token to invalidate, may be null */ + @RequiresPermission(anyOf = {MANAGE_ACCOUNTS, USE_CREDENTIALS}) public void invalidateAuthToken(final String accountType, final String authToken) { if (accountType == null) throw new IllegalArgumentException("accountType is null"); try { @@ -964,6 +985,7 @@ public class AccountManager { * @return The cached auth token for this account and type, or null if * no auth token is cached or the account does not exist. */ + @RequiresPermission(AUTHENTICATE_ACCOUNTS) public String peekAuthToken(final Account account, final String authTokenType) { if (account == null) throw new IllegalArgumentException("account is null"); if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); @@ -990,6 +1012,7 @@ public class AccountManager { * @param account The account to set a password for * @param password The password to set, null to clear the password */ + @RequiresPermission(AUTHENTICATE_ACCOUNTS) public void setPassword(final Account account, final String password) { if (account == null) throw new IllegalArgumentException("account is null"); try { @@ -1014,6 +1037,7 @@ public class AccountManager { * * @param account The account whose password to clear */ + @RequiresPermission(MANAGE_ACCOUNTS) public void clearPassword(final Account account) { if (account == null) throw new IllegalArgumentException("account is null"); try { @@ -1039,6 +1063,7 @@ public class AccountManager { * @param key The userdata key to set. Must not be null * @param value The value to set, null to clear this userdata key */ + @RequiresPermission(AUTHENTICATE_ACCOUNTS) public void setUserData(final Account account, final String key, final String value) { if (account == null) throw new IllegalArgumentException("account is null"); if (key == null) throw new IllegalArgumentException("key is null"); @@ -1066,6 +1091,7 @@ public class AccountManager { * @param authTokenType The type of the auth token, see {#getAuthToken} * @param authToken The auth token to add to the cache */ + @RequiresPermission(AUTHENTICATE_ACCOUNTS) public void setAuthToken(Account account, final String authTokenType, final String authToken) { if (account == null) throw new IllegalArgumentException("account is null"); if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); @@ -1100,6 +1126,7 @@ public class AccountManager { * @throws java.io.IOException if the authenticator experienced an I/O problem * creating a new auth token, usually because of network trouble */ + @RequiresPermission(USE_CREDENTIALS) public String blockingGetAuthToken(Account account, String authTokenType, boolean notifyAuthFailure) throws OperationCanceledException, IOException, AuthenticatorException { @@ -1174,6 +1201,7 @@ public class AccountManager { * authenticator-dependent. The caller should verify the validity of the * account before requesting an auth token. */ + @RequiresPermission(USE_CREDENTIALS) public AccountManagerFuture<Bundle> getAuthToken( final Account account, final String authTokenType, final Bundle options, final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) { @@ -1264,6 +1292,7 @@ public class AccountManager { * boolean, AccountManagerCallback, android.os.Handler)} instead */ @Deprecated + @RequiresPermission(USE_CREDENTIALS) public AccountManagerFuture<Bundle> getAuthToken( final Account account, final String authTokenType, final boolean notifyAuthFailure, @@ -1342,6 +1371,7 @@ public class AccountManager { * authenticator-dependent. The caller should verify the validity of the * account before requesting an auth token. */ + @RequiresPermission(USE_CREDENTIALS) public AccountManagerFuture<Bundle> getAuthToken( final Account account, final String authTokenType, final Bundle options, final boolean notifyAuthFailure, @@ -1411,6 +1441,7 @@ public class AccountManager { * creating a new account, usually because of network trouble * </ul> */ + @RequiresPermission(MANAGE_ACCOUNTS) public AccountManagerFuture<Bundle> addAccount(final String accountType, final String authTokenType, final String[] requiredFeatures, final Bundle addAccountOptions, @@ -1598,6 +1629,7 @@ public class AccountManager { * verifying the password, usually because of network trouble * </ul> */ + @RequiresPermission(MANAGE_ACCOUNTS) public AccountManagerFuture<Bundle> confirmCredentials(final Account account, final Bundle options, final Activity activity, @@ -1674,6 +1706,7 @@ public class AccountManager { * verifying the password, usually because of network trouble * </ul> */ + @RequiresPermission(MANAGE_ACCOUNTS) public AccountManagerFuture<Bundle> updateCredentials(final Account account, final String authTokenType, final Bundle options, final Activity activity, @@ -1725,6 +1758,7 @@ public class AccountManager { * updating settings, usually because of network trouble * </ul> */ + @RequiresPermission(MANAGE_ACCOUNTS) public AccountManagerFuture<Bundle> editProperties(final String accountType, final Activity activity, final AccountManagerCallback<Bundle> callback, final Handler handler) { @@ -2258,6 +2292,7 @@ public class AccountManager { * updating settings, usually because of network trouble * </ul> */ + @RequiresPermission(MANAGE_ACCOUNTS) public AccountManagerFuture<Bundle> getAuthTokenByFeatures( final String accountType, final String authTokenType, final String[] features, final Activity activity, final Bundle addAccountOptions, @@ -2382,6 +2417,7 @@ public class AccountManager { * @throws IllegalArgumentException if listener is null * @throws IllegalStateException if listener was already added */ + @RequiresPermission(GET_ACCOUNTS) public void addOnAccountsUpdatedListener(final OnAccountsUpdateListener listener, Handler handler, boolean updateImmediately) { if (listener == null) { diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index e79e20c..7260d10 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -21,6 +21,7 @@ import android.annotation.DrawableRes; import android.annotation.IdRes; import android.annotation.IntDef; import android.annotation.LayoutRes; +import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; @@ -891,6 +892,7 @@ public class Activity extends ContextThemeWrapper * @see #onRestoreInstanceState * @see #onPostCreate */ + @MainThread @CallSuper protected void onCreate(@Nullable Bundle savedInstanceState) { if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState); @@ -6496,6 +6498,11 @@ public class Activity extends ContextThemeWrapper return (w == null) ? 0 : w.getAttributes().windowAnimations; } + @Override + public void onAttachFragment(Fragment fragment) { + Activity.this.onAttachFragment(fragment); + } + @Nullable @Override public View onFindViewById(int id) { diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 576a046..9bbb4be 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -16,8 +16,10 @@ package android.app; +import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.graphics.Canvas; import android.graphics.Matrix; @@ -26,6 +28,7 @@ import android.os.BatteryStats; import android.os.IBinder; import android.os.ParcelFileDescriptor; +import android.util.Log; import com.android.internal.app.ProcessStats; import com.android.internal.os.TransferPipe; import com.android.internal.util.FastPrintWriter; @@ -2396,7 +2399,24 @@ public class ActivityManager { } catch (RemoteException e) { } } - + + /** + * Kills the specified UID. + * @param uid The UID to kill. + * @param reason The reason for the kill. + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.KILL_UID) + public void killUid(int uid, String reason) { + try { + ActivityManagerNative.getDefault().killUid(uid, reason); + } catch (RemoteException e) { + Log.e(TAG, "Couldn't kill uid:" + uid, e); + } + } + /** * Have the system perform a force stop of everything associated with * the given application package. All processes that share its uid diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 2e45b79..da6d8c5 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1638,6 +1638,12 @@ public final class ActivityThread { return sCurrentActivityThread; } + public static String currentOpPackageName() { + ActivityThread am = currentActivityThread(); + return (am != null && am.getApplication() != null) + ? am.getApplication().getOpPackageName() : null; + } + public static String currentPackageName() { ActivityThread am = currentActivityThread(); return (am != null && am.mBoundApplication != null) diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 8a3c9c8..5aa399b 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -223,8 +223,12 @@ public class AppOpsManager { public static final int OP_PROCESS_OUTGOING_CALLS = 54; /** @hide User the fingerprint API. */ public static final int OP_USE_FINGERPRINT = 55; + /** @hide Access to body sensors such as heart rate, etc. */ + public static final int OP_BODY_SENSORS = 56; + /** @hide Read previously received cell broadcast messages. */ + public static final int OP_READ_CELL_BROADCASTS = 57; /** @hide */ - public static final int _NUM_OP = 56; + public static final int _NUM_OP = 58; /** Access to coarse location information. */ public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -280,9 +284,6 @@ public class AppOpsManager { /** @hide Allows an application to send SMS messages. */ public static final String OPSTR_SEND_SMS = "android:send_sms"; - /** @hide Allows an application to add system alert windows. */ - public static final String OPSTR_SYSTEM_ALERT_WINDOW - = "android:system_alert_window"; /** @hide Required to be able to access the camera device. */ public static final String OPSTR_CAMERA = "android:camera"; @@ -295,6 +296,18 @@ public class AppOpsManager { /** @hide Required to access phone state related information. */ public static final String OPSTR_ADD_VOICEMAIL = "android:add_voicemail"; + /** @hide Access APIs for SIP calling over VOIP or WiFi */ + public static final String OPSTR_USE_SIP + = "android:use_sip"; + /** @hide Use the fingerprint API. */ + public static final String OPSTR_USE_FINGERPRINT + = "android:use_fingerprint"; + /** @hide Access to body sensors such as heart rate, etc. */ + public static final String OPSTR_BODY_SENSORS + = "android:body_sensors"; + /** @hide Read previously received cell broadcast messages. */ + public static final String OPSTR_READ_CELL_BROADCASTS + = "android:read_cell_broadcasts"; /** * This maps each operation to the operation that serves as the @@ -360,7 +373,9 @@ public class AppOpsManager { OP_ADD_VOICEMAIL, OP_USE_SIP, OP_PROCESS_OUTGOING_CALLS, - OP_USE_FINGERPRINT + OP_USE_FINGERPRINT, + OP_BODY_SENSORS, + OP_READ_CELL_BROADCASTS }; /** @@ -372,30 +387,30 @@ public class AppOpsManager { OPSTR_FINE_LOCATION, null, null, + OPSTR_READ_CONTACTS, + OPSTR_WRITE_CONTACTS, + OPSTR_READ_CALL_LOG, + OPSTR_WRITE_CALL_LOG, + OPSTR_READ_CALENDAR, + OPSTR_WRITE_CALENDAR, null, null, null, + OPSTR_CALL_PHONE, + OPSTR_READ_SMS, null, + OPSTR_RECEIVE_SMS, null, + OPSTR_RECEIVE_MMS, + OPSTR_RECEIVE_WAP_PUSH, + OPSTR_SEND_SMS, null, null, null, null, null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, + OPSTR_CAMERA, + OPSTR_RECORD_AUDIO, null, null, null, @@ -419,11 +434,13 @@ public class AppOpsManager { null, null, null, + OPSTR_READ_PHONE_STATE, + OPSTR_ADD_VOICEMAIL, + OPSTR_USE_SIP, null, - null, - null, - null, - null + OPSTR_USE_FINGERPRINT, + OPSTR_BODY_SENSORS, + OPSTR_READ_CELL_BROADCASTS }; /** @@ -486,7 +503,9 @@ public class AppOpsManager { "ADD_VOICEMAIL", "USE_SIP", "PROCESS_OUTGOING_CALLS", - "USE_FINGERPRINT" + "USE_FINGERPRINT", + "BODY_SENSORS", + "READ_CELL_BROADCASTS" }; /** @@ -549,7 +568,9 @@ public class AppOpsManager { Manifest.permission.ADD_VOICEMAIL, Manifest.permission.USE_SIP, Manifest.permission.PROCESS_OUTGOING_CALLS, - Manifest.permission.USE_FINGERPRINT + Manifest.permission.USE_FINGERPRINT, + Manifest.permission.BODY_SENSORS, + Manifest.permission.READ_CELL_BROADCASTS }; /** @@ -613,7 +634,9 @@ public class AppOpsManager { null, // ADD_VOICEMAIL null, // USE_SIP null, // PROCESS_OUTGOING_CALLS - null // USE_FINGERPRINT + null, // USE_FINGERPRINT + null, // BODY_SENSORS + null // READ_CELL_BROADCASTS }; /** @@ -676,7 +699,9 @@ public class AppOpsManager { false, //ADD_VOICEMAIL false, // USE_SIP false, // PROCESS_OUTGOING_CALLS - false // USE_FINGERPRINT + false, // USE_FINGERPRINT + false, // BODY_SENSORS + false // READ_CELL_BROADCASTS }; /** @@ -738,6 +763,8 @@ public class AppOpsManager { AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED, + AppOpsManager.MODE_ALLOWED, + AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED }; @@ -804,37 +831,20 @@ public class AppOpsManager { false, false, false, + false, + false, false }; /** - * This is a mapping from a permission name to public app op name. + * Mapping from an app op name to the app op code. */ - private static final ArrayMap<String, String> sPermToOp = new ArrayMap<>(); - static { - sPermToOp.put(Manifest.permission.ACCESS_COARSE_LOCATION, OPSTR_COARSE_LOCATION); - sPermToOp.put(Manifest.permission.ACCESS_FINE_LOCATION, OPSTR_FINE_LOCATION); - sPermToOp.put(Manifest.permission.PACKAGE_USAGE_STATS, OPSTR_GET_USAGE_STATS); - sPermToOp.put(Manifest.permission.READ_CONTACTS, OPSTR_READ_CONTACTS); - sPermToOp.put(Manifest.permission.WRITE_CONTACTS, OPSTR_WRITE_CONTACTS); - sPermToOp.put(Manifest.permission.READ_CALL_LOG, OPSTR_READ_CALL_LOG); - sPermToOp.put(Manifest.permission.WRITE_CALL_LOG, OPSTR_WRITE_CALL_LOG); - sPermToOp.put(Manifest.permission.READ_CALENDAR, OPSTR_READ_CALENDAR); - sPermToOp.put(Manifest.permission.WRITE_CALENDAR, OPSTR_WRITE_CALENDAR); - sPermToOp.put(Manifest.permission.CALL_PHONE, OPSTR_CALL_PHONE); - sPermToOp.put(Manifest.permission.READ_SMS, OPSTR_READ_SMS); - sPermToOp.put(Manifest.permission.RECEIVE_SMS, OPSTR_RECEIVE_SMS); - sPermToOp.put(Manifest.permission.RECEIVE_MMS, OPSTR_RECEIVE_MMS); - sPermToOp.put(Manifest.permission.RECEIVE_WAP_PUSH, OPSTR_RECEIVE_WAP_PUSH); - sPermToOp.put(Manifest.permission.SEND_SMS, OPSTR_SEND_SMS); - sPermToOp.put(Manifest.permission.SYSTEM_ALERT_WINDOW, OPSTR_SYSTEM_ALERT_WINDOW); - sPermToOp.put(Manifest.permission.CAMERA, OPSTR_CAMERA); - sPermToOp.put(Manifest.permission.RECORD_AUDIO, OPSTR_RECORD_AUDIO); - sPermToOp.put(Manifest.permission.READ_PHONE_STATE, OPSTR_READ_PHONE_STATE); - sPermToOp.put(Manifest.permission.ADD_VOICEMAIL, OPSTR_ADD_VOICEMAIL); - } + private static HashMap<String, Integer> sOpStrToOp = new HashMap<>(); - private static HashMap<String, Integer> sOpStrToOp = new HashMap<String, Integer>(); + /** + * Mapping from a permission to the corresponding app op. + */ + private static HashMap<String, Integer> sPermToOp = new HashMap<>(); static { if (sOpToSwitch.length != _NUM_OP) { @@ -874,6 +884,11 @@ public class AppOpsManager { sOpStrToOp.put(sOpToString[i], i); } } + for (int i=0; i<_NUM_OP; i++) { + if (sOpPerms[i] != null) { + sPermToOp.put(sOpPerms[i], i); + } + } } /** @@ -922,6 +937,15 @@ public class AppOpsManager { } /** + * Retrieve the app op code for a permission, or null if there is not one. + * @hide + */ + public static int permissionToOpCode(String permission) { + Integer boxedOpCode = sPermToOp.get(permission); + return boxedOpCode != null ? boxedOpCode : OP_NONE; + } + + /** * Retrieve whether the op allows the system (and system ui) to * bypass the user restriction. * @hide @@ -1185,7 +1209,11 @@ public class AppOpsManager { */ @SystemApi public static String permissionToOp(String permission) { - return sPermToOp.get(permission); + final Integer opCode = sPermToOp.get(permission); + if (opCode == null) { + return null; + } + return sOpToString[opCode]; } /** diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java index 169952a..0f286fb 100644 --- a/core/java/android/app/ExitTransitionCoordinator.java +++ b/core/java/android/app/ExitTransitionCoordinator.java @@ -239,7 +239,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { getWindow().setBackgroundDrawable(new ColorDrawable(Color.BLACK)); } ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(mActivity, this, - mAllSharedElementNames, resultCode, data); + mSharedElementNames, resultCode, data); mActivity.convertToTranslucent(new Activity.TranslucentConversionListener() { @Override public void onTranslucentConversionComplete(boolean drawComplete) { diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index 91d810e..40c5c64 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -1314,6 +1314,12 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene com.android.internal.R.styleable.Fragment_fragmentAllowReturnTransitionOverlap, true); } a.recycle(); + + final Activity hostActivity = mHost == null ? null : mHost.getActivity(); + if (hostActivity != null) { + mCalled = false; + onInflate(hostActivity, attrs, savedInstanceState); + } } /** diff --git a/core/java/android/app/FragmentHostCallback.java b/core/java/android/app/FragmentHostCallback.java index dad2c79..3e753f0 100644 --- a/core/java/android/app/FragmentHostCallback.java +++ b/core/java/android/app/FragmentHostCallback.java @@ -23,7 +23,6 @@ import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.util.ArrayMap; -import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; @@ -140,6 +139,14 @@ public abstract class FragmentHostCallback<E> extends FragmentContainer { return mWindowAnimations; } + /** + * Called when a {@link Fragment} is being attached to this host, immediately + * after the call to its {@link Fragment#onAttach(Context)} method and before + * {@link Fragment#onCreate(Bundle)}. + */ + public void onAttachFragment(Fragment fragment) { + } + @Nullable @Override public View onFindViewById(int id) { @@ -187,14 +194,6 @@ public abstract class FragmentHostCallback<E> extends FragmentContainer { } } - void onFragmentInflate(Fragment fragment, AttributeSet attrs, Bundle savedInstanceState) { - fragment.onInflate(mContext, attrs, savedInstanceState); - } - - void onFragmentAttach(Fragment fragment) { - fragment.onAttach(mContext); - } - void doLoaderStart() { if (mLoadersStarted) { return; diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index 62436e9..6b5239d 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -844,13 +844,13 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate f.mFragmentManager = mParent != null ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl(); f.mCalled = false; - mHost.onFragmentAttach(f); + f.onAttach(mHost.getContext()); if (!f.mCalled) { throw new SuperNotCalledException("Fragment " + f + " did not call through to super.onAttach()"); } if (f.mParentFragment == null) { - mHost.onFragmentAttach(f); + mHost.onAttachFragment(f); } if (!f.mRetaining) { @@ -2107,7 +2107,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate fragment.mTag = tag; fragment.mInLayout = true; fragment.mFragmentManager = this; - mHost.onFragmentInflate(fragment, attrs, fragment.mSavedFragmentState); + fragment.onInflate(mHost.getContext(), attrs, fragment.mSavedFragmentState); addFragment(fragment, true); } else if (fragment.mInLayout) { // A fragment already exists and it is not one we restored from @@ -2124,7 +2124,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate // from last saved state), then give it the attributes to // initialize itself. if (!fragment.mRetaining) { - mHost.onFragmentInflate(fragment, attrs, fragment.mSavedFragmentState); + fragment.onInflate(mHost.getContext(), attrs, fragment.mSavedFragmentState); } } diff --git a/core/java/android/app/IntentService.java b/core/java/android/app/IntentService.java index 96767ae..3cda973 100644 --- a/core/java/android/app/IntentService.java +++ b/core/java/android/app/IntentService.java @@ -16,6 +16,7 @@ package android.app; +import android.annotation.WorkerThread; import android.content.Intent; import android.os.Handler; import android.os.HandlerThread; @@ -158,5 +159,6 @@ public abstract class IntentService extends Service { * @param intent The value passed to {@link * android.content.Context#startService(Intent)}. */ + @WorkerThread protected abstract void onHandleIntent(Intent intent); } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 2cf23af..49b2549 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -2095,6 +2095,7 @@ public class Notification implements Parcelable try { Constructor<? extends Style> constructor = styleClass.getConstructor(); + constructor.setAccessible(true); style = constructor.newInstance(); style.restoreFromExtras(extras); } catch (Throwable t) { @@ -5493,477 +5494,6 @@ public class Notification implements Parcelable } /** - * <p> - * Helper class to add content info extensions to notifications. To create a notification with - * content info extensions: - * <ol> - * <li>Create an {@link Notification.Builder}, setting any desired properties. - * <li>Create a {@link ContentInfoExtender}. - * <li>Set content info specific properties using the {@code add} and {@code set} methods of - * {@link ContentInfoExtender}. - * <li>Call {@link Notification.Builder#extend(Notification.Extender)} to apply the extensions - * to a notification. - * </ol> - * - * <pre class="prettyprint">Notification notification = new Notification.Builder(context) * ... * .extend(new ContentInfoExtender() * .set*(...)) * .build(); * </pre> - * <p> - * Content info extensions can be accessed on an existing notification by using the - * {@code ContentInfoExtender(Notification)} constructor, and then using the {@code get} methods - * to access values. - */ - public static final class ContentInfoExtender implements Extender { - private static final String TAG = "ContentInfoExtender"; - - // Key for the Content info extensions bundle in the main Notification extras bundle - private static final String EXTRA_CONTENT_INFO_EXTENDER = "android.CONTENT_INFO_EXTENSIONS"; - - // Keys within EXTRA_CONTENT_INFO_EXTENDER for individual content info options. - - private static final String KEY_CONTENT_TYPE = "android.contentType"; - - private static final String KEY_CONTENT_GENRES = "android.contentGenre"; - - private static final String KEY_CONTENT_PRICING_TYPE = "android.contentPricing.type"; - - private static final String KEY_CONTENT_PRICING_VALUE = "android.contentPricing.value"; - - private static final String KEY_CONTENT_STATUS = "android.contentStatus"; - - private static final String KEY_CONTENT_MATURITY_RATING = "android.contentMaturity"; - - private static final String KEY_CONTENT_RUN_LENGTH = "android.contentLength"; - - - /** - * Value to be used with {@link #setContentTypes} to indicate that the content referred by - * the notification item is a video clip. - */ - public static final String CONTENT_TYPE_VIDEO = "android.contentType.video"; - - /** - * Value to be used with {@link #setContentTypes} to indicate that the content referred by - * the notification item is a movie. - */ - public static final String CONTENT_TYPE_MOVIE = "android.contentType.movie"; - - /** - * Value to be used with {@link #setContentTypes} to indicate that the content referred by - * the notification item is a trailer. - */ - public static final String CONTENT_TYPE_TRAILER = "android.contentType.trailer"; - - /** - * Value to be used with {@link #setContentTypes} to indicate that the content referred by - * the notification item is serial. It can refer to an entire show, a single season or - * series, or a single episode. - */ - public static final String CONTENT_TYPE_SERIAL = "android.contentType.serial"; - - /** - * Value to be used with {@link #setContentTypes} to indicate that the content referred by - * the notification item is a song or album. - */ - public static final String CONTENT_TYPE_MUSIC = "android.contentType.music"; - - /** - * Value to be used with {@link #setContentTypes} to indicate that the content referred by - * the notification item is a radio station. - */ - public static final String CONTENT_TYPE_RADIO = "android.contentType.radio"; - - /** - * Value to be used with {@link #setContentTypes} to indicate that the content referred by - * the notification item is a podcast. - */ - public static final String CONTENT_TYPE_PODCAST = "android.contentType.podcast"; - - /** - * Value to be used with {@link #setContentTypes} to indicate that the content referred by - * the notification item is a news item. - */ - public static final String CONTENT_TYPE_NEWS = "android.contentType.news"; - - /** - * Value to be used with {@link #setContentTypes} to indicate that the content referred by - * the notification item is sports. - */ - public static final String CONTENT_TYPE_SPORTS = "android.contentType.sports"; - - /** - * Value to be used with {@link #setContentTypes} to indicate that the content referred by - * the notification item is an application. - */ - public static final String CONTENT_TYPE_APP = "android.contentType.app"; - - /** - * Value to be used with {@link #setContentTypes} to indicate that the content referred by - * the notification item is a game. - */ - public static final String CONTENT_TYPE_GAME = "android.contentType.game"; - - /** - * Value to be used with {@link #setContentTypes} to indicate that the content referred by - * the notification item is a book. - */ - public static final String CONTENT_TYPE_BOOK = "android.contentType.book"; - - /** - * Value to be used with {@link #setContentTypes} to indicate that the content referred by - * the notification item is a comic book. - */ - public static final String CONTENT_TYPE_COMIC = "android.contentType.comic"; - - /** - * Value to be used with {@link #setContentTypes} to indicate that the content referred by - * the notification item is a magazine. - */ - public static final String CONTENT_TYPE_MAGAZINE = "android.contentType.magazine"; - - /** - * Value to be used with {@link #setContentTypes} to indicate that the content referred by - * the notification item is a website. - */ - public static final String CONTENT_TYPE_WEBSITE = "android.contentType.website"; - - - /** - * Value to be used with {@link #setPricingInformation} to indicate that the content - * referred by the notification item is free to consume. - */ - public static final String CONTENT_PRICING_FREE = "android.contentPrice.free"; - - /** - * Value to be used with {@link #setPricingInformation} to indicate that the content - * referred by the notification item is available as a rental, and the price value provided - * is the rental price for the item. - */ - public static final String CONTENT_PRICING_RENTAL = "android.contentPrice.rental"; - - /** - * Value to be used with {@link #setPricingInformation} to indicate that the content - * referred by the notification item is available for purchase, and the price value provided - * is the purchase price for the item. - */ - public static final String CONTENT_PRICING_PURCHASE = "android.contentPrice.purchase"; - - /** - * Value to be used with {@link #setPricingInformation} to indicate that the content - * referred by the notification item is available currently as a pre-order, and the price - * value provided is the purchase price for the item. - */ - public static final String CONTENT_PRICING_PREORDER = "android.contentPrice.preorder"; - - /** - * Value to be used with {@link #setPricingInformation} to indicate that the content - * referred by the notification item is available as part of a subscription based service, - * and the price value provided is the subscription price for the service. - */ - public static final String CONTENT_PRICING_SUBSCRIPTION = - "android.contentPrice.subscription"; - - /** - * Value to be used with {@link #setStatus} to indicate that the content referred by the - * notification is available and ready to be consumed immediately. - */ - public static final int CONTENT_STATUS_READY = 0; - - /** - * Value to be used with {@link #setStatus} to indicate that the content referred by the - * notification is pending, waiting on either a download or purchase operation to complete - * before it can be consumed. - */ - public static final int CONTENT_STATUS_PENDING = 1; - - /** - * Value to be used with {@link #setStatus} to indicate that the content referred by the - * notification is available, but needs to be first purchased, rented, subscribed or - * downloaded before it can be consumed. - */ - public static final int CONTENT_STATUS_AVAILABLE = 2; - - /** - * Value to be used with {@link #setStatus} to indicate that the content referred by the - * notification is not available. This could be content not available in a certain region or - * incompatible with the device in use. - */ - public static final int CONTENT_STATUS_UNAVAILABLE = 3; - - /** - * Value to be used with {@link #setMaturityRating} to indicate that the content referred by - * the notification is suitable for all audiences. - */ - public static final String CONTENT_MATURITY_ALL = "android.contentMaturity.all"; - - /** - * Value to be used with {@link #setMaturityRating} to indicate that the content - * referred by the notification is suitable for audiences of low maturity and above. - */ - public static final String CONTENT_MATURITY_LOW = "android.contentMaturity.low"; - - /** - * Value to be used with {@link #setMaturityRating} to indicate that the content - * referred by the notification is suitable for audiences of medium maturity and above. - */ - public static final String CONTENT_MATURITY_MEDIUM = "android.contentMaturity.medium"; - - /** - * Value to be used with {@link #setMaturityRating} to indicate that the content - * referred by the notification is suitable for audiences of high maturity and above. - */ - public static final String CONTENT_MATURITY_HIGH = "android.contentMaturity.high"; - - private String[] mTypes; - private String[] mGenres; - private String mPricingType; - private String mPricingValue; - private int mContentStatus = -1; - private String mMaturityRating; - private long mRunLength = -1; - - /** - * Create a {@link ContentInfoExtender} with default options. - */ - public ContentInfoExtender() { - } - - /** - * Create a {@link ContentInfoExtender} from the ContentInfoExtender options of an existing - * Notification. - * - * @param notif The notification from which to copy options. - */ - public ContentInfoExtender(Notification notif) { - Bundle contentBundle = notif.extras == null ? - null : notif.extras.getBundle(EXTRA_CONTENT_INFO_EXTENDER); - if (contentBundle != null) { - mTypes = contentBundle.getStringArray(KEY_CONTENT_TYPE); - mGenres = contentBundle.getStringArray(KEY_CONTENT_GENRES); - mPricingType = contentBundle.getString(KEY_CONTENT_PRICING_TYPE); - mPricingValue = contentBundle.getString(KEY_CONTENT_PRICING_VALUE); - mContentStatus = contentBundle.getInt(KEY_CONTENT_STATUS, -1); - mMaturityRating = contentBundle.getString(KEY_CONTENT_MATURITY_RATING); - mRunLength = contentBundle.getLong(KEY_CONTENT_RUN_LENGTH, -1); - } - } - - /** - * Apply content extensions to a notification that is being built. This is typically called - * by the {@link Notification.Builder#extend(Notification.Extender)} method of - * {@link Notification.Builder}. - */ - @Override - public Notification.Builder extend(Notification.Builder builder) { - Bundle contentBundle = new Bundle(); - - if (mTypes != null) { - contentBundle.putStringArray(KEY_CONTENT_TYPE, mTypes); - } - if (mGenres != null) { - contentBundle.putStringArray(KEY_CONTENT_GENRES, mGenres); - } - if (mPricingType != null) { - contentBundle.putString(KEY_CONTENT_PRICING_TYPE, mPricingType); - } - if (mPricingValue != null) { - contentBundle.putString(KEY_CONTENT_PRICING_VALUE, mPricingValue); - } - if (mContentStatus != -1) { - contentBundle.putInt(KEY_CONTENT_STATUS, mContentStatus); - } - if (mMaturityRating != null) { - contentBundle.putString(KEY_CONTENT_MATURITY_RATING, mMaturityRating); - } - if (mRunLength > 0) { - contentBundle.putLong(KEY_CONTENT_RUN_LENGTH, mRunLength); - } - - builder.getExtras().putBundle(EXTRA_CONTENT_INFO_EXTENDER, contentBundle); - return builder; - } - - /** - * Sets the content types associated with the notification content. The first tag entry will - * be considered the primary type for the content and will be used for ranking purposes. - * Other secondary type tags may be provided, if applicable, and may be used for filtering - * purposes. - * - * @param types Array of predefined type tags (see the <code>CONTENT_TYPE_*</code> - * constants) that describe the content referred to by a notification. - */ - public ContentInfoExtender setContentTypes(String[] types) { - mTypes = types; - return this; - } - - /** - * Returns an array containing the content types that describe the content associated with - * the notification. The first tag entry is considered the primary type for the content, and - * is used for content ranking purposes. - * - * @return An array of predefined type tags (see the <code>CONTENT_TYPE_*</code> constants) - * that describe the content associated with the notification. - * @see ContentInfoExtender#setContentTypes - */ - public String[] getContentTypes() { - return mTypes; - } - - /** - * Returns the primary content type tag for the content associated with the notification. - * - * @return A predefined type tag (see the <code>CONTENT_TYPE_*</code> constants) indicating - * the primary type for the content associated with the notification. - * @see ContentInfoExtender#setContentTypes - */ - public String getPrimaryContentType() { - if (mTypes == null || mTypes.length == 0) { - return null; - } - return mTypes[0]; - } - - /** - * Sets the content genres associated with the notification content. These genres may be - * used for content ranking. Genres are open ended String tags. - * <p> - * Some examples: "comedy", "action", "dance", "electronica", "racing", etc. - * - * @param genres Array of genre string tags that describe the content referred to by a - * notification. - */ - public ContentInfoExtender setGenres(String[] genres) { - mGenres = genres; - return this; - } - - /** - * Returns an array containing the content genres that describe the content associated with - * the notification. - * - * @return An array of genre tags that describe the content associated with the - * notification. - * @see ContentInfoExtender#setGenres - */ - public String[] getGenres() { - return mGenres; - } - - /** - * Sets the pricing and availability information for the content associated with the - * notification. The provided information will indicate the access model for the content - * (free, rental, purchase or subscription) and the price value (if not free). - * - * @param priceType Pricing type for this content. Must be one of the predefined pricing - * type tags (see the <code>CONTENT_PRICING_*</code> constants). - * @param priceValue A string containing a representation of the content price in the - * current locale and currency. - * @return This object for method chaining. - */ - public ContentInfoExtender setPricingInformation(String priceType, String priceValue) { - mPricingType = priceType; - mPricingValue = priceValue; - return this; - } - - /** - * Gets the pricing type for the content associated with the notification. - * - * @return A predefined tag indicating the pricing type for the content (see the <code> - * CONTENT_PRICING_*</code> constants). - * @see ContentInfoExtender#setPricingInformation - */ - public String getPricingType() { - return mPricingType; - } - - /** - * Gets the price value (when applicable) for the content associated with a notification. - * The value will be provided as a String containing the price in the appropriate currency - * for the current locale. - * - * @return A string containing a representation of the content price in the current locale - * and currency. - * @see ContentInfoExtender#setPricingInformation - */ - public String getPricingValue() { - if (mPricingType == null || CONTENT_PRICING_FREE.equals(mPricingType)) { - return null; - } - return mPricingValue; - } - - /** - * Sets the availability status for the content associated with the notification. This - * status indicates whether the referred content is ready to be consumed on the device, or - * if the user must first purchase, rent, subscribe to, or download the content. - * - * @param contentStatus The status value for this content. Must be one of the predefined - * content status values (see the <code>CONTENT_STATUS_*</code> constants). - */ - public ContentInfoExtender setStatus(int contentStatus) { - mContentStatus = contentStatus; - return this; - } - - /** - * Returns status value for the content associated with the notification. This status - * indicates whether the referred content is ready to be consumed on the device, or if the - * user must first purchase, rent, subscribe to, or download the content. - * - * @return The status value for this content, or -1 is a valid status has not been specified - * (see the <code>CONTENT_STATUS_*</code> for the defined valid status values). - * @see ContentInfoExtender#setStatus - */ - public int getStatus() { - return mContentStatus; - } - - /** - * Sets the maturity level rating for the content associated with the notification. - * - * @param maturityRating A tag indicating the maturity level rating for the content. This - * tag must be one of the predefined maturity rating tags (see the <code> - * CONTENT_MATURITY_*</code> constants). - */ - public ContentInfoExtender setMaturityRating(String maturityRating) { - mMaturityRating = maturityRating; - return this; - } - - /** - * Returns the maturity level rating for the content associated with the notification. - * - * @return returns a predefined tag indicating the maturity level rating for the content - * (see the <code> CONTENT_MATURITY_*</code> constants). - * @see ContentInfoExtender#setMaturityRating - */ - public String getMaturityRating() { - return mMaturityRating; - } - - /** - * Sets the running time (when applicable) for the content associated with the notification. - * - * @param length The runing time, in seconds, of the content associated with the - * notification. - */ - public ContentInfoExtender setRunningTime(long length) { - mRunLength = length; - return this; - } - - /** - * Returns the running time for the content associated with the notification. - * - * @return The running time, in seconds, of the content associated with the notification. - * @see ContentInfoExtender#setRunningTime - */ - public long getRunningTime() { - return mRunLength; - } - } - - /** * Get an array of Notification objects from a parcelable array bundle field. * Update the bundle to have a typed array so fetches in the future don't need * to do an array copy. diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java index d8556a2..6fca0de 100644 --- a/core/java/android/app/backup/BackupAgent.java +++ b/core/java/android/app/backup/BackupAgent.java @@ -33,15 +33,21 @@ import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; import android.system.StructStat; +import android.util.ArraySet; import android.util.Log; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.util.HashSet; +import java.util.Collection; import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.CountDownLatch; +import org.xmlpull.v1.XmlPullParserException; + /** * Provides the central interface between an * application and Android's data backup infrastructure. An application that wishes @@ -164,7 +170,6 @@ public abstract class BackupAgent extends ContextWrapper { * to do one-time initialization before the actual backup or restore operation * is begun. * <p> - * Agents do not need to override this method. */ public void onCreate() { } @@ -268,19 +273,41 @@ public abstract class BackupAgent extends ContextWrapper { * listed above. Apps only need to override this method if they need to impose special * limitations on which files are being stored beyond the control that * {@link #getNoBackupFilesDir()} offers. + * Alternatively they can provide an xml resource to specify what data to include or exclude. + * * * @param data A structured wrapper pointing to the backup destination. * @throws IOException * * @see Context#getNoBackupFilesDir() + * @see ApplicationInfo#fullBackupContent * @see #fullBackupFile(File, FullBackupDataOutput) * @see #onRestoreFile(ParcelFileDescriptor, long, File, int, long, long) */ public void onFullBackup(FullBackupDataOutput data) throws IOException { - ApplicationInfo appInfo = getApplicationInfo(); + FullBackup.BackupScheme backupScheme = FullBackup.getBackupScheme(this); + if (!backupScheme.isFullBackupContentEnabled()) { + return; + } + + Map<String, Set<String>> manifestIncludeMap; + ArraySet<String> manifestExcludeSet; + try { + manifestIncludeMap = + backupScheme.maybeParseAndGetCanonicalIncludePaths(); + manifestExcludeSet = backupScheme.maybeParseAndGetCanonicalExcludePaths(); + } catch (IOException | XmlPullParserException e) { + if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(FullBackup.TAG_XML_PARSER, + "Exception trying to parse fullBackupContent xml file!" + + " Aborting full backup.", e); + } + return; + } + + final String packageName = getPackageName(); + final ApplicationInfo appInfo = getApplicationInfo(); - // Note that we don't need to think about the no_backup dir because it's outside - // all of the ones we will be traversing String rootDir = new File(appInfo.dataDir).getCanonicalPath(); String filesDir = getFilesDir().getCanonicalPath(); String nobackupDir = getNoBackupFilesDir().getCanonicalPath(); @@ -292,34 +319,49 @@ public abstract class BackupAgent extends ContextWrapper { ? new File(appInfo.nativeLibraryDir).getCanonicalPath() : null; - // Filters, the scan queue, and the set of resulting entities - HashSet<String> filterSet = new HashSet<String>(); - String packageName = getPackageName(); + // Maintain a set of excluded directories so that as we traverse the tree we know we're not + // going places we don't expect, and so the manifest includes can't take precedence over + // what the framework decides is not to be included. + final ArraySet<String> traversalExcludeSet = new ArraySet<String>(); - // Okay, start with the app's root tree, but exclude all of the canonical subdirs + // Add the directories we always exclude. + traversalExcludeSet.add(cacheDir); + traversalExcludeSet.add(codeCacheDir); + traversalExcludeSet.add(nobackupDir); if (libDir != null) { - filterSet.add(libDir); + traversalExcludeSet.add(libDir); } - filterSet.add(cacheDir); - filterSet.add(codeCacheDir); - filterSet.add(databaseDir); - filterSet.add(sharedPrefsDir); - filterSet.add(filesDir); - filterSet.add(nobackupDir); - fullBackupFileTree(packageName, FullBackup.ROOT_TREE_TOKEN, rootDir, filterSet, data); - - // Now do the same for the files dir, db dir, and shared prefs dir - filterSet.add(rootDir); - filterSet.remove(filesDir); - fullBackupFileTree(packageName, FullBackup.DATA_TREE_TOKEN, filesDir, filterSet, data); - - filterSet.add(filesDir); - filterSet.remove(databaseDir); - fullBackupFileTree(packageName, FullBackup.DATABASE_TREE_TOKEN, databaseDir, filterSet, data); - - filterSet.add(databaseDir); - filterSet.remove(sharedPrefsDir); - fullBackupFileTree(packageName, FullBackup.SHAREDPREFS_TREE_TOKEN, sharedPrefsDir, filterSet, data); + + traversalExcludeSet.add(databaseDir); + traversalExcludeSet.add(sharedPrefsDir); + traversalExcludeSet.add(filesDir); + + // Root dir first. + applyXmlFiltersAndDoFullBackupForDomain( + packageName, FullBackup.ROOT_TREE_TOKEN, manifestIncludeMap, + manifestExcludeSet, traversalExcludeSet, data); + traversalExcludeSet.add(rootDir); + + // Data dir next. + traversalExcludeSet.remove(filesDir); + applyXmlFiltersAndDoFullBackupForDomain( + packageName, FullBackup.DATA_TREE_TOKEN, manifestIncludeMap, + manifestExcludeSet, traversalExcludeSet, data); + traversalExcludeSet.add(filesDir); + + // Database directory. + traversalExcludeSet.remove(databaseDir); + applyXmlFiltersAndDoFullBackupForDomain( + packageName, FullBackup.DATABASE_TREE_TOKEN, manifestIncludeMap, + manifestExcludeSet, traversalExcludeSet, data); + traversalExcludeSet.add(databaseDir); + + // SharedPrefs. + traversalExcludeSet.remove(sharedPrefsDir); + applyXmlFiltersAndDoFullBackupForDomain( + packageName, FullBackup.SHAREDPREFS_TREE_TOKEN, manifestIncludeMap, + manifestExcludeSet, traversalExcludeSet, data); + traversalExcludeSet.add(sharedPrefsDir); // getExternalFilesDir() location associated with this app. Technically there should // not be any files here if the app does not properly have permission to access @@ -331,8 +373,36 @@ public abstract class BackupAgent extends ContextWrapper { if (Process.myUid() != Process.SYSTEM_UID) { File efLocation = getExternalFilesDir(null); if (efLocation != null) { - fullBackupFileTree(packageName, FullBackup.MANAGED_EXTERNAL_TREE_TOKEN, - efLocation.getCanonicalPath(), null, data); + applyXmlFiltersAndDoFullBackupForDomain( + packageName, FullBackup.MANAGED_EXTERNAL_TREE_TOKEN, manifestIncludeMap, + manifestExcludeSet, traversalExcludeSet, data); + } + + } + } + + /** + * Check whether the xml yielded any <include/> tag for the provided <code>domainToken</code>. + * If so, perform a {@link #fullBackupFileTree} which backs up the file or recurses if the path + * is a directory. + */ + private void applyXmlFiltersAndDoFullBackupForDomain(String packageName, String domainToken, + Map<String, Set<String>> includeMap, + ArraySet<String> filterSet, + ArraySet<String> traversalExcludeSet, + FullBackupDataOutput data) + throws IOException { + if (includeMap == null || includeMap.size() == 0) { + // Do entire sub-tree for the provided token. + fullBackupFileTree(packageName, domainToken, + FullBackup.getBackupScheme(this).tokenToDirectoryPath(domainToken), + filterSet, traversalExcludeSet, data); + } else if (includeMap.get(domainToken) != null) { + // This will be null if the xml parsing didn't yield any rules for + // this domain (there may still be rules for other domains). + for (String includeFile : includeMap.get(domainToken)) { + fullBackupFileTree(packageName, domainToken, includeFile, filterSet, + traversalExcludeSet, data); } } } @@ -430,21 +500,31 @@ public abstract class BackupAgent extends ContextWrapper { // without transmitting any file data. if (DEBUG) Log.i(TAG, "backupFile() of " + filePath + " => domain=" + domain + " rootpath=" + rootpath); - + FullBackup.backupToTar(getPackageName(), domain, null, rootpath, filePath, output); } /** * Scan the dir tree (if it actually exists) and process each entry we find. If the - * 'excludes' parameter is non-null, it is consulted each time a new file system entity + * 'excludes' parameters are non-null, they are consulted each time a new file system entity * is visited to see whether that entity (and its subtree, if appropriate) should be * omitted from the backup process. * + * @param systemExcludes An optional list of excludes. * @hide */ - protected final void fullBackupFileTree(String packageName, String domain, String rootPath, - HashSet<String> excludes, FullBackupDataOutput output) { - File rootFile = new File(rootPath); + protected final void fullBackupFileTree(String packageName, String domain, String startingPath, + ArraySet<String> manifestExcludes, + ArraySet<String> systemExcludes, + FullBackupDataOutput output) { + // Pull out the domain and set it aside to use when making the tarball. + String domainPath = FullBackup.getBackupScheme(this).tokenToDirectoryPath(domain); + if (domainPath == null) { + // Should never happen. + return; + } + + File rootFile = new File(startingPath); if (rootFile.exists()) { LinkedList<File> scanQueue = new LinkedList<File>(); scanQueue.add(rootFile); @@ -456,7 +536,10 @@ public abstract class BackupAgent extends ContextWrapper { filePath = file.getCanonicalPath(); // prune this subtree? - if (excludes != null && excludes.contains(filePath)) { + if (manifestExcludes != null && manifestExcludes.contains(filePath)) { + continue; + } + if (systemExcludes != null && systemExcludes.contains(filePath)) { continue; } @@ -475,14 +558,20 @@ public abstract class BackupAgent extends ContextWrapper { } } catch (IOException e) { if (DEBUG) Log.w(TAG, "Error canonicalizing path of " + file); + if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(FullBackup.TAG_XML_PARSER, "Error canonicalizing path of " + file); + } continue; } catch (ErrnoException e) { if (DEBUG) Log.w(TAG, "Error scanning file " + file + " : " + e); + if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(FullBackup.TAG_XML_PARSER, "Error scanning file " + file + " : " + e); + } continue; } // Finally, back this file up (or measure it) before proceeding - FullBackup.backupToTar(packageName, domain, null, rootPath, filePath, output); + FullBackup.backupToTar(packageName, domain, null, domainPath, filePath, output); } } } @@ -516,10 +605,91 @@ public abstract class BackupAgent extends ContextWrapper { public void onRestoreFile(ParcelFileDescriptor data, long size, File destination, int type, long mode, long mtime) throws IOException { + FullBackup.BackupScheme bs = FullBackup.getBackupScheme(this); + if (!bs.isFullBackupContentEnabled()) { + if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(FullBackup.TAG_XML_PARSER, + "onRestoreFile \"" + destination.getCanonicalPath() + + "\" : fullBackupContent not enabled for " + getPackageName()); + } + return; + } + Map<String, Set<String>> includes = null; + ArraySet<String> excludes = null; + final String destinationCanonicalPath = destination.getCanonicalPath(); + try { + includes = bs.maybeParseAndGetCanonicalIncludePaths(); + excludes = bs.maybeParseAndGetCanonicalExcludePaths(); + } catch (XmlPullParserException e) { + if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(FullBackup.TAG_XML_PARSER, + "onRestoreFile \"" + destinationCanonicalPath + + "\" : Exception trying to parse fullBackupContent xml file!" + + " Aborting onRestoreFile.", e); + } + return; + } + + if (excludes != null && + isFileSpecifiedInPathList(destination, excludes)) { + if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(FullBackup.TAG_XML_PARSER, + "onRestoreFile: \"" + destinationCanonicalPath + "\": listed in" + + " excludes; skipping."); + } + return; + } + + if (includes != null && !includes.isEmpty()) { + // Rather than figure out the <include/> domain based on the path (a lot of code, and + // it's a small list), we'll go through and look for it. + boolean explicitlyIncluded = false; + for (Set<String> domainIncludes : includes.values()) { + explicitlyIncluded |= isFileSpecifiedInPathList(destination, domainIncludes); + if (explicitlyIncluded) { + break; + } + } + if (!explicitlyIncluded) { + if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(FullBackup.TAG_XML_PARSER, + "onRestoreFile: Trying to restore \"" + + destinationCanonicalPath + "\" but it isn't specified" + + " in the included files; skipping."); + } + return; + } + } FullBackup.restoreFile(data, size, type, mode, mtime, destination); } /** + * @return True if the provided file is either directly in the provided list, or the provided + * file is within a directory in the list. + */ + private boolean isFileSpecifiedInPathList(File file, Collection<String> canonicalPathList) + throws IOException { + for (String canonicalPath : canonicalPathList) { + File fileFromList = new File(canonicalPath); + if (fileFromList.isDirectory()) { + if (file.isDirectory()) { + // If they are both directories check exact equals. + return file.equals(fileFromList); + } else { + // O/w we have to check if the file is within the directory from the list. + return file.getCanonicalPath().startsWith(canonicalPath); + } + } else { + if (file.equals(fileFromList)) { + // Need to check the explicit "equals" so we don't end up with substrings. + return true; + } + } + } + return false; + } + + /** * Only specialized platform agents should overload this entry point to support * restores to crazy non-app locations. * @hide @@ -533,31 +703,9 @@ public abstract class BackupAgent extends ContextWrapper { + " domain=" + domain + " relpath=" + path + " mode=" + mode + " mtime=" + mtime); - // Parse out the semantic domains into the correct physical location - if (domain.equals(FullBackup.DATA_TREE_TOKEN)) { - basePath = getFilesDir().getCanonicalPath(); - } else if (domain.equals(FullBackup.DATABASE_TREE_TOKEN)) { - basePath = getDatabasePath("foo").getParentFile().getCanonicalPath(); - } else if (domain.equals(FullBackup.ROOT_TREE_TOKEN)) { - basePath = new File(getApplicationInfo().dataDir).getCanonicalPath(); - } else if (domain.equals(FullBackup.SHAREDPREFS_TREE_TOKEN)) { - basePath = getSharedPrefsFile("foo").getParentFile().getCanonicalPath(); - } else if (domain.equals(FullBackup.CACHE_TREE_TOKEN)) { - basePath = getCacheDir().getCanonicalPath(); - } else if (domain.equals(FullBackup.MANAGED_EXTERNAL_TREE_TOKEN)) { - // make sure we can try to restore here before proceeding - if (Process.myUid() != Process.SYSTEM_UID) { - File efLocation = getExternalFilesDir(null); - if (efLocation != null) { - basePath = getExternalFilesDir(null).getCanonicalPath(); - mode = -1; // < 0 is a token to skip attempting a chmod() - } - } - } else if (domain.equals(FullBackup.NO_BACKUP_TREE_TOKEN)) { - basePath = getNoBackupFilesDir().getCanonicalPath(); - } else { - // Not a supported location - Log.i(TAG, "Unrecognized domain " + domain); + basePath = FullBackup.getBackupScheme(this).tokenToDirectoryPath(domain); + if (domain.equals(FullBackup.MANAGED_EXTERNAL_TREE_TOKEN)) { + mode = -1; // < 0 is a token to skip attempting a chmod() } // Now that we've figured out where the data goes, send it on its way diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java index 259884e..7718a36 100644 --- a/core/java/android/app/backup/FullBackup.java +++ b/core/java/android/app/backup/FullBackup.java @@ -16,16 +16,31 @@ package android.app.backup; -import android.os.ParcelFileDescriptor; +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.XmlResourceParser; +import android.os.*; +import android.os.Process; import android.system.ErrnoException; import android.system.Os; +import android.text.TextUtils; +import android.util.ArrayMap; +import android.util.ArraySet; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; + +import org.xmlpull.v1.XmlPullParser; + import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.xmlpull.v1.XmlPullParserException; /** * Global constant definitions et cetera related to the full-backup-to-fd * binary format. Nothing in this namespace is part of any API; it's all @@ -35,6 +50,8 @@ import java.io.IOException; */ public class FullBackup { static final String TAG = "FullBackup"; + /** Enable this log tag to get verbose information while parsing the client xml. */ + static final String TAG_XML_PARSER = "BackupXmlParserLogging"; public static final String APK_TREE_TOKEN = "a"; public static final String OBB_TREE_TOKEN = "obb"; @@ -60,6 +77,27 @@ public class FullBackup { static public native int backupToTar(String packageName, String domain, String linkdomain, String rootpath, String path, FullBackupDataOutput output); + private static final Map<String, BackupScheme> kPackageBackupSchemeMap = + new ArrayMap<String, BackupScheme>(); + + static synchronized BackupScheme getBackupScheme(Context context) { + BackupScheme backupSchemeForPackage = + kPackageBackupSchemeMap.get(context.getPackageName()); + if (backupSchemeForPackage == null) { + backupSchemeForPackage = new BackupScheme(context); + kPackageBackupSchemeMap.put(context.getPackageName(), backupSchemeForPackage); + } + return backupSchemeForPackage; + } + + public static BackupScheme getBackupSchemeForTest(Context context) { + BackupScheme testing = new BackupScheme(context); + testing.mExcludes = new ArraySet(); + testing.mIncludes = new ArrayMap(); + return testing; + } + + /** * Copy data from a socket to the given File location on permanent storage. The * modification time and access mode of the resulting file will be set if desired, @@ -106,6 +144,8 @@ public class FullBackup { if (!parent.exists()) { // in practice this will only be for the default semantic directories, // and using the default mode for those is appropriate. + // This can also happen for the case where a parent directory has been + // excluded, but a file within that directory has been included. parent.mkdirs(); } out = new FileOutputStream(outFile); @@ -154,4 +194,363 @@ public class FullBackup { outFile.setLastModified(mtime); } } + + @VisibleForTesting + public static class BackupScheme { + private final File FILES_DIR; + private final File DATABASE_DIR; + private final File ROOT_DIR; + private final File SHAREDPREF_DIR; + private final File EXTERNAL_DIR; + private final File CACHE_DIR; + private final File NOBACKUP_DIR; + + final int mFullBackupContent; + final PackageManager mPackageManager; + final String mPackageName; + + /** + * Parse out the semantic domains into the correct physical location. + */ + String tokenToDirectoryPath(String domainToken) { + try { + if (domainToken.equals(FullBackup.DATA_TREE_TOKEN)) { + return FILES_DIR.getCanonicalPath(); + } else if (domainToken.equals(FullBackup.DATABASE_TREE_TOKEN)) { + return DATABASE_DIR.getCanonicalPath(); + } else if (domainToken.equals(FullBackup.ROOT_TREE_TOKEN)) { + return ROOT_DIR.getCanonicalPath(); + } else if (domainToken.equals(FullBackup.SHAREDPREFS_TREE_TOKEN)) { + return SHAREDPREF_DIR.getCanonicalPath(); + } else if (domainToken.equals(FullBackup.CACHE_TREE_TOKEN)) { + return CACHE_DIR.getCanonicalPath(); + } else if (domainToken.equals(FullBackup.MANAGED_EXTERNAL_TREE_TOKEN)) { + if (EXTERNAL_DIR != null) { + return EXTERNAL_DIR.getCanonicalPath(); + } else { + return null; + } + } else if (domainToken.equals(FullBackup.NO_BACKUP_TREE_TOKEN)) { + return NOBACKUP_DIR.getCanonicalPath(); + } + // Not a supported location + Log.i(TAG, "Unrecognized domain " + domainToken); + return null; + } catch (IOException e) { + Log.i(TAG, "Error reading directory for domain: " + domainToken); + return null; + } + + } + /** + * A map of domain -> list of canonical file names in that domain that are to be included. + * We keep track of the domain so that we can go through the file system in order later on. + */ + Map<String, Set<String>> mIncludes; + /**e + * List that will be populated with the canonical names of each file or directory that is + * to be excluded. + */ + ArraySet<String> mExcludes; + + BackupScheme(Context context) { + mFullBackupContent = context.getApplicationInfo().fullBackupContent; + mPackageManager = context.getPackageManager(); + mPackageName = context.getPackageName(); + FILES_DIR = context.getFilesDir(); + DATABASE_DIR = context.getDatabasePath("foo").getParentFile(); + ROOT_DIR = new File(context.getApplicationInfo().dataDir); + SHAREDPREF_DIR = context.getSharedPrefsFile("foo").getParentFile(); + CACHE_DIR = context.getCacheDir(); + NOBACKUP_DIR = context.getNoBackupFilesDir(); + if (android.os.Process.myUid() != Process.SYSTEM_UID) { + EXTERNAL_DIR = context.getExternalFilesDir(null); + } else { + EXTERNAL_DIR = null; + } + } + + boolean isFullBackupContentEnabled() { + if (mFullBackupContent < 0) { + // android:fullBackupContent="false", bail. + if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(FullBackup.TAG_XML_PARSER, "android:fullBackupContent - \"false\""); + } + return false; + } + return true; + } + + /** + * @return A mapping of domain -> canonical paths within that domain. Each of these paths + * specifies a file that the client has explicitly included in their backup set. If this + * map is empty we will back up the entire data directory (including managed external + * storage). + */ + public synchronized Map<String, Set<String>> maybeParseAndGetCanonicalIncludePaths() + throws IOException, XmlPullParserException { + if (mIncludes == null) { + maybeParseBackupSchemeLocked(); + } + return mIncludes; + } + + /** + * @return A set of canonical paths that are to be excluded from the backup/restore set. + */ + public synchronized ArraySet<String> maybeParseAndGetCanonicalExcludePaths() + throws IOException, XmlPullParserException { + if (mExcludes == null) { + maybeParseBackupSchemeLocked(); + } + return mExcludes; + } + + private void maybeParseBackupSchemeLocked() throws IOException, XmlPullParserException { + // This not being null is how we know that we've tried to parse the xml already. + mIncludes = new ArrayMap<String, Set<String>>(); + mExcludes = new ArraySet<String>(); + + if (mFullBackupContent == 0) { + // android:fullBackupContent="true" which means that we'll do everything. + if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(FullBackup.TAG_XML_PARSER, "android:fullBackupContent - \"true\""); + } + } else { + // android:fullBackupContent="@xml/some_resource". + if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(FullBackup.TAG_XML_PARSER, + "android:fullBackupContent - found xml resource"); + } + XmlResourceParser parser = null; + try { + parser = mPackageManager + .getResourcesForApplication(mPackageName) + .getXml(mFullBackupContent); + parseBackupSchemeFromXmlLocked(parser, mExcludes, mIncludes); + } catch (PackageManager.NameNotFoundException e) { + // Throw it as an IOException + throw new IOException(e); + } finally { + if (parser != null) { + parser.close(); + } + } + } + } + + @VisibleForTesting + public void parseBackupSchemeFromXmlLocked(XmlPullParser parser, + Set<String> excludes, + Map<String, Set<String>> includes) + throws IOException, XmlPullParserException { + int event = parser.getEventType(); // START_DOCUMENT + while (event != XmlPullParser.START_TAG) { + event = parser.next(); + } + + if (!"full-backup-content".equals(parser.getName())) { + throw new XmlPullParserException("Xml file didn't start with correct tag" + + " (<full-backup-content>). Found \"" + parser.getName() + "\""); + } + + if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(TAG_XML_PARSER, "\n"); + Log.v(TAG_XML_PARSER, "===================================================="); + Log.v(TAG_XML_PARSER, "Found valid fullBackupContent; parsing xml resource."); + Log.v(TAG_XML_PARSER, "===================================================="); + Log.v(TAG_XML_PARSER, ""); + } + + while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) { + switch (event) { + case XmlPullParser.START_TAG: + validateInnerTagContents(parser); + final String domainFromXml = parser.getAttributeValue(null, "domain"); + final File domainDirectory = + getDirectoryForCriteriaDomain(domainFromXml); + if (domainDirectory == null) { + if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(TAG_XML_PARSER, "...parsing \"" + parser.getName() + "\": " + + "domain=\"" + domainFromXml + "\" invalid; skipping"); + } + break; + } + final File canonicalFile = + extractCanonicalFile(domainDirectory, + parser.getAttributeValue(null, "path")); + if (canonicalFile == null) { + break; + } + + Set<String> activeSet = parseCurrentTagForDomain( + parser, excludes, includes, domainFromXml); + activeSet.add(canonicalFile.getCanonicalPath()); + if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(TAG_XML_PARSER, "...parsed " + canonicalFile.getCanonicalPath() + + " for domain \"" + domainFromXml + "\""); + } + + // Special case journal files (not dirs) for sqlite database. frowny-face. + // Note that for a restore, the file is never a directory (b/c it doesn't + // exist). We have no way of knowing a priori whether or not to expect a + // dir, so we add the -journal anyway to be safe. + if ("database".equals(domainFromXml) && !canonicalFile.isDirectory()) { + final String canonicalJournalPath = + canonicalFile.getCanonicalPath() + "-journal"; + activeSet.add(canonicalJournalPath); + if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(TAG_XML_PARSER, "...automatically generated " + + canonicalJournalPath + ". Ignore if nonexistant."); + } + } + } + } + if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(TAG_XML_PARSER, "\n"); + Log.v(TAG_XML_PARSER, "Xml resource parsing complete."); + Log.v(TAG_XML_PARSER, "Final tally."); + Log.v(TAG_XML_PARSER, "Includes:"); + if (includes.isEmpty()) { + Log.v(TAG_XML_PARSER, " ...nothing specified (This means the entirety of app" + + " data minus excludes)"); + } else { + for (Map.Entry<String, Set<String>> entry : includes.entrySet()) { + Log.v(TAG_XML_PARSER, " domain=" + entry.getKey()); + for (String includeData : entry.getValue()) { + Log.v(TAG_XML_PARSER, " " + includeData); + } + } + } + + Log.v(TAG_XML_PARSER, "Excludes:"); + if (excludes.isEmpty()) { + Log.v(TAG_XML_PARSER, " ...nothing to exclude."); + } else { + for (String excludeData : excludes) { + Log.v(TAG_XML_PARSER, " " + excludeData); + } + } + + Log.v(TAG_XML_PARSER, " "); + Log.v(TAG_XML_PARSER, "===================================================="); + Log.v(TAG_XML_PARSER, "\n"); + } + } + + private Set<String> parseCurrentTagForDomain(XmlPullParser parser, + Set<String> excludes, + Map<String, Set<String>> includes, + String domain) + throws XmlPullParserException { + if ("include".equals(parser.getName())) { + final String domainToken = getTokenForXmlDomain(domain); + Set<String> includeSet = includes.get(domainToken); + if (includeSet == null) { + includeSet = new ArraySet<String>(); + includes.put(domainToken, includeSet); + } + return includeSet; + } else if ("exclude".equals(parser.getName())) { + return excludes; + } else { + // Unrecognised tag => hard failure. + if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(TAG_XML_PARSER, "Invalid tag found in xml \"" + + parser.getName() + "\"; aborting operation."); + } + throw new XmlPullParserException("Unrecognised tag in backup" + + " criteria xml (" + parser.getName() + ")"); + } + } + + /** + * Map xml specified domain (human-readable, what clients put in their manifest's xml) to + * BackupAgent internal data token. + * @return null if the xml domain was invalid. + */ + private String getTokenForXmlDomain(String xmlDomain) { + if ("root".equals(xmlDomain)) { + return FullBackup.ROOT_TREE_TOKEN; + } else if ("file".equals(xmlDomain)) { + return FullBackup.DATA_TREE_TOKEN; + } else if ("database".equals(xmlDomain)) { + return FullBackup.DATABASE_TREE_TOKEN; + } else if ("sharedpref".equals(xmlDomain)) { + return FullBackup.SHAREDPREFS_TREE_TOKEN; + } else if ("external".equals(xmlDomain)) { + return FullBackup.MANAGED_EXTERNAL_TREE_TOKEN; + } else { + return null; + } + } + + /** + * + * @param domain Directory where the specified file should exist. Not null. + * @param filePathFromXml parsed from xml. Not sanitised before calling this function so may be + * null. + * @return The canonical path of the file specified or null if no such file exists. + */ + private File extractCanonicalFile(File domain, String filePathFromXml) { + if (filePathFromXml == null) { + // Allow things like <include domain="sharedpref"/> + filePathFromXml = ""; + } + if (filePathFromXml.contains("..")) { + if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(TAG_XML_PARSER, "...resolved \"" + domain.getPath() + " " + filePathFromXml + + "\", but the \"..\" path is not permitted; skipping."); + } + return null; + } + if (filePathFromXml.contains("//")) { + if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) { + Log.v(TAG_XML_PARSER, "...resolved \"" + domain.getPath() + " " + filePathFromXml + + "\", which contains the invalid \"//\" sequence; skipping."); + } + return null; + } + return new File(domain, filePathFromXml); + } + + /** + * @param domain parsed from xml. Not sanitised before calling this function so may be null. + * @return The directory relevant to the domain specified. + */ + private File getDirectoryForCriteriaDomain(String domain) { + if (TextUtils.isEmpty(domain)) { + return null; + } + if ("file".equals(domain)) { + return FILES_DIR; + } else if ("database".equals(domain)) { + return DATABASE_DIR; + } else if ("root".equals(domain)) { + return ROOT_DIR; + } else if ("sharedpref".equals(domain)) { + return SHAREDPREF_DIR; + } else if ("external".equals(domain)) { + return EXTERNAL_DIR; + } else { + return null; + } + } + + /** + * Let's be strict about the type of xml the client can write. If we see anything untoward, + * throw an XmlPullParserException. + */ + private void validateInnerTagContents(XmlPullParser parser) + throws XmlPullParserException { + if (parser.getAttributeCount() > 2) { + throw new XmlPullParserException("At most 2 tag attributes allowed for \"" + + parser.getName() + "\" tag (\"domain\" & \"path\"."); + } + if (!"include".equals(parser.getName()) && !"exclude".equals(parser.getName())) { + throw new XmlPullParserException("A valid tag is one of \"<include/>\" or" + + " \"<exclude/>. You provided \"" + parser.getName() + "\""); + } + } + } } diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 9b4dcc6..0a77868 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -1692,7 +1692,8 @@ public final class BluetoothAdapter { * @param context Context of the application * @param listener The service Listener for connection callbacks. * @param profile The Bluetooth profile; either {@link BluetoothProfile#HEALTH}, - * {@link BluetoothProfile#HEADSET} or {@link BluetoothProfile#A2DP}. + * {@link BluetoothProfile#HEADSET}, {@link BluetoothProfile#A2DP}. + * {@link BluetoothProfile#GATT} or {@link BluetoothProfile#GATT_SERVER}. * @return true on success, false on error */ public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener, diff --git a/core/java/android/bluetooth/BluetoothHealthCallback.java b/core/java/android/bluetooth/BluetoothHealthCallback.java index baf2ade..128376f 100644 --- a/core/java/android/bluetooth/BluetoothHealthCallback.java +++ b/core/java/android/bluetooth/BluetoothHealthCallback.java @@ -17,6 +17,7 @@ package android.bluetooth; +import android.annotation.BinderThread; import android.os.ParcelFileDescriptor; import android.util.Log; @@ -39,6 +40,7 @@ public abstract class BluetoothHealthCallback { * {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_SUCCESS} or * {@link BluetoothHealth#APP_CONFIG_UNREGISTRATION_FAILURE} */ + @BinderThread public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration config, int status) { Log.d(TAG, "onHealthAppConfigurationStatusChange: " + config + "Status: " + status); @@ -58,6 +60,7 @@ public abstract class BluetoothHealthCallback { * @param channelId The id associated with the channel. This id will be used * in future calls like when disconnecting the channel. */ + @BinderThread public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config, BluetoothDevice device, int prevState, int newState, ParcelFileDescriptor fd, int channelId) { diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java index 7b4c6f9..014cb22 100644 --- a/core/java/android/bluetooth/BluetoothSap.java +++ b/core/java/android/bluetooth/BluetoothSap.java @@ -28,13 +28,41 @@ import android.os.IBinder; import android.os.ServiceManager; import android.util.Log; - +/** + * This class provides the APIs to control the Bluetooth SIM + * Access Profile (SAP). + * + * <p>BluetoothSap is a proxy object for controlling the Bluetooth + * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get + * the BluetoothSap proxy object. + * + * <p>Each method is protected with its appropriate permission. + * @hide + */ public final class BluetoothSap implements BluetoothProfile { private static final String TAG = "BluetoothSap"; private static final boolean DBG = true; private static final boolean VDBG = false; + /** + * Intent used to broadcast the change in connection state of the profile. + * + * <p>This intent will have 4 extras: + * <ul> + * <li> {@link #EXTRA_STATE} - The current state of the profile. </li> + * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li> + * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> + * </ul> + * + * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of + * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, + * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}. + * + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to + * receive. + * @hide + */ public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.sap.profile.action.CONNECTION_STATE_CHANGED"; @@ -43,12 +71,22 @@ public final class BluetoothSap implements BluetoothProfile { private ServiceListener mServiceListener; private BluetoothAdapter mAdapter; - /** There was an error trying to obtain the state */ - public static final int STATE_ERROR = -1; + /** + * There was an error trying to obtain the state. + * @hide + */ + public static final int STATE_ERROR = -1; - public static final int RESULT_FAILURE = 0; + /** + * Connection state change succceeded. + * @hide + */ public static final int RESULT_SUCCESS = 1; - /** Connection canceled before completion. */ + + /** + * Connection canceled before completion. + * @hide + */ public static final int RESULT_CANCELED = 2; final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback = @@ -124,6 +162,7 @@ public final class BluetoothSap implements BluetoothProfile { * Other public functions of BluetoothSap will return default error * results once close() has been called. Multiple invocations of close() * are ok. + * @hide */ public synchronized void close() { IBluetoothManager mgr = mAdapter.getBluetoothManager(); @@ -152,6 +191,7 @@ public final class BluetoothSap implements BluetoothProfile { * Get the current state of the BluetoothSap service. * @return One of the STATE_ return codes, or STATE_ERROR if this proxy * object is currently not connected to the Sap service. + * @hide */ public int getState() { if (VDBG) log("getState()"); @@ -171,6 +211,7 @@ public final class BluetoothSap implements BluetoothProfile { * @return The remote Bluetooth device, or null if not in connected or * connecting state, or if this proxy object is not connected to * the Sap service. + * @hide */ public BluetoothDevice getClient() { if (VDBG) log("getClient()"); @@ -189,6 +230,7 @@ public final class BluetoothSap implements BluetoothProfile { * Returns true if the specified Bluetooth device is connected. * Returns false if not connected, or if this proxy object is not * currently connected to the Sap service. + * @hide */ public boolean isConnected(BluetoothDevice device) { if (VDBG) log("isConnected(" + device + ")"); @@ -206,6 +248,7 @@ public final class BluetoothSap implements BluetoothProfile { /** * Initiate connection. Initiation of outgoing connections is not * supported for SAP server. + * @hide */ public boolean connect(BluetoothDevice device) { if (DBG) log("connect(" + device + ")" + "not supported for SAPS"); @@ -218,6 +261,7 @@ public final class BluetoothSap implements BluetoothProfile { * @param device Remote Bluetooth Device * @return false on error, * true otherwise + * @hide */ public boolean disconnect(BluetoothDevice device) { if (DBG) log("disconnect(" + device + ")"); @@ -238,6 +282,7 @@ public final class BluetoothSap implements BluetoothProfile { * Get the list of connected devices. Currently at most one. * * @return list of connected devices + * @hide */ public List<BluetoothDevice> getConnectedDevices() { if (DBG) log("getConnectedDevices()"); @@ -257,6 +302,7 @@ public final class BluetoothSap implements BluetoothProfile { * Get the list of devices matching specified states. Currently at most one. * * @return list of matching devices + * @hide */ public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { if (DBG) log("getDevicesMatchingStates()"); @@ -276,6 +322,7 @@ public final class BluetoothSap implements BluetoothProfile { * Get connection state of device * * @return device connection state + * @hide */ public int getConnectionState(BluetoothDevice device) { if (DBG) log("getConnectionState(" + device + ")"); @@ -300,6 +347,7 @@ public final class BluetoothSap implements BluetoothProfile { * @param device Paired bluetooth device * @param priority * @return true if priority is set, false on error + * @hide */ public boolean setPriority(BluetoothDevice device, int priority) { if (DBG) log("setPriority(" + device + ", " + priority + ")"); @@ -325,6 +373,7 @@ public final class BluetoothSap implements BluetoothProfile { * * @param device Bluetooth device * @return priority of the device + * @hide */ public int getPriority(BluetoothDevice device) { if (VDBG) log("getPriority(" + device + ")"); diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java index 5702d11..5cf2300 100644 --- a/core/java/android/bluetooth/BluetoothSocket.java +++ b/core/java/android/bluetooth/BluetoothSocket.java @@ -91,9 +91,13 @@ public final class BluetoothSocket implements Closeable { public static final int MAX_RFCOMM_CHANNEL = 30; /*package*/ static final int MAX_L2CAP_PACKAGE_SIZE = 0xFFFF; - /** Keep TYPE_ fields in sync with BluetoothSocket.cpp */ + /** RFCOMM socket */ public static final int TYPE_RFCOMM = 1; + + /** SCO socket */ public static final int TYPE_SCO = 2; + + /** L2CAP socket */ public static final int TYPE_L2CAP = 3; /*package*/ static final int EBADFD = 77; @@ -578,8 +582,8 @@ public final class BluetoothSocket implements Closeable { } /** - * Get the type of the underlying connection - * @return one of TYPE_ + * Get the type of the underlying connection. + * @return one of {@link #TYPE_RFCOMM}, {@link #TYPE_SCO} or {@link #TYPE_L2CAP} */ public int getConnectionType() { return mType; diff --git a/core/java/android/bluetooth/le/ScanCallback.java b/core/java/android/bluetooth/le/ScanCallback.java index 27b96bd..61b2e78 100644 --- a/core/java/android/bluetooth/le/ScanCallback.java +++ b/core/java/android/bluetooth/le/ScanCallback.java @@ -53,8 +53,10 @@ public abstract class ScanCallback { /** * Callback when a BLE advertisement has been found. * - * @param callbackType Determines how this callback was triggered. Could be of - * {@link ScanSettings#CALLBACK_TYPE_ALL_MATCHES} + * @param callbackType Determines how this callback was triggered. Could be one of + * {@link ScanSettings#CALLBACK_TYPE_ALL_MATCHES}, + * {@link ScanSettings#CALLBACK_TYPE_FIRST_MATCH} or + * {@link ScanSettings#CALLBACK_TYPE_MATCH_LOST} * @param result A Bluetooth LE scan result. */ public void onScanResult(int callbackType, ScanResult result) { diff --git a/core/java/android/bluetooth/le/ScanSettings.java b/core/java/android/bluetooth/le/ScanSettings.java index dad486d..4eeb577 100644 --- a/core/java/android/bluetooth/le/ScanSettings.java +++ b/core/java/android/bluetooth/le/ScanSettings.java @@ -59,17 +59,13 @@ public final class ScanSettings implements Parcelable { /** * A result callback is only triggered for the first advertisement packet received that matches * the filter criteria. - * @hide */ - @SystemApi public static final int CALLBACK_TYPE_FIRST_MATCH = 2; /** * Receive a callback when advertisements are no longer received from a device that has been * previously reported by a first match callback. - * @hide */ - @SystemApi public static final int CALLBACK_TYPE_MATCH_LOST = 4; @@ -78,21 +74,18 @@ public final class ScanSettings implements Parcelable { */ /** * Match one advertisement per filter - * @hide */ public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1; /** * Match few advertisement per filter, depends on current capability and availibility of * the resources in hw - * @hide */ public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2; /** * Match as many advertisement per filter as hw could allow, depends on current * capability and availibility of the resources in hw - * @hide */ public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3; @@ -100,14 +93,12 @@ public final class ScanSettings implements Parcelable { /** * In Aggressive mode, hw will determine a match sooner even with feeble signal strength * and few number of sightings/match in a duration. - * @hide */ public static final int MATCH_MODE_AGGRESSIVE = 1; /** * For sticky mode, higher threshold of signal strength and sightings is required * before reporting by hw - * @hide */ public static final int MATCH_MODE_STICKY = 2; @@ -324,7 +315,6 @@ public final class ScanSettings implements Parcelable { * {@link ScanSettings#MATCH_NUM_FEW_ADVERTISEMENT} or * {@link ScanSettings#MATCH_NUM_MAX_ADVERTISEMENT} * @throws IllegalArgumentException If the {@code matchMode} is invalid. - * @hide */ public Builder setNumOfMatches(int numOfMatches) { if (numOfMatches < MATCH_NUM_ONE_ADVERTISEMENT @@ -342,7 +332,6 @@ public final class ScanSettings implements Parcelable { * {@link ScanSettings#MATCH_MODE_AGGRESSIVE} or * {@link ScanSettings#MATCH_MODE_STICKY} * @throws IllegalArgumentException If the {@code matchMode} is invalid. - * @hide */ public Builder setMatchMode(int matchMode) { if (matchMode < MATCH_MODE_AGGRESSIVE diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 6c32873..707ef30 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -96,6 +96,21 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { public String backupAgentName; /** + * An optional attribute that indicates the app supports automatic backup of app data. + * <p>0 is the default and means the app's entire data folder + managed external storage will + * be backed up; + * Any negative value indicates the app does not support full-data backup, though it may still + * want to participate via the traditional key/value backup API; + * A positive number specifies an xml resource in which the application has defined its backup + * include/exclude criteria. + * <p>If android:allowBackup is set to false, this attribute is ignored. + * + * @see {@link android.content.Context#getNoBackupFilesDir} + * @see {@link #FLAG_ALLOW_BACKUP} + */ + public int fullBackupContent = 0; + + /** * The default extra UI options for activities in this application. * Set from the {@link android.R.attr#uiOptions} attribute in the * activity's manifest. @@ -686,6 +701,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { pw.println(prefix + "uiOptions=0x" + Integer.toHexString(uiOptions)); } pw.println(prefix + "supportsRtl=" + (hasRtlSupport() ? "true" : "false")); + if (fullBackupContent > 0) { + pw.println(prefix + "fullBackupContent=@xml/" + fullBackupContent); + } else { + pw.println(prefix + "fullBackupContent=" + (fullBackupContent < 0 ? "false" : "true")); + } super.dumpBack(pw, prefix); } @@ -763,6 +783,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { uiOptions = orig.uiOptions; backupAgentName = orig.backupAgentName; hardwareAccelerated = orig.hardwareAccelerated; + fullBackupContent = orig.fullBackupContent; } @@ -816,6 +837,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeInt(descriptionRes); dest.writeInt(uiOptions); dest.writeInt(hardwareAccelerated ? 1 : 0); + dest.writeInt(fullBackupContent); } public static final Parcelable.Creator<ApplicationInfo> CREATOR @@ -868,6 +890,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { descriptionRes = source.readInt(); uiOptions = source.readInt(); hardwareAccelerated = source.readInt() != 0; + fullBackupContent = source.readInt(); } /** diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 0b24594..94b0223 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -96,9 +96,9 @@ interface IPackageManager { void removePermission(String name); - boolean grantPermission(String packageName, String permissionName, int userId); + void grantPermission(String packageName, String permissionName, int userId); - boolean revokePermission(String packageName, String permissionName, int userId); + void revokePermission(String packageName, String permissionName, int userId); boolean isProtectedBroadcast(String actionName); diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 9596c42..acc27c3 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -2421,8 +2421,8 @@ public class PackageParser { if (allowBackup) { ai.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; - // backupAgent, killAfterRestore, and restoreAnyVersion are only relevant - // if backup is possible for the given application. + // backupAgent, killAfterRestore, fullBackupContent and restoreAnyVersion are only + // relevant if backup is possible for the given application. String backupAgent = sa.getNonConfigurationString( com.android.internal.R.styleable.AndroidManifestApplication_backupAgent, Configuration.NATIVE_CONFIG_VERSION); @@ -2449,6 +2449,20 @@ public class PackageParser { ai.flags |= ApplicationInfo.FLAG_FULL_BACKUP_ONLY; } } + + TypedValue v = sa.peekValue( + com.android.internal.R.styleable.AndroidManifestApplication_fullBackupContent); + if (v != null && (ai.fullBackupContent = v.resourceId) == 0) { + if (DEBUG_BACKUP) { + Slog.v(TAG, "fullBackupContent specified as boolean=" + + (v.data == 0 ? "false" : "true")); + } + // "false" => -1, "true" => 0 + ai.fullBackupContent = (v.data == 0 ? -1 : 0); + } + if (DEBUG_BACKUP) { + Slog.v(TAG, "fullBackupContent=" + ai.fullBackupContent + " for " + pkgName); + } } TypedValue v = sa.peekValue( diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index d88594d..1fc69c0 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -460,9 +460,8 @@ public class Camera { mEventHandler = null; } - String packageName = ActivityThread.currentPackageName(); - - return native_setup(new WeakReference<Camera>(this), cameraId, halVersion, packageName); + return native_setup(new WeakReference<Camera>(this), cameraId, halVersion, + ActivityThread.currentOpPackageName()); } private int cameraInitNormal(int cameraId) { diff --git a/core/java/android/hardware/ICameraService.aidl b/core/java/android/hardware/ICameraService.aidl index 9bc2f46..7b96e20 100644 --- a/core/java/android/hardware/ICameraService.aidl +++ b/core/java/android/hardware/ICameraService.aidl @@ -38,13 +38,13 @@ interface ICameraService int getCameraInfo(int cameraId, out CameraInfo info); int connect(ICameraClient client, int cameraId, - String clientPackageName, + String opPackageName, int clientUid, // Container for an ICamera object out BinderHolder device); int connectDevice(ICameraDeviceCallbacks callbacks, int cameraId, - String clientPackageName, + String opPackageName, int clientUid, // Container for an ICameraDeviceUser object out BinderHolder device); @@ -69,7 +69,7 @@ interface ICameraService int connectLegacy(ICameraClient client, int cameraId, int halVersion, - String clientPackageName, + String opPackageName, int clientUid, // Container for an ICamera object out BinderHolder device); diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java index 11037fd..22a9e9c 100644 --- a/core/java/android/hardware/SystemSensorManager.java +++ b/core/java/android/hardware/SystemSensorManager.java @@ -41,16 +41,19 @@ import java.util.List; */ public class SystemSensorManager extends SensorManager { private static native void nativeClassInit(); - private static native int nativeGetNextSensor(Sensor sensor, int next); - private static native int nativeEnableDataInjection(boolean enable); + private static native long nativeCreate(String opPackageName); + private static native int nativeGetNextSensor(long nativeInstance, Sensor sensor, int next); + private static native int nativeEnableDataInjection(long nativeInstance, boolean enable); private static boolean sSensorModuleInitialized = false; - private static final Object sSensorModuleLock = new Object(); - private static final ArrayList<Sensor> sFullSensorsList = new ArrayList<Sensor>(); - private static final SparseArray<Sensor> sHandleToSensor = new SparseArray<Sensor>(); private static InjectEventQueue mInjectEventQueue = null; private static boolean mDataInjectionMode = false; + private final Object mLock = new Object(); + + private final ArrayList<Sensor> mFullSensorsList = new ArrayList<>(); + private final SparseArray<Sensor> mHandleToSensor = new SparseArray<>(); + // Listener list private final HashMap<SensorEventListener, SensorEventQueue> mSensorListeners = new HashMap<SensorEventListener, SensorEventQueue>(); @@ -60,44 +63,44 @@ public class SystemSensorManager extends SensorManager { // Looper associated with the context in which this instance was created. private final Looper mMainLooper; private final int mTargetSdkLevel; - private final String mPackageName; + private final Context mContext; private final boolean mHasDataInjectionPermissions; + private final long mNativeInstance; /** {@hide} */ public SystemSensorManager(Context context, Looper mainLooper) { mMainLooper = mainLooper; mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion; - mPackageName = context.getPackageName(); - synchronized(sSensorModuleLock) { + mContext = context; + mNativeInstance = nativeCreate(context.getOpPackageName()); + + synchronized(mLock) { if (!sSensorModuleInitialized) { sSensorModuleInitialized = true; - nativeClassInit(); - - // initialize the sensor list - final ArrayList<Sensor> fullList = sFullSensorsList; - int i = 0; - do { - Sensor sensor = new Sensor(); - i = nativeGetNextSensor(sensor, i); - if (i>=0) { - //Log.d(TAG, "found sensor: " + sensor.getName() + - // ", handle=" + sensor.getHandle()); - fullList.add(sensor); - sHandleToSensor.append(sensor.getHandle(), sensor); - } - } while (i>0); } mHasDataInjectionPermissions = context.checkSelfPermission( Manifest.permission.HARDWARE_TEST) == PackageManager.PERMISSION_GRANTED; } + + // initialize the sensor list + int i = 0; + while(true) { + Sensor sensor = new Sensor(); + i = nativeGetNextSensor(mNativeInstance, sensor, i); + if (i <= 0) { + break; + } + mFullSensorsList.add(sensor); + mHandleToSensor.append(sensor.getHandle(), sensor); + } } /** @hide */ @Override protected List<Sensor> getFullSensorList() { - return sFullSensorsList; + return mFullSensorsList; } @@ -232,8 +235,8 @@ public class SystemSensorManager extends SensorManager { throw new SecurityException("Permission denial. Calling enableDataInjection without " + Manifest.permission.HARDWARE_TEST); } - synchronized (sSensorModuleLock) { - int ret = nativeEnableDataInjection(enable); + synchronized (mLock) { + int ret = nativeEnableDataInjection(mNativeInstance, enable); // The HAL does not support injection. Ignore. if (ret != 0) { Log.e(TAG, "HAL does not support data injection"); @@ -255,7 +258,7 @@ public class SystemSensorManager extends SensorManager { throw new SecurityException("Permission denial. Calling injectSensorData without " + Manifest.permission.HARDWARE_TEST); } - synchronized (sSensorModuleLock) { + synchronized (mLock) { if (!mDataInjectionMode) { Log.e(TAG, "Data injection mode not activated before calling injectSensorData"); return false; @@ -284,15 +287,17 @@ public class SystemSensorManager extends SensorManager { * SensorManager instance. */ private static abstract class BaseEventQueue { - private native long nativeInitBaseEventQueue(WeakReference<BaseEventQueue> eventQWeak, - MessageQueue msgQ, float[] scratch, String packageName, int mode); + private static native long nativeInitBaseEventQueue(long nativeManager, + WeakReference<BaseEventQueue> eventQWeak, MessageQueue msgQ, float[] scratch, + String packageName, int mode, String opPackageName); private static native int nativeEnableSensor(long eventQ, int handle, int rateUs, int maxBatchReportLatencyUs); private static native int nativeDisableSensor(long eventQ, int handle); private static native void nativeDestroySensorEventQueue(long eventQ); private static native int nativeFlushSensor(long eventQ); private static native int nativeInjectSensorData(long eventQ, int handle, - float[] values,int accuracy, long timestamp); + float[] values,int accuracy, long timestamp); + private long nSensorEventQueue; private final SparseBooleanArray mActiveSensors = new SparseBooleanArray(); protected final SparseIntArray mSensorAccuracies = new SparseIntArray(); @@ -305,8 +310,9 @@ public class SystemSensorManager extends SensorManager { protected static final int OPERATING_MODE_DATA_INJECTION = 1; BaseEventQueue(Looper looper, SystemSensorManager manager, int mode) { - nSensorEventQueue = nativeInitBaseEventQueue(new WeakReference<BaseEventQueue>(this), - looper.getQueue(), mScratch, manager.mPackageName, mode); + nSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance, + new WeakReference<>(this), looper.getQueue(), mScratch, + manager.mContext.getPackageName(), mode, manager.mContext.getOpPackageName()); mCloseGuard.open("dispose"); mManager = manager; } @@ -339,7 +345,7 @@ public class SystemSensorManager extends SensorManager { for (int i=0 ; i<mActiveSensors.size(); i++) { if (mActiveSensors.valueAt(i) == true) { int handle = mActiveSensors.keyAt(i); - Sensor sensor = sHandleToSensor.get(handle); + Sensor sensor = mManager.mHandleToSensor.get(handle); if (sensor != null) { disableSensor(sensor); mActiveSensors.put(handle, false); @@ -452,7 +458,7 @@ public class SystemSensorManager extends SensorManager { @Override protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy, long timestamp) { - final Sensor sensor = sHandleToSensor.get(handle); + final Sensor sensor = mManager.mHandleToSensor.get(handle); SensorEvent t = null; synchronized (mSensorsEvents) { t = mSensorsEvents.get(handle); @@ -481,7 +487,7 @@ public class SystemSensorManager extends SensorManager { @SuppressWarnings("unused") protected void dispatchFlushCompleteEvent(int handle) { if (mListener instanceof SensorEventListener2) { - final Sensor sensor = sHandleToSensor.get(handle); + final Sensor sensor = mManager.mHandleToSensor.get(handle); ((SensorEventListener2)mListener).onFlushCompleted(sensor); } return; @@ -519,7 +525,7 @@ public class SystemSensorManager extends SensorManager { @Override protected void dispatchSensorEvent(int handle, float[] values, int accuracy, long timestamp) { - final Sensor sensor = sHandleToSensor.get(handle); + final Sensor sensor = mManager.mHandleToSensor.get(handle); TriggerEvent t = null; synchronized (mTriggerEvents) { t = mTriggerEvents.get(handle); @@ -546,7 +552,7 @@ public class SystemSensorManager extends SensorManager { } } - static final class InjectEventQueue extends BaseEventQueue { + final class InjectEventQueue extends BaseEventQueue { public InjectEventQueue(Looper looper, SystemSensorManager manager) { super(looper, manager, OPERATING_MODE_DATA_INJECTION); } diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index e2d2f61..9327f00 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -314,7 +314,7 @@ public final class CameraManager { "Camera service is currently unavailable"); } cameraService.connectDevice(callbacks, id, - mContext.getPackageName(), USE_CALLING_UID, holder); + mContext.getOpPackageName(), USE_CALLING_UID, holder); cameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder()); } else { // Use legacy camera implementation for HAL1 devices diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 2d63e3f..d8c3361 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -2571,10 +2571,8 @@ public class ConnectivityManager { * method assumes that the caller has previously called {@link #registerNetworkCallback} to * listen for network changes. * - * @param network{@link Network} specifying which network you're interested. + * @param network {@link Network} specifying which network you're interested. * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid. - * - * @hide */ public boolean requestBandwidthUpdate(Network network) { try { diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java index 47e8e69..243ddf7 100644 --- a/core/java/android/os/AsyncTask.java +++ b/core/java/android/os/AsyncTask.java @@ -16,6 +16,9 @@ package android.os; +import android.annotation.MainThread; +import android.annotation.WorkerThread; + import java.util.ArrayDeque; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; @@ -350,6 +353,7 @@ public abstract class AsyncTask<Params, Progress, Result> { * @see #onPostExecute * @see #publishProgress */ + @WorkerThread protected abstract Result doInBackground(Params... params); /** @@ -358,6 +362,7 @@ public abstract class AsyncTask<Params, Progress, Result> { * @see #onPostExecute * @see #doInBackground */ + @MainThread protected void onPreExecute() { } @@ -374,6 +379,7 @@ public abstract class AsyncTask<Params, Progress, Result> { * @see #onCancelled(Object) */ @SuppressWarnings({"UnusedDeclaration"}) + @MainThread protected void onPostExecute(Result result) { } @@ -387,6 +393,7 @@ public abstract class AsyncTask<Params, Progress, Result> { * @see #doInBackground */ @SuppressWarnings({"UnusedDeclaration"}) + @MainThread protected void onProgressUpdate(Progress... values) { } @@ -405,6 +412,7 @@ public abstract class AsyncTask<Params, Progress, Result> { * @see #isCancelled() */ @SuppressWarnings({"UnusedParameters"}) + @MainThread protected void onCancelled(Result result) { onCancelled(); } @@ -421,6 +429,7 @@ public abstract class AsyncTask<Params, Progress, Result> { * @see #cancel(boolean) * @see #isCancelled() */ + @MainThread protected void onCancelled() { } @@ -535,6 +544,7 @@ public abstract class AsyncTask<Params, Progress, Result> { * @see #executeOnExecutor(java.util.concurrent.Executor, Object[]) * @see #execute(Runnable) */ + @MainThread public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); } @@ -572,6 +582,7 @@ public abstract class AsyncTask<Params, Progress, Result> { * * @see #execute(Object[]) */ + @MainThread public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { if (mStatus != Status.PENDING) { @@ -604,6 +615,7 @@ public abstract class AsyncTask<Params, Progress, Result> { * @see #execute(Object[]) * @see #executeOnExecutor(java.util.concurrent.Executor, Object[]) */ + @MainThread public static void execute(Runnable runnable) { sDefaultExecutor.execute(runnable); } @@ -622,6 +634,7 @@ public abstract class AsyncTask<Params, Progress, Result> { * @see #onProgressUpdate * @see #doInBackground */ + @WorkerThread protected final void publishProgress(Progress... values) { if (!isCancelled()) { getHandler().obtainMessage(MESSAGE_POST_PROGRESS, diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java index 5e9b8c1..74699fd 100644 --- a/core/java/android/os/Bundle.java +++ b/core/java/android/os/Bundle.java @@ -211,8 +211,9 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { } else if (obj instanceof Parcelable[]) { Parcelable[] array = (Parcelable[]) obj; for (int n = array.length - 1; n >= 0; n--) { - if ((array[n].describeContents() - & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) { + Parcelable p = array[n]; + if (p != null && ((p.describeContents() + & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) { fdFound = true; break; } @@ -221,7 +222,8 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { SparseArray<? extends Parcelable> array = (SparseArray<? extends Parcelable>) obj; for (int n = array.size() - 1; n >= 0; n--) { - if ((array.valueAt(n).describeContents() + Parcelable p = array.valueAt(n); + if (p != null && (p.describeContents() & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) { fdFound = true; break; diff --git a/core/java/android/os/IPermissionController.aidl b/core/java/android/os/IPermissionController.aidl index 0cc1603..5e8590a 100644 --- a/core/java/android/os/IPermissionController.aidl +++ b/core/java/android/os/IPermissionController.aidl @@ -21,4 +21,5 @@ package android.os; interface IPermissionController { boolean checkPermission(String permission, int pid, int uid); String[] getPackagesForUid(int uid); + boolean isRuntimePermission(String permission); } diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 50e7d1c..3fdabee 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -584,7 +584,7 @@ public class StorageManager { // Nickname always takes precedence when defined if (!TextUtils.isEmpty(vol.fsUuid)) { final VolumeRecord rec = findRecordByUuid(vol.fsUuid); - if (!TextUtils.isEmpty(rec.nickname)) { + if (rec != null && !TextUtils.isEmpty(rec.nickname)) { return rec.nickname; } } diff --git a/core/java/android/preference/GenericInflater.java b/core/java/android/preference/GenericInflater.java index 918933b..3319e64 100644 --- a/core/java/android/preference/GenericInflater.java +++ b/core/java/android/preference/GenericInflater.java @@ -376,6 +376,7 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent> { Class clazz = mContext.getClassLoader().loadClass( prefix != null ? (prefix + name) : name); constructor = clazz.getConstructor(mConstructorSignature); + constructor.setAccessible(true); sConstructorMap.put(name, constructor); } diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 396cf19..e07e846 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -9062,5 +9062,15 @@ public final class ContactsContract { */ public static final Uri CONTENT_URI = Uri.withAppendedPath(METADATA_AUTHORITY_URI, "metadata_sync"); + + /** + * The MIME type of {@link #CONTENT_URI} providing a directory of contact metadata + */ + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/contact_metadata"; + + /** + * The MIME type of a {@link #CONTENT_URI} subdirectory of a single contact metadata. + */ + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact_metadata"; } } diff --git a/core/java/android/service/carrier/CarrierMessagingService.java b/core/java/android/service/carrier/CarrierMessagingService.java index 0592a84..d7bf10c 100644 --- a/core/java/android/service/carrier/CarrierMessagingService.java +++ b/core/java/android/service/carrier/CarrierMessagingService.java @@ -80,6 +80,11 @@ public abstract class CarrierMessagingService extends Service { */ public static final int DOWNLOAD_STATUS_ERROR = 2; + /** + * Flag to request SMS delivery status report. + */ + public static final int SEND_FLAG_REQUEST_DELIVERY_STATUS = 1; + private final ICarrierMessagingWrapper mWrapper = new ICarrierMessagingWrapper(); /** @@ -103,12 +108,14 @@ public abstract class CarrierMessagingService extends Service { /** * Override this method to intercept text SMSs sent from the device. + * @deprecated Override {@link #onSendTextSms} below instead. * * @param text the text to send * @param subId SMS subscription ID of the SIM * @param destAddress phone number of the recipient of the message * @param callback result callback. Call with a {@link SendSmsResult}. */ + @Deprecated public void onSendTextSms( @NonNull String text, int subId, @NonNull String destAddress, @NonNull ResultCallback<SendSmsResult> callback) { @@ -120,7 +127,25 @@ public abstract class CarrierMessagingService extends Service { } /** + * Override this method to intercept text SMSs sent from the device. + * + * @param text the text to send + * @param subId SMS subscription ID of the SIM + * @param destAddress phone number of the recipient of the message + * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and + * {@link #SEND_FLAG_REQUEST_DELIVERY_STATUS}. + * @param callback result callback. Call with a {@link SendSmsResult}. + */ + public void onSendTextSms( + @NonNull String text, int subId, @NonNull String destAddress, + int sendSmsFlag, @NonNull ResultCallback<SendSmsResult> callback) { + // optional + onSendTextSms(text, subId, destAddress, callback); + } + + /** * Override this method to intercept binary SMSs sent from the device. + * @deprecated Override {@link #onSendDataSms} below instead. * * @param data the binary content * @param subId SMS subscription ID of the SIM @@ -128,6 +153,7 @@ public abstract class CarrierMessagingService extends Service { * @param destPort the destination port * @param callback result callback. Call with a {@link SendSmsResult}. */ + @Deprecated public void onSendDataSms(@NonNull byte[] data, int subId, @NonNull String destAddress, int destPort, @NonNull ResultCallback<SendSmsResult> callback) { @@ -139,13 +165,33 @@ public abstract class CarrierMessagingService extends Service { } /** + * Override this method to intercept binary SMSs sent from the device. + * + * @param data the binary content + * @param subId SMS subscription ID of the SIM + * @param destAddress phone number of the recipient of the message + * @param destPort the destination port + * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and + * {@link #SEND_FLAG_REQUEST_DELIVERY_STATUS}. + * @param callback result callback. Call with a {@link SendSmsResult}. + */ + public void onSendDataSms(@NonNull byte[] data, int subId, + @NonNull String destAddress, int destPort, int sendSmsFlag, + @NonNull ResultCallback<SendSmsResult> callback) { + // optional + onSendDataSms(data, subId, destAddress, destPort, callback); + } + + /** * Override this method to intercept long SMSs sent from the device. + * @deprecated Override {@link #onSendMultipartTextSms} below instead. * * @param parts a {@link List} of the message parts * @param subId SMS subscription ID of the SIM * @param destAddress phone number of the recipient of the message * @param callback result callback. Call with a {@link SendMultipartSmsResult}. */ + @Deprecated public void onSendMultipartTextSms(@NonNull List<String> parts, int subId, @NonNull String destAddress, @NonNull ResultCallback<SendMultipartSmsResult> callback) { @@ -158,6 +204,23 @@ public abstract class CarrierMessagingService extends Service { } /** + * Override this method to intercept long SMSs sent from the device. + * + * @param parts a {@link List} of the message parts + * @param subId SMS subscription ID of the SIM + * @param destAddress phone number of the recipient of the message + * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and + * {@link #SEND_FLAG_REQUEST_DELIVERY_STATUS}. + * @param callback result callback. Call with a {@link SendMultipartSmsResult}. + */ + public void onSendMultipartTextSms(@NonNull List<String> parts, + int subId, @NonNull String destAddress, int sendSmsFlag, + @NonNull ResultCallback<SendMultipartSmsResult> callback) { + // optional + onSendMultipartTextSms(parts, subId, destAddress, callback); + } + + /** * Override this method to intercept MMSs sent from the device. * * @param pduUri the content provider URI of the PDU to send @@ -355,8 +418,9 @@ public abstract class CarrierMessagingService extends Service { @Override public void sendTextSms(String text, int subId, String destAddress, - final ICarrierMessagingCallback callback) { - onSendTextSms(text, subId, destAddress, new ResultCallback<SendSmsResult>() { + int sendSmsFlag, final ICarrierMessagingCallback callback) { + onSendTextSms(text, subId, destAddress, sendSmsFlag, + new ResultCallback<SendSmsResult>() { @Override public void onReceiveResult(final SendSmsResult result) throws RemoteException { callback.onSendSmsComplete(result.getSendStatus(), result.getMessageRef()); @@ -366,8 +430,9 @@ public abstract class CarrierMessagingService extends Service { @Override public void sendDataSms(byte[] data, int subId, String destAddress, int destPort, - final ICarrierMessagingCallback callback) { - onSendDataSms(data, subId, destAddress, destPort, new ResultCallback<SendSmsResult>() { + int sendSmsFlag, final ICarrierMessagingCallback callback) { + onSendDataSms(data, subId, destAddress, destPort, sendSmsFlag, + new ResultCallback<SendSmsResult>() { @Override public void onReceiveResult(final SendSmsResult result) throws RemoteException { callback.onSendSmsComplete(result.getSendStatus(), result.getMessageRef()); @@ -377,8 +442,8 @@ public abstract class CarrierMessagingService extends Service { @Override public void sendMultipartTextSms(List<String> parts, int subId, String destAddress, - final ICarrierMessagingCallback callback) { - onSendMultipartTextSms(parts, subId, destAddress, + int sendSmsFlag, final ICarrierMessagingCallback callback) { + onSendMultipartTextSms(parts, subId, destAddress, sendSmsFlag, new ResultCallback<SendMultipartSmsResult>() { @Override public void onReceiveResult(final SendMultipartSmsResult result) diff --git a/core/java/android/service/carrier/ICarrierMessagingService.aidl b/core/java/android/service/carrier/ICarrierMessagingService.aidl index 40a9047..2d96c3d 100644 --- a/core/java/android/service/carrier/ICarrierMessagingService.aidl +++ b/core/java/android/service/carrier/ICarrierMessagingService.aidl @@ -48,9 +48,10 @@ oneway interface ICarrierMessagingService { * @param text the text to send * @param subId SMS subscription ID of the SIM * @param destAddress phone number of the recipient of the message + * @param sendSmsFlag flag for sending SMS * @param callback the callback to notify upon completion */ - void sendTextSms(String text, int subId, String destAddress, + void sendTextSms(String text, int subId, String destAddress, int sendSmsFlag, in ICarrierMessagingCallback callback); /** @@ -62,10 +63,11 @@ oneway interface ICarrierMessagingService { * @param subId SMS subscription ID of the SIM * @param destAddress phone number of the recipient of the message * @param destPort port number of the recipient of the message + * @param sendSmsFlag flag for sending SMS * @param callback the callback to notify upon completion */ void sendDataSms(in byte[] data, int subId, String destAddress, int destPort, - in ICarrierMessagingCallback callback); + int sendSmsFlag, in ICarrierMessagingCallback callback); /** * Request sending a new multi-part text SMS from the device. @@ -75,10 +77,11 @@ oneway interface ICarrierMessagingService { * @param parts the parts of the multi-part text SMS to send * @param subId SMS subscription ID of the SIM * @param destAddress phone number of the recipient of the message + * @param sendSmsFlag flag for sending SMS * @param callback the callback to notify upon completion */ void sendMultipartTextSms(in List<String> parts, int subId, String destAddress, - in ICarrierMessagingCallback callback); + int sendSmsFlag, in ICarrierMessagingCallback callback); /** * Request sending a new MMS PDU from the device. diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index f09f4d2..968cd72 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -692,7 +692,6 @@ public class ZenModeConfig implements Parcelable { .authority(SYSTEM_AUTHORITY) .appendPath(EVENT_PATH) .appendQueryParameter("calendar", Long.toString(event.calendar)) - .appendQueryParameter("attendance", Integer.toString(event.attendance)) .appendQueryParameter("reply", Integer.toString(event.reply)) .build(); } @@ -710,22 +709,16 @@ public class ZenModeConfig implements Parcelable { if (!isEvent) return null; final EventInfo rt = new EventInfo(); rt.calendar = tryParseLong(conditionId.getQueryParameter("calendar"), 0L); - rt.attendance = tryParseInt(conditionId.getQueryParameter("attendance"), 0); rt.reply = tryParseInt(conditionId.getQueryParameter("reply"), 0); return rt; } public static class EventInfo { - public static final int ATTENDANCE_REQUIRED_OR_OPTIONAL = 0; - public static final int ATTENDANCE_REQUIRED = 1; - public static final int ATTENDANCE_OPTIONAL = 2; - - public static final int REPLY_ANY = 0; - public static final int REPLY_ANY_EXCEPT_NO = 1; + public static final int REPLY_ANY_EXCEPT_NO = 0; + public static final int REPLY_YES_OR_MAYBE = 1; public static final int REPLY_YES = 2; public long calendar; // CalendarContract.Calendars._ID, or 0 for any - public int attendance; public int reply; @Override @@ -738,14 +731,12 @@ public class ZenModeConfig implements Parcelable { if (!(o instanceof EventInfo)) return false; final EventInfo other = (EventInfo) o; return calendar == other.calendar - && attendance == other.attendance && reply == other.reply; } public EventInfo copy() { final EventInfo rt = new EventInfo(); rt.calendar = calendar; - rt.attendance = attendance; rt.reply = reply; return rt; } diff --git a/core/java/android/service/voice/VoiceInteractionServiceInfo.java b/core/java/android/service/voice/VoiceInteractionServiceInfo.java index 4bc97c9..997d586 100644 --- a/core/java/android/service/voice/VoiceInteractionServiceInfo.java +++ b/core/java/android/service/voice/VoiceInteractionServiceInfo.java @@ -43,7 +43,7 @@ public class VoiceInteractionServiceInfo { private String mSessionService; private String mRecognitionService; private String mSettingsActivity; - private boolean mSupportsAssistGesture; + private boolean mSupportsAssist; public VoiceInteractionServiceInfo(PackageManager pm, ComponentName comp) throws PackageManager.NameNotFoundException { @@ -95,8 +95,8 @@ public class VoiceInteractionServiceInfo { com.android.internal.R.styleable.VoiceInteractionService_recognitionService); mSettingsActivity = array.getString( com.android.internal.R.styleable.VoiceInteractionService_settingsActivity); - mSupportsAssistGesture = array.getBoolean( - com.android.internal.R.styleable.VoiceInteractionService_supportsAssistGesture, + mSupportsAssist = array.getBoolean( + com.android.internal.R.styleable.VoiceInteractionService_supportsAssist, false); array.recycle(); if (mSessionService == null) { @@ -145,7 +145,7 @@ public class VoiceInteractionServiceInfo { return mSettingsActivity; } - public boolean getSupportsAssistGesture() { - return mSupportsAssistGesture; + public boolean getSupportsAssist() { + return mSupportsAssist; } } diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java index 239b386..fc65f63 100644 --- a/core/java/android/text/DynamicLayout.java +++ b/core/java/android/text/DynamicLayout.java @@ -283,15 +283,14 @@ public class DynamicLayout extends Layout if (reflowed == null) { reflowed = new StaticLayout(null); - b = StaticLayout.Builder.obtain(text, where, where + after, getWidth()); + b = StaticLayout.Builder.obtain(text, where, where + after, getPaint(), getWidth()); } b.setText(text, where, where + after) .setPaint(getPaint()) .setWidth(getWidth()) .setTextDir(getTextDirectionHeuristic()) - .setSpacingMult(getSpacingMultiplier()) - .setSpacingAdd(getSpacingAdd()) + .setLineSpacing(getSpacingAdd(), getSpacingMultiplier()) .setEllipsizedWidth(mEllipsizedWidth) .setEllipsize(mEllipsizeAt) .setBreakStrategy(mBreakStrategy); diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index 67794b1..451abea 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -16,6 +16,7 @@ package android.text; +import android.annotation.Nullable; import android.graphics.Paint; import android.text.style.LeadingMarginSpan; import android.text.style.LeadingMarginSpan.LeadingMarginSpan2; @@ -46,18 +47,31 @@ public class StaticLayout extends Layout { static final String TAG = "StaticLayout"; /** - * Builder for static layouts. It would be better if this were a public - * API (as it would offer much greater flexibility for adding new options) - * but for the time being it's just internal. - * - * @hide + * Builder for static layouts. The builder is a newer pattern for constructing + * StaticLayout objects and should be preferred over the constructors, + * particularly to access newer features. To build a static layout, first + * call {@link #obtain} with the required arguments (text, paint, and width), + * then call setters for optional parameters, and finally {@link #build} + * to build the StaticLayout object. Parameters not explicitly set will get + * default values. */ public final static class Builder { private Builder() { mNativePtr = nNewBuilder(); } - public static Builder obtain(CharSequence source, int start, int end, int width) { + /** + * Obtain a builder for constructing StaticLayout objects + * + * @param source The text to be laid out, optionally with spans + * @param start The index of the start of the text + * @param end The index + 1 of the end of the text + * @param paint The base paint used for layout + * @param width The width in pixels + * @return a builder object used for constructing the StaticLayout + */ + public static Builder obtain(CharSequence source, int start, int end, TextPaint paint, + int width) { Builder b = sPool.acquire(); if (b == null) { b = new Builder(); @@ -67,6 +81,7 @@ public class StaticLayout extends Layout { b.mText = source; b.mStart = start; b.mEnd = end; + b.mPaint = paint; b.mWidth = width; b.mAlignment = Alignment.ALIGN_NORMAL; b.mTextDir = TextDirectionHeuristics.FIRSTSTRONG_LTR; @@ -98,6 +113,18 @@ public class StaticLayout extends Layout { return setText(source, 0, source.length()); } + /** + * Set the text. Only useful when re-using the builder, which is done for + * the internal implementation of {@link DynamicLayout} but not as part + * of normal {@link StaticLayout} usage. + * + * @param source The text to be laid out, optionally with spans + * @param start The index of the start of the text + * @param end The index + 1 of the end of the text + * @return this builder, useful for chaining + * + * @hide + */ public Builder setText(CharSequence source, int start, int end) { mText = source; mStart = start; @@ -105,11 +132,27 @@ public class StaticLayout extends Layout { return this; } + /** + * Set the paint. Internal for reuse cases only. + * + * @param paint The base paint used for layout + * @return this builder, useful for chaining + * + * @hide + */ public Builder setPaint(TextPaint paint) { mPaint = paint; return this; } + /** + * Set the width. Internal for reuse cases only. + * + * @param width The width in pixels + * @return this builder, useful for chaining + * + * @hide + */ public Builder setWidth(int width) { mWidth = width; if (mEllipsize == null) { @@ -118,53 +161,126 @@ public class StaticLayout extends Layout { return this; } + /** + * Set the alignment. The default is {@link Layout.Alignment#ALIGN_NORMAL}. + * + * @param alignment Alignment for the resulting {@link StaticLayout} + * @return this builder, useful for chaining + */ public Builder setAlignment(Alignment alignment) { mAlignment = alignment; return this; } + /** + * Set the text direction heuristic. The text direction heuristic is used to + * resolve text direction based per-paragraph based on the input text. The default is + * {@link TextDirectionHeuristics#FIRSTSTRONG_LTR}. + * + * @param textDir text direction heuristic for resolving BiDi behavior. + * @return this builder, useful for chaining + */ public Builder setTextDir(TextDirectionHeuristic textDir) { mTextDir = textDir; return this; } - // TODO: combine the following, as they're almost always set together? - public Builder setSpacingMult(float spacingMult) { - mSpacingMult = spacingMult; - return this; - } - - public Builder setSpacingAdd(float spacingAdd) { + /** + * Set line spacing parameters. The default is 0.0 for {@code spacingAdd} + * and 1.0 for {@code spacingMult}. + * + * @param spacingAdd line spacing add + * @param spacingMult line spacing multiplier + * @return this builder, useful for chaining + * @see android.widget.TextView#setLineSpacing + */ + public Builder setLineSpacing(float spacingAdd, float spacingMult) { mSpacingAdd = spacingAdd; + mSpacingMult = spacingMult; return this; } + /** + * Set whether to include extra space beyond font ascent and descent (which is + * needed to avoid clipping in some languages, such as Arabic and Kannada). The + * default is {@code true}. + * + * @param includePad whether to include padding + * @return this builder, useful for chaining + * @see android.widget.TextView#setIncludeFontPadding + */ public Builder setIncludePad(boolean includePad) { mIncludePad = includePad; return this; } - // TODO: combine the following? + /** + * Set the width as used for ellipsizing purposes, if it differs from the + * normal layout width. The default is the {@code width} + * passed to {@link #obtain}. + * + * @param ellipsizedWidth width used for ellipsizing, in pixels + * @return this builder, useful for chaining + * @see android.widget.TextView#setEllipsize + */ public Builder setEllipsizedWidth(int ellipsizedWidth) { mEllipsizedWidth = ellipsizedWidth; return this; } - public Builder setEllipsize(TextUtils.TruncateAt ellipsize) { + /** + * Set ellipsizing on the layout. Causes words that are longer than the view + * is wide, or exceeding the number of lines (see #setMaxLines) in the case + * of {@link android.text.TextUtils.TruncateAt#END} or + * {@link android.text.TextUtils.TruncateAt#MARQUEE}, to be ellipsized instead + * of broken. The default is + * {@code null}, indicating no ellipsis is to be applied. + * + * @param ellipsize type of ellipsis behavior + * @return this builder, useful for chaining + * @see android.widget.TextView#setEllipsize + */ + public Builder setEllipsize(@Nullable TextUtils.TruncateAt ellipsize) { mEllipsize = ellipsize; return this; } + /** + * Set maximum number of lines. This is particularly useful in the case of + * ellipsizing, where it changes the layout of the last line. The default is + * unlimited. + * + * @param maxLines maximum number of lines in the layout + * @return this builder, useful for chaining + * @see android.widget.TextView#setMaxLines + */ public Builder setMaxLines(int maxLines) { mMaxLines = maxLines; return this; } + /** + * Set break strategy, useful for selecting high quality or balanced paragraph + * layout options. The default is {@link Layout#BREAK_STRATEGY_SIMPLE}. + * + * @param breakStrategy break strategy for paragraph layout + * @return this builder, useful for chaining + * @see android.widget.TextView#setBreakStrategy + */ public Builder setBreakStrategy(@BreakStrategy int breakStrategy) { mBreakStrategy = breakStrategy; return this; } + /** + * Set indents. Arguments are arrays holding an indent amount, one per line, measured in + * pixels. For lines past the last element in the array, the last element repeats. + * + * @param leftIndents array of indent values for left margin, in pixels + * @param rightIndents array of indent values for right margin, in pixels + * @return this builder, useful for chaining + * @see android.widget.TextView#setIndents + */ public Builder setIndents(int[] leftIndents, int[] rightIndents) { int leftLen = leftIndents == null ? 0 : leftIndents.length; int rightLen = rightIndents == null ? 0 : rightIndents.length; @@ -218,6 +334,15 @@ public class StaticLayout extends Layout { nAddReplacementRun(mNativePtr, start, end, width); } + /** + * Build the {@link StaticLayout} after options have been set. + * + * <p>Note: the builder object must not be reused in any way after calling this + * method. Setting parameters after calling this method, or calling it a second + * time on the same builder object, will likely lead to unexpected results. + * + * @return the newly constructed {@link StaticLayout} object + */ public StaticLayout build() { StaticLayout result = new StaticLayout(this); Builder.recycle(this); @@ -327,12 +452,10 @@ public class StaticLayout extends Layout { : new Ellipsizer(source), paint, outerwidth, align, textDir, spacingmult, spacingadd); - Builder b = Builder.obtain(source, bufstart, bufend, outerwidth) - .setPaint(paint) + Builder b = Builder.obtain(source, bufstart, bufend, paint, outerwidth) .setAlignment(align) .setTextDir(textDir) - .setSpacingMult(spacingmult) - .setSpacingAdd(spacingadd) + .setLineSpacing(spacingadd, spacingmult) .setIncludePad(includepad) .setEllipsizedWidth(ellipsizedWidth) .setEllipsize(ellipsize) diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java index c942042..ebc2aac 100644 --- a/core/java/android/transition/Transition.java +++ b/core/java/android/transition/Transition.java @@ -792,6 +792,9 @@ public abstract class Transition implements Cloneable { * views are ignored and only the ids are used). */ boolean isValidTarget(View target) { + if (target == null) { + return false; + } int targetId = target.getId(); if (mTargetIdExcludes != null && mTargetIdExcludes.contains(targetId)) { return false; diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java index ca37d49..cbf76bc 100644 --- a/core/java/android/transition/TransitionInflater.java +++ b/core/java/android/transition/TransitionInflater.java @@ -211,10 +211,10 @@ public class TransitionInflater { .asSubclass(expectedType); if (c != null) { constructor = c.getConstructor(sConstructorSignature); + constructor.setAccessible(true); sConstructors.put(className, constructor); } } - constructor.setAccessible(true); return constructor.newInstance(mContext, attrs); } } catch (InstantiationException e) { diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java index cd68fd1..ed7fd86 100644 --- a/core/java/android/transition/Visibility.java +++ b/core/java/android/transition/Visibility.java @@ -19,12 +19,17 @@ package android.transition; import com.android.internal.R; import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.animation.Animator.AnimatorPauseListener; import android.animation.AnimatorListenerAdapter; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; +import android.view.animation.Animation; +import android.view.animation.Animation.AnimationListener; + /** * This transition tracks changes to the visibility of target views in the * start and end scenes. Visibility is determined not just by the @@ -286,6 +291,12 @@ public abstract class Visibility extends Transition { return null; } } + final boolean isForcedVisibility = mForcedStartVisibility != -1 || + mForcedEndVisibility != -1; + if (isForcedVisibility) { + // Make sure that we reverse the effect of onDisappear's setTransitionAlpha(0) + endValues.view.setTransitionAlpha(1); + } return onAppear(sceneRoot, endValues.view, startValues, endValues); } @@ -418,9 +429,9 @@ public abstract class Visibility extends Transition { sceneRoot.getOverlay().remove(overlayView); } else { final View finalOverlayView = overlayView; - animator.addListener(new AnimatorListenerAdapter() { + addListener(new TransitionListenerAdapter() { @Override - public void onAnimationEnd(Animator animation) { + public void onTransitionEnd(Transition transition) { finalSceneRoot.getOverlay().remove(finalOverlayView); } }); @@ -438,40 +449,10 @@ public abstract class Visibility extends Transition { } Animator animator = onDisappear(sceneRoot, viewToKeep, startValues, endValues); if (animator != null) { - final View finalViewToKeep = viewToKeep; - animator.addListener(new AnimatorListenerAdapter() { - boolean mCanceled = false; - - @Override - public void onAnimationPause(Animator animation) { - if (!mCanceled && !isForcedVisibility) { - finalViewToKeep.setVisibility(finalVisibility); - } - } - - @Override - public void onAnimationResume(Animator animation) { - if (!mCanceled && !isForcedVisibility) { - finalViewToKeep.setVisibility(View.VISIBLE); - } - } - - @Override - public void onAnimationCancel(Animator animation) { - mCanceled = true; - } - - @Override - public void onAnimationEnd(Animator animation) { - if (!mCanceled) { - if (isForcedVisibility) { - finalViewToKeep.setTransitionAlpha(0); - } else { - finalViewToKeep.setVisibility(finalVisibility); - } - } - } - }); + DisappearListener disappearListener = new DisappearListener(viewToKeep, + finalVisibility, isForcedVisibility); + animator.addListener(disappearListener); + addListener(disappearListener); } else if (!isForcedVisibility) { viewToKeep.setVisibility(originalVisibility); } @@ -517,4 +498,68 @@ public abstract class Visibility extends Transition { TransitionValues endValues) { return null; } + + private static class DisappearListener + extends TransitionListenerAdapter implements AnimatorListener, AnimatorPauseListener { + private final boolean mIsForcedVisibility; + private final View mView; + private final int mFinalVisibility; + + boolean mCanceled = false; + + public DisappearListener(View view, int finalVisibility, boolean isForcedVisibility) { + this.mView = view; + this.mIsForcedVisibility = isForcedVisibility; + this.mFinalVisibility = finalVisibility; + } + + @Override + public void onAnimationPause(Animator animation) { + if (!mCanceled && !mIsForcedVisibility) { + mView.setVisibility(mFinalVisibility); + } + } + + @Override + public void onAnimationResume(Animator animation) { + if (!mCanceled && !mIsForcedVisibility) { + mView.setVisibility(View.VISIBLE); + } + } + + @Override + public void onAnimationCancel(Animator animation) { + mCanceled = true; + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationStart(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + hideViewWhenNotCanceled(); + } + + @Override + public void onTransitionEnd(Transition transition) { + hideViewWhenNotCanceled(); + } + + private void hideViewWhenNotCanceled() { + if (!mCanceled) { + if (mIsForcedVisibility) { + mView.setTransitionAlpha(0); + } else { + mView.setVisibility(mFinalVisibility); + } + } + } + } } diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java index 46dd857..48167c8 100644 --- a/core/java/android/view/DisplayListCanvas.java +++ b/core/java/android/view/DisplayListCanvas.java @@ -271,7 +271,7 @@ public class DisplayListCanvas extends Canvas { Bitmap bitmap = patch.getBitmap(); throwIfCannotDraw(bitmap); final long nativePaint = paint == null ? 0 : paint.getNativeInstance(); - nDrawPatch(mNativeCanvasWrapper, bitmap.getSkBitmap(), patch.mNativeChunk, + nDrawPatch(mNativeCanvasWrapper, bitmap, patch.mNativeChunk, dst.left, dst.top, dst.right, dst.bottom, nativePaint); } @@ -281,11 +281,11 @@ public class DisplayListCanvas extends Canvas { Bitmap bitmap = patch.getBitmap(); throwIfCannotDraw(bitmap); final long nativePaint = paint == null ? 0 : paint.getNativeInstance(); - nDrawPatch(mNativeCanvasWrapper, bitmap.getSkBitmap(), patch.mNativeChunk, + nDrawPatch(mNativeCanvasWrapper, bitmap, patch.mNativeChunk, dst.left, dst.top, dst.right, dst.bottom, nativePaint); } - private static native void nDrawPatch(long renderer, long bitmap, long chunk, + private static native void nDrawPatch(long renderer, Bitmap bitmap, long chunk, float left, float top, float right, float bottom, long paint); public void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy, diff --git a/core/java/android/view/GhostView.java b/core/java/android/view/GhostView.java index d58e7c0..bc38e1a 100644 --- a/core/java/android/view/GhostView.java +++ b/core/java/android/view/GhostView.java @@ -41,7 +41,7 @@ public class GhostView extends View { final ViewGroup parent = (ViewGroup) mView.getParent(); setGhostedVisibility(View.INVISIBLE); parent.mRecreateDisplayList = true; - parent.getDisplayList(); + parent.updateDisplayListIfDirty(); } @Override @@ -49,7 +49,7 @@ public class GhostView extends View { if (canvas instanceof DisplayListCanvas) { DisplayListCanvas dlCanvas = (DisplayListCanvas) canvas; mView.mRecreateDisplayList = true; - RenderNode renderNode = mView.getDisplayList(); + RenderNode renderNode = mView.updateDisplayListIfDirty(); if (renderNode.isValid()) { dlCanvas.insertReorderBarrier(); // enable shadow for this rendernode dlCanvas.drawRenderNode(renderNode); @@ -84,7 +84,7 @@ public class GhostView extends View { final ViewGroup parent = (ViewGroup) mView.getParent(); if (parent != null) { parent.mRecreateDisplayList = true; - parent.getDisplayList(); + parent.updateDisplayListIfDirty(); } } } diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index 1503728..37312d0 100644 --- a/core/java/android/view/LayoutInflater.java +++ b/core/java/android/view/LayoutInflater.java @@ -590,6 +590,7 @@ public abstract class LayoutInflater { } } constructor = clazz.getConstructor(mConstructorSignature); + constructor.setAccessible(true); sConstructorMap.put(name, constructor); } else { // If we have a filter, apply it to cached constructor @@ -615,7 +616,6 @@ public abstract class LayoutInflater { Object[] args = mConstructorArgs; args[1] = attrs; - constructor.setAccessible(true); final View view = constructor.newInstance(args); if (view instanceof ViewStub) { // Use the same context when inflating ViewStub later. diff --git a/core/java/android/view/MenuInflater.java b/core/java/android/view/MenuInflater.java index b49a59e..dc8cadf 100644 --- a/core/java/android/view/MenuInflater.java +++ b/core/java/android/view/MenuInflater.java @@ -544,6 +544,7 @@ public class MenuInflater { try { Class<?> clazz = mContext.getClassLoader().loadClass(className); Constructor<?> constructor = clazz.getConstructor(constructorSignature); + constructor.setAccessible(true); return (T) constructor.newInstance(arguments); } catch (Exception e) { Log.w(LOG_TAG, "Cannot instantiate class: " + className, e); diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 5017a38..91e6d68 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -269,7 +269,7 @@ public class ThreadedRenderer extends HardwareRenderer { view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED) == View.PFLAG_INVALIDATED; view.mPrivateFlags &= ~View.PFLAG_INVALIDATED; - view.getDisplayList(); + view.updateDisplayListIfDirty(); view.mRecreateDisplayList = false; } @@ -285,7 +285,7 @@ public class ThreadedRenderer extends HardwareRenderer { callbacks.onHardwarePreDraw(canvas); canvas.insertReorderBarrier(); - canvas.drawRenderNode(view.getDisplayList()); + canvas.drawRenderNode(view.updateDisplayListIfDirty()); canvas.insertInorderBarrier(); callbacks.onHardwarePostDraw(canvas); @@ -460,8 +460,6 @@ public class ThreadedRenderer extends HardwareRenderer { if (buffer != null) { long[] map = atlas.getMap(); if (map != null) { - // TODO Remove after fixing b/15425820 - validateMap(context, map); nSetAtlas(renderProxy, buffer, map); } // If IAssetAtlas is not the same class as the IBinder @@ -476,32 +474,6 @@ public class ThreadedRenderer extends HardwareRenderer { Log.w(LOG_TAG, "Could not acquire atlas", e); } } - - private static void validateMap(Context context, long[] map) { - Log.d("Atlas", "Validating map..."); - HashSet<Long> preloadedPointers = new HashSet<Long>(); - - // We only care about drawables that hold bitmaps - final Resources resources = context.getResources(); - final LongSparseArray<Drawable.ConstantState> drawables = resources.getPreloadedDrawables(); - - final int count = drawables.size(); - ArrayList<Bitmap> tmpList = new ArrayList<Bitmap>(); - for (int i = 0; i < count; i++) { - drawables.valueAt(i).addAtlasableBitmaps(tmpList); - for (int j = 0; j < tmpList.size(); j++) { - preloadedPointers.add(tmpList.get(j).getSkBitmap()); - } - tmpList.clear(); - } - - for (int i = 0; i < map.length; i += 4) { - if (!preloadedPointers.contains(map[i])) { - Log.w("Atlas", String.format("Pointer 0x%X, not in getPreloadedDrawables?", map[i])); - map[i] = 0; - } - } - } } static native void setupShadersDiskCache(String cacheFile); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 81ad5ad..75dc0a2 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -28,6 +28,7 @@ import android.annotation.LayoutRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; +import android.annotation.UiThread; import android.content.ClipData; import android.content.Context; import android.content.ContextWrapper; @@ -700,6 +701,7 @@ import java.util.concurrent.atomic.AtomicInteger; * * @see android.view.ViewGroup */ +@UiThread public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource { private static final boolean DBG = false; @@ -8595,7 +8597,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public boolean performAccessibilityActionInternal(int action, Bundle arguments) { if (isNestedScrollingEnabled() && (action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD - || action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)) { + || action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD + || action == R.id.accessibilityActionScrollUp + || action == R.id.accessibilityActionScrollLeft + || action == R.id.accessibilityActionScrollDown + || action == R.id.accessibilityActionScrollRight)) { if (dispatchNestedPrePerformAccessibilityAction(action, arguments)) { return true; } @@ -11091,25 +11097,34 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * <p>Sets the opacity of the view. This is a value from 0 to 1, where 0 means the view is - * completely transparent and 1 means the view is completely opaque.</p> + * Sets the opacity of the view to a value from 0 to 1, where 0 means the view is + * completely transparent and 1 means the view is completely opaque. * - * <p> Note that setting alpha to a translucent value (0 < alpha < 1) can have significant - * performance implications, especially for large views. It is best to use the alpha property - * sparingly and transiently, as in the case of fading animations.</p> + * <p class="note"><strong>Note:</strong> setting alpha to a translucent value (0 < alpha < 1) + * can have significant performance implications, especially for large views. It is best to use + * the alpha property sparingly and transiently, as in the case of fading animations.</p> * * <p>For a view with a frequently changing alpha, such as during a fading animation, it is * strongly recommended for performance reasons to either override - * {@link #hasOverlappingRendering()} to return false if appropriate, or setting a - * {@link #setLayerType(int, android.graphics.Paint) layer type} on the view.</p> + * {@link #hasOverlappingRendering()} to return <code>false</code> if appropriate, or setting a + * {@link #setLayerType(int, android.graphics.Paint) layer type} on the view for the duration + * of the animation. On versions {@link android.os.Build.VERSION_CODES#MNC} and below, + * the default path for rendering an unlayered View with alpha could add multiple milliseconds + * of rendering cost, even for simple or small views. Starting with + * {@link android.os.Build.VERSION_CODES#MNC}, {@link #LAYER_TYPE_HARDWARE} is automatically + * applied to the view at the rendering level.</p> * * <p>If this view overrides {@link #onSetAlpha(int)} to return true, then this view is * responsible for applying the opacity itself.</p> * - * <p>Note that if the view is backed by a - * {@link #setLayerType(int, android.graphics.Paint) layer} and is associated with a - * {@link #setLayerPaint(android.graphics.Paint) layer paint}, setting an alpha value less than - * 1.0 will supersede the alpha of the layer paint.</p> + * <p>On versions {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and below, note that if + * the view is backed by a {@link #setLayerType(int, android.graphics.Paint) layer} and is + * associated with a {@link #setLayerPaint(android.graphics.Paint) layer paint}, setting an + * alpha value less than 1.0 will supersede the alpha of the layer paint.</p> + * + * <p>Starting with {@link android.os.Build.VERSION_CODES#MNC}, setting a translucent alpha + * value will clip a View to its bounds, unless the View returns <code>false</code> from + * {@link #hasOverlappingRendering}.</p> * * @param alpha The opacity of the view. * @@ -14702,11 +14717,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return !(mAttachInfo == null || mAttachInfo.mHardwareRenderer == null); } - private void updateDisplayListIfDirty() { + /** + * Gets the RenderNode for the view, and updates its DisplayList (if needed and supported) + * @hide + */ + @NonNull + public RenderNode updateDisplayListIfDirty() { final RenderNode renderNode = mRenderNode; if (!canHaveDisplayList()) { // can't populate RenderNode, don't try - return; + return renderNode; } if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 @@ -14720,7 +14740,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mPrivateFlags &= ~PFLAG_DIRTY_MASK; dispatchGetDisplayList(); - return; // no work needed + return renderNode; // no work needed } // If we got here, we're recreating it. Mark it as such to ensure that @@ -14769,19 +14789,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID; mPrivateFlags &= ~PFLAG_DIRTY_MASK; } - } - - /** - * Returns a RenderNode with View draw content recorded, which can be - * used to draw this view again without executing its draw method. - * - * @return A RenderNode ready to replay, or null if caching is not enabled. - * - * @hide - */ - public RenderNode getDisplayList() { - updateDisplayListIfDirty(); - return mRenderNode; + return renderNode; } private void resetDisplayList() { @@ -15543,7 +15551,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (drawingWithRenderNode) { // Delay getting the display list until animation-driven alpha values are // set up and possibly passed on to the view - renderNode = getDisplayList(); + renderNode = updateDisplayListIfDirty(); if (!renderNode.isValid()) { // Uncommon, but possible. If a view is removed from the hierarchy during the call // to getDisplayList(), the display list will be marked invalid and we should not diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index d0d4201..f240fd6 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -18,6 +18,7 @@ package android.view; import android.animation.LayoutTransition; import android.annotation.IdRes; +import android.annotation.UiThread; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; @@ -105,6 +106,7 @@ import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; * @attr ref android.R.styleable#ViewGroup_splitMotionEvents * @attr ref android.R.styleable#ViewGroup_layoutMode */ +@UiThread public abstract class ViewGroup extends View implements ViewParent, ViewManager { private static final String TAG = "ViewGroup"; @@ -3524,10 +3526,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } private void recreateChildDisplayList(View child) { - child.mRecreateDisplayList = (child.mPrivateFlags & PFLAG_INVALIDATED) - == PFLAG_INVALIDATED; + child.mRecreateDisplayList = (child.mPrivateFlags & PFLAG_INVALIDATED) != 0; child.mPrivateFlags &= ~PFLAG_INVALIDATED; - child.getDisplayList(); + child.updateDisplayListIfDirty(); child.mRecreateDisplayList = false; } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 4158340..fda6e63 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2322,10 +2322,8 @@ public final class ViewRootImpl implements ViewParent, * @hide */ void outputDisplayList(View view) { - RenderNode renderNode = view.getDisplayList(); - if (renderNode != null) { - renderNode.output(); - } + RenderNode renderNode = view.updateDisplayListIfDirty(); + renderNode.output(); } /** diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index bf4b7ae..c785149 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -3500,6 +3500,30 @@ public class AccessibilityNodeInfo implements Parcelable { new AccessibilityAction(R.id.accessibilityActionScrollToPosition, null); /** + * Action to scroll the node content up. + */ + public static final AccessibilityAction ACTION_SCROLL_UP = + new AccessibilityAction(R.id.accessibilityActionScrollUp, null); + + /** + * Action to scroll the node content left. + */ + public static final AccessibilityAction ACTION_SCROLL_LEFT = + new AccessibilityAction(R.id.accessibilityActionScrollLeft, null); + + /** + * Action to scroll the node content down. + */ + public static final AccessibilityAction ACTION_SCROLL_DOWN = + new AccessibilityAction(R.id.accessibilityActionScrollDown, null); + + /** + * Action to scroll the node content right. + */ + public static final AccessibilityAction ACTION_SCROLL_RIGHT = + new AccessibilityAction(R.id.accessibilityActionScrollRight, null); + + /** * Action that stylus button presses the node. */ public static final AccessibilityAction ACTION_STYLUS_BUTTON_PRESS = @@ -3531,6 +3555,10 @@ public class AccessibilityNodeInfo implements Parcelable { sStandardActions.add(ACTION_SET_TEXT); sStandardActions.add(ACTION_SHOW_ON_SCREEN); sStandardActions.add(ACTION_SCROLL_TO_POSITION); + sStandardActions.add(ACTION_SCROLL_UP); + sStandardActions.add(ACTION_SCROLL_LEFT); + sStandardActions.add(ACTION_SCROLL_DOWN); + sStandardActions.add(ACTION_SCROLL_RIGHT); sStandardActions.add(ACTION_STYLUS_BUTTON_PRESS); } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 1df43d0..c57a53a 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -1506,10 +1506,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (isEnabled()) { if (canScrollUp()) { info.addAction(AccessibilityAction.ACTION_SCROLL_BACKWARD); + info.addAction(AccessibilityAction.ACTION_SCROLL_UP); info.setScrollable(true); } if (canScrollDown()) { info.addAction(AccessibilityAction.ACTION_SCROLL_FORWARD); + info.addAction(AccessibilityAction.ACTION_SCROLL_DOWN); info.setScrollable(true); } } @@ -1537,14 +1539,16 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te return true; } switch (action) { - case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { + case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: + case R.id.accessibilityActionScrollDown: { if (isEnabled() && getLastVisiblePosition() < getCount() - 1) { final int viewportHeight = getHeight() - mListPadding.top - mListPadding.bottom; smoothScrollBy(viewportHeight, PositionScroller.SCROLL_DURATION); return true; } } return false; - case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: { + case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: + case R.id.accessibilityActionScrollUp: { if (isEnabled() && mFirstPosition > 0) { final int viewportHeight = getHeight() - mListPadding.top - mListPadding.bottom; smoothScrollBy(-viewportHeight, PositionScroller.SCROLL_DURATION); diff --git a/core/java/android/widget/CursorAdapter.java b/core/java/android/widget/CursorAdapter.java index 30c74c0..d8ce60c 100644 --- a/core/java/android/widget/CursorAdapter.java +++ b/core/java/android/widget/CursorAdapter.java @@ -16,6 +16,7 @@ package android.widget; +import android.annotation.WorkerThread; import android.content.Context; import android.content.res.Resources; import android.database.ContentObserver; @@ -425,6 +426,7 @@ public abstract class CursorAdapter extends BaseAdapter implements Filterable, * @see #getFilterQueryProvider() * @see #setFilterQueryProvider(android.widget.FilterQueryProvider) */ + @WorkerThread public Cursor runQueryOnBackgroundThread(CharSequence constraint) { if (mFilterQueryProvider != null) { return mFilterQueryProvider.runQuery(constraint); diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 169aef9..8d35b83 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -318,6 +318,7 @@ public class Editor { } getPositionListener().addSubscriber(mCursorAnchorInfoNotifier, true); + resumeBlink(); } void onDetachedFromWindow() { @@ -327,9 +328,7 @@ public class Editor { hideError(); } - if (mBlink != null) { - mBlink.removeCallbacks(mBlink); - } + suspendBlink(); if (mInsertionPointCursorController != null) { mInsertionPointCursorController.onDetached(); @@ -1402,12 +1401,11 @@ public class Editor { InputMethodManager imm = InputMethodManager.peekInstance(); if (imm != null) { if (imm.isActive(mTextView)) { - boolean reported = false; if (ims.mContentChanged || ims.mSelectionModeChanged) { // We are in extract mode and the content has changed // in some way... just report complete new text to the // input method. - reported = reportExtractedText(); + reportExtractedText(); } } } @@ -1924,10 +1922,6 @@ public class Editor { mSuggestionsPopupWindow.show(); } - boolean areSuggestionsShown() { - return mSuggestionsPopupWindow != null && mSuggestionsPopupWindow.isShowing(); - } - void onScrollChanged() { if (mPositionListener != null) { mPositionListener.onScrollChanged(); @@ -4625,8 +4619,6 @@ public class Editor { } static class InputMethodState { - Rect mCursorRectInWindow = new Rect(); - float[] mTmpOffset = new float[2]; ExtractedTextRequest mExtractedTextRequest; final ExtractedText mExtractedText = new ExtractedText(); int mBatchEditNesting; diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java index 324c2aa..0879c5d 100644 --- a/core/java/android/widget/HorizontalScrollView.java +++ b/core/java/android/widget/HorizontalScrollView.java @@ -40,6 +40,8 @@ import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.AnimationUtils; +import com.android.internal.R; + import java.util.List; /** @@ -768,7 +770,8 @@ public class HorizontalScrollView extends FrameLayout { return true; } switch (action) { - case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { + case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: + case R.id.accessibilityActionScrollRight: { if (!isEnabled()) { return false; } @@ -779,7 +782,8 @@ public class HorizontalScrollView extends FrameLayout { return true; } } return false; - case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: { + case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: + case R.id.accessibilityActionScrollLeft: { if (!isEnabled()) { return false; } @@ -807,10 +811,12 @@ public class HorizontalScrollView extends FrameLayout { if (scrollRange > 0) { info.setScrollable(true); if (isEnabled() && mScrollX > 0) { - info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD); + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_LEFT); } if (isEnabled() && mScrollX < scrollRange) { - info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD); + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_RIGHT); } } } diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java index 10e4db3..5953a98 100644 --- a/core/java/android/widget/RemoteViewsAdapter.java +++ b/core/java/android/widget/RemoteViewsAdapter.java @@ -618,7 +618,15 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback // remove based on both its position as well as it's current memory usage, as well // as whether it was directly requested vs. whether it was preloaded by our caching // mechanism. - mIndexRemoteViews.remove(getFarthestPositionFrom(pruneFromPosition, visibleWindow)); + int trimIndex = getFarthestPositionFrom(pruneFromPosition, visibleWindow); + + // Need to check that this is a valid index, to cover the case where you have only + // a single view in the cache, but it's larger than the max memory limit + if (trimIndex < 0) { + break; + } + + mIndexRemoteViews.remove(trimIndex); } // Update the metadata cache diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index 2026169..98d61d3 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -819,7 +819,8 @@ public class ScrollView extends FrameLayout { return false; } switch (action) { - case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { + case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: + case R.id.accessibilityActionScrollDown: { final int viewportHeight = getHeight() - mPaddingBottom - mPaddingTop; final int targetScrollY = Math.min(mScrollY + viewportHeight, getScrollRange()); if (targetScrollY != mScrollY) { @@ -827,7 +828,8 @@ public class ScrollView extends FrameLayout { return true; } } return false; - case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: { + case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: + case R.id.accessibilityActionScrollUp: { final int viewportHeight = getHeight() - mPaddingBottom - mPaddingTop; final int targetScrollY = Math.max(mScrollY - viewportHeight, 0); if (targetScrollY != mScrollY) { @@ -853,10 +855,13 @@ public class ScrollView extends FrameLayout { if (scrollRange > 0) { info.setScrollable(true); if (mScrollY > 0) { - info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + info.addAction( + AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD); + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_UP); } if (mScrollY < scrollRange) { - info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD); + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_DOWN); } } } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 774a864..449173f 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -6630,12 +6630,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // TODO: code duplication with makeSingleLayout() if (mHintLayout == null) { StaticLayout.Builder builder = StaticLayout.Builder.obtain(mHint, 0, - mHint.length(), hintWidth) - .setPaint(mTextPaint) + mHint.length(), mTextPaint, hintWidth) .setAlignment(alignment) .setTextDir(mTextDir) - .setSpacingMult(mSpacingMult) - .setSpacingAdd(mSpacingAdd) + .setLineSpacing(mSpacingAdd, mSpacingMult) .setIncludePad(mIncludePad) .setBreakStrategy(mBreakStrategy); if (mLeftIndents != null || mRightIndents != null) { @@ -6721,12 +6719,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } if (result == null) { StaticLayout.Builder builder = StaticLayout.Builder.obtain(mTransformed, - 0, mTransformed.length(), wantWidth) - .setPaint(mTextPaint) + 0, mTransformed.length(), mTextPaint, wantWidth) .setAlignment(alignment) .setTextDir(mTextDir) - .setSpacingMult(mSpacingMult) - .setSpacingAdd(mSpacingAdd) + .setLineSpacing(mSpacingAdd, mSpacingMult) .setIncludePad(mIncludePad) .setBreakStrategy(mBreakStrategy); if (mLeftIndents != null || mRightIndents != null) { diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl index 99bf9f3..86c1b2f 100644 --- a/core/java/com/android/internal/app/IAppOpsService.aidl +++ b/core/java/com/android/internal/app/IAppOpsService.aidl @@ -30,6 +30,7 @@ interface IAppOpsService { void startWatchingMode(int op, String packageName, IAppOpsCallback callback); void stopWatchingMode(IAppOpsCallback callback); IBinder getToken(IBinder clientToken); + int permissionToOpCode(String permission); // Remaining methods are only used in Java. int checkPackage(int uid, String packageName); @@ -42,5 +43,4 @@ interface IAppOpsService { void setUserRestrictions(in Bundle restrictions, int userHandle); void removeUser(int userHandle); - } diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl index d149c5b..4c6db24 100644 --- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl +++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl @@ -105,5 +105,5 @@ interface IVoiceInteractionManagerService { * Indicates whether the currently active voice interaction service is capable of handling the * assist gesture. */ - boolean activeServiceSupportsAssistGesture(); + boolean activeServiceSupportsAssist(); } diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java index 3f96174..6173832 100644 --- a/core/java/com/android/internal/logging/MetricsLogger.java +++ b/core/java/com/android/internal/logging/MetricsLogger.java @@ -32,6 +32,7 @@ public class MetricsLogger implements MetricsConstants { public static final int NOTIFICATION_ZEN_MODE_EXTERNAL_RULE = 145; public static final int ACTION_BAN_APP_NOTES = 146; public static final int NOTIFICATION_ZEN_MODE_EVENT_RULE = 147; + public static final int ACTION_DISMISS_ALL_NOTES = 148; public static void visible(Context context, int category) throws IllegalArgumentException { if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) { diff --git a/core/java/com/android/internal/midi/MidiConstants.java b/core/java/com/android/internal/midi/MidiConstants.java index f78f75a..c13e5fc 100644 --- a/core/java/com/android/internal/midi/MidiConstants.java +++ b/core/java/com/android/internal/midi/MidiConstants.java @@ -87,13 +87,13 @@ public final class MidiConstants { } // Returns true if this command can be used for running status - public static boolean allowRunningStatus(int command) { + public static boolean allowRunningStatus(byte command) { // only Channel Voice and Channel Mode commands can use running status return (command >= STATUS_NOTE_OFF && command < STATUS_SYSTEM_EXCLUSIVE); } // Returns true if this command cancels running status - public static boolean cancelsRunningStatus(int command) { + public static boolean cancelsRunningStatus(byte command) { // System Common messages cancel running status return (command >= STATUS_SYSTEM_EXCLUSIVE && command <= STATUS_END_SYSEX); } diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java index 441e640..e76302b 100644 --- a/core/java/com/android/internal/widget/ViewPager.java +++ b/core/java/com/android/internal/widget/ViewPager.java @@ -47,6 +47,8 @@ import android.view.animation.Interpolator; import android.widget.EdgeEffect; import android.widget.Scroller; +import com.android.internal.R; + import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -2720,10 +2722,12 @@ public class ViewPager extends ViewGroup { if (canScrollHorizontally(1)) { info.addAction(AccessibilityAction.ACTION_SCROLL_FORWARD); + info.addAction(AccessibilityAction.ACTION_SCROLL_RIGHT); } if (canScrollHorizontally(-1)) { info.addAction(AccessibilityAction.ACTION_SCROLL_BACKWARD); + info.addAction(AccessibilityAction.ACTION_SCROLL_LEFT); } } @@ -2735,12 +2739,14 @@ public class ViewPager extends ViewGroup { switch (action) { case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: + case R.id.accessibilityActionScrollRight: if (canScrollHorizontally(1)) { setCurrentItem(mCurItem + 1); return true; } return false; case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: + case R.id.accessibilityActionScrollLeft: if (canScrollHorizontally(-1)) { setCurrentItem(mCurItem - 1); return true; diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp index 7a934bd..8ae2e3b 100755 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -1,3 +1,7 @@ +#define LOG_TAG "Bitmap" + +#include "Bitmap.h" + #include "Paint.h" #include "SkBitmap.h" #include "SkPixelRef.h" @@ -14,11 +18,322 @@ #include "android_util_Binder.h" #include "android_nio_utils.h" #include "CreateJavaOutputStreamAdaptor.h" +#include <Caches.h> #include "core_jni_helpers.h" #include <jni.h> +namespace android { + +class WrappedPixelRef : public SkPixelRef { +public: + WrappedPixelRef(Bitmap* wrapper, void* storage, + const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable) + : SkPixelRef(info) + , mBitmap(*wrapper) + , mStorage(storage) { + reconfigure(info, rowBytes, ctable); + } + + ~WrappedPixelRef() { + // Tell SkRefCnt that everything is as it expects by forcing + // the refcnt to 1 + internal_dispose_restore_refcnt_to_1(); + SkSafeUnref(mColorTable); + } + + void reconfigure(const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable) { + if (kIndex_8_SkColorType != info.colorType()) { + ctable = nullptr; + } + mRowBytes = rowBytes; + if (mColorTable != ctable) { + SkSafeUnref(mColorTable); + mColorTable = ctable; + SkSafeRef(mColorTable); + } + // Dirty hack is dirty + // TODO: Figure something out here, Skia's current design makes this + // really hard to work with. Skia really, really wants immutable objects, + // but with the nested-ref-count hackery going on that's just not + // feasible without going insane trying to figure it out + SkImageInfo* myInfo = const_cast<SkImageInfo*>(&this->info()); + *myInfo = info; + + // Docs say to only call this in the ctor, but we're going to call + // it anyway even if this isn't always the ctor. + // TODO: Fix this too as part of the above TODO + setPreLocked(mStorage, mRowBytes, mColorTable); + } + + // Can't mark as override since SkPixelRef::rowBytes isn't virtual + // but that's OK since we just want BitmapWrapper to be able to rely + // on calling rowBytes() on an unlocked pixelref, which it will be + // doing on a WrappedPixelRef type, not a SkPixelRef, so static + // dispatching will do what we want. + size_t rowBytes() const { return mRowBytes; } + SkColorTable* colorTable() const { return mColorTable; } + + bool hasHardwareMipMap() const { + return mHasHardwareMipMap; + } + + void setHasHardwareMipMap(bool hasMipMap) { + mHasHardwareMipMap = hasMipMap; + } + +protected: + virtual bool onNewLockPixels(LockRec* rec) override { + rec->fPixels = mStorage; + rec->fRowBytes = mRowBytes; + rec->fColorTable = mColorTable; + return true; + } + + virtual void onUnlockPixels() override { + // nothing + } + + virtual size_t getAllocatedSizeInBytes() const override { + return info().getSafeSize(mRowBytes); + } + +private: + Bitmap& mBitmap; + void* mStorage; + size_t mRowBytes = 0; + SkColorTable* mColorTable = nullptr; + bool mHasHardwareMipMap = false; + + virtual void internal_dispose() const override { + mBitmap.onStrongRefDestroyed(); + } +}; + +Bitmap::Bitmap(JNIEnv* env, jbyteArray storageObj, void* address, + const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable) + : mPixelStorageType(PixelStorageType::Java) { + env->GetJavaVM(&mPixelStorage.java.jvm); + mPixelStorage.java.jweakRef = env->NewWeakGlobalRef(storageObj); + mPixelStorage.java.jstrongRef = nullptr; + mPixelRef.reset(new WrappedPixelRef(this, address, info, rowBytes, ctable)); + // Note: this will trigger a call to onStrongRefDestroyed(), but + // we want the pixel ref to have a ref count of 0 at this point + mPixelRef->unref(); +} + +Bitmap::Bitmap(void* address, void* context, FreeFunc freeFunc, + const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable) + : mPixelStorageType(PixelStorageType::External) { + mPixelStorage.external.address = address; + mPixelStorage.external.context = context; + mPixelStorage.external.freeFunc = freeFunc; + mPixelRef.reset(new WrappedPixelRef(this, address, info, rowBytes, ctable)); + // Note: this will trigger a call to onStrongRefDestroyed(), but + // we want the pixel ref to have a ref count of 0 at this point + mPixelRef->unref(); +} + +Bitmap::~Bitmap() { + doFreePixels(); +} + +void Bitmap::freePixels() { + AutoMutex _lock(mLock); + if (mPinnedRefCount == 0) { + doFreePixels(); + mPixelStorageType = PixelStorageType::Invalid; + } +} + +void Bitmap::doFreePixels() { + switch (mPixelStorageType) { + case PixelStorageType::Invalid: + // already free'd, nothing to do + break; + case PixelStorageType::External: + mPixelStorage.external.freeFunc(mPixelStorage.external.address, + mPixelStorage.external.context); + break; + case PixelStorageType::Java: + JNIEnv* env = jniEnv(); + LOG_ALWAYS_FATAL_IF(mPixelStorage.java.jstrongRef, + "Deleting a bitmap wrapper while there are outstanding strong " + "references! mPinnedRefCount = %d", mPinnedRefCount); + env->DeleteWeakGlobalRef(mPixelStorage.java.jweakRef); + break; + } + + if (android::uirenderer::Caches::hasInstance()) { + android::uirenderer::Caches::getInstance().textureCache.releaseTexture( + mPixelRef->getStableID()); + } +} + +bool Bitmap::hasHardwareMipMap() { + return mPixelRef->hasHardwareMipMap(); +} + +void Bitmap::setHasHardwareMipMap(bool hasMipMap) { + mPixelRef->setHasHardwareMipMap(hasMipMap); +} + +const SkImageInfo& Bitmap::info() const { + assertValid(); + return mPixelRef->info(); +} + +size_t Bitmap::rowBytes() const { + return mPixelRef->rowBytes(); +} + +SkPixelRef* Bitmap::pixelRef() const { + assertValid(); + return mPixelRef.get(); +} + +void Bitmap::reconfigure(const SkImageInfo& info, size_t rowBytes, + SkColorTable* ctable) { + mPixelRef->reconfigure(info, rowBytes, ctable); +} + +void Bitmap::reconfigure(const SkImageInfo& info) { + mPixelRef->reconfigure(info, mPixelRef->rowBytes(), mPixelRef->colorTable()); +} + +void Bitmap::detachFromJava() { + bool disposeSelf; + { + android::AutoMutex _lock(mLock); + mAttachedToJava = false; + disposeSelf = shouldDisposeSelfLocked(); + } + if (disposeSelf) { + delete this; + } +} + +bool Bitmap::shouldDisposeSelfLocked() { + return mPinnedRefCount == 0 && !mAttachedToJava; +} + +JNIEnv* Bitmap::jniEnv() { + JNIEnv* env; + auto success = mPixelStorage.java.jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + LOG_ALWAYS_FATAL_IF(success != JNI_OK, + "Failed to get JNIEnv* from JVM: %p", mPixelStorage.java.jvm); + return env; +} + +void Bitmap::onStrongRefDestroyed() { + bool disposeSelf = false; + { + android::AutoMutex _lock(mLock); + if (mPinnedRefCount > 0) { + mPinnedRefCount--; + if (mPinnedRefCount == 0) { + unpinPixelsLocked(); + disposeSelf = shouldDisposeSelfLocked(); + } + } + } + if (disposeSelf) { + delete this; + } +} + +void Bitmap::pinPixelsLocked() { + switch (mPixelStorageType) { + case PixelStorageType::Invalid: + LOG_ALWAYS_FATAL("Cannot pin invalid pixels!"); + break; + case PixelStorageType::External: + // Nothing to do + break; + case PixelStorageType::Java: { + JNIEnv* env = jniEnv(); + if (!mPixelStorage.java.jstrongRef) { + mPixelStorage.java.jstrongRef = reinterpret_cast<jbyteArray>( + env->NewGlobalRef(mPixelStorage.java.jweakRef)); + if (!mPixelStorage.java.jstrongRef) { + LOG_ALWAYS_FATAL("Failed to acquire strong reference to pixels"); + } + } + break; + } + } +} + +void Bitmap::unpinPixelsLocked() { + switch (mPixelStorageType) { + case PixelStorageType::Invalid: + LOG_ALWAYS_FATAL("Cannot unpin invalid pixels!"); + break; + case PixelStorageType::External: + // Don't need to do anything + break; + case PixelStorageType::Java: { + JNIEnv* env = jniEnv(); + if (mPixelStorage.java.jstrongRef) { + env->DeleteGlobalRef(mPixelStorage.java.jstrongRef); + mPixelStorage.java.jstrongRef = nullptr; + } + break; + } + } +} + +void Bitmap::getSkBitmap(SkBitmap* outBitmap) { + assertValid(); + android::AutoMutex _lock(mLock); + mPixelRef->ref(); + if (mPixelRef->unique()) { + // We just restored this from 0, pin the pixels and inc the strong count + // Note that there *might be* an incoming onStrongRefDestroyed from whatever + // last unref'd + pinPixelsLocked(); + mPinnedRefCount++; + } + // Safe because mPixelRef is a WrappedPixelRef type, otherwise rowBytes() + // would require locking the pixels first. + outBitmap->setInfo(mPixelRef->info(), mPixelRef->rowBytes()); + outBitmap->setPixelRef(mPixelRef.get())->unref(); + outBitmap->setHasHardwareMipMap(hasHardwareMipMap()); +} + +void Bitmap::assertValid() const { + LOG_ALWAYS_FATAL_IF(mPixelStorageType == PixelStorageType::Invalid, + "Error, cannot access an invalid/free'd bitmap here!"); +} + +} // namespace android + +using namespace android; + +// Convenience class that does not take a global ref on the pixels, relying +// on the caller already having a local JNI ref +class LocalScopedBitmap { +public: + LocalScopedBitmap(jlong bitmapHandle) + : mBitmap(reinterpret_cast<Bitmap*>(bitmapHandle)) {} + + Bitmap* operator->() { + return mBitmap; + } + + void* pixels() { + return mBitmap->pixelRef()->pixels(); + } + + bool valid() { + return mBitmap && mBitmap->valid(); + } + +private: + Bitmap* mBitmap; +}; + /////////////////////////////////////////////////////////////////////////////// // Conversions to/from SkColor, for get/setPixels, and the create method, which // is basically like setPixels @@ -328,8 +643,8 @@ static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors, SkBitmap bitmap; bitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType)); - jbyteArray buff = GraphicsJNI::allocateJavaPixelRef(env, &bitmap, NULL); - if (NULL == buff) { + Bitmap* nativeBitmap = GraphicsJNI::allocateJavaPixelRef(env, &bitmap, NULL); + if (!nativeBitmap) { return NULL; } @@ -338,39 +653,41 @@ static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors, 0, 0, width, height, bitmap); } - return GraphicsJNI::createBitmap(env, new SkBitmap(bitmap), buff, - getPremulBitmapCreateFlags(isMutable), NULL, NULL); + return GraphicsJNI::createBitmap(env, nativeBitmap, + getPremulBitmapCreateFlags(isMutable)); } static jobject Bitmap_copy(JNIEnv* env, jobject, jlong srcHandle, jint dstConfigHandle, jboolean isMutable) { - const SkBitmap* src = reinterpret_cast<SkBitmap*>(srcHandle); + SkBitmap src; + reinterpret_cast<Bitmap*>(srcHandle)->getSkBitmap(&src); SkColorType dstCT = GraphicsJNI::legacyBitmapConfigToColorType(dstConfigHandle); SkBitmap result; JavaPixelAllocator allocator(env); - if (!src->copyTo(&result, dstCT, &allocator)) { + if (!src.copyTo(&result, dstCT, &allocator)) { return NULL; } - return GraphicsJNI::createBitmap(env, new SkBitmap(result), allocator.getStorageObj(), - getPremulBitmapCreateFlags(isMutable), NULL, NULL); + Bitmap* bitmap = allocator.getStorageObjAndReset(); + return GraphicsJNI::createBitmap(env, bitmap, + getPremulBitmapCreateFlags(isMutable)); } static void Bitmap_destructor(JNIEnv* env, jobject, jlong bitmapHandle) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); - delete bitmap; + LocalScopedBitmap bitmap(bitmapHandle); + bitmap->detachFromJava(); } static jboolean Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); - bitmap->setPixels(NULL, NULL); + LocalScopedBitmap bitmap(bitmapHandle); + bitmap->freePixels(); return JNI_TRUE; } static void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jlong bitmapHandle, jint width, jint height, jint configHandle, jint allocSize, jboolean requestPremul) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); + LocalScopedBitmap bitmap(bitmapHandle); SkColorType colorType = GraphicsJNI::legacyBitmapConfigToColorType(configHandle); // ARGB_4444 is a deprecated format, convert automatically to 8888 @@ -383,11 +700,9 @@ static void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jlong bitmapHandle, doThrowIAE(env, "Bitmap not large enough to support new configuration"); return; } - SkPixelRef* ref = bitmap->pixelRef(); - ref->ref(); SkAlphaType alphaType; - if (bitmap->colorType() != kRGB_565_SkColorType - && bitmap->alphaType() == kOpaque_SkAlphaType) { + if (bitmap->info().colorType() != kRGB_565_SkColorType + && bitmap->info().alphaType() == kOpaque_SkAlphaType) { // If the original bitmap was set to opaque, keep that setting, unless it // was 565, which is required to be opaque. alphaType = kOpaque_SkAlphaType; @@ -395,22 +710,7 @@ static void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jlong bitmapHandle, // Otherwise respect the premultiplied request. alphaType = requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType; } - bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType)); - // FIXME: Skia thinks of an SkPixelRef as having a constant SkImageInfo (except for - // its alphatype), so it would make more sense from Skia's perspective to create a - // new SkPixelRef. That said, libhwui uses the pointer to the SkPixelRef as a key - // for its cache, so it won't realize this is the same Java Bitmap. - SkImageInfo& info = const_cast<SkImageInfo&>(ref->info()); - // Use the updated from the SkBitmap, which may have corrected an invalid alphatype. - // (e.g. 565 non-opaque) - info = bitmap->info(); - bitmap->setPixelRef(ref); - - // notifyPixelsChanged will increment the generation ID even though the actual pixel data - // hasn't been touched. This signals the renderer that the bitmap (including width, height, - // colortype and alphatype) has changed. - ref->notifyPixelsChanged(); - ref->unref(); + bitmap->reconfigure(SkImageInfo::Make(width, height, colorType, alphaType)); } // These must match the int values in Bitmap.java @@ -423,7 +723,8 @@ enum JavaEncodeFormat { static jboolean Bitmap_compress(JNIEnv* env, jobject clazz, jlong bitmapHandle, jint format, jint quality, jobject jstream, jbyteArray jstorage) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); + + LocalScopedBitmap bitmap(bitmapHandle); SkImageEncoder::Type fm; switch (format) { @@ -440,92 +741,92 @@ static jboolean Bitmap_compress(JNIEnv* env, jobject clazz, jlong bitmapHandle, return JNI_FALSE; } - bool success = false; - if (NULL != bitmap) { - SkAutoLockPixels alp(*bitmap); + if (!bitmap.valid()) { + return JNI_FALSE; + } - if (NULL == bitmap->getPixels()) { - return JNI_FALSE; - } + bool success = false; - SkWStream* strm = CreateJavaOutputStreamAdaptor(env, jstream, jstorage); - if (NULL == strm) { - return JNI_FALSE; - } + std::unique_ptr<SkWStream> strm(CreateJavaOutputStreamAdaptor(env, jstream, jstorage)); + if (!strm.get()) { + return JNI_FALSE; + } - SkImageEncoder* encoder = SkImageEncoder::Create(fm); - if (NULL != encoder) { - success = encoder->encodeStream(strm, *bitmap, quality); - delete encoder; - } - delete strm; + std::unique_ptr<SkImageEncoder> encoder(SkImageEncoder::Create(fm)); + if (encoder.get()) { + SkBitmap skbitmap; + bitmap->getSkBitmap(&skbitmap); + success = encoder->encodeStream(strm.get(), skbitmap, quality); } return success ? JNI_TRUE : JNI_FALSE; } static void Bitmap_erase(JNIEnv* env, jobject, jlong bitmapHandle, jint color) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); - bitmap->eraseColor(color); + LocalScopedBitmap bitmap(bitmapHandle); + SkBitmap skBitmap; + bitmap->getSkBitmap(&skBitmap); + skBitmap.eraseColor(color); } static jint Bitmap_rowBytes(JNIEnv* env, jobject, jlong bitmapHandle) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); + LocalScopedBitmap bitmap(bitmapHandle); return static_cast<jint>(bitmap->rowBytes()); } static jint Bitmap_config(JNIEnv* env, jobject, jlong bitmapHandle) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); - return GraphicsJNI::colorTypeToLegacyBitmapConfig(bitmap->colorType()); + LocalScopedBitmap bitmap(bitmapHandle); + return GraphicsJNI::colorTypeToLegacyBitmapConfig(bitmap->info().colorType()); } static jint Bitmap_getGenerationId(JNIEnv* env, jobject, jlong bitmapHandle) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); - return static_cast<jint>(bitmap->getGenerationID()); + LocalScopedBitmap bitmap(bitmapHandle); + return static_cast<jint>(bitmap->pixelRef()->getGenerationID()); } static jboolean Bitmap_isPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); - if (bitmap->alphaType() == kPremul_SkAlphaType) { + LocalScopedBitmap bitmap(bitmapHandle); + if (bitmap->info().alphaType() == kPremul_SkAlphaType) { return JNI_TRUE; } return JNI_FALSE; } static jboolean Bitmap_hasAlpha(JNIEnv* env, jobject, jlong bitmapHandle) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); - return !bitmap->isOpaque() ? JNI_TRUE : JNI_FALSE; + LocalScopedBitmap bitmap(bitmapHandle); + return !bitmap->info().isOpaque() ? JNI_TRUE : JNI_FALSE; } static void Bitmap_setHasAlpha(JNIEnv* env, jobject, jlong bitmapHandle, jboolean hasAlpha, jboolean requestPremul) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); + LocalScopedBitmap bitmap(bitmapHandle); if (hasAlpha) { - bitmap->setAlphaType(requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); + bitmap->pixelRef()->changeAlphaType( + requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); } else { - bitmap->setAlphaType(kOpaque_SkAlphaType); + bitmap->pixelRef()->changeAlphaType(kOpaque_SkAlphaType); } } static void Bitmap_setPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle, jboolean isPremul) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); - if (!bitmap->isOpaque()) { + LocalScopedBitmap bitmap(bitmapHandle); + if (!bitmap->info().isOpaque()) { if (isPremul) { - bitmap->setAlphaType(kPremul_SkAlphaType); + bitmap->pixelRef()->changeAlphaType(kPremul_SkAlphaType); } else { - bitmap->setAlphaType(kUnpremul_SkAlphaType); + bitmap->pixelRef()->changeAlphaType(kUnpremul_SkAlphaType); } } } static jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, jlong bitmapHandle) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); + LocalScopedBitmap bitmap(bitmapHandle); return bitmap->hasHardwareMipMap() ? JNI_TRUE : JNI_FALSE; } static void Bitmap_setHasMipMap(JNIEnv* env, jobject, jlong bitmapHandle, jboolean hasMipMap) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); + LocalScopedBitmap bitmap(bitmapHandle); bitmap->setHasHardwareMipMap(hasMipMap); } @@ -580,8 +881,8 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { } } - jbyteArray buffer = GraphicsJNI::allocateJavaPixelRef(env, bitmap.get(), ctable); - if (NULL == buffer) { + android::Bitmap* nativeBitmap = GraphicsJNI::allocateJavaPixelRef(env, bitmap.get(), ctable); + if (!nativeBitmap) { SkSafeUnref(ctable); return NULL; } @@ -593,6 +894,7 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { android::Parcel::ReadableBlob blob; android::status_t status = p->readBlob(size, &blob); if (status) { + nativeBitmap->detachFromJava(); doThrowRE(env, "Could not read bitmap from parcel blob."); return NULL; } @@ -603,7 +905,7 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { blob.release(); - return GraphicsJNI::createBitmap(env, bitmap.release(), buffer, + return GraphicsJNI::createBitmap(env, nativeBitmap, getPremulBitmapCreateFlags(isMutable), NULL, NULL, density); } @@ -611,24 +913,25 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, jlong bitmapHandle, jboolean isMutable, jint density, jobject parcel) { - const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); if (parcel == NULL) { SkDebugf("------- writeToParcel null parcel\n"); return JNI_FALSE; } android::Parcel* p = android::parcelForJavaObject(env, parcel); + SkBitmap bitmap; + reinterpret_cast<Bitmap*>(bitmapHandle)->getSkBitmap(&bitmap); p->writeInt32(isMutable); - p->writeInt32(bitmap->colorType()); - p->writeInt32(bitmap->alphaType()); - p->writeInt32(bitmap->width()); - p->writeInt32(bitmap->height()); - p->writeInt32(bitmap->rowBytes()); + p->writeInt32(bitmap.colorType()); + p->writeInt32(bitmap.alphaType()); + p->writeInt32(bitmap.width()); + p->writeInt32(bitmap.height()); + p->writeInt32(bitmap.rowBytes()); p->writeInt32(density); - if (bitmap->colorType() == kIndex_8_SkColorType) { - SkColorTable* ctable = bitmap->getColorTable(); + if (bitmap.colorType() == kIndex_8_SkColorType) { + SkColorTable* ctable = bitmap.getColorTable(); if (ctable != NULL) { int count = ctable->count(); p->writeInt32(count); @@ -639,7 +942,7 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, } } - size_t size = bitmap->getSize(); + size_t size = bitmap.getSize(); android::Parcel::WritableBlob blob; android::status_t status = p->writeBlob(size, &blob); @@ -648,14 +951,14 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, return JNI_FALSE; } - bitmap->lockPixels(); - const void* pSrc = bitmap->getPixels(); + bitmap.lockPixels(); + const void* pSrc = bitmap.getPixels(); if (pSrc == NULL) { memset(blob.data(), 0, size); } else { memcpy(blob.data(), pSrc, size); } - bitmap->unlockPixels(); + bitmap.unlockPixels(); blob.release(); return JNI_TRUE; @@ -664,17 +967,17 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, static jobject Bitmap_extractAlpha(JNIEnv* env, jobject clazz, jlong srcHandle, jlong paintHandle, jintArray offsetXY) { - const SkBitmap* src = reinterpret_cast<SkBitmap*>(srcHandle); + SkBitmap src; + reinterpret_cast<Bitmap*>(srcHandle)->getSkBitmap(&src); const android::Paint* paint = reinterpret_cast<android::Paint*>(paintHandle); SkIPoint offset; - SkBitmap* dst = new SkBitmap; + SkBitmap dst; JavaPixelAllocator allocator(env); - src->extractAlpha(dst, paint, &allocator, &offset); + src.extractAlpha(&dst, paint, &allocator, &offset); // If Skia can't allocate pixels for destination bitmap, it resets // it, that is set its pixels buffer to NULL, and zero width and height. - if (dst->getPixels() == NULL && src->getPixels() != NULL) { - delete dst; + if (dst.getPixels() == NULL && src.getPixels() != NULL) { doThrowOOME(env, "failed to allocate pixels for alpha"); return NULL; } @@ -685,53 +988,55 @@ static jobject Bitmap_extractAlpha(JNIEnv* env, jobject clazz, env->ReleaseIntArrayElements(offsetXY, array, 0); } - return GraphicsJNI::createBitmap(env, dst, allocator.getStorageObj(), - getPremulBitmapCreateFlags(true), NULL, NULL); + return GraphicsJNI::createBitmap(env, allocator.getStorageObjAndReset(), + getPremulBitmapCreateFlags(true)); } /////////////////////////////////////////////////////////////////////////////// static jint Bitmap_getPixel(JNIEnv* env, jobject, jlong bitmapHandle, jint x, jint y) { - const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); - SkAutoLockPixels alp(*bitmap); + SkBitmap bitmap; + reinterpret_cast<Bitmap*>(bitmapHandle)->getSkBitmap(&bitmap); + SkAutoLockPixels alp(bitmap); - ToColorProc proc = ChooseToColorProc(*bitmap); + ToColorProc proc = ChooseToColorProc(bitmap); if (NULL == proc) { return 0; } - const void* src = bitmap->getAddr(x, y); + const void* src = bitmap.getAddr(x, y); if (NULL == src) { return 0; } SkColor dst[1]; - proc(dst, src, 1, bitmap->getColorTable()); + proc(dst, src, 1, bitmap.getColorTable()); return static_cast<jint>(dst[0]); } static void Bitmap_getPixels(JNIEnv* env, jobject, jlong bitmapHandle, jintArray pixelArray, jint offset, jint stride, jint x, jint y, jint width, jint height) { - const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); - SkAutoLockPixels alp(*bitmap); + SkBitmap bitmap; + reinterpret_cast<Bitmap*>(bitmapHandle)->getSkBitmap(&bitmap); + SkAutoLockPixels alp(bitmap); - ToColorProc proc = ChooseToColorProc(*bitmap); + ToColorProc proc = ChooseToColorProc(bitmap); if (NULL == proc) { return; } - const void* src = bitmap->getAddr(x, y); + const void* src = bitmap.getAddr(x, y); if (NULL == src) { return; } - SkColorTable* ctable = bitmap->getColorTable(); + SkColorTable* ctable = bitmap.getColorTable(); jint* dst = env->GetIntArrayElements(pixelArray, NULL); SkColor* d = (SkColor*)dst + offset; while (--height >= 0) { proc(d, src, width, ctable); d += stride; - src = (void*)((const char*)src + bitmap->rowBytes()); + src = (void*)((const char*)src + bitmap.rowBytes()); } env->ReleaseIntArrayElements(pixelArray, dst, 0); } @@ -740,79 +1045,85 @@ static void Bitmap_getPixels(JNIEnv* env, jobject, jlong bitmapHandle, static void Bitmap_setPixel(JNIEnv* env, jobject, jlong bitmapHandle, jint x, jint y, jint colorHandle) { - const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); + SkBitmap bitmap; + reinterpret_cast<Bitmap*>(bitmapHandle)->getSkBitmap(&bitmap); SkColor color = static_cast<SkColor>(colorHandle); - SkAutoLockPixels alp(*bitmap); - if (NULL == bitmap->getPixels()) { + SkAutoLockPixels alp(bitmap); + if (NULL == bitmap.getPixels()) { return; } - FromColorProc proc = ChooseFromColorProc(*bitmap); + FromColorProc proc = ChooseFromColorProc(bitmap); if (NULL == proc) { return; } - proc(bitmap->getAddr(x, y), &color, 1, x, y); - bitmap->notifyPixelsChanged(); + proc(bitmap.getAddr(x, y), &color, 1, x, y); + bitmap.notifyPixelsChanged(); } static void Bitmap_setPixels(JNIEnv* env, jobject, jlong bitmapHandle, jintArray pixelArray, jint offset, jint stride, jint x, jint y, jint width, jint height) { - const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); + SkBitmap bitmap; + reinterpret_cast<Bitmap*>(bitmapHandle)->getSkBitmap(&bitmap); GraphicsJNI::SetPixels(env, pixelArray, offset, stride, - x, y, width, height, *bitmap); + x, y, width, height, bitmap); } static void Bitmap_copyPixelsToBuffer(JNIEnv* env, jobject, jlong bitmapHandle, jobject jbuffer) { - const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); - SkAutoLockPixels alp(*bitmap); - const void* src = bitmap->getPixels(); + SkBitmap bitmap; + reinterpret_cast<Bitmap*>(bitmapHandle)->getSkBitmap(&bitmap); + SkAutoLockPixels alp(bitmap); + const void* src = bitmap.getPixels(); if (NULL != src) { android::AutoBufferPointer abp(env, jbuffer, JNI_TRUE); // the java side has already checked that buffer is large enough - memcpy(abp.pointer(), src, bitmap->getSize()); + memcpy(abp.pointer(), src, bitmap.getSize()); } } static void Bitmap_copyPixelsFromBuffer(JNIEnv* env, jobject, jlong bitmapHandle, jobject jbuffer) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); - SkAutoLockPixels alp(*bitmap); - void* dst = bitmap->getPixels(); + SkBitmap bitmap; + reinterpret_cast<Bitmap*>(bitmapHandle)->getSkBitmap(&bitmap); + SkAutoLockPixels alp(bitmap); + void* dst = bitmap.getPixels(); if (NULL != dst) { android::AutoBufferPointer abp(env, jbuffer, JNI_FALSE); // the java side has already checked that buffer is large enough - memcpy(dst, abp.pointer(), bitmap->getSize()); - bitmap->notifyPixelsChanged(); + memcpy(dst, abp.pointer(), bitmap.getSize()); + bitmap.notifyPixelsChanged(); } } static jboolean Bitmap_sameAs(JNIEnv* env, jobject, jlong bm0Handle, jlong bm1Handle) { - const SkBitmap* bm0 = reinterpret_cast<SkBitmap*>(bm0Handle); - const SkBitmap* bm1 = reinterpret_cast<SkBitmap*>(bm1Handle); - if (bm0->width() != bm1->width() || - bm0->height() != bm1->height() || - bm0->colorType() != bm1->colorType()) { + SkBitmap bm0; + SkBitmap bm1; + reinterpret_cast<Bitmap*>(bm0Handle)->getSkBitmap(&bm0); + reinterpret_cast<Bitmap*>(bm1Handle)->getSkBitmap(&bm1); + if (bm0.width() != bm1.width() || + bm0.height() != bm1.height() || + bm0.colorType() != bm1.colorType()) { return JNI_FALSE; } - SkAutoLockPixels alp0(*bm0); - SkAutoLockPixels alp1(*bm1); + SkAutoLockPixels alp0(bm0); + SkAutoLockPixels alp1(bm1); // if we can't load the pixels, return false - if (NULL == bm0->getPixels() || NULL == bm1->getPixels()) { + if (NULL == bm0.getPixels() || NULL == bm1.getPixels()) { return JNI_FALSE; } - if (bm0->colorType() == kIndex_8_SkColorType) { - SkColorTable* ct0 = bm0->getColorTable(); - SkColorTable* ct1 = bm1->getColorTable(); + if (bm0.colorType() == kIndex_8_SkColorType) { + SkColorTable* ct0 = bm0.getColorTable(); + SkColorTable* ct1 = bm1.getColorTable(); if (NULL == ct0 || NULL == ct1) { return JNI_FALSE; } @@ -829,16 +1140,16 @@ static jboolean Bitmap_sameAs(JNIEnv* env, jobject, jlong bm0Handle, // now compare each scanline. We can't do the entire buffer at once, // since we don't care about the pixel values that might extend beyond // the width (since the scanline might be larger than the logical width) - const int h = bm0->height(); - const size_t size = bm0->width() * bm0->bytesPerPixel(); + const int h = bm0.height(); + const size_t size = bm0.width() * bm0.bytesPerPixel(); for (int y = 0; y < h; y++) { // SkBitmap::getAddr(int, int) may return NULL due to unrecognized config // (ex: kRLE_Index8_Config). This will cause memcmp method to crash. Since bm0 // and bm1 both have pixel data() (have passed NULL == getPixels() check), // those 2 bitmaps should be valid (only unrecognized), we return JNI_FALSE // to warn user those 2 unrecognized config bitmaps may be different. - void *bm0Addr = bm0->getAddr(0, y); - void *bm1Addr = bm1->getAddr(0, y); + void *bm0Addr = bm0.getAddr(0, y); + void *bm1Addr = bm1.getAddr(0, y); if(bm0Addr == NULL || bm1Addr == NULL) { return JNI_FALSE; @@ -851,10 +1162,11 @@ static jboolean Bitmap_sameAs(JNIEnv* env, jobject, jlong bm0Handle, return JNI_TRUE; } -static void Bitmap_prepareToDraw(JNIEnv* env, jobject, jlong bitmapHandle) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); - bitmap->lockPixels(); - bitmap->unlockPixels(); +static jlong Bitmap_refPixelRef(JNIEnv* env, jobject, jlong bitmapHandle) { + LocalScopedBitmap bitmap(bitmapHandle); + SkPixelRef* pixelRef = bitmap.valid() ? bitmap->pixelRef() : nullptr; + SkSafeRef(pixelRef); + return reinterpret_cast<jlong>(pixelRef); } /////////////////////////////////////////////////////////////////////////////// @@ -895,7 +1207,7 @@ static JNINativeMethod gBitmapMethods[] = { { "nativeCopyPixelsFromBuffer", "(JLjava/nio/Buffer;)V", (void*)Bitmap_copyPixelsFromBuffer }, { "nativeSameAs", "(JJ)Z", (void*)Bitmap_sameAs }, - { "nativePrepareToDraw", "(J)V", (void*)Bitmap_prepareToDraw }, + { "nativeRefPixelRef", "(J)J", (void*)Bitmap_refPixelRef }, }; int register_android_graphics_Bitmap(JNIEnv* env) diff --git a/core/jni/android/graphics/Bitmap.h b/core/jni/android/graphics/Bitmap.h new file mode 100644 index 0000000..d6e5c61 --- /dev/null +++ b/core/jni/android/graphics/Bitmap.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef BITMAP_H_ +#define BITMAP_H_ + +#include <jni.h> +#include <SkBitmap.h> +#include <SkColorTable.h> +#include <SkImageInfo.h> +#include <utils/Mutex.h> +#include <memory> + +namespace android { + +enum class PixelStorageType { + Invalid, + External, + Java, +}; + +class WrappedPixelRef; + +typedef void (*FreeFunc)(void* addr, void* context); + +/** + * Glue-thingy that deals with managing the interaction between the Java + * Bitmap object & SkBitmap along with trying to map a notion of strong/weak + * lifecycles onto SkPixelRef which only has strong counts to avoid requiring + * two GC passes to free the byte[] that backs a Bitmap. + * + * Since not all Bitmaps are byte[]-backed it also supports external allocations, + * which currently is used by screenshots to wrap a gralloc buffer. + */ +class Bitmap { +public: + Bitmap(JNIEnv* env, jbyteArray storageObj, void* address, + const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable); + Bitmap(void* address, void* context, FreeFunc freeFunc, + const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable); + + const SkImageInfo& info() const; + + // Returns nullptr if it is not backed by a jbyteArray + jbyteArray javaByteArray() const { + return mPixelStorageType == PixelStorageType::Java + ? mPixelStorage.java.jstrongRef : nullptr; + } + + int width() const { return info().width(); } + int height() const { return info().height(); } + size_t rowBytes() const; + SkPixelRef* pixelRef() const; + bool valid() const { return mPixelStorageType != PixelStorageType::Invalid; } + + void reconfigure(const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable); + void reconfigure(const SkImageInfo& info); + + void getSkBitmap(SkBitmap* outBitmap); + void detachFromJava(); + + void freePixels(); + + bool hasHardwareMipMap(); + void setHasHardwareMipMap(bool hasMipMap); + +private: + friend class WrappedPixelRef; + + ~Bitmap(); + void doFreePixels(); + void onStrongRefDestroyed(); + + void pinPixelsLocked(); + void unpinPixelsLocked(); + JNIEnv* jniEnv(); + bool shouldDisposeSelfLocked(); + void assertValid() const; + + android::Mutex mLock; + int mPinnedRefCount = 0; + std::unique_ptr<WrappedPixelRef> mPixelRef; + PixelStorageType mPixelStorageType; + bool mAttachedToJava = true; + + union { + struct { + void* address; + void* context; + FreeFunc freeFunc; + } external; + struct { + JavaVM* jvm; + jweak jweakRef; + jbyteArray jstrongRef; + } java; + } mPixelStorage; +}; + +} // namespace android + +#endif /* BITMAP_H_ */ diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp index d4069a1..cdd397d 100644 --- a/core/jni/android/graphics/BitmapFactory.cpp +++ b/core/jni/android/graphics/BitmapFactory.cpp @@ -156,13 +156,11 @@ private: class RecyclingPixelAllocator : public SkBitmap::Allocator { public: - RecyclingPixelAllocator(SkPixelRef* pixelRef, unsigned int size) - : mPixelRef(pixelRef), mSize(size) { - SkSafeRef(mPixelRef); + RecyclingPixelAllocator(android::Bitmap* bitmap, unsigned int size) + : mBitmap(bitmap), mSize(size) { } ~RecyclingPixelAllocator() { - SkSafeUnref(mPixelRef); } virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) { @@ -185,11 +183,9 @@ public: return false; } - // Create a new pixelref with the new ctable that wraps the previous pixelref - SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef), - info, bitmap->rowBytes(), ctable); + mBitmap->reconfigure(info, bitmap->rowBytes(), ctable); + bitmap->setPixelRef(mBitmap->pixelRef()); - bitmap->setPixelRef(pr)->unref(); // since we're already allocated, we lockPixels right away // HeapAllocator/JavaPixelAllocator behaves this way too bitmap->lockPixels(); @@ -197,7 +193,7 @@ public: } private: - SkPixelRef* const mPixelRef; + android::Bitmap* const mBitmap; const unsigned int mSize; }; @@ -258,27 +254,24 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding decoder->setPreferQualityOverSpeed(preferQualityOverSpeed); decoder->setRequireUnpremultipliedColors(requireUnpremultiplied); - SkBitmap* outputBitmap = NULL; + android::Bitmap* reuseBitmap = nullptr; unsigned int existingBufferSize = 0; if (javaBitmap != NULL) { - outputBitmap = GraphicsJNI::getSkBitmapDeprecated(env, javaBitmap); - if (outputBitmap->isImmutable()) { + reuseBitmap = GraphicsJNI::getBitmap(env, javaBitmap); + if (reuseBitmap->pixelRef()->isImmutable()) { ALOGW("Unable to reuse an immutable bitmap as an image decoder target."); javaBitmap = NULL; - outputBitmap = NULL; + reuseBitmap = nullptr; } else { existingBufferSize = GraphicsJNI::getBitmapAllocationByteCount(env, javaBitmap); } } - SkAutoTDelete<SkBitmap> adb(outputBitmap == NULL ? new SkBitmap : NULL); - if (outputBitmap == NULL) outputBitmap = adb.get(); - NinePatchPeeker peeker(decoder); decoder->setPeeker(&peeker); JavaPixelAllocator javaAllocator(env); - RecyclingPixelAllocator recyclingAllocator(outputBitmap->pixelRef(), existingBufferSize); + RecyclingPixelAllocator recyclingAllocator(reuseBitmap, existingBufferSize); ScaleCheckingAllocator scaleCheckingAllocator(scale, existingBufferSize); SkBitmap::Allocator* outputAllocator = (javaBitmap != NULL) ? (SkBitmap::Allocator*)&recyclingAllocator : (SkBitmap::Allocator*)&javaAllocator; @@ -374,6 +367,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding } } + SkBitmap outputBitmap; if (willScale) { // This is weird so let me explain: we could use the scale parameter // directly, but for historical reasons this is how the corresponding @@ -388,26 +382,27 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding // FIXME: If the alphaType is kUnpremul and the image has alpha, the // colors may not be correct, since Skia does not yet support drawing // to/from unpremultiplied bitmaps. - outputBitmap->setInfo(SkImageInfo::Make(scaledWidth, scaledHeight, + outputBitmap.setInfo(SkImageInfo::Make(scaledWidth, scaledHeight, colorType, decodingBitmap.alphaType())); - if (!outputBitmap->tryAllocPixels(outputAllocator, NULL)) { + if (!outputBitmap.tryAllocPixels(outputAllocator, NULL)) { return nullObjectReturn("allocation failed for scaled bitmap"); } // If outputBitmap's pixels are newly allocated by Java, there is no need // to erase to 0, since the pixels were initialized to 0. if (outputAllocator != &javaAllocator) { - outputBitmap->eraseColor(0); + outputBitmap.eraseColor(0); } SkPaint paint; paint.setFilterQuality(kLow_SkFilterQuality); - SkCanvas canvas(*outputBitmap); + SkCanvas canvas(outputBitmap); canvas.scale(sx, sy); + canvas.drawARGB(0x00, 0x00, 0x00, 0x00); canvas.drawBitmap(decodingBitmap, 0.0f, 0.0f, &paint); } else { - outputBitmap->swap(decodingBitmap); + outputBitmap.swap(decodingBitmap); } if (padding) { @@ -422,22 +417,19 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding // if we get here, we're in kDecodePixels_Mode and will therefore // already have a pixelref installed. - if (outputBitmap->pixelRef() == NULL) { + if (outputBitmap.pixelRef() == NULL) { return nullObjectReturn("Got null SkPixelRef"); } if (!isMutable && javaBitmap == NULL) { // promise we will never change our pixels (great for sharing and pictures) - outputBitmap->setImmutable(); + outputBitmap.setImmutable(); } - // detach bitmap from its autodeleter, since we want to own it now - adb.detach(); - if (javaBitmap != NULL) { bool isPremultiplied = !requireUnpremultiplied; - GraphicsJNI::reinitBitmap(env, javaBitmap, outputBitmap, isPremultiplied); - outputBitmap->notifyPixelsChanged(); + GraphicsJNI::reinitBitmap(env, javaBitmap, outputBitmap.info(), isPremultiplied); + outputBitmap.notifyPixelsChanged(); // If a java bitmap was passed in for reuse, pass it back return javaBitmap; } @@ -447,7 +439,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding if (!requireUnpremultiplied) bitmapCreateFlags |= GraphicsJNI::kBitmapCreateFlag_Premultiplied; // now create the java bitmap - return GraphicsJNI::createBitmap(env, outputBitmap, javaAllocator.getStorageObj(), + return GraphicsJNI::createBitmap(env, javaAllocator.getStorageObjAndReset(), bitmapCreateFlags, ninePatchChunk, ninePatchInsets, -1); } diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp index aeea808..08a3f6f 100644 --- a/core/jni/android/graphics/BitmapRegionDecoder.cpp +++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp @@ -212,26 +212,21 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle, region.fTop = start_y; region.fRight = start_x + width; region.fBottom = start_y + height; - SkBitmap* bitmap = NULL; - SkAutoTDelete<SkBitmap> adb; + SkBitmap bitmap; if (tileBitmap != NULL) { // Re-use bitmap. - bitmap = GraphicsJNI::getSkBitmapDeprecated(env, tileBitmap); - } - if (bitmap == NULL) { - bitmap = new SkBitmap; - adb.reset(bitmap); + GraphicsJNI::getSkBitmap(env, tileBitmap, &bitmap); } - if (!brd->decodeRegion(bitmap, region, prefColorType, sampleSize)) { + if (!brd->decodeRegion(&bitmap, region, prefColorType, sampleSize)) { return nullObjectReturn("decoder->decodeRegion returned false"); } // update options (if any) if (NULL != options) { - env->SetIntField(options, gOptions_widthFieldID, bitmap->width()); - env->SetIntField(options, gOptions_heightFieldID, bitmap->height()); + env->SetIntField(options, gOptions_widthFieldID, bitmap.width()); + env->SetIntField(options, gOptions_heightFieldID, bitmap.height()); // TODO: set the mimeType field with the data from the codec. // but how to reuse a set of strings, rather than allocating new one // each time? @@ -240,19 +235,16 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle, } if (tileBitmap != NULL) { - bitmap->notifyPixelsChanged(); + bitmap.notifyPixelsChanged(); return tileBitmap; } - // detach bitmap from its autodeleter, since we want to own it now - adb.detach(); - JavaPixelAllocator* allocator = (JavaPixelAllocator*) decoder->getAllocator(); - jbyteArray buff = allocator->getStorageObjAndReset(); int bitmapCreateFlags = 0; if (!requireUnpremultiplied) bitmapCreateFlags |= GraphicsJNI::kBitmapCreateFlag_Premultiplied; - return GraphicsJNI::createBitmap(env, bitmap, buff, bitmapCreateFlags, NULL, NULL, -1); + return GraphicsJNI::createBitmap(env, allocator->getStorageObjAndReset(), + bitmapCreateFlags); } static jint nativeGetHeight(JNIEnv* env, jobject, jlong brdHandle) { diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp index f793df1..0deb8cc 100644 --- a/core/jni/android/graphics/Graphics.cpp +++ b/core/jni/android/graphics/Graphics.cpp @@ -154,7 +154,7 @@ static jfieldID gPointF_xFieldID; static jfieldID gPointF_yFieldID; static jclass gBitmap_class; -static jfieldID gBitmap_skBitmapPtr; +static jfieldID gBitmap_nativePtr; static jmethodID gBitmap_constructorMethodID; static jmethodID gBitmap_reinitMethodID; static jmethodID gBitmap_getAllocationByteCountMethodID; @@ -338,27 +338,22 @@ SkColorType GraphicsJNI::legacyBitmapConfigToColorType(jint legacyConfig) { return static_cast<SkColorType>(gConfig2ColorType[legacyConfig]); } -SkBitmap* GraphicsJNI::getSkBitmapDeprecated(JNIEnv* env, jobject bitmap) { +android::Bitmap* GraphicsJNI::getBitmap(JNIEnv* env, jobject bitmap) { SkASSERT(env); SkASSERT(bitmap); SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class)); - jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_skBitmapPtr); - SkBitmap* b = reinterpret_cast<SkBitmap*>(bitmapHandle); + jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr); + android::Bitmap* b = reinterpret_cast<android::Bitmap*>(bitmapHandle); SkASSERT(b); return b; } void GraphicsJNI::getSkBitmap(JNIEnv* env, jobject bitmap, SkBitmap* outBitmap) { - // TODO: We have to copy from the existing bitmap due to rowBytes not - // being updated on the SkPixelRef at reconfigure time. This is a short term - // problem that will be fixed with the specialized wrapper - *outBitmap = *getSkBitmapDeprecated(env, bitmap); + getBitmap(env, bitmap)->getSkBitmap(outBitmap); } SkPixelRef* GraphicsJNI::getSkPixelRef(JNIEnv* env, jobject bitmap) { - jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_skBitmapPtr); - SkBitmap* b = reinterpret_cast<SkBitmap*>(bitmapHandle); - return b->pixelRef(); + return getBitmap(env, bitmap)->pixelRef(); } SkColorType GraphicsJNI::getNativeBitmapColorType(JNIEnv* env, jobject jconfig) { @@ -396,47 +391,43 @@ SkRegion* GraphicsJNI::getNativeRegion(JNIEnv* env, jobject region) /////////////////////////////////////////////////////////////////////////////////////////// // Assert that bitmap's SkAlphaType is consistent with isPremultiplied. -static void assert_premultiplied(const SkBitmap& bitmap, bool isPremultiplied) { +static void assert_premultiplied(const SkImageInfo& info, bool isPremultiplied) { // kOpaque_SkAlphaType and kIgnore_SkAlphaType mean that isPremultiplied is // irrelevant. This just tests to ensure that the SkAlphaType is not // opposite of isPremultiplied. if (isPremultiplied) { - SkASSERT(bitmap.alphaType() != kUnpremul_SkAlphaType); + SkASSERT(info.alphaType() != kUnpremul_SkAlphaType); } else { - SkASSERT(bitmap.alphaType() != kPremul_SkAlphaType); + SkASSERT(info.alphaType() != kPremul_SkAlphaType); } } -jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer, - int bitmapCreateFlags, jbyteArray ninePatchChunk, jobject ninePatchInsets, int density) -{ - SkASSERT(bitmap); - SkASSERT(bitmap->pixelRef()); - SkASSERT(!env->ExceptionCheck()); +jobject GraphicsJNI::createBitmap(JNIEnv* env, android::Bitmap* bitmap, + int bitmapCreateFlags, jbyteArray ninePatchChunk, jobject ninePatchInsets, + int density) { bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable; bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied; - // The caller needs to have already set the alpha type properly, so the // native SkBitmap stays in sync with the Java Bitmap. - assert_premultiplied(*bitmap, isPremultiplied); + assert_premultiplied(bitmap->info(), isPremultiplied); jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID, - reinterpret_cast<jlong>(bitmap), buffer, + reinterpret_cast<jlong>(bitmap), bitmap->javaByteArray(), bitmap->width(), bitmap->height(), density, isMutable, isPremultiplied, ninePatchChunk, ninePatchInsets); hasException(env); // For the side effect of logging. return obj; } -void GraphicsJNI::reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap, +void GraphicsJNI::reinitBitmap(JNIEnv* env, jobject javaBitmap, const SkImageInfo& info, bool isPremultiplied) { // The caller needs to have already set the alpha type properly, so the // native SkBitmap stays in sync with the Java Bitmap. - assert_premultiplied(*bitmap, isPremultiplied); + assert_premultiplied(info, isPremultiplied); env->CallVoidMethod(javaBitmap, gBitmap_reinitMethodID, - bitmap->width(), bitmap->height(), isPremultiplied); + info.width(), info.height(), isPremultiplied); } int GraphicsJNI::getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap) @@ -477,51 +468,6 @@ static JNIEnv* vm2env(JavaVM* vm) /////////////////////////////////////////////////////////////////////////////// -AndroidPixelRef::AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage, - size_t rowBytes, jbyteArray storageObj, SkColorTable* ctable) : - SkMallocPixelRef(info, storage, rowBytes, ctable, (storageObj == NULL)), - fWrappedPixelRef(NULL) { - SkASSERT(storage); - SkASSERT(storageObj); - SkASSERT(env); - - if (env->GetJavaVM(&fVM) != JNI_OK) { - SkDebugf("------ [%p] env->GetJavaVM failed\n", env); - sk_throw(); - } - - fStorageObj = (jbyteArray) env->NewGlobalRef(storageObj); -} - -AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info, - size_t rowBytes, SkColorTable* ctable) : - SkMallocPixelRef(info, wrappedPixelRef.getAddr(), rowBytes, ctable, false), - fWrappedPixelRef(wrappedPixelRef.fWrappedPixelRef ? - wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef) -{ - SkASSERT(fWrappedPixelRef); - SkSafeRef(fWrappedPixelRef); - - // don't need to initialize this, as all the relevant logic delegates to the wrapped ref - fStorageObj = NULL; -} - -AndroidPixelRef::~AndroidPixelRef() { - if (fWrappedPixelRef) { - SkSafeUnref(fWrappedPixelRef); - } else { - SkASSERT(fStorageObj); - JNIEnv* env = vm2env(fVM); - env->DeleteGlobalRef(fStorageObj); - } - - if (android::uirenderer::Caches::hasInstance()) { - android::uirenderer::Caches::getInstance().textureCache.releaseTexture(getStableID()); - } -} - -/////////////////////////////////////////////////////////////////////////////// - static bool computeAllocationSize(const SkBitmap& bitmap, size_t* size) { int32_t rowBytes32 = SkToS32(bitmap.rowBytes()); int64_t bigSize = (int64_t)bitmap.height() * rowBytes32; @@ -533,7 +479,7 @@ static bool computeAllocationSize(const SkBitmap& bitmap, size_t* size) { return true; } -jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, +android::Bitmap* GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ctable) { const SkImageInfo& info = bitmap->info(); if (info.fColorType == kUnknown_SkColorType) { @@ -562,13 +508,14 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, return NULL; } SkASSERT(addr); - SkPixelRef* pr = new AndroidPixelRef(env, info, (void*) addr, rowBytes, arrayObj, ctable); - bitmap->setPixelRef(pr)->unref(); + android::Bitmap* wrapper = new android::Bitmap(env, arrayObj, (void*) addr, + info, rowBytes, ctable); + wrapper->getSkBitmap(bitmap); // since we're already allocated, we lockPixels right away // HeapAllocator behaves this way too bitmap->lockPixels(); - return arrayObj; + return wrapper; } struct AndroidPixelRefContext { @@ -627,21 +574,22 @@ bool GraphicsJNI::allocatePixels(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ct /////////////////////////////////////////////////////////////////////////////// -JavaPixelAllocator::JavaPixelAllocator(JNIEnv* env) - : fStorageObj(NULL), - fAllocCount(0) { - if (env->GetJavaVM(&fVM) != JNI_OK) { - SkDebugf("------ [%p] env->GetJavaVM failed\n", env); - sk_throw(); +JavaPixelAllocator::JavaPixelAllocator(JNIEnv* env) { + LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&mJavaVM) != JNI_OK, + "env->GetJavaVM failed"); +} + +JavaPixelAllocator::~JavaPixelAllocator() { + if (mStorage) { + mStorage->detachFromJava(); } } bool JavaPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) { - JNIEnv* env = vm2env(fVM); + JNIEnv* env = vm2env(mJavaVM); - fStorageObj = GraphicsJNI::allocateJavaPixelRef(env, bitmap, ctable); - fAllocCount += 1; - return fStorageObj != NULL; + mStorage = GraphicsJNI::allocateJavaPixelRef(env, bitmap, ctable); + return mStorage != nullptr; } //////////////////////////////////////////////////////////////////////////////// @@ -687,7 +635,7 @@ int register_android_graphics_Graphics(JNIEnv* env) gPointF_yFieldID = getFieldIDCheck(env, gPointF_class, "y", "F"); gBitmap_class = make_globalref(env, "android/graphics/Bitmap"); - gBitmap_skBitmapPtr = getFieldIDCheck(env, gBitmap_class, "mSkBitmapPtr", "J"); + gBitmap_nativePtr = getFieldIDCheck(env, gBitmap_class, "mNativePtr", "J"); gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>", "(J[BIIIZZ[BLandroid/graphics/NinePatch$InsetStruct;)V"); gBitmap_reinitMethodID = env->GetMethodID(gBitmap_class, "reinit", "(IIZ)V"); gBitmap_getAllocationByteCountMethodID = env->GetMethodID(gBitmap_class, "getAllocationByteCount", "()I"); diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h index 8eb43f8..e748bac 100644 --- a/core/jni/android/graphics/GraphicsJNI.h +++ b/core/jni/android/graphics/GraphicsJNI.h @@ -1,6 +1,7 @@ #ifndef _ANDROID_GRAPHICS_GRAPHICS_JNI_H_ #define _ANDROID_GRAPHICS_GRAPHICS_JNI_H_ +#include "Bitmap.h" #include "SkBitmap.h" #include "SkDevice.h" #include "SkPixelRef.h" @@ -49,7 +50,7 @@ public: static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf); static android::Canvas* getNativeCanvas(JNIEnv*, jobject canvas); - static SkBitmap* getSkBitmapDeprecated(JNIEnv*, jobject bitmap); + static android::Bitmap* getBitmap(JNIEnv*, jobject bitmap); static void getSkBitmap(JNIEnv*, jobject bitmap, SkBitmap* outBitmap); static SkPixelRef* getSkPixelRef(JNIEnv*, jobject bitmap); static SkRegion* getNativeRegion(JNIEnv*, jobject region); @@ -71,22 +72,18 @@ public: */ static SkColorType getNativeBitmapColorType(JNIEnv*, jobject jconfig); - /** Create a java Bitmap object given the native bitmap (required) and optional - storage array (may be null). - bitmap's SkAlphaType must already be in sync with bitmapCreateFlags. + /* + * Create a java Bitmap object given the native bitmap + * bitmap's SkAlphaType must already be in sync with bitmapCreateFlags. */ - static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer, - int bitmapCreateFlags, jbyteArray ninePatch, jobject ninePatchInsets, int density = -1); - - static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreateFlags, - jbyteArray ninePatch, int density = -1) { - return createBitmap(env, bitmap, NULL, bitmapCreateFlags, ninePatch, NULL, density); - } + static jobject createBitmap(JNIEnv* env, android::Bitmap* bitmap, + int bitmapCreateFlags, jbyteArray ninePatchChunk = NULL, + jobject ninePatchInsets = NULL, int density = -1); /** Reinitialize a bitmap. bitmap must already have its SkAlphaType set in sync with isPremultiplied */ - static void reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap, + static void reinitBitmap(JNIEnv* env, jobject javaBitmap, const SkImageInfo& info, bool isPremultiplied); static int getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap); @@ -95,7 +92,7 @@ public: static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap); - static jbyteArray allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, + static android::Bitmap* allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ctable); /** @@ -113,30 +110,6 @@ public: static bool SetPixels(JNIEnv* env, jintArray colors, int srcOffset, int srcStride, int x, int y, int width, int height, const SkBitmap& dstBitmap); - - static jbyteArray getBitmapStorageObj(SkPixelRef *pixref); -}; - -class AndroidPixelRef : public SkMallocPixelRef { -public: - AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage, size_t rowBytes, - jbyteArray storageObj, SkColorTable* ctable); - - /** - * Creates an AndroidPixelRef that wraps (and refs) another to reuse/share - * the same storage and java byte array refcounting, yet have a different - * color table. - */ - AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info, - size_t rowBytes, SkColorTable* ctable); - - virtual ~AndroidPixelRef(); - -private: - AndroidPixelRef* const fWrappedPixelRef; // if set, delegate memory management calls to this - - JavaVM* fVM; - jbyteArray fStorageObj; // The Java byte[] object used as the bitmap backing store }; /** Allocator which allocates the backing buffer in the Java heap. @@ -147,30 +120,22 @@ private: class JavaPixelAllocator : public SkBitmap::Allocator { public: JavaPixelAllocator(JNIEnv* env); - // overrides - virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable); + ~JavaPixelAllocator(); - /** Return the Java array object created for the last allocation. - * This returns a local JNI reference which the caller is responsible - * for storing appropriately (usually by passing it to the Bitmap - * constructor). - */ - jbyteArray getStorageObj() { return fStorageObj; } + virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) override; - /** Same as getStorageObj(), but also resets the allocator so that it - * can allocate again. + /** + * Fetches the backing allocation object. Must be called! */ - jbyteArray getStorageObjAndReset() { - jbyteArray result = fStorageObj; - fStorageObj = NULL; - fAllocCount = 0; + android::Bitmap* getStorageObjAndReset() { + android::Bitmap* result = mStorage; + mStorage = NULL; return result; }; private: - JavaVM* fVM; - jbyteArray fStorageObj; - int fAllocCount; + JavaVM* mJavaVM; + android::Bitmap* mStorage = nullptr; }; enum JNIAccess { diff --git a/core/jni/android/graphics/NinePatch.cpp b/core/jni/android/graphics/NinePatch.cpp index 3f8bfe2..348b0ec 100644 --- a/core/jni/android/graphics/NinePatch.cpp +++ b/core/jni/android/graphics/NinePatch.cpp @@ -64,7 +64,7 @@ public: return JNI_FALSE; } - static jlong validateNinePatchChunk(JNIEnv* env, jobject, jlong, jbyteArray obj) { + static jlong validateNinePatchChunk(JNIEnv* env, jobject, jbyteArray obj) { size_t chunkSize = env->GetArrayLength(obj); if (chunkSize < (int) (sizeof(Res_png_9patch))) { jniThrowRuntimeException(env, "Array too small for chunk."); @@ -88,13 +88,13 @@ public: } } - static void draw(JNIEnv* env, SkCanvas* canvas, SkRect& bounds, const SkBitmap* bitmap, + static void draw(JNIEnv* env, SkCanvas* canvas, SkRect& bounds, const SkBitmap& bitmap, Res_png_9patch* chunk, const SkPaint* paint, jint destDensity, jint srcDensity) { if (destDensity == srcDensity || destDensity == 0 || srcDensity == 0) { ALOGV("Drawing unscaled 9-patch: (%g,%g)-(%g,%g)", SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop), SkScalarToFloat(bounds.fRight), SkScalarToFloat(bounds.fBottom)); - NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL); + NinePatch_Draw(canvas, bounds, bitmap, *chunk, paint, NULL); } else { canvas->save(); @@ -111,25 +111,25 @@ public: SkScalarToFloat(bounds.fRight), SkScalarToFloat(bounds.fBottom), srcDensity, destDensity); - NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL); + NinePatch_Draw(canvas, bounds, bitmap, *chunk, paint, NULL); canvas->restore(); } } static void drawF(JNIEnv* env, jobject, jlong canvasHandle, jobject boundsRectF, - jlong bitmapHandle, jlong chunkHandle, jlong paintHandle, + jobject jbitmap, jlong chunkHandle, jlong paintHandle, jint destDensity, jint srcDensity) { SkCanvas* canvas = reinterpret_cast<Canvas*>(canvasHandle)->asSkCanvas(); - const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); Res_png_9patch* chunk = reinterpret_cast<Res_png_9patch*>(chunkHandle); const Paint* paint = reinterpret_cast<Paint*>(paintHandle); SkASSERT(canvas); SkASSERT(boundsRectF); - SkASSERT(bitmap); SkASSERT(chunk); // paint is optional + SkBitmap bitmap; + GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap); SkRect bounds; GraphicsJNI::jrectf_to_rect(env, boundsRectF, &bounds); @@ -137,36 +137,36 @@ public: } static void drawI(JNIEnv* env, jobject, jlong canvasHandle, jobject boundsRect, - jlong bitmapHandle, jlong chunkHandle, jlong paintHandle, + jobject jbitmap, jlong chunkHandle, jlong paintHandle, jint destDensity, jint srcDensity) { SkCanvas* canvas = reinterpret_cast<Canvas*>(canvasHandle)->asSkCanvas(); - const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); Res_png_9patch* chunk = reinterpret_cast<Res_png_9patch*>(chunkHandle); const Paint* paint = reinterpret_cast<Paint*>(paintHandle); SkASSERT(canvas); SkASSERT(boundsRect); - SkASSERT(bitmap); SkASSERT(chunk); // paint is optional + SkBitmap bitmap; + GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap); SkRect bounds; GraphicsJNI::jrect_to_rect(env, boundsRect, &bounds); draw(env, canvas, bounds, bitmap, chunk, paint, destDensity, srcDensity); } - static jlong getTransparentRegion(JNIEnv* env, jobject, jlong bitmapHandle, + static jlong getTransparentRegion(JNIEnv* env, jobject, jobject jbitmap, jlong chunkHandle, jobject boundsRect) { - const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); Res_png_9patch* chunk = reinterpret_cast<Res_png_9patch*>(chunkHandle); - SkASSERT(bitmap); SkASSERT(chunk); SkASSERT(boundsRect); + SkBitmap bitmap; + GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap); SkRect bounds; GraphicsJNI::jrect_to_rect(env, boundsRect, &bounds); SkRegion* region = NULL; - NinePatch_Draw(NULL, bounds, *bitmap, *chunk, NULL, ®ion); + NinePatch_Draw(NULL, bounds, bitmap, *chunk, NULL, ®ion); return reinterpret_cast<jlong>(region); } @@ -176,13 +176,16 @@ public: ///////////////////////////////////////////////////////////////////////////////////////// static JNINativeMethod gNinePatchMethods[] = { - { "isNinePatchChunk", "([B)Z", (void*) SkNinePatchGlue::isNinePatchChunk }, - { "validateNinePatchChunk", "(J[B)J", (void*) SkNinePatchGlue::validateNinePatchChunk }, - { "nativeFinalize", "(J)V", (void*) SkNinePatchGlue::finalize }, - { "nativeDraw", "(JLandroid/graphics/RectF;JJJII)V", (void*) SkNinePatchGlue::drawF }, - { "nativeDraw", "(JLandroid/graphics/Rect;JJJII)V", (void*) SkNinePatchGlue::drawI }, - { "nativeGetTransparentRegion", "(JJLandroid/graphics/Rect;)J", - (void*) SkNinePatchGlue::getTransparentRegion } + { "isNinePatchChunk", "([B)Z", (void*) SkNinePatchGlue::isNinePatchChunk }, + { "validateNinePatchChunk", "([B)J", + (void*) SkNinePatchGlue::validateNinePatchChunk }, + { "nativeFinalize", "(J)V", (void*) SkNinePatchGlue::finalize }, + { "nativeDraw", "(JLandroid/graphics/RectF;Landroid/graphics/Bitmap;JJII)V", + (void*) SkNinePatchGlue::drawF }, + { "nativeDraw", "(JLandroid/graphics/Rect;Landroid/graphics/Bitmap;JJII)V", + (void*) SkNinePatchGlue::drawI }, + { "nativeGetTransparentRegion", "(Landroid/graphics/Bitmap;JLandroid/graphics/Rect;)J", + (void*) SkNinePatchGlue::getTransparentRegion } }; int register_android_graphics_NinePatch(JNIEnv* env) { diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp index 50a1069..9b5fb3a 100644 --- a/core/jni/android_graphics_Canvas.cpp +++ b/core/jni/android_graphics_Canvas.cpp @@ -318,11 +318,12 @@ static void drawVertices(JNIEnv* env, jobject, jlong canvasHandle, indices, indexCount, *paint); } -static void drawBitmap(JNIEnv* env, jobject jcanvas, jlong canvasHandle, jlong bitmapHandle, +static void drawBitmap(JNIEnv* env, jobject jcanvas, jlong canvasHandle, jobject jbitmap, jfloat left, jfloat top, jlong paintHandle, jint canvasDensity, jint screenDensity, jint bitmapDensity) { Canvas* canvas = get_canvas(canvasHandle); - const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); + SkBitmap bitmap; + GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap); const Paint* paint = reinterpret_cast<Paint*>(paintHandle); if (canvasDensity == bitmapDensity || canvasDensity == 0 || bitmapDensity == 0) { @@ -332,9 +333,9 @@ static void drawBitmap(JNIEnv* env, jobject jcanvas, jlong canvasHandle, jlong b filteredPaint = *paint; } filteredPaint.setFilterQuality(kLow_SkFilterQuality); - canvas->drawBitmap(*bitmap, left, top, &filteredPaint); + canvas->drawBitmap(bitmap, left, top, &filteredPaint); } else { - canvas->drawBitmap(*bitmap, left, top, paint); + canvas->drawBitmap(bitmap, left, top, paint); } } else { canvas->save(SkCanvas::kMatrixClip_SaveFlag); @@ -348,37 +349,39 @@ static void drawBitmap(JNIEnv* env, jobject jcanvas, jlong canvasHandle, jlong b } filteredPaint.setFilterQuality(kLow_SkFilterQuality); - canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint); + canvas->drawBitmap(bitmap, 0, 0, &filteredPaint); canvas->restore(); } } -static void drawBitmapMatrix(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle, +static void drawBitmapMatrix(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap, jlong matrixHandle, jlong paintHandle) { - const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle); const Paint* paint = reinterpret_cast<Paint*>(paintHandle); - get_canvas(canvasHandle)->drawBitmap(*bitmap, *matrix, paint); + SkBitmap bitmap; + GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap); + get_canvas(canvasHandle)->drawBitmap(bitmap, *matrix, paint); } -static void drawBitmapRect(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle, +static void drawBitmapRect(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, jlong paintHandle, jint screenDensity, jint bitmapDensity) { Canvas* canvas = get_canvas(canvasHandle); - const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); const Paint* paint = reinterpret_cast<Paint*>(paintHandle); + SkBitmap bitmap; + GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap); if (screenDensity != 0 && screenDensity != bitmapDensity) { Paint filteredPaint; if (paint) { filteredPaint = *paint; } filteredPaint.setFilterQuality(kLow_SkFilterQuality); - canvas->drawBitmap(*bitmap, srcLeft, srcTop, srcRight, srcBottom, + canvas->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom, dstLeft, dstTop, dstRight, dstBottom, &filteredPaint); } else { - canvas->drawBitmap(*bitmap, srcLeft, srcTop, srcRight, srcBottom, + canvas->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom, dstLeft, dstTop, dstRight, dstBottom, paint); } } @@ -406,16 +409,17 @@ static void drawBitmapArray(JNIEnv* env, jobject, jlong canvasHandle, get_canvas(canvasHandle)->drawBitmap(bitmap, x, y, paint); } -static void drawBitmapMesh(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle, +static void drawBitmapMesh(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap, jint meshWidth, jint meshHeight, jfloatArray jverts, jint vertIndex, jintArray jcolors, jint colorIndex, jlong paintHandle) { const int ptCount = (meshWidth + 1) * (meshHeight + 1); AutoJavaFloatArray vertA(env, jverts, vertIndex + (ptCount << 1)); AutoJavaIntArray colorA(env, jcolors, colorIndex + ptCount); - const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); const Paint* paint = reinterpret_cast<Paint*>(paintHandle); - get_canvas(canvasHandle)->drawBitmapMesh(*bitmap, meshWidth, meshHeight, + SkBitmap bitmap; + GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap); + get_canvas(canvasHandle)->drawBitmapMesh(bitmap, meshWidth, meshHeight, vertA.ptr(), colorA.ptr(), paint); } @@ -700,11 +704,11 @@ static JNINativeMethod gMethods[] = { {"native_drawArc","(JFFFFFFZJ)V", (void*) CanvasJNI::drawArc}, {"native_drawPath","(JJJ)V", (void*) CanvasJNI::drawPath}, {"nativeDrawVertices", "(JII[FI[FI[II[SIIJ)V", (void*)CanvasJNI::drawVertices}, - {"native_drawBitmap","(JJFFJIII)V", (void*) CanvasJNI::drawBitmap}, - {"nativeDrawBitmapMatrix", "(JJJJ)V", (void*)CanvasJNI::drawBitmapMatrix}, - {"native_drawBitmap","(JJFFFFFFFFJII)V", (void*) CanvasJNI::drawBitmapRect}, + {"native_drawBitmap","(JLandroid/graphics/Bitmap;FFJIII)V", (void*) CanvasJNI::drawBitmap}, + {"nativeDrawBitmapMatrix", "(JLandroid/graphics/Bitmap;JJ)V", (void*)CanvasJNI::drawBitmapMatrix}, + {"native_drawBitmap","(JLandroid/graphics/Bitmap;FFFFFFFFJII)V", (void*) CanvasJNI::drawBitmapRect}, {"native_drawBitmap", "(J[IIIFFIIZJ)V", (void*)CanvasJNI::drawBitmapArray}, - {"nativeDrawBitmapMesh", "(JJII[FI[IIJ)V", (void*)CanvasJNI::drawBitmapMesh}, + {"nativeDrawBitmapMesh", "(JLandroid/graphics/Bitmap;II[FI[IIJ)V", (void*)CanvasJNI::drawBitmapMesh}, {"native_drawText","(J[CIIFFIJJ)V", (void*) CanvasJNI::drawTextChars}, {"native_drawText","(JLjava/lang/String;IIFFIJJ)V", (void*) CanvasJNI::drawTextString}, {"native_drawTextRun","(J[CIIIIFFZJJ)V", (void*) CanvasJNI::drawTextRunChars}, diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp index 0cf596c..f5f8b1f 100644 --- a/core/jni/android_hardware_SensorManager.cpp +++ b/core/jni/android_hardware_SensorManager.cpp @@ -134,13 +134,21 @@ getInternedString(JNIEnv *env, const String8* string) { return internedString; } +static jlong +nativeCreate +(JNIEnv *env, jclass clazz, jstring opPackageName) +{ + ScopedUtfChars opPackageNameUtf(env, opPackageName); + return (jlong) new SensorManager(String16(opPackageNameUtf.c_str())); +} + static jint -nativeGetNextSensor(JNIEnv *env, jclass clazz, jobject sensor, jint next) +nativeGetNextSensor(JNIEnv *env, jclass clazz, jlong sensorManager, jobject sensor, jint next) { - SensorManager& mgr(SensorManager::getInstance()); + SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); Sensor const* const* sensorList; - size_t count = mgr.getSensorList(&sensorList); + size_t count = mgr->getSensorList(&sensorList); if (size_t(next) >= count) { return -1; } @@ -174,9 +182,10 @@ nativeGetNextSensor(JNIEnv *env, jclass clazz, jobject sensor, jint next) return size_t(next) < count ? next : 0; } -static int nativeEnableDataInjection(JNIEnv *_env, jclass _this, jboolean enable) { - SensorManager& mgr(SensorManager::getInstance()); - return mgr.enableDataInjection(enable); +static int nativeEnableDataInjection(JNIEnv *_env, jclass _this, jlong sensorManager, + jboolean enable) { + SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); + return mgr->enableDataInjection(enable); } //---------------------------------------------------------------------------- @@ -281,12 +290,12 @@ private: } }; -static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jobject eventQWeak, jobject msgQ, - jfloatArray scratch, jstring packageName, jint mode) { - SensorManager& mgr(SensorManager::getInstance()); +static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager, + jobject eventQWeak, jobject msgQ, jfloatArray scratch, jstring packageName, jint mode) { + SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); ScopedUtfChars packageUtf(env, packageName); String8 clientName(packageUtf.c_str()); - sp<SensorEventQueue> queue(mgr.createEventQueue(clientName, mode)); + sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode)); sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ); if (messageQueue == NULL) { @@ -339,20 +348,23 @@ static JNINativeMethod gSystemSensorManagerMethods[] = { {"nativeClassInit", "()V", (void*)nativeClassInit }, + {"nativeCreate", + "(Ljava/lang/String;)J", + (void*)nativeCreate }, {"nativeGetNextSensor", - "(Landroid/hardware/Sensor;I)I", + "(JLandroid/hardware/Sensor;I)I", (void*)nativeGetNextSensor }, {"nativeEnableDataInjection", - "(Z)I", + "(JZ)I", (void*)nativeEnableDataInjection }, }; static JNINativeMethod gBaseEventQueueMethods[] = { {"nativeInitBaseEventQueue", - "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;[FLjava/lang/String;I)J", - (void*)nativeInitSensorEventQueue }, + "(JLjava/lang/ref/WeakReference;Landroid/os/MessageQueue;[FLjava/lang/String;ILjava/lang/String;)J", + (void*)nativeInitSensorEventQueue }, {"nativeEnableSensor", "(JIII)I", diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index d4fb572..2692ad8 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -270,49 +270,10 @@ static void read_mapinfo(FILE *fp, stats_t* stats) if ((strstr(name, "[heap]") == name)) { whichHeap = HEAP_NATIVE; - } else if (strncmp(name, "/dev/ashmem", 11) == 0) { - if (strncmp(name, "/dev/ashmem/dalvik-", 19) == 0) { - whichHeap = HEAP_DALVIK_OTHER; - if (strstr(name, "/dev/ashmem/dalvik-LinearAlloc") == name) { - subHeap = HEAP_DALVIK_LINEARALLOC; - } else if ((strstr(name, "/dev/ashmem/dalvik-alloc space") == name) || - (strstr(name, "/dev/ashmem/dalvik-main space") == name)) { - // This is the regular Dalvik heap. - whichHeap = HEAP_DALVIK; - subHeap = HEAP_DALVIK_NORMAL; - } else if (strstr(name, "/dev/ashmem/dalvik-large object space") == name) { - whichHeap = HEAP_DALVIK; - subHeap = HEAP_DALVIK_LARGE; - } else if (strstr(name, "/dev/ashmem/dalvik-non moving space") == name) { - whichHeap = HEAP_DALVIK; - subHeap = HEAP_DALVIK_NON_MOVING; - } else if (strstr(name, "/dev/ashmem/dalvik-zygote space") == name) { - whichHeap = HEAP_DALVIK; - subHeap = HEAP_DALVIK_ZYGOTE; - } else if (strstr(name, "/dev/ashmem/dalvik-indirect ref") == name) { - subHeap = HEAP_DALVIK_INDIRECT_REFERENCE_TABLE; - } else if (strstr(name, "/dev/ashmem/dalvik-jit-code-cache") == name) { - subHeap = HEAP_DALVIK_CODE_CACHE; - } else { - subHeap = HEAP_DALVIK_ACCOUNTING; // Default to accounting. - } - } else if (strncmp(name, "/dev/ashmem/CursorWindow", 24) == 0) { - whichHeap = HEAP_CURSOR; - } else if (strncmp(name, "/dev/ashmem/libc malloc", 23) == 0) { - whichHeap = HEAP_NATIVE; - } else { - whichHeap = HEAP_ASHMEM; - } } else if (strncmp(name, "[anon:libc_malloc]", 18) == 0) { whichHeap = HEAP_NATIVE; } else if (strncmp(name, "[stack", 6) == 0) { whichHeap = HEAP_STACK; - } else if (strncmp(name, "/dev/", 5) == 0) { - if (strncmp(name, "/dev/kgsl-3d0", 13) == 0) { - whichHeap = HEAP_GL_DEV; - } else { - whichHeap = HEAP_UNKNOWN_DEV; - } } else if (nameLen > 3 && strcmp(name+nameLen-3, ".so") == 0) { whichHeap = HEAP_SO; is_swappable = true; @@ -325,7 +286,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats) } else if (nameLen > 4 && strcmp(name+nameLen-4, ".ttf") == 0) { whichHeap = HEAP_TTF; is_swappable = true; - } else if ((nameLen > 4 && strcmp(name+nameLen-4, ".dex") == 0) || + } else if ((nameLen > 4 && strstr(name, ".dex") != NULL) || (nameLen > 5 && strcmp(name+nameLen-5, ".odex") == 0)) { whichHeap = HEAP_DEX; is_swappable = true; @@ -335,6 +296,45 @@ static void read_mapinfo(FILE *fp, stats_t* stats) } else if (nameLen > 4 && strcmp(name+nameLen-4, ".art") == 0) { whichHeap = HEAP_ART; is_swappable = true; + } else if (strncmp(name, "/dev/", 5) == 0) { + if (strncmp(name, "/dev/kgsl-3d0", 13) == 0) { + whichHeap = HEAP_GL_DEV; + } else if (strncmp(name, "/dev/ashmem", 11) == 0) { + if (strncmp(name, "/dev/ashmem/dalvik-", 19) == 0) { + whichHeap = HEAP_DALVIK_OTHER; + if (strstr(name, "/dev/ashmem/dalvik-LinearAlloc") == name) { + subHeap = HEAP_DALVIK_LINEARALLOC; + } else if ((strstr(name, "/dev/ashmem/dalvik-alloc space") == name) || + (strstr(name, "/dev/ashmem/dalvik-main space") == name)) { + // This is the regular Dalvik heap. + whichHeap = HEAP_DALVIK; + subHeap = HEAP_DALVIK_NORMAL; + } else if (strstr(name, "/dev/ashmem/dalvik-large object space") == name) { + whichHeap = HEAP_DALVIK; + subHeap = HEAP_DALVIK_LARGE; + } else if (strstr(name, "/dev/ashmem/dalvik-non moving space") == name) { + whichHeap = HEAP_DALVIK; + subHeap = HEAP_DALVIK_NON_MOVING; + } else if (strstr(name, "/dev/ashmem/dalvik-zygote space") == name) { + whichHeap = HEAP_DALVIK; + subHeap = HEAP_DALVIK_ZYGOTE; + } else if (strstr(name, "/dev/ashmem/dalvik-indirect ref") == name) { + subHeap = HEAP_DALVIK_INDIRECT_REFERENCE_TABLE; + } else if (strstr(name, "/dev/ashmem/dalvik-jit-code-cache") == name) { + subHeap = HEAP_DALVIK_CODE_CACHE; + } else { + subHeap = HEAP_DALVIK_ACCOUNTING; // Default to accounting. + } + } else if (strncmp(name, "/dev/ashmem/CursorWindow", 24) == 0) { + whichHeap = HEAP_CURSOR; + } else if (strncmp(name, "/dev/ashmem/libc malloc", 23) == 0) { + whichHeap = HEAP_NATIVE; + } else { + whichHeap = HEAP_ASHMEM; + } + } else { + whichHeap = HEAP_UNKNOWN_DEV; + } } else if (strncmp(name, "[anon:", 6) == 0) { whichHeap = HEAP_UNKNOWN; } else if (nameLen > 0) { diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp index a362684..39449b0 100644 --- a/core/jni/android_view_DisplayListCanvas.cpp +++ b/core/jni/android_view_DisplayListCanvas.cpp @@ -132,10 +132,10 @@ static jint android_view_DisplayListCanvas_getMaxTextureHeight(JNIEnv* env, jobj // ---------------------------------------------------------------------------- static void android_view_DisplayListCanvas_drawPatch(JNIEnv* env, jobject clazz, - jlong rendererPtr, jlong bitmapPtr, jlong patchPtr, + jlong rendererPtr, jobject jbitmap, jlong patchPtr, float left, float top, float right, float bottom, jlong paintPtr) { - SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); - + SkBitmap bitmap; + GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap); DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr); Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(patchPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); @@ -273,7 +273,7 @@ static JNINativeMethod gMethods[] = { { "nCallDrawGLFunction", "(JJ)V", (void*) android_view_DisplayListCanvas_callDrawGLFunction }, - { "nDrawPatch", "(JJJFFFFJ)V", (void*) android_view_DisplayListCanvas_drawPatch }, + { "nDrawPatch", "(JLandroid/graphics/Bitmap;JFFFFJ)V", (void*) android_view_DisplayListCanvas_drawPatch }, { "nDrawRects", "(JJJ)V", (void*) android_view_DisplayListCanvas_drawRegionAsRects }, { "nDrawRoundRect", "(JJJJJJJJ)V", (void*) android_view_DisplayListCanvas_drawRoundRectProps }, diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index a8355c2..1965cd3 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -23,6 +23,7 @@ #include "android_os_Parcel.h" #include "android_util_Binder.h" +#include "android/graphics/Bitmap.h" #include "android/graphics/GraphicsJNI.h" #include "android/graphics/Region.h" @@ -168,22 +169,19 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, } } - const ssize_t rowBytes = + const size_t rowBytes = screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat()); - SkBitmap* bitmap = new SkBitmap(); - bitmap->setInfo(screenshotInfo, (size_t)rowBytes); - if (screenshotInfo.fWidth > 0 && screenshotInfo.fHeight > 0) { - // takes ownership of ScreenshotClient - SkMallocPixelRef* pixels = SkMallocPixelRef::NewWithProc(screenshotInfo, - (size_t) rowBytes, NULL, (void*) screenshot->getPixels(), &DeleteScreenshot, - (void*) (screenshot.get())); - screenshot.detach(); - pixels->setImmutable(); - bitmap->setPixelRef(pixels)->unref(); - bitmap->lockPixels(); + if (!screenshotInfo.fWidth || !screenshotInfo.fHeight) { + return NULL; } + Bitmap* bitmap = new Bitmap( + (void*) screenshot->getPixels(), (void*) screenshot.get(), DeleteScreenshot, + screenshotInfo, rowBytes, nullptr); + screenshot.detach(); + bitmap->pixelRef()->setImmutable(); + return GraphicsJNI::createBitmap(env, bitmap, GraphicsJNI::kBitmapCreateFlag_Premultiplied, NULL); } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 942e6a6..a162b4a 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2433,6 +2433,12 @@ <permission android:name="android.permission.QUERY_DO_NOT_ASK_CREDENTIALS_ON_BOOT" android:protectionLevel="signature" /> + <!-- @SystemApi Allows applications to kill UIDs. + <p>Not for use by third-party applications. + @hide --> + <permission android:name="android.permission.KILL_UID" + android:protectionLevel="signature" /> + <!-- The system process is explicitly the only one allowed to launch the confirmation UI for full backup/restore --> <uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index ad596db..922db05 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Stel op"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Haal uit"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Verken"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ontbreek"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Sit hierdie toestel weer in"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Skuif tans <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Skuif tans data"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Skuif voltooi"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Data na <xliff:g id="NAME">%s</xliff:g> geskuif"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Kon nie data skuif nie"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Data oor op oorspronklike ligging"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Geen passende aktiwiteite gevind nie."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Roeteer media-uitvoer"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Laat \'n program toe om media-uitvoere na ander eksterne toestelle te roeteer."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Vra ontsluitpatroon voordat jy ontspeld"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Vra wagwoord voordat jy ontspeld"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Deur jou administrateur geïnstalleer"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Deur jou administrateur uitgevee"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Om batterylewe te help verbeter, verminder batterybespaarder jou toestel se werkverrigting en beperk vibrasie, liggingdienste en die meeste agtergronddata. E-pos, boodskappe en ander programme wat op sinkronisering staatmaak, sal dalk nie opdateer tensy jy hulle oopmaak nie.\n\nBatterybespaarder skakel outomaties af wanneer jou toestel besig is om te laai."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 827d662..ad6605a 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"አዋቅር"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"አስወጣ"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"ያስሱ"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ይጎድላል"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"ይህን መሣሪያ ዳግም ያስገቡ"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g>ን በመውሰድ ላይ"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"ውሂብን በመውሰድ ላይ"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"መውሰድ ተጠናቅቋል"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"ውሂብ ወደ <xliff:g id="NAME">%s</xliff:g> ተወስዷል"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"ውሂብ መውሰድ አልተቻለም"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"ውሂብ በመጀመሪያው አካባቢ ላይ ተትቷል"</string> <string name="activity_list_empty" msgid="1675388330786841066">"ምንም ተመሳሳይ እንቅስቃሴዎች አልተገኙም።"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"የሚዲያ ውፅአት መንገድ"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"አንድ መተግበሪያ የሚዲያ ውፅአትን ወደ ሌላ ውጫዊ መሳሪያ እንዲመራ ይፈቅድለታል።"</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ከመንቀል በፊት የማስከፈቻ ስርዓተ-ጥለት ጠይቅ"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ከመንቀል በፊት የይለፍ ቃል ጠይቅ"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"በእርስዎ አስተዳዳሪ ተጭኗል"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"በእርስዎ አስተዳዳሪ ተሰርዟል"</string> <string name="battery_saver_description" msgid="1960431123816253034">"የባትሪ ዕድሜን ለማሻሻል ማገዝ እንዲቻል፣ ኢሜይል፣ መልዕክት አላላክ እና ሌሎች በማመሳሰል ላይ የሚመረኮዙ መተግበሪያዎች እርስዎ ካልከፈቱዋቸው በቀር አይዘምኑም።\n\nየባትሪ ኃይል ቆጣቢ የእርስዎ መሣሪያ ኃይል በሚሞላበት ጊዜ በራስ-ሰር ይጠፋል።"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 9b3672a..3591a37 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1106,22 +1106,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"الإعداد"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"إلغاء"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"استكشاف"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> مفقود"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"أعد إدخال هذا الجهاز"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"جارٍ نقل <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"جارٍ نقل البيانات"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"اكتمل النقل"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"تم نقل البيانات إلى <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"تعذر نقل البيانات"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"تم ترك البيانات في الموقع الأصلي"</string> <string name="activity_list_empty" msgid="1675388330786841066">"لم يتم العثور على أي أنشطة متطابقة."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"توجيه إخراج الوسائط"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"للسماح للتطبيق بتوجيه إخراج الوسائط إلى أجهزة خارجية أخرى."</string> @@ -1502,6 +1494,7 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"المطالبة بنقش إلغاء القفل قبل إزالة التثبيت"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"المطالبة بكلمة المرور قبل إزالة التثبيت"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"تم تثبيت الحزمة عن طريق المشرف"</string> + <string name="package_updated_device_owner" msgid="8856631322440187071">"تم التحديث بواسطة المشرف"</string> <string name="package_deleted_device_owner" msgid="7650577387493101353">"تم حذف الحزمة عن طريق المشرف"</string> <string name="battery_saver_description" msgid="1960431123816253034">"للمساعدة في تحسين عمر البطارية، يساعد موفر البطارية في تقليل أداء الجهاز ويفرض قيدًا على الاهتزاز وخدمات الموقع ومعظم بيانات الخلفية. قد لا يتم تحديث البريد الإلكتروني والمراسلة والتطبيقات الأخرى التي تعتمد على المزامنة ما لم تفتحها.\n\nيتم إيقاف موفر البطارية تلقائيًا أثناء شحن الجهاز."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index a7a4742..d173305 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Настройване"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Изваждане"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Изследване"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Липсва <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Поставете отново това у-во"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> се премества"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Данните се преместват"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Преместването завърши"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Данните са преместени в/ъв <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Данните не бяха преместени"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Данните останаха в първоначалното местоположение"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Не бяха намерени съответстващи дейности."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Насочване на изходящата мултимедия"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Разрешава на приложението да насочва изходящата мултимедия към други външни устройства."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Запитване за фигура за отключване преди освобождаване"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запитване за парола преди освобождаване"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Инсталирано от администратора ви"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Изтрито от администратора ви"</string> <string name="battery_saver_description" msgid="1960431123816253034">"С цел удължаване на живота на батерията режимът за запазването й намалява ефективността на устройството ви и ограничава вибрирането, услугите за местоположение и повечето данни на заден план. Приложенията за електронна поща, съобщения и др., които разчитат на синхронизиране, може да не се актуализират, освен ако не ги отворите.\n\nРежимът за запазване на батерията се изключва автоматично, когато устройството ви се зарежда."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml index af2eb07..cec614b 100644 --- a/core/res/res/values-bn-rBD/strings.xml +++ b/core/res/res/values-bn-rBD/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"সেটআপ"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"বের করে নিন"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"ঘুরে দেখুন"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> অনুপস্থিত"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"এই ডিভাইসটিকে পুনরায় সন্নিবেশ করান"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> সরানো হচ্ছে"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"ডেটা সরানো হচ্ছে"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"সরানো সম্পূর্ণ হয়েছে"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"ডেটা <xliff:g id="NAME">%s</xliff:g> এ সরানো হয়েছে"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"ডেটা সরানো যায়নি"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"মূল অবস্থানে ডেটা রাখুন"</string> <string name="activity_list_empty" msgid="1675388330786841066">"কোনো সমরূপ কার্যকলাপ খুঁজে পাওয়া যায়নি৷"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"মিডিয়া আউটপুট রুট করুন"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"অ্যাপ্লিকেশানটিকে অন্যান্য বহিরাগত ডিভাইসে মিডিয়া আউটপুট রুট করার অনুমতি দেয়৷"</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"আনপিন করার আগে আনলক প্যাটার্ন চান"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"আনপিন করার আগে পাসওয়ার্ড চান"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"আপনার প্রশাসক দ্বারা ইনস্টল করা হয়েছে"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"আপনার প্রশাসক দ্বারা মুছে ফেলা হয়েছে"</string> <string name="battery_saver_description" msgid="1960431123816253034">"ব্যাটরির লাইফ উন্নত করতে সহায়তা করতে, ব্যাটারি সাশ্রয়কারী আপনার ডিভাইসের কার্যসম্পাদনা হ্রাস করে এবং কম্পন, অবস্থান পরিষেবাসমূহ এবং অধিকাংশ ব্যাকগ্রাউন্ড ডেটা সীমিত করে৷ ইমেল, বার্তাপ্রেরণ এবং অন্যান্য অ্যাপ্লিকেশানগুলিকে যেগুলি সিঙ্কের উপর নির্ভর করে সেগুলিকে আপনি না খোলা পর্যন্ত নাও আপডেট হতে পারে৷\n\nআপনার ডিভাইসটিকে যখন চার্জ করা হয় তখন ব্যাটারি সাশ্রয়কারী স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যায়৷"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 394c520..8a726f7 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Configura"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Expulsa"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Explora"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"No es detecta <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Torna a inserir el dispositiu"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"S\'està desplaçant l\'aplicació <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"S\'estan desplaçant dades"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"S\'ha completat el desplaçament"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"S\'han desplaçat dades a <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"No s\'han pogut desplaçar dades"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"S\'han deixat dades a la ubicació original"</string> <string name="activity_list_empty" msgid="1675388330786841066">"No s\'ha trobat cap activitat coincident."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Indicació de ruta de sortida de contingut multimèdia"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permet que una aplicació indiqui la ruta de sortida de contingut multimèdia a altres dispositius externs."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Sol·licita el patró de desbloqueig per anul·lar la fixació"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demana la contrasenya abans d\'anul·lar la fixació"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"L\'administrador ho ha instal·lat"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"L\'administrador ho ha suprimit"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Per allargar la durada de la bateria, l\'estalvi de bateria redueix el rendiment del dispositiu i limita l\'ús de la vibració, dels serveis d\'ubicació i de la majoria de les dades en segon pla. És possible que el correu electrònic, la missatgeria i altres aplicacions que depenen de la sincronització no s\'actualitzin fins que els obris.\n\nL\'estalvi de bateria es desactiva de manera automàtica quan el dispositiu es posa a carregar."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 90d0ba2..b02bbe3 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -1092,22 +1092,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Nastavení"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Odpojit"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Prozkoumat"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> chybí"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Znovu toto zařízení vložte"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Přesouvání aplikace <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Probíhá přesun dat"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Přesunutí bylo dokončeno"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Data byla přesunuta do úložiště <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Data nelze přesunout"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Data zůstala v původním umístění"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Nebyly nalezeny žádné odpovídající aktivity."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Směrování výstupu médií"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Umožňuje aplikaci směrovat výstup médií do dalších externích zařízení."</string> @@ -1484,6 +1476,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Před uvolněním požádat o bezpečnostní gesto"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Před uvolněním požádat o heslo"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Nainstalováno administrátorem"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Smazáno administrátorem"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Spořič baterie za účelem prodloužení výdrže baterie snižuje výkon zařízení a omezuje vibrace, služby určování polohy a většinu dat na pozadí. E-mail, aplikace pro zasílání zpráv a další aplikace, které používají synchronizaci, se nemusejí aktualizovat, dokud je neotevřete.\n\nPři nabíjení zařízení se spořič baterie automaticky vypne."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 7ec459f..43e2c95 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Konfigurer"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Skub ud"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Udforsk"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> er ikke til stede"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Sæt denne enhed i igen"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Flytter <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Flytter data"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Flytningen er gennemført"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Data flyttes til <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Dine data kunne ikke flyttes"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Dine data er stadig på den oprindelige placering"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Der blev ikke fundet nogen matchende aktiviteter."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Viderefør medieoutput"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Tillader, at en applikation viderefører medieoutput til andre eksterne enheder."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Bed om oplåsningsmønster ved deaktivering"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Bed om adgangskode inden frigørelse"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Installeret af din administrator"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Slettet af din administrator"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Batterisparefunktionen hjælper med at forlænge batteriets levetid ved at reducere enhedens ydeevne og begrænse vibration, placeringstjenester og det meste baggrundsdata. E-mail, beskedfunktioner og andre apps, der benytter synkronisering, opdateres muligvis ikke, medmindre du åbner dem.\n\nBatterisparefunktionen slukker automatisk, når enheden oplader."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 4bd91f2..975bc0a 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Einrichten"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Auswerfen"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Entdecken"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> fehlt"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Dieses Medium wieder einlegen"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> wird verschoben"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Daten werden verschoben"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Verschieben abgeschlossen"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Daten auf <xliff:g id="NAME">%s</xliff:g> verschoben"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Fehler bei Datenverschiebung"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Daten verbleiben am ursprünglichen Speicherort"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Keine passenden Aktivitäten gefunden"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Medienausgabe umleiten"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Ermöglicht der App, die Medienausgabe auf andere externe Geräte umzuleiten."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Vor dem Beenden nach Entsperrungsmuster fragen"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Vor dem Beenden nach Passwort fragen"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Von Ihrem Administrator installiert"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Von Ihrem Administrator gelöscht"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Der Energiesparmodus schont den Akku, indem er die Leistung des Geräts reduziert und die Vibrationsfunktion sowie die meisten Hintergrunddatenaktivitäten einschränkt. E-Mail, SMS/MMS und andere Apps, die auf Ihrem Gerät synchronisiert werden, werden möglicherweise erst nach dem Öffnen aktualisiert.\n\nDer Energiesparmodus wird automatisch deaktiviert, wenn Ihr Gerät aufgeladen wird."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 836ed89..4d79581 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Ρύθμιση"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Εξαγωγή"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Εξερεύνηση"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Λείπει το μέσο <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Τοποθετήστε ξανά τη συσκευή"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Μετακίνηση <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Μετακίνηση δεδομένων"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Η μετακίνηση ολοκληρώθηκε"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Τα δεδομένα μεταφέρθηκαν σε <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Αδύνατη μετακίνηση των δεδομένων"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Δεδομένα που απέμειναν στην αρχική τοποθεσία"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Δεν βρέθηκαν δραστηριότητες που να συμφωνούν με τα κριτήρια."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Διαγραφή διαδρομής δεδομένων εξόδου μέσων"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Επιτρέπει σε μια εφαρμογή τη διαγραφή διαδρομής δεδομένων εξόδου μέσων σε άλλες εξωτερικές συσκευές."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Να γίνεται ερώτηση για το μοτίβο ξεκλειδώματος, πριν από το ξεκαρφίτσωμα"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Να γίνεται ερώτηση για τον κωδικό πρόσβασης, πριν από το ξεκαρφίτσωμα"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Εγκαταστάθηκε από το διαχειριστή σας"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Διαγράφηκε από το διαχειριστή σας"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Προκειμένου να βελτιώσει τη διάρκεια ζωής της μπαταρίας σας, η Εξοικονόμηση μπαταρίας μειώνει την απόδοση της συσκευής σας και περιορίζει λειτουργίες όπως η δόνηση, οι υπηρεσίες τοποθεσίας και τα περισσότερα δεδομένα παρασκηνίου. Το ηλεκτρονικό ταχυδρομείο, η ανταλλαγή μηνυμάτων και άλλες εφαρμογές που βασίζονται στο συγχρονισμό ενδέχεται να μην ενημερώνονται έως ότου τις ανοίξετε.\n\nΗ Εξοικονόμηση μπαταρίας απενεργοποιείται αυτόματα όταν η συσκευή σας φορτίζει."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 031f165..8bd4b57 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Set up"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Eject"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Explore"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> missing"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Reinsert this device"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Moving <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Moving data"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Move complete"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Data moved to <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Couldn\'t move data"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Data left at original location"</string> <string name="activity_list_empty" msgid="1675388330786841066">"No matching activities found."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Route media output"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Allows an application to route media output to other external devices."</string> @@ -1466,6 +1458,7 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Ask for unlock pattern before unpinning"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Ask for password before unpinning"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Installed by your administrator"</string> + <string name="package_updated_device_owner" msgid="8856631322440187071">"Updated by your administrator"</string> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Deleted by your administrator"</string> <string name="battery_saver_description" msgid="1960431123816253034">"To help improve battery life, battery saver reduces your device’s performance and limits vibration, location services and most background data. Email, messaging, and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 031f165..8bd4b57 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Set up"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Eject"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Explore"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> missing"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Reinsert this device"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Moving <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Moving data"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Move complete"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Data moved to <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Couldn\'t move data"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Data left at original location"</string> <string name="activity_list_empty" msgid="1675388330786841066">"No matching activities found."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Route media output"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Allows an application to route media output to other external devices."</string> @@ -1466,6 +1458,7 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Ask for unlock pattern before unpinning"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Ask for password before unpinning"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Installed by your administrator"</string> + <string name="package_updated_device_owner" msgid="8856631322440187071">"Updated by your administrator"</string> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Deleted by your administrator"</string> <string name="battery_saver_description" msgid="1960431123816253034">"To help improve battery life, battery saver reduces your device’s performance and limits vibration, location services and most background data. Email, messaging, and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 031f165..8bd4b57 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Set up"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Eject"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Explore"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> missing"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Reinsert this device"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Moving <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Moving data"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Move complete"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Data moved to <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Couldn\'t move data"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Data left at original location"</string> <string name="activity_list_empty" msgid="1675388330786841066">"No matching activities found."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Route media output"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Allows an application to route media output to other external devices."</string> @@ -1466,6 +1458,7 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Ask for unlock pattern before unpinning"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Ask for password before unpinning"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Installed by your administrator"</string> + <string name="package_updated_device_owner" msgid="8856631322440187071">"Updated by your administrator"</string> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Deleted by your administrator"</string> <string name="battery_saver_description" msgid="1960431123816253034">"To help improve battery life, battery saver reduces your device’s performance and limits vibration, location services and most background data. Email, messaging, and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 656abbf..f5cf89b 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Configuración"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Expulsar"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Explorar"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"No se encuentra dispositivo <xliff:g id="NAME">%s</xliff:g>."</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Volver a insertar dispositivo"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Transfiriendo la aplicación <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Transfiriendo los datos"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Transferencia completa"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Se transfirieron los datos a <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"No se pudieron transferir datos."</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Los datos quedaron en la ubicación original"</string> <string name="activity_list_empty" msgid="1675388330786841066">"No se encontraron actividades coincidentes."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Dirigir salida de medios"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que la aplicación dirija salidas de medios a otros dispositivos externos."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Solicitar patrón de desbloqueo para quitar fijación"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicitar contraseña para quitar fijación"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Lo instaló el administrador."</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Lo eliminó el administrador."</string> <string name="battery_saver_description" msgid="1960431123816253034">"Para ayudar a mejorar la duración de la batería, el ahorro de batería reduce el rendimiento del dispositivo y limita la vibración, los servicios de ubicación y la mayoría de los datos en segundo plano. Es posible que el correo electrónico, la mensajería y otras aplicaciones que se basan en la sincronización no puedan actualizarse, a menos que los abras.\n\nEl ahorro de batería se desactiva de forma automática cuando el dispositivo se está cargando."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index fe8c676..be2e58a 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Configurar"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Expulsar"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Explorar"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Falta <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Volver a insertar dispositivo"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Moviendo <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Moviendo datos"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Datos movidos"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Datos movidos a <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"No se pudieron mover los datos"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Han quedado datos en la ubicación original"</string> <string name="activity_list_empty" msgid="1675388330786841066">"No se ha encontrado ninguna actividad coincidente."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Dirigir salida de medio"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que la aplicación dirija salidas de medios a otros dispositivos externos."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Solicitar patrón de desbloqueo para desactivar"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicitar contraseña para desactivar"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalado por tu administrador"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminado por tu administrador"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Para ayudar a mejorar la duración de la batería, la función de ahorro de energía reduce el rendimiento del dispositivo y limita la vibración, los servicios de ubicación y la mayor parte de la transmisión de datos en segundo plano. Es posible que las aplicaciones que se sincronizan, como las de correo y mensajes, no se actualicen a menos que las abras.\n\nLa función de ahorro de energía se desactiva automáticamente cuando el dispositivo se está cargando."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml index 7259886..735b56d 100644 --- a/core/res/res/values-et-rEE/strings.xml +++ b/core/res/res/values-et-rEE/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Seadistamine"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Eemaldamine"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Avastamine"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Üksust <xliff:g id="NAME">%s</xliff:g> pole"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Sisestage see seade uuesti"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Seadme <xliff:g id="NAME">%s</xliff:g> teisaldamine"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Andmete teisaldamine"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Teisaldamine lõpetati"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Andmed teisaldati üksusesse <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Andmeid ei saanud teisaldada"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Andmed on algses asukohas alles"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Sobivat tegevust ei leitud"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Meediaväljundi teekonna koostamine"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Võimaldab rakendusel koostada teekonna meediaväljundist teistesse välistesse seadmetesse."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Enne vabastamist küsi avamismustrit"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Enne vabastamist küsi parooli"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Installis teie administraator"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Kustutas teie administraator"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Aku kestuse parandamiseks vähendab akusäästja teie seadme toimivust ning piirab vibratsiooni, asukohateenuseid ja suuremat osa taustaandmetest. E-posti, sõnumsidet ja muid sünkroonimisele tuginevaid rakendusi võidakse värskendada ainult siis, kui te need avate.\n\nAkusäästja lülitatakse seadme laadimise ajal automaatselt välja."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml index f12151c..25e8308 100644 --- a/core/res/res/values-eu-rES/strings.xml +++ b/core/res/res/values-eu-rES/strings.xml @@ -275,7 +275,7 @@ <string name="permlab_getTasks" msgid="6466095396623933906">"Eskuratu abian diren aplikazioak"</string> <string name="permdesc_getTasks" msgid="7454215995847658102">"Unean edo duela gutxi exekutatutako zereginei buruzko informazioa lortzeko baimena ematen die aplikazioei. Horrela, aplikazioak gailuan erabiltzen ari diren aplikazioei buruzko informazioa ezagut dezake."</string> <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Kudeatu profilen eta gailuen jabeak"</string> - <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Profilaren eta gailuaren jabeak zehazteko baimena ematen die aplikazioei"</string> + <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Profilaren eta gailuaren jabeak zehazteko baimena ematen die aplikazioei."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"Ordenatu abian diren aplikazioak"</string> <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Zereginak aurreko eta atzeko planora eramateko baimena ematen die aplikazioei. Aplikazioak zuk ezer egin gabe egin dezake hori."</string> <string name="permlab_enableCarMode" msgid="5684504058192921098">"gaitu auto modua"</string> @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Konfigurazioa"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Atera"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Arakatu"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Ez dago <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Sartu gailua berriro"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> mugitzen"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Datuak mugitzen"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Mugitu dira datuak"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Mugitu dira datuak <xliff:g id="NAME">%s</xliff:g> gailura"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Ezin izan dira mugitu datuak"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Jatorrizko tokian utzi dira datuak"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Ez da bat datorren jarduerarik aurkitu."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Multimedia-irteera bideratzea"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Multimedia elementuak kanpoko gailuetara bideratzeko baimena ematen die aplikazioei."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Eskatu desblokeatzeko eredua aingura kendu aurretik"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Eskatu pasahitza aingura kendu aurretik"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Administratzaileak instalatu du"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Administratzaileak ezabatu du"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Bateriak gehiago iraun dezan, bateria-aurrezleak gailuaren funtzionamendua, dardara, kokapen-zerbitzuak eta atzeko planoko datuen erabilera gehiena mugatzen ditu. Posta elektronikoa, mezuak eta sinkronizatzen diren gainerako zerbitzuak ez dira eguneratuko ireki ezean.\n\nGailua kargatzen ezarri orduko desaktibatzen da bateria-aurrezlea."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 2808a78..93caee260 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"تنظیم"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"بیرون راندن"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"کاوش"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> وجود ندارد"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"جاگذاری مجدد این دستگاه"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"در حال انتقال <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"در حال انتقال اطلاعات"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"انتقال کامل شد"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"اطلاعات به <xliff:g id="NAME">%s</xliff:g> منتقل شد"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"اطلاعات منتقل نشدند"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"اطلاعات در مکان اصلی باقی ماندند"</string> <string name="activity_list_empty" msgid="1675388330786841066">"فعالیتی مطابق با این مورد یافت نشد."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"تعیین مسیر خروجی رسانه"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"به یک برنامه اجازه میدهد خروجی رسانه را به دستگاههای خارجی دیگر تعیین مسیر کند."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"درخواست الگوی باز کردن قفل قبل از برداشتن پین"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"درخواست گذرواژه قبل از برداشتن پین"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"توسط سرپرستتان نصب شد"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"توسط سرپرستتان حذف شد"</string> <string name="battery_saver_description" msgid="1960431123816253034">"برای کمک به بهبود ماندگاری باتری، ابزار صرفهجویی در مصرف باتری عملکرد دستگاهتان را کاهش میدهد و لرزش، سرویسهای مبتنی بر مکان، و دسترسی به اکثر دادهها در پسزمینه را محدود میکند. ایمیل، پیامرسانی و برنامههای دیگری که به همگامسازی متکی هستند، تا زمانی که آنها را باز نکنید نمیتوانند بهروز شوند.\n\nابزار صرفهجویی در مصرف باتری به صورت خودکار در هنگام شارژ شدن دستگاه خاموش میشود."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 1d71bd1..79aa234 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Asennus"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Poista"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Tutustu"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> puuttuu."</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Liitä tämä laite uudelleen."</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Siirretään <xliff:g id="NAME">%s</xliff:g>."</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Siirretään tietoja."</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Siirto on valmis."</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Tiedot on siirretty kohteeseen <xliff:g id="NAME">%s</xliff:g>."</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Tietojen siirto epäonnistui."</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Tietoja jäi alkuperäiseen paikkaan."</string> <string name="activity_list_empty" msgid="1675388330786841066">"Osuvia toimintoja ei löytynyt."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Median reititys"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Antaa sovelluksen reitittää mediaa muihin ulkoisiin laitteisiin."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pyydä lukituksenpoistokuvio ennen irrotusta"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pyydä salasana ennen irrotusta"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Järjestelmänvalvoja on asentanut paketin."</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Järjestelmänvalvoja on poistanut paketin."</string> <string name="battery_saver_description" msgid="1960431123816253034">"Jos haluat parantaa akun kestoa, virransäästö vähentää laitteesi suorituskykyä ja rajoittaa värinää, sijaintipalveluita ja useimpia taustatietoja. Sähköposti, viestit ja muut synkronointiin perustuvat sovellukset eivät välttämättä päivity, ellet avaa niitä.\n\nVirransäästö poistuu käytöstä automaattisesti, kun laitteesi latautuu."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 2b81a18..f76a253 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Configuration"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Éjecter"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Découvrir"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Mémoire de stockage <xliff:g id="NAME">%s</xliff:g> manquante"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Réinsérez le dispositif"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Déplacement de <xliff:g id="NAME">%s</xliff:g> en cours..."</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Déplacement des données..."</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Déplacement terminé"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Données déplacées vers <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Imposs. de déplacer les données"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Les données sont restées à l\'emplacement d\'origine"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Aucune activité correspondante trouvée."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Diriger la sortie multimédia"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permet à une application de diriger la sortie multimédia vers d\'autres appareils externes."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Demander le schéma de déverrouillage avant d\'annuler l\'épinglage"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demander le mot de passe avant d\'annuler l\'épinglage"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Installé par votre administrateur"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Supprimé par votre administrateur"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Pour améliorer l\'autonomie de la pile, la fonction d\'économie d\'énergie réduit les performances de votre appareil et limite la vibration, les services de localisation ainsi que la plupart des données en arrière-plan. Les applications Courriel, Messages et d\'autres qui reposent sur la synchronisation ne peuvent pas se mettre à jour, sauf si vous les ouvrez. \n\n L\'économiseur d\'énergie se désactive automatiquement lorsque votre appareil est en charge."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 55c4f5d..e777106 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Configurer"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Éjecter"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Parcourir"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Mémoire de stockage \"<xliff:g id="NAME">%s</xliff:g>\" manquante"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Réinsérez cette mémoire."</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Transfert de l\'application <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Déplacement des données en cours"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Transfert terminé"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Les données ont bien été transférées sur la mémoire de stockage \"<xliff:g id="NAME">%s</xliff:g>\""</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Impossible de transférer données"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Les données sont restées à l\'emplacement d\'origine"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Aucune activité correspondante trouvée."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Diriger la sortie multimédia"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permet à une application de diriger la sortie multimédia vers d\'autres appareils externes."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Demander le schéma de déverrouillage avant d\'annuler l\'épinglage"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demander le mot de passe avant d\'annuler l\'épinglage"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Installé par votre administrateur"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Supprimé par votre administrateur"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Pour améliorer l\'autonomie de la batterie, l\'économiseur de batterie réduit les performances de votre appareil, et il désactive le vibreur, les services de localisation et la plupart des données en arrière-plan. La messagerie électronique, les SMS/MMS et les autres applications basées sur la synchronisation ne sont mises à jour que si vous les ouvrez.\n\nL\'économiseur de batterie s\'éteint automatiquement lorsque votre appareil est en charge."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml index c2c67bc..c6e2247 100644 --- a/core/res/res/values-gl-rES/strings.xml +++ b/core/res/res/values-gl-rES/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Configuración"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Expulsar"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Explorar"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Falta <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Volve inserir o dispositivo"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Migrando <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Migrando datos"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Migración completa"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Migráronse os datos a <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Non se puideron migrar os datos"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Quedan datos na localización orixinal"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Non se atoparon actividades que coincidan."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Dirixir saída multimedia"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite a unha aplicación dirixir a saída multimedia a outros dispositivos externos."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Solicitar un padrón de desbloqueo antes de soltar a pantalla"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicitar un contrasinal antes de soltar a pantalla"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalado polo administrador"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminado polo administrador"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Para axudar a mellorar a duración da batería, a función aforro de batería reduce o rendemento do teu dispositivo e limita a vibración, os servizos de localización e a maioría dos datos en segundo plano. É posible que o correo electrónico, as mensaxes e outras aplicacións que dependen da sincronización non se actualicen a menos que os abras. \n\nA función aforro de batería desactívase automaticamente cando pos a cargar o teu dispositivo."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml index 2a3df74..5e9e6be 100644 --- a/core/res/res/values-gu-rIN/strings.xml +++ b/core/res/res/values-gu-rIN/strings.xml @@ -274,10 +274,8 @@ <string name="permdesc_receiveWapPush" msgid="748232190220583385">"એપ્લિકેશનને WAP સંદેશા પ્રાપ્ત કરવાની અને તેના પર પ્રક્રિયા કરવાની મંજૂરી આપે છે. આ પરવાનગીમાં તમને દર્શાવ્યા વિના તમને મોકલેલ સંદેશાઓનું નિરીક્ષણ કરવાની અને કાઢી નાખવાની ક્ષમતાનો સમાવેશ થાય છે."</string> <string name="permlab_getTasks" msgid="6466095396623933906">"ચાલુ એપ્લિકેશન્સ પુનઃપ્રાપ્ત કરો"</string> <string name="permdesc_getTasks" msgid="7454215995847658102">"એપ્લિકેશનને વર્તમાનમાં અને તાજેતરમાં ચાલી રહેલ કાર્યો વિશેની વિગતવાર માહિતી પુનઃપ્રાપ્ત કરવાની મંજૂરી આપે છે. આ એપ્લિકેશનને ઉપકરણ પર કઈ એપ્લિકેશન્સનો ઉપયોગ થાય છે તેના વિશેની માહિતી શોધવાની મંજૂરી આપી શકે છે."</string> - <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) --> - <skip /> - <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) --> - <skip /> + <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"પ્રોફાઇલ અને ઉપકરણ માલિકોને સંચાલિત કરો"</string> + <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"એપ્લિકેશન્સને પ્રોફાઇલ માલિકો અને ઉપકરણ માલિકો સેટ કરવાની મંજૂરી આપે છે."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"ચાલુ એપ્લિકેશન્સને ફરી ગોઠવો"</string> <string name="permdesc_reorderTasks" msgid="7734217754877439351">"એપ્લિકેશનને અગ્રભૂમિ અને પૃષ્ટભૂમિમાં કાર્યો ખસેડવાની મંજૂરી આપે છે. તમારા ઇનપુટ વિના એપ્લિકેશન આ કરી શકે છે."</string> <string name="permlab_enableCarMode" msgid="5684504058192921098">"કાર મોડ સક્ષમ કરો"</string> @@ -1080,6 +1078,22 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"સેટઅપ"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"બહાર કાઢો"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"અન્વેષણ કરો"</string> + <!-- no translation found for ext_media_missing_title (620980315821543904) --> + <skip /> + <!-- no translation found for ext_media_missing_message (5761133583368750174) --> + <skip /> + <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> + <skip /> + <!-- no translation found for ext_media_move_title (1022809140035962662) --> + <skip /> + <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> + <skip /> + <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> + <skip /> + <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> + <skip /> + <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> + <skip /> <string name="activity_list_empty" msgid="1675388330786841066">"કોઈ મેળ ખાતી પ્રવૃત્તિઓ મળી નથી."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"મીડિયા આઉટપુટ રૂટ કરો"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"એપ્લિકેશનને અન્ય બાહ્ય ઉપકરણો પર મીડિયા આઉટપુટને રૂટ કરવની મંજૂરી આપે છે."</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 5d954e2..9c4df9a 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"सेट करें"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"निकालें"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"एक्सप्लोर करें"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> गुम है"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"इस डिवाइस को पुन: लगाएं"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> को ले जाया जा रहा है"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"डेटा ले जाया जा रहा है"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"ले जाना पूर्ण हुआ"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"डेटा को <xliff:g id="NAME">%s</xliff:g> पर ले जाया गया"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"डेटा नहीं ले जाया जा सका"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"डेटा मूल स्थान पर छूट गया है"</string> <string name="activity_list_empty" msgid="1675388330786841066">"कोई मिलती-जुलती गतिविधि नहीं मिली."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"मीडिया आउटपुट को रूट करें"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"ऐप्स को मीडिया आउटपुट को अन्य बाहरी डिवाइस पर रूट करने देता है."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"अनपिन करने से पहले अनलॉक पैटर्न के लिए पूछें"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"अनपिन करने से पहले पासवर्ड के लिए पूछें"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"आपके नियंत्रक द्वारा इंस्टॉल किया गया"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"आपके नियंत्रक द्वारा हटाया गया"</string> <string name="battery_saver_description" msgid="1960431123816253034">"बैटरी जीवन काल को बेहतर बनाने में सहायता के लिए, बैटरी सेवर आपके डिवाइस के प्रदर्शन को कम कर देता है और कंपन, स्थान सेवाओं और अधिकांश पृष्ठभूमि डेटा को सीमित कर देता है. हो सकता है कि ईमेल, संदेश सेवा तथा समन्वयन पर आधारित अन्य ऐप्स तब तक ना खुलें जब तक कि आप उन्हें नहीं खोलते.\n\nजब आपका डिवाइस चार्ज हो रहा होता है तो बैटरी सेवर अपने आप बंद हो जाता है."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index cf81cd1..16503b8 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -1085,22 +1085,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Postavljanje"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Izbaci"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Istražite"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> nedostaje"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Ponovo umetnite uređaj"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Premještanje aplikacije <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Premještanje podataka"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Premještanje dovršeno"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Podaci su premješteni u pohranu <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Podaci nisu premješteni"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Podaci su ostali na izvornoj lokaciji"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Nisu pronađene podudarne radnje."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Usmjeravanje medijskog izlaza"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Aplikaciji omogućuje usmjeravanje medijskog izlaza na druge vanjske uređaje."</string> @@ -1475,6 +1467,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Traži uzorak za otključavanje radi otkvačivanja"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Traži zaporku radi otkvačivanja"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalirao administrator"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisao administrator"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Da bi se produljilo trajanje baterije, ušteda baterije smanjuje rad uređaja i ograničava vibraciju, usluge lokacije i većinu pozadinskih podataka. Aplikacije za e-poštu, slanje poruka i druge aplikacije koje se oslanjaju na sinkronizaciju možda se neće ažurirati ako ih ne otvorite.\n\nUšteda baterije isključuje se automatski dok se uređaj puni."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index ae606b2..f2f5538 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Beállítás"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Kiadás"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Felfedezés"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"A(z) <xliff:g id="NAME">%s</xliff:g> nem található"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Helyezze be újra az eszközt"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> áthelyezése"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Az áthelyezés folyamatban van"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Az áthelyezés befejeződött"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Adatok áthelyezve ide: <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Sikertelen az adatok áthelyezése"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Maradtak adatok az eredeti helyen"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Nincs megfelelő tevékenység."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Médiafájlok kimenetének irányítása"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Lehetővé teszi az alkalmazás számára, hogy más külső eszközökre irányítsa a médiafájlok lejátszását."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Feloldási minta kérése a rögzítés feloldásához"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Jelszó kérése a rögzítés feloldásához"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"A rendszergazda telepítette"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"A rendszergazda törölte"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Az akkumulátoridő növelése érdekében az energiatakarékos mód csökkenti az eszköz teljesítményét, és korlátozza a rezgést, a helyszolgáltatásokat, valamint a legtöbb háttéradatot is. Előfordulhat, hogy azok az e-mail-, üzenetküldő és egyéb alkalmazások, amelyek szinkronizálására számít, csak akkor frissítenek, ha megnyitja azokat.\n\nAz energiatakarékos mód automatikusan kikapcsol, ha eszköze töltőn van."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml index f393c87..6d21523 100644 --- a/core/res/res/values-hy-rAM/strings.xml +++ b/core/res/res/values-hy-rAM/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Կարգավորում"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Անջատել"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Ուսումնասիրել"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g>-ը տեղադրված չէ"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Նորից զետեղեք այս սարքը"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g>-ի տեղափոխում"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Տվյալների տեղափոխում"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Տեղափոխումն ավարտվեց"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Տվյալները տեղափոխվեցին <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Չհաջողվեց տեղափոխել տվյալները"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Սկզբնական տեղադրությունում մնացած տվյալները"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Համընկնող գործունեություններ չգտնվեցին:"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Երթուղել մեդիա արտածումը"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Թույլ է տալիս հավելվածին մեդիա արտածումը երթուղել այլ արտաքին սարքեր:"</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Ապաամրացնելուց առաջ հարցնել ապակողպող նախշը"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Ապաամրացնելուց առաջ հարցնել գաղտնաբառը"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Ադմինիստրատորը տեղադրել է այն"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Ադմինիստրատորը ջնջել է այն"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Մարտկոցի աշխատանքի ժամկետը երկարացնելու նպատակով, մարտկոցի էներգիայի խնայման գործառույթը սահմանափակում է սարքի աշխատանքը, թրթռոցը, տեղադրության ծառայությունները և հետնաշերտում աշխատող շատ գործընթացներ: Էլփոստը, հաղորդագրությունների փոխանակումը և տվյալների համաժամեցումից կախված այլ հավելվածները կարող են չթարմացվել, եթե դուք դրանք չգործարկեք:\n\nԵրբ ձեր սարքը լիցքավորվում է, մարտկոցի էներգիայի խնայման գործառույթն ինքնաշխատորեն անջատվում է:"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 298f204..f0945ca 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Siapkan"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Keluarkan"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Jelajahi"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Tidak ada <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Colokkan kembali perangkat ini"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Memindahkan <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Memindahkan data"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Pemindahan selesai"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Data dipindahkan ke <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Tidak dapat memindahkan data"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Data tertinggal di lokasi asal"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Tidak ditemukan aktivitas yang sesuai."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Menentukan rute keluaran media"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Memungkinkan aplikasi menentukan rute keluaran media ke perangkat eksternal lainnya."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Meminta pola pembukaan kunci sebelum melepas sematan"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Meminta sandi sebelum melepas sematan"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Dipasang oleh administrator"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Dihapus oleh administrator"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Untuk membantu meningkatkan masa pakai baterai, penghemat baterai mengurangi kinerja perangkat dan membatasi getaran, layanan lokasi, dan kebanyakan data latar belakang. Email, perpesanan, dan aplikasi lain yang mengandalkan sinkronisasi mungkin tidak diperbarui kecuali jika dibuka.\n\nPenghemat baterai otomatis nonaktif jika perangkat diisi dayanya."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml index b36322b..e999e0f 100644 --- a/core/res/res/values-is-rIS/strings.xml +++ b/core/res/res/values-is-rIS/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Uppsetning"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Fjarlægja"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Kanna"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> vantar"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Settu þetta tæki aftur í"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Flytur <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Flytur gögn"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Flutningi lokið"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Gögn flutt á <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Ekki var hægt að færa gögnin"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Gögn eftir á upprunalega staðnum"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Engar aðgerðir með samsvörun fundust."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Beina margmiðlunarúttaki"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Leyfir forriti að beina margmiðlunarúttaki til annarra ytri tækja."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Biðja um opnunarmynstur til að losa"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Biðja um aðgangsorð til að losa"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Uppsett af kerfisstjóra"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Eytt af kerfisstjóra"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Til að auka endingu rafhlöðunnar mun orkusparnaður draga úr afköstum tækisins og takmarka titring, staðsetningarþjónustu og megnið af bakgrunnsgögnum. Ekki er víst að tölvupóstur, skilaboð og önnur forrit sem reiða sig á samstillingu uppfærist nema þú opnir þau.\n\nSjálfkrafa er slökkt á orkusparnaði þegar tækið er í hleðslu."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 5a2bf7a..6b29541 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Configura"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Espelli"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Scopri"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> mancante"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Reinserisci il dispositivo"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Spostamento di <xliff:g id="NAME">%s</xliff:g> in corso"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Spostamento dei dati in corso"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Spostamento completato"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Dati spostati sulla <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Impossibile spostare i dati"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Dati lasciati nella posizione originaria"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Nessuna attività corrispondente trovata."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Indirizzamento uscita media"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Consente a un\'applicazione di indirizzare l\'uscita di media verso altri dispositivi esterni."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Richiedi sequenza di sblocco prima di sbloccare"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Richiedi password prima di sbloccare"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Installato dall\'amministratore"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminato dall\'amministratore"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Per aumentare la durata della batteria, la funzione di risparmio energetico riduce le prestazioni del dispositivo e limita vibrazione, servizi di localizzazione e la maggior parte dei dati in background. App di email, messaggi e altre app che si basano sulla sincronizzazione potrebbero essere aggiornate soltanto all\'apertura.\n\nLa funzione di risparmio energetico viene disattivata automaticamente quando il dispositivo è in carica."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 0f2a691..3e6b5d3 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1092,22 +1092,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"הגדר"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"הוצא"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"גלה"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> חסר"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"הכנס שוב את ההתקן הזה"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"מעביר את <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"מעביר נתונים"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"ההעברה הושלמה"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"הנתונים הועברו אל <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"לא ניתן היה להעביר את הנתונים"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"הנתונים נותרו במיקום המקורי"</string> <string name="activity_list_empty" msgid="1675388330786841066">"לא נמצאו פעילויות תואמות."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"ניתוב פלט מדיה"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"מאפשר לאפליקציה לנתב פלט מדיה למכשירים חיצוניים אחרים."</string> @@ -1484,6 +1476,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"בקש קו ביטול נעילה לפני ביטול הצמדה"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"בקש סיסמה לפני ביטול הצמדה"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"הותקנה על ידי מנהל המערכת שלך"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"נמחקה על ידי מנהל המערכת שלך"</string> <string name="battery_saver_description" msgid="1960431123816253034">"כדי לעזור בשיפור חיי הסוללה, תכונת החיסכון בסוללה מצמצמת את פעולות המכשיר ומגבילה רטט, שירותי מיקום ואת רוב נתוני הרקע. אימייל, העברת הודעות ואפליקציות אחרות המסתמכות על סנכרון עשויות שלא להתעדכן, אלא אם תפתח אותן.\n\nתכונת החיסכון בסוללה מושבתת אוטומטית כשהמכשיר בטעינה."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 71eec56..09d1380 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"セットアップ"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"取り外し"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"外部メディア"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g>が見つかりません"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"このデバイスを再挿入してください"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g>を移動しています"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"データを移動しています"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"移動が完了しました"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"データを<xliff:g id="NAME">%s</xliff:g>に移動しました"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"データを移動できませんでした"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"データは元の場所にあります"</string> <string name="activity_list_empty" msgid="1675388330786841066">"一致するアクティビティが見つかりません。"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"メディア出力のルーティング"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"メディア出力を他の外部デバイスにルーティングすることをアプリに許可します。"</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"画面固定を解除する前にロック解除パターンの入力を求める"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"オフライン再生を解除する前にパスワードの入力を求める"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"管理者によってインストールされました"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"管理者によって削除されました"</string> <string name="battery_saver_description" msgid="1960431123816253034">"バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンスを抑え、バイブレーション、位置情報サービス、大半のバックグラウンドデータを制限します。メール、SMSや、同期を使用するその他のアプリは、起動しても更新されないことがあります。\n\nバッテリーセーバーは端末の充電中は自動的にOFFになります。"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml index 1fc1b95..5813e50 100644 --- a/core/res/res/values-ka-rGE/strings.xml +++ b/core/res/res/values-ka-rGE/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"დაყენება"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"გამოღება"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"დათვალიერება"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> აკლია"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"ხელახლა შეაერთეთ ეს მოწყობილობა"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"მიმდინარეობს <xliff:g id="NAME">%s</xliff:g>-ის გადატანა"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"მიმდინარეობს მონაცემთა გადატანა"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"გადატანა დასრულდა"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"მონაცემები გადატანილი იქნა <xliff:g id="NAME">%s</xliff:g>-ში"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"მონაცემების გადატანა ვერ მოხერხდა"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"მონაცემები დარჩა თავდაპირველ მდებარეობაში"</string> <string name="activity_list_empty" msgid="1675388330786841066">"შესატყვისი აქტივობები არ არის."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"მულტიმედია მონაცემების გადამისამართება"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"აპლიკაციას შეეძლება გადაამისამართოს მულტიმედია მონაცემები სხვა გარე მოწყობილობებისკენ."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ფიქსაციის მოხსნამდე განბლოკვის ნიმუშის მოთხოვნა"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ფიქსაციის მოხსნამდე პაროლის მოთხოვნა"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"თქვენი ადმინისტრატორის მიერ დაყენებული"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"თქვენი ადმინისტრატორის მიერ წაშლილი"</string> <string name="battery_saver_description" msgid="1960431123816253034">"ელემენტის მოქმედების ვადის გაუმჯობესებისათვის, ელემენტის დამზოგი ამცირებს თქვენი მოწყობილობის შესრულებას და ზღუდავს ვიბრაციას, ადგილმდებარეობის მომსახურებებს და ძირითად ფონურ მონაცემებს. ელ-ფოსტა, შეტყობინებები და სხვა სინქრონიზაციაზე დაყრდნობილი აპლიკაციების განახლება არ მოხდება მათ გახსნეამდე. \n\n ელემენტის დამზოგველი ავტომატურად გამოირთვება, როდესაც თქვენს მოწყობილობას დამტენთან შეაერთებთ."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml index 5808e6d..24ec8b1 100644 --- a/core/res/res/values-kk-rKZ/strings.xml +++ b/core/res/res/values-kk-rKZ/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Орнату"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Шығару"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Зерттеу"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> жоқ"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Бұл құрылғыны қайта салыңыз"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> жылжытылуда"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Деректер тасымалдануда"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Тасымалдау аяқталды"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Деректер <xliff:g id="NAME">%s</xliff:g> ішіне тасымалданды"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Деректерді тасымалдау мүмкін емес"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Деректер бастапқы орнында қалды"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Сәйкес әрекеттер табылмады."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Медиа шығысын бағыттау"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Қолданбаға медиа шығысын басқа сыртқы құрылғыларға бағыттау мүмкіндігін береді."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Босату алдында бекітпесін ашу өрнегін сұрау"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Босату алдында құпия сөзді сұрау"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Әкімші орнатқан"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Әкімші жойған"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Батареяның қызмет көрсету мерзімін жақсарту үшін батарея үнемдегіш құрылғының өнімділігін төмендетеді және дірілді, орынды анықтау қызметтерін және фондық деректердің көпшілігін шектейді. Электрондық пошта, хабар алмасу және синхрондауға негізделген басқа қолданбалар ашқанша жаңартылмауы мүмкін.\n\nБатарея үнемдегіш құрылғы зарядталып жатқанда автоматты түрде өшеді."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml index 423506f..dbe5104 100644 --- a/core/res/res/values-km-rKH/strings.xml +++ b/core/res/res/values-km-rKH/strings.xml @@ -1080,22 +1080,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"ដំឡើង"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"ដកចេញ"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"រុករក"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"បាត់ <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"បញ្ចូលឧបករណ៍នេះឡើងវិញ"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"កំពុងផ្លាស់ទី <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"កំពុងផ្លាស់ទីទិន្នន័យ…"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"ផ្លាស់ទីទាំងស្រុង"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"ទិន្នន័យបានផ្លាស់ទីទៅ <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"មិនអាចផ្លាស់ទីទិន្នន័យបានទេ"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"ទិន្នន័យនៅក្នុងទីតាំងដើមដដែល"</string> <string name="activity_list_empty" msgid="1675388330786841066">"រកមិនឃើញសកម្មភាពផ្គូផ្គង។"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"នាំផ្លូវលទ្ធផលមេឌៀ"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"ឲ្យកម្មវិធីនាំផ្លូវលទ្ធផលមេឌៀទៅឧបករណ៍ខាងក្រៅផ្សេង។"</string> @@ -1468,6 +1460,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"សួររកលំនាំដោះសោមុនពេលផ្ដាច់"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"សួររកពាក្យសម្ងាត់មុនពេលផ្ដាច់"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"បានដំឡើងដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"បានលុបដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string> <string name="battery_saver_description" msgid="1960431123816253034">"ដើម្បីជួយឲ្យថាមពលថ្មប្រសើរឡើង កម្មវិធីសន្សំសំចៃថាមពលថ្មកាត់បន្ថយប្រតិបត្តិការឧបករណ៍របស់អ្នក និងកម្រិតភាពញ័រ សេវាកម្មទីតាំង និងទិន្នន័យផ្ទៃខាងក្រោយស្ទើរតែទាំងអស់។ ការផ្ញើសារអ៊ីម៉ែល និងកម្មវិធីផ្សេងទៀតដែលពឹងផ្អែកលើការធ្វើសមកាលកម្មអាចនឹងមិនធ្វើបច្ចុប្បន្នភាពទេ លុះត្រាតែអ្នកបើកពួកវា។\n\nកម្មវិធីសន្សំសំចៃបិទដោយស្វ័យប្រវត្តិ នៅពេលដែលឧបករណ៍របស់អ្នកកំពុងសាកថ្ម។"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml index eca6ee8..9631a65 100644 --- a/core/res/res/values-kn-rIN/strings.xml +++ b/core/res/res/values-kn-rIN/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"ಸೆಟಪ್"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"ಎಜೆಕ್ಟ್ ಮಾಡು"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"ಎಕ್ಸ್ಪ್ಲೋರ್"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ಕಾಣೆಯಾಗಿದೆ"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"ಈ ಸಾಧನವನ್ನು ಮರುಸೇರಿಸಿ"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> ಸರಿಸಲಾಗುತ್ತಿದೆ"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"ಡೇಟಾ ಸರಿಸಲಾಗುತ್ತಿದೆ"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"ಸರಿಸುವಿಕೆ ಪೂರ್ಣಗೊಂಡಿದೆ"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"<xliff:g id="NAME">%s</xliff:g> ಗೆ ಡೇಟಾ ಸರಿಸಲಾಗಿದೆ"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"ಡೇಟಾ ಸರಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"ಮೂಲ ಸ್ಥಳದಲ್ಲಿ ಡೇಟಾ ಉಳಿದಿದೆ"</string> <string name="activity_list_empty" msgid="1675388330786841066">"ಯಾವುದೇ ಹೊಂದಾಣಿಕೆಯ ಚಟುವಟಿಕೆಗಳು ಕಂಡುಬಂದಿಲ್ಲ."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"ಮೀಡಿಯಾ ಔಟ್ಪುಟ್ ಅನ್ನು ರೂಟ್ ಮಾಡಿ"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"ಇತರ ಬಾಹ್ಯ ಸಾಧನಗಳಿಗೆ ಮೀಡಿಯಾ ಔಟ್ಪುಟ್ ಅನ್ನು ರೂಟ್ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ಅನ್ಪಿನ್ ಮಾಡುವುದಕ್ಕೂ ಮೊದಲು ಅನ್ಲಾಕ್ ನಮೂನೆಯನ್ನು ಕೇಳಿ"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ಅನ್ಪಿನ್ ಮಾಡುವುದಕ್ಕೂ ಮೊದಲು ಪಾಸ್ವರ್ಡ್ ಕೇಳಿ"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರಿಂದ ಸ್ಥಾಪಿಸಲಾಗಿದೆ"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರಿಂದ ಅಳಿಸಲಾಗಿದೆ"</string> <string name="battery_saver_description" msgid="1960431123816253034">"ನಿಮ್ಮ ಬ್ಯಾಟರಿಯ ಬಾಳಿಕೆಯನ್ನು ಸುಧಾರಿಸಲು ಸಹಾಯ ಮಾಡಲು, ಬ್ಯಾಟರಿ ಉಳಿಕೆಯು ನಿಮ್ಮ ಸಾಧನದ ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ ಮತ್ತು ವೈಬ್ರೇಷನ್, ಸ್ಥಳ ಸೇವೆಗಳು ಹಾಗೂ ಹೆಚ್ಚಿನ ಹಿನ್ನೆಲೆ ಡೇಟಾವನ್ನು ಮಿತಿಗೊಳಿಸುತ್ತದೆ. ಸಿಂಕ್ ಮಾಡುವುದನ್ನು ಅವಲಂಬಿಸಿರುವ ಇಮೇಲ್, ಸಂದೇಶ ಕಳುಹಿಸುವಿಕೆ, ಮತ್ತು ಇತರ ಅಪ್ಲಿಕೇಶನ್ಗಳು ನೀವು ತೆರೆಯದ ಹೊರತು ನವೀಕರಣಗೊಳ್ಳುವುದಿಲ್ಲ.\n\nನಿಮ್ಮ ಸಾಧನವು ಚಾರ್ಜ್ ಆಗುತ್ತಿರುವ ಸಮಯದಲ್ಲಿ ಬ್ಯಾಟರಿ ಉಳಿಕೆಯು ಆಫ್ ಆಗುತ್ತದೆ."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 853a6ed..d6f9ed6 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"설정"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"꺼내기"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"둘러보기"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> 없음"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"기기 다시 삽입"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> 이동 중"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"데이터 이동 중"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"이동 완료"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"데이터를 <xliff:g id="NAME">%s</xliff:g>(으)로 이동했습니다."</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"데이터를 이동할 수 없음"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"원래 위치에 데이터 남아 있음"</string> <string name="activity_list_empty" msgid="1675388330786841066">"일치하는 활동이 없습니다."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"미디어 출력 연결"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"앱이 미디어 출력을 기타 외부 기기에 연결할 수 있도록 허용합니다."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"고정 해제 이전에 잠금해제 패턴 요청"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"고정 해제 이전에 비밀번호 요청"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"관리자가 설치함"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"관리자가 삭제함"</string> <string name="battery_saver_description" msgid="1960431123816253034">"배터리 수명 개선을 위해, 배터리 세이버는 기기의 성능을 줄이고 진동, 위치 서비스 및 대부분의 백그라운드 데이터를 제한합니다. 이메일, 메시지 및 동기화에 의존하는 기타 앱은 앱을 열 때까지 업데이트되지 않을 수 있습니다.\n\n배터리 세이버는 기기를 충전 중일 때는 자동으로 사용 중지됩니다."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml index ee87665..5e5948e 100644 --- a/core/res/res/values-ky-rKG/strings.xml +++ b/core/res/res/values-ky-rKG/strings.xml @@ -1883,6 +1883,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Бошотуудан мурун кулпуну ачкан үлгү суралсын"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Бошотуудан мурун сырсөз суралсын"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Администраторуңуз тарабынан орнотулган"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Администраторуңуз тарабынан жок кылынган"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Батареянын өмүрүн узартуу үчүн, батареяны үнөмдөгүч түзмөгүңүздүн ишинин майнаптуулугун азайтып, дирилдөө, жайгашкан жерди аныктоо кызматтары жана фондук дайындардын көпчүлүгүн чектеп коёт. Электрондук почта, билдирүү жазышуу жана башка шайкештештирүүгө байланыштуу колдонмолор ачылмайынча жаңыртылбай калышы мүмкүн.\n\nБатарея үнөмдөгүч түзмөгүңүз кубатталып жатканда автоматтык түрдө өчүп калат."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml index 5128827..e8104fc 100644 --- a/core/res/res/values-lo-rLA/strings.xml +++ b/core/res/res/values-lo-rLA/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"ຕິດຕັ້ງ"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"ເອົາອອກ"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"ຄົ້ນຫາ"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ຂາດໄປ"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"ໃສ່ອຸປະກອນນີ້ເຂົ້າໃໝ່"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"ກຳລັງຍ້າຍ <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"ກຳລັງຍ້າຍຂໍ້ມູນ"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"ການຍ້າຍສຳເລັດ"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"ຍ້າຍຂໍ້ມູນໃສ່ <xliff:g id="NAME">%s</xliff:g> ແລ້ວ"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"ບໍ່ສາມາດຍ້າຍຂໍ້ມູນໄດ້"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"ຂໍ້ມູນເຫຼືອໄວ້ຢູ່ໃນທີ່ຕັ້ງເດີມ"</string> <string name="activity_list_empty" msgid="1675388330786841066">"ບໍ່ພົບກິດຈະກຳທີ່ກົງກັນ."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"ກຳນົດເສັ້ນທາງເອົ້າພຸດຂອງສື່"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ກຳນົດເສັ້ນທາງເອົ້າພຸດຂອງສື່ໄປຫາອຸປະກອນພາຍນອກອື່ນໆ."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ຖາມຫາຮູບແບບປົດລັອກກ່ອນຍົກເລີກການປັກໝຸດ"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ຖາມຫາລະຫັດຜ່ານກ່ອນຍົກເລີກການປັກໝຸດ"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"ຜູ້ຄວບຄຸມຂອງທ່ານຕິດຕັ້ງໃສ່ແລ້ວ"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"ຖືກຜູ້ຄວບຄຸມຂອງທ່ານລຶບໄປແລ້ວ"</string> <string name="battery_saver_description" msgid="1960431123816253034">"ເພື່ອຊ່ວຍເພີ່ມອາຍຸແບັດເຕີຣີ, ຕົວປະຢັດໄຟແບັດເຕີຣີຫຼຸດປະສິດທິພາບການເຮັດວຽກຂອງອຸປະກອນຂອງທ່ານລົງ ແລະຈຳກັດການສັ່ນ, ການບໍລິການຫາທີ່ຕັ້ງ, ແລະຂໍ້ມູນພື້ນຫຼັງເກືອບທັງໝົດ. ອີເມວ, ການສົ່ງຂໍ້ຄວາມ, ແລະແອັບອື່ນໆທີ່ອາໄສການຊິງຄ໌ອາດຈະບໍ່ອັບເດດ ນອກຈາກວ່າທ່ານເປີດມັນ.\n\nຕົວປະຢັດໄຟແບັດເຕີຣີຈະປິດອັດຕະໂນມັດ ເມື່ອອຸປະກອນຂອງທ່ານກຳລັງສາກຢູ່."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index ededc9a..3ebe665 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -1092,22 +1092,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Sąranka"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Pašalinti"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Naršyti"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Trūksta <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Iš naujo įdėkite šį įrenginį"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Perkeliama programa „<xliff:g id="NAME">%s</xliff:g>“"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Perkeliami duomenys"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Perkėlimo veiksmas užbaigtas"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Duomenys perkelti į <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Nepavyko perkelti duomenų"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Duomenys palikti pradinėje vietoje"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Nerasta atitinkančios veiklos."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Medijos išvesties nukreipimas"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Leidžiama programai nukreipti medijos išvestį į kitus išorinius įrenginius."</string> @@ -1484,6 +1476,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Prašyti atrakinimo piešinio prieš atsegant"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Prašyti slaptažodžio prieš atsegant"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Įdiegė administratorius"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Ištrynė administratorius"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Kad tausotų akumuliatoriaus energiją akumuliatoriaus tausojimo priemonė sumažina įrenginio veikimą ir apriboja vibravimą, vietovės paslaugas bei daugumą foninių duomenų. El. pašto, susirašinėjimo žinutėmis ir kitos programos, kurios veikia sinchronizavimo pagrindu, gali būti neatnaujintos, nebent jas atidarysite.\n\nAkumuliatoriaus tausojimo priemonė automatiškai išjungiama, kai įrenginys įkraunamas."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 9110e70..788082a 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -1085,22 +1085,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Iestatīt"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Izstumt"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Izpētīt"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Nav ierīces <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Vēlreiz ievietojiet ierīci."</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Notiek lietotnes <xliff:g id="NAME">%s</xliff:g> pārvietošana"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Notiek datu pārvietošana"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Pārvietošana ir pabeigta"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Dati ir pārvietoti uz ierīci <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Nevarēja pārvietot datus"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Dati tika atstāti sākotnējā atrašanās vietā"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Nav atrasta neviena atbilstoša darbība."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Multivides datu izejas maršrutēšana"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Ļauj lietojumprogrammai maršrutēt multivides datu izeju uz citām ārējām ierīcēm."</string> @@ -1475,6 +1467,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pirms atspraušanas pieprasīt grafisko atslēgu"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pirms atspraušanas pieprasīt paroli"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalēja jūsu administrators"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Izdzēsa jūsu administrators"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Lai paildzinātu akumulatora darbību, akumulatora jaudas taupīšanas režīmā tiek samazināta ierīces veiktspēja un tiek ierobežota vibrācija, atrašanās vietu pakalpojumi un lielākā daļa fona datu. E-pasta, ziņojumapmaiņas un cita veida lietotnes, kuru darbības pamatā ir datu sinhronizācija, var netikt atjauninātas, ja tās neatverat.\n\nTiklīdz tiek sākta ierīces uzlāde, akumulatora jaudas taupīšanas režīms automātiski tiek izslēgts."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-mcc310-mnc260-sq-rAL/strings.xml b/core/res/res/values-mcc310-mnc260-sq-rAL/strings.xml index 42eb1ca..84ac153 100644 --- a/core/res/res/values-mcc310-mnc260-sq-rAL/strings.xml +++ b/core/res/res/values-mcc310-mnc260-sq-rAL/strings.xml @@ -23,7 +23,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="7239039348648848288">"Për të bërë telefonata dhe për të dërguar mesazhe me Wi-Fi, në fillim kërkoji operatorit celular të konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi nga Parametrat."</item> + <item msgid="7239039348648848288">"Për të bërë telefonata dhe për të dërguar mesazhe me Wi-Fi, në fillim kërkoji operatorit celular ta konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi, nga Cilësimet."</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="483847327467331298">"Regjistrohu me operatorin tënd celular"</item> diff --git a/core/res/res/values-mcc311-mnc480/config.xml b/core/res/res/values-mcc311-mnc480/config.xml index 56f8aa2..39ea2bf 100755 --- a/core/res/res/values-mcc311-mnc480/config.xml +++ b/core/res/res/values-mcc311-mnc480/config.xml @@ -43,6 +43,11 @@ provisioning, availability etc --> <bool name="config_carrier_volte_available">true</bool> + <!-- Flag specifying whether VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_vt_available">true</bool> + <!-- Flag specifying whether VoLTE availability is based on provisioning --> <bool name="config_carrier_volte_provisioned">true</bool> diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml index 4f5c913..ee8e4cb 100644 --- a/core/res/res/values-mk-rMK/strings.xml +++ b/core/res/res/values-mk-rMK/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Поставување"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Извади"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Истражувај"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> недостасува"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Повторно вметнете го овој уред"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Се преместува <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Се преместуваат податоци"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Преместувањето е завршено"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Податоците се преместени во <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Не може да се прем. податоците"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Податоците се оставени на провобитната локација"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Не се пронајдени соодветни активности."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Насочи излез за медиуми"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Овозможува апликацијата да насочува излез за медиуми кон други надворешни уреди."</string> @@ -1468,6 +1460,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Прашај за шема за отклучување пред откачување"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Прашај за лозинка пред откачување"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Инсталирано од администраторот"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Избришано од администраторот"</string> <string name="battery_saver_description" msgid="1960431123816253034">"За да ви помогне да ја подобрите трајноста на батеријата, штедачот на батеријата ја намалува изведбата на уредот и го ограничува вибрирањето, услугите за локација и повеќето податоци од заднина. Е-поштата, испраќањето пораки и другите апликации кои се потпираат на синхронизација можеби нема да се ажурираат доколку не ги отворите.\n\nШтедачот на батеријата автоматски се исклучува кога уредот се полни."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml index 62c5b1f..a1d5bcb 100644 --- a/core/res/res/values-ml-rIN/strings.xml +++ b/core/res/res/values-ml-rIN/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"സജ്ജമാക്കുക"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"നിരസിക്കുക"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"പര്യവേക്ഷണം ചെയ്യുക"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> കാണുന്നില്ല"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"ഈ ഉപകരണം വീണ്ടും നൽകുക"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> നീക്കുന്നു"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"വിവരം നീക്കുന്നു"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"നീക്കുന്ന പ്രവർത്തനം പൂർത്തിയായി"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"<xliff:g id="NAME">%s</xliff:g> എന്നതിലേക്ക് വിവരം നീക്കി"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"വിവരം നീക്കാനായില്ല"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"യഥാർത്ഥ ലൊക്കേഷനിൽ വിവരം ശേഷിക്കുന്നു"</string> <string name="activity_list_empty" msgid="1675388330786841066">"പൊരുത്തമുള്ള പ്രവർത്തനങ്ങളൊന്നും കണ്ടെത്തിയില്ല."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"മീഡിയ ഔട്ട്പുട്ട് റൂട്ടുചെയ്യുക"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"മീഡിയ ഔട്ട്പുട്ടിനെ മറ്റ് ബാഹ്യ ഉപകരണങ്ങളിലേക്ക് റൂട്ടുചെയ്യാൻ ഒരു അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"അൺപിൻ ചെയ്യുന്നതിനുമുമ്പ് അൺലോക്ക് പാറ്റേൺ ആവശ്യപ്പെടുക"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"അൺപിൻ ചെയ്യുന്നതിനുമുമ്പ് പാസ്വേഡ് ആവശ്യപ്പെടുക"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"നിങ്ങളുടെ അഡ്മിനിസ്ട്രേറ്റർ ഇൻസ്റ്റാളുചെയ്തു"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"നിങ്ങളുടെ അഡ്മിനിസ്ട്രേറ്റർ ഇല്ലാതാക്കി"</string> <string name="battery_saver_description" msgid="1960431123816253034">"ബാറ്ററി ആയുസ്സ് മെച്ചപ്പെടുത്താൻ സഹായിക്കുന്നതിന്, ബാറ്ററി സേവർ നിങ്ങളുടെ ഉപകരണത്തിന്റെ പ്രകടനത്തെ കുറയ്ക്കുകയും വൈബ്രേഷനെയും മിക്ക പശ്ചാത്തല വിവരത്തെയും പരിമിതപ്പെടുത്തുകയും ചെയ്യുന്നു. ഇമെയിൽ, സന്ദേശമയയ്ക്കൽ, സമന്വയിപ്പിക്കലിനെ ആശ്രയിച്ചുള്ള മറ്റ് അപ്ലിക്കേഷനുകൾ എന്നിവ നിങ്ങൾ തുറക്കുന്നതുവരെ അപ്ഡേറ്റുചെയ്യാനിടയില്ല.\n\nനിങ്ങളുടെ ഉപകരണം ചാർജ്ജുചെയ്യുമ്പോൾ ബാറ്ററി സേവർ സ്വയം ഓഫാകും."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml index 971a6a8..20d289b 100644 --- a/core/res/res/values-mn-rMN/strings.xml +++ b/core/res/res/values-mn-rMN/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Тохируулга"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Салгах"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Судлах"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> байхгүй байна"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Энэ төхөөрөмжийг дахин оруул"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g>-ыг зөөж байна"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Өгөгдөл зөөвөрлөж байна..."</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Бүрэн бүтнээр шилжүүлэх"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Өгөгдөл <xliff:g id="NAME">%s</xliff:g>-д зөөгдсөн"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Өгөгдлийг зөөх боломжгүй байна"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Анхны байршилд өгөгдөл үлдсэн байна"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Таарах активити олдсонгүй."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Медиа гаралтыг чиглүүлэх"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Аппликешн нь медиа гаралтыг бусад гадаад төхөөрөмжрүү чиглүүлэх боломжтой."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Тогтоосныг суллахаас өмнө түгжээ тайлах хээ асуух"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Тогтоосныг суллахаас өмнө нууц үг асуух"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Таны админ суулгасан байна"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Таны админ устгасан байна"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Батарей хадгалах функц нь таны төхөөрөмжийн цэнэгийг хадгалахын тулд гүйцэтгэлийг багасгаж, чичрэлтийг бууруулж, байршлын үйлчилгээнүүд болон бусад өгөгдлийн хэмжээг багасгадаг юм. И-мэйл, мессеж болон бусад синхрон хийдэг апликейшнүүд дараа дахин нээгдэх хүртлээ автоматаар шинэчлэлт хийхгүй.\n\nМөн батарей хадгалах функц нь таныг төхөөрөмжөө цэнэглэх үед автоматаар унтрах юм."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml index 8bca6a5..bf8a4e8 100644 --- a/core/res/res/values-mr-rIN/strings.xml +++ b/core/res/res/values-mr-rIN/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"सेटअप"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"बाहेर काढा"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"एक्सप्लोर करा"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> गहाळ आहे"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"हे डिव्हाइस पुन्हा घाला"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> हलवित आहे"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"डेटा हलवित आहे"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"हलविणे पूर्ण"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"<xliff:g id="NAME">%s</xliff:g> वर डेटा हलविला"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"डेटा हलविणे शक्य झाले नाही"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"मूळ स्थानावर डेटा सोडला"</string> <string name="activity_list_empty" msgid="1675388330786841066">"कोणतेही जुळणारे क्रियाकलाप आढळले नाहीत."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"मीडिया आउटपुट मार्गस्थ करा"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"अन्य बाह्य डिव्हाइसेसवरील रूट मीडिया आउटपुट वर अनुप्रयोगास अनुमती देते."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"अनपिन करण्यापूर्वी अनलॉक नमुन्यासाठी विचारा"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"अनपिन करण्यापूर्वी संकेतशब्दासाठी विचारा"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"आपल्या प्रशासकाद्वारे स्थापित केले आहे"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"आपल्या प्रशासकाद्वारे हटविले आहे"</string> <string name="battery_saver_description" msgid="1960431123816253034">"बॅटरीचे आयुष्य सुधारित करण्यात मदत करण्यासाठी, बॅटरी बचतकर्ता आपल्या डिव्हाइसचे कार्यप्रदर्शन कमी करतो आणि कंपन, स्थान सेवा आणि बराच पार्श्वभूमी डेटा मर्यादित करतो. संकालनावर अवलंबून असणारे ईमेल, संदेशन आणि इतर अॅप्स आपण उघडल्याशिवाय अद्यतनित होऊ शकत नाहीत.\n\nआपले डिव्हाइस चार्ज होत असते तेव्हा बॅटरी बचतकर्ता स्वयंचलितपणे बंद होतो."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml index f068fcd..65109a8 100644 --- a/core/res/res/values-ms-rMY/strings.xml +++ b/core/res/res/values-ms-rMY/strings.xml @@ -274,8 +274,8 @@ <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Membenarkan apl menerima dan memproses mesej WAP. Kebenaran ini termasuk keupayaan untuk memantau atau memadam mesej yang dihantar kepada anda tanpa menunjukkannya kepada anda."</string> <string name="permlab_getTasks" msgid="6466095396623933906">"dapatkan semula apl yang sedang dijalankan"</string> <string name="permdesc_getTasks" msgid="7454215995847658102">"Membenarkan apl mengambil maklumat tentang tugasan yang sedang dan baru berjalan. Ini boleh membenarkan apl untuk menemui maklumat tentang apl mana yang digunakan pada peranti."</string> - <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Urus profil dan pemilik peranti"</string> - <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Membenarkan apl menetapkan profil pemilik dan pemilik peranti."</string> + <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Urus pemilik profil dan peranti"</string> + <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Membenarkan apl menetapkan pemilik profil dan pemilik peranti."</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"susun semula tertib apl yang dijalankan"</string> <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Membenarkan apl memindahkan tugasan ke latar depan dan latar belakang. Apl boleh melakukan ini tanpa input anda."</string> <string name="permlab_enableCarMode" msgid="5684504058192921098">"dayakan mod kereta"</string> @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Persediaan"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Tanggalkan"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Teroka"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> tiada"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Sisipkan semula peranti ini"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Mengalihkan <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Mengalihkan data"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Pengalihan selesai"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Data dipindahkan ke <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Tidak dapat memindahkan data"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Data dibiarkan di lokasi asal"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Tiada aktiviti yang sepadan ditemui."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Buat laluan output media"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Membenarkan apl untuk membuat laluan output media ke peranti luaran lain."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Minta corak buka kunci sebelum menyahsemat"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Minta kata laluan sebelum menyahsemat"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Dipasang oleh pentadbir anda"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Dipadamkan oleh pentadbir anda"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Untuk membantu memperbaik hayat bateri, penjimat bateri mengurangkan prestasi peranti anda dan menghadkan getaran, perkhidmatan lokasi dan kebanyakan data latar belakang. E-mel, pemesejan dan apl lain yang bergantung kepada penyegerakan mungkin tidak mengemas kini, melainkan anda membuka apl itu.\n\nPenjimat bateri dimatikan secara automatik semasa peranti anda sedang dicas."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml index e315f56..e63f651 100644 --- a/core/res/res/values-my-rMM/strings.xml +++ b/core/res/res/values-my-rMM/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"စဖွင့်သတ်မှတ်ရန်"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"ထုတ်မည်"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"စူးစမ်းရန်"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ပျောက်နေသည်"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"ဤစက်ပစ္စည်းအား ပြန်ထည့်ရန်"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> ရွှေ့နေစဉ်"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"ဒေတာများ ရွှေ့နေစဉ်"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"ရွှေ့ပြီး၏"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"<xliff:g id="NAME">%s</xliff:g> သို့ ဒေတာ ရွှေ့ခဲ့၏"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"ဒေတာမရွှေ့နိုင်ပါ"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"မူရင်းနေရာတွင် ဒေတာ ကျန်ခဲ့၏"</string> <string name="activity_list_empty" msgid="1675388330786841066">"တိုက်ဆိုင်သော ပြုလုပ်ချက် ရှာမတွေ့ပါ"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"မီဒီယာထွက်ပေါက်အား လမ်းလွှဲပြောင်းခြင်း"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"အပလီကေးရှင်းအား မီဒီယာ ထုတ်လွှတ်မှုကို အခြားပြင်ပ စက်ပစ္စည်းများသို့ လွှဲပြောင်းခွင့်ပြုပါ"</string> @@ -1466,6 +1458,7 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ပင်မဖြုတ်မီမှာ သော့ဖွင့် ရေးဆွဲမှုပုံစံကို မေးကြည့်ရန်"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ပင်မဖြုတ်မီမှာ စကားဝှက်ကို မေးကြည့်ရန်"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"သင့် အက်ဒမင်မှ သွင်းယူထား၏"</string> + <string name="package_updated_device_owner" msgid="8856631322440187071">"သင့်စီမံခန့်ခွဲသူမှ အဆင့်မြှင့်ထားပါသည်။"</string> <string name="package_deleted_device_owner" msgid="7650577387493101353">"သင့် အက်ဒမင်အား ဖျက်ပစ်ရန်"</string> <string name="battery_saver_description" msgid="1960431123816253034">"ဘက်ထရီသက်တမ်း ကြာရှည်ခံရန်၊ ဘက်ထရီအားထိန်းသည် သင့်ကိရိယာ၏ ဆောင်ရွက်ချက်ကို လျှော့ပေးပြီး တုန်ခါမှု၊ တည်နေရာဝန်ဆောင်မှုများနှင့်၊ နောက်ခံဒေတာအများစုကို ကန့်သတ်ပေး၏။ စင့်လုပ်ပေးရလေ့ရှိသည့် အီးမေး၊ စာပို့ခြင်းနှင့်၊ အခြားအပလီကေးရှင်းများကို ၎င်းတို့အား သင် ဖွင့်မှသာ အဆင့်မြှင့်မွမ်းမံမည်ဖြစ်၏။ \n\n ကိရိယာအား အားသွင်းနေစဉ် ဘက်ထရီအားထိန်းအား အလိုအလျောက် ပိတ်ထားသည်။"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 9f0f3b6..1f0198d 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Konfigurering"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Løs ut"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Utforsk"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> mangler"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Sett inn enheten på nytt"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Flytter <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Flytter dataene"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Flyttingen er fullført"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Dataene er flyttet til <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Kunne ikke flytte dataene"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Dataene er fremdeles på det opprinnelige stedet"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Finner ingen samsvarende aktiviteter."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Videresending av medieutdata"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Lar en app videresende medieutdata til andre eksterne enheter."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Krev bruk av opplåsningsmønster for å løsne apper"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Krev passord for å løsne apper"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Installert av administratoren"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Slettet av administratoren"</string> <string name="battery_saver_description" msgid="1960431123816253034">"For å bidra til å forbedre batterilevetiden reduserer batterispareren ytelsen til enheten din og begrenser vibrering, posisjonstjenester og mesteparten av bakgrunnsdataene. E-post, sending av meldinger og andre apper som er avhengig av synkronisering oppdateres kanskje ikke med mindre du åpner dem.\n\nBatterisparing slås av automatisk når enheten lader."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml index 66f8ae2..899d1cb 100644 --- a/core/res/res/values-ne-rNP/strings.xml +++ b/core/res/res/values-ne-rNP/strings.xml @@ -1086,22 +1086,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"सेटअप"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"निकाल्नुहोस्"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"अन्वेषण गर्नुहोस्"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> हराइरहेको"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"यो यन्त्र पुनःहाल्नुहोस्"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> सार्दै"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"डेटा सार्दै..."</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"सबै सार्नुहोस्"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"डेटा <xliff:g id="NAME">%s</xliff:g> मा सारियो"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"डेटा सार्न सकिएन"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"डेटा मूल स्थानबाट छुट्यो"</string> <string name="activity_list_empty" msgid="1675388330786841066">"कुनै मिल्ने गतिविधि पाइएन।"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"मिडिया परिणाम दिशानिर्देश गर्नुहोस्"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"मिडिया परिणामलाई अन्य बाहिरी उपकरणहरूसँग लैजानको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string> @@ -1474,6 +1466,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"पिन निकाल्नुअघि खोल्ने रूपरेखा सोध्नुहोस्"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"पिन निकाल्नुअघि पासवर्ड सोध्नुहोस्"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"तपाईँको प्रशासकद्वारा स्थापना गरिएको"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"तपाईँको प्रशासकद्वारा हटाइएको"</string> <string name="battery_saver_description" msgid="1960431123816253034">"ब्याट्रीको आयु सुधार्न, ब्याट्री रक्षकले तपाईँको यन्त्रको कार्यसम्पादन घटाउँछ र भाइब्रेसन, स्थान सेवा र बहुसंख्यक पृष्ठभूमि डेटा सीमित गर्दछ। इमेल, सन्देश, र अन्य अनुप्रयोगहरू जुन सिङ्कमा भर पर्छन् अद्यावधिक नहुन सक्छन् जबसम्म तपाईँ तिनीहरूलाई खोल्नुहुन्न\n\n ब्याट्री रक्षक स्वत: निस्कृय हुन्छ जब तपाईँको यन्त्र चार्ज हुँदै हुन्छ।"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 7391d4b..c6de087 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Configuratie"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Uitwerpen"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Verkennen"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ontbreekt"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Plaats dit apparaat opnieuw"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> verplaatsen"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Gegevens verplaatsen"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Verplaatsen voltooid"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Gegevens verplaatst naar <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Kan gegevens niet verplaatsen"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Gegevens staan nog op originele locatie"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Geen overeenkomende activiteiten gevonden."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Media-uitvoer aansturen"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Hiermee kan een app media-uitvoer naar andere externe apparaten doorsturen."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Vragen om ontgrendelingspatroon voordat items worden losgemaakt"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Vragen om wachtwoord voordat items worden losgemaakt"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Geïnstalleerd door uw beheerder"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Verwijderd door uw beheerder"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Accubesparing beperkt de prestaties van uw apparaat, de trilstand, locatieservices en de meeste achtergrondgegevens om de gebruiksduur van de accu te verlengen.\n\nAccubesparing wordt automatisch uitgeschakeld terwijl uw apparaat wordt opgeladen."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml index af4a068..0e9658b 100644 --- a/core/res/res/values-pa-rIN/strings.xml +++ b/core/res/res/values-pa-rIN/strings.xml @@ -274,10 +274,8 @@ <string name="permdesc_receiveWapPush" msgid="748232190220583385">"ਐਪ ਨੂੰ WAP ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਅਨੁਮਤੀ ਵਿੱਚ ਸ਼ਾਮਲ ਹੈ ਐਪ ਦੀ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਤੇ ਭੇਜੇ ਗਏ ਸੁਨੇਹਿਆਂ ਨੂੰ ਤੁਹਾਨੂੰ ਦਿਖਾਏ ਬਿਨਾਂ ਨਿਰੀਖਣ ਕਰਨ ਅਤੇ ਮਿਟਾਉਣ ਦੀ ਸਮਰੱਥਾ।"</string> <string name="permlab_getTasks" msgid="6466095396623933906">"ਚੱਲ ਰਹੇ ਐਪਸ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰੋ"</string> <string name="permdesc_getTasks" msgid="7454215995847658102">"ਐਪ ਨੂੰ ਵਰਤਮਾਨ ਵਿੱਚ ਅਤੇ ਹੁਣੇ ਜਿਹੇ ਚੱਲ ਰਹੇ ਕੰਮਾਂ ਬਾਰੇ ਵਿਸਤ੍ਰਿਤ ਜਾਣਕਾਰੀ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ ਇਸ ਬਾਰੇ ਜਾਣਕਾਰੀ ਖੋਜਣ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ ਕਿ ਡਿਵਾਈਸ ਤੇ ਕਿਹੜੀਆਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵਰਤੀਆਂ ਜਾਂਦੀਆਂ ਹਨ।"</string> - <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) --> - <skip /> - <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) --> - <skip /> + <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"ਪ੍ਰੋਫ਼ਾਈਲ ਅਤੇ ਡਿਵਾਈਸ ਦੇ ਮਾਲਕਾਂ ਨੂੰ ਪ੍ਰਬੰਧਿਤ ਕਰੋ"</string> + <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"ਪ੍ਰੋਫ਼ਾਈਲ ਦੇ ਮਾਲਕ ਅਤੇ ਡਿਵਾਈਸ ਦਾ ਮਾਲਕ ਨੂੰ ਸੈੱਟ ਕਰਨ ਲਈ ਐਪਸ ਨੂੰ ਅਨੁਮਤੀ ਦਿੰਦਾ ਹੈ।"</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"ਚੱਲ ਰਹੇ ਐਪਸ ਨੂੰ ਦੁਬਾਰਾ ਕ੍ਰਮ ਦਿਓ"</string> <string name="permdesc_reorderTasks" msgid="7734217754877439351">"ਐਪ ਨੂੰ ਕੰਮਾਂ ਨੂੰ ਅਗਲੇ ਭਾਗ ਅਤੇ ਪਿਛੋਕੜ ਵਿੱਚ ਮੂਵ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਐਪ ਤੁਹਾਡੇ ਇਨਪੁਟ ਤੋਂ ਬਿਨਾਂ ਇਹ ਕਰ ਸਕਦਾ ਹੈ।"</string> <string name="permlab_enableCarMode" msgid="5684504058192921098">"ਕਾਰ ਮੋਡ ਸਮਰੱਥ ਬਣਾਓ"</string> @@ -1080,6 +1078,22 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"ਸੈੱਟਅੱਪ"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"ਬਾਹਰ ਕੱਢੋ"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"ਐਕਸਪਲੋਰ ਕਰੋ"</string> + <!-- no translation found for ext_media_missing_title (620980315821543904) --> + <skip /> + <!-- no translation found for ext_media_missing_message (5761133583368750174) --> + <skip /> + <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> + <skip /> + <!-- no translation found for ext_media_move_title (1022809140035962662) --> + <skip /> + <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> + <skip /> + <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> + <skip /> + <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> + <skip /> + <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> + <skip /> <string name="activity_list_empty" msgid="1675388330786841066">"ਕੋਈ ਮੇਲ ਖਾਂਦੀਆਂ ਗਤੀਵਿਧੀਆਂ ਨਹੀਂ ਮਿਲੀਆਂ।"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"ਰੂਟ ਮੀਡੀਆ ਆਊਟਪੁਟ"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"ਇੱਕ ਐਪਲੀਕੇਸ਼ਨ ਨੂੂੰ ਹੋਰਾਂ ਬਾਹਰੀ ਡਿਵਾਈਸਾਂ ਲਈ ਮੀਡੀਆ ਆਊਟਪੁਟ ਰੂਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index d87fd22..e71d9fe 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -1092,22 +1092,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Skonfiguruj"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Wysuń"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Przeglądaj"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Brak: <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Ponownie włóż urządzenie"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Przenoszę <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Przenoszę dane"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Przenoszenie zakończone"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Dane przeniesione na: <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Nie udało się przenieść danych"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Dane pozostały w oryginalnej lokalizacji"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Nie znaleziono pasujących działań."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Kierowanie wyjścia multimediów"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Pozwala aplikacji na kierowanie wyjściowych danych multimedialnych do innych urządzeń zewnętrznych."</string> @@ -1484,6 +1476,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Aby odpiąć, poproś o wzór odblokowania"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Aby odpiąć, poproś o hasło"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Zainstalowany przez administratora"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Usunięty przez administratora"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Aby wydłużyć czas pracy baterii, Oszczędzanie baterii ogranicza aktywność urządzenia, w tym wibracje, usługi lokalizacyjne i przetwarzanie większości danych w tle. Poczta, czat i inne synchronizowane aplikacje mogą nie aktualizować swojej zawartości, dopóki ich nie otworzysz.\n\nOszczędzanie baterii wyłącza się automatycznie podczas ładowania urządzenia."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 28c14da..5c624ce 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Configuração"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Ejetar"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Explorar"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> em falta"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Reinserir este dispositivo"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"A mover <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"A mover dados"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Transferência concluída"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Os dados foram movidos para <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Não foi possível mover os dados"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Os dados permaneceram na localização original"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Não foi encontrada nenhuma atividade correspondente."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Encaminhar saída de som multimédia"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que a aplicação encaminhe a saída de som multimédia para outros dispositivos externos."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pedir sequência de desbloqueio antes de soltar"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pedir palavra-passe antes de soltar"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalado pelo administrador"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminado pelo administrador"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Para ajudar a melhorar a autonomia da bateria, a poupança de bateria reduz o desempenho do seu dispositivo e limita a vibração, os serviços de localização e a maioria dos dados em segundo plano. O email, as mensagens e outras aplicações que dependem da sincronização não podem ser atualizados exceto se os abrir.\n\nA poupança de bateria desliga-se automaticamente quando o dispositivo está a carregar."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index b1551b0..810d66e 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Configurar"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Ejetar"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Explorar"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ausente"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Reinserir este dispositivo"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Movendo <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Movendo dados"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Transferência concluída"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Dados movidos para <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Não foi possível mover os dados"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Dados deixados no local original"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Nenhum atividade correspondente foi encontrada."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Rotear saída de mídia"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que um app faça o roteamento de saída de mídia para outros dispositivos externos."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pedir padrão de desbloqueio antes de liberar"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pedir senha antes de liberar"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalado pelo seu administrador"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Excluído pelo seu administrador"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Para ajudar a melhorar a duração da bateria, o economizador de bateria reduz o desempenho e os limites de vibração do dispositivo, os serviços de localização e a maioria dos dados de segundo plano. E-mail, mensagens e outros aplicativos que dependem de sincronização não podem ser atualizados, a não ser que você os abra.\n\nO economizador de bateria é desligado automaticamente quando o dispositivo está sendo carregado."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 1790122..b4497db 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -1085,22 +1085,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Configurați"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Scoateți"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Explorați"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> lipsește"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Reintroduceți dispozitivul"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Se mută <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Se mută datele"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Mutare finalizată"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Date mutate pe <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Nu s-au putut muta datele"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Au rămas date în locația inițială"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Nu s-a găsit nicio activitate potrivită."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Direcţionează rezultatele media"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite unei aplicații să direcţioneze rezultate media către alte dispozitive externe."</string> @@ -1475,6 +1467,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Solicită modelul pentru deblocare înainte de a anula fixarea"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicită parola înainte de a anula fixarea"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalat de administrator"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Șters de administrator"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Pentru a îmbunătăți autonomia bateriei, funcția de economisire a energiei reduce performanțele dispozitivului și limitează vibrațiile, serviciile de localizare și majoritatea datelor de fundal. Este posibil ca e-mailurile, mesageria și alte aplicații care depind de sincronizare să nu se actualizeze dacă nu le deschideți.\n\nFuncția de economisire a energiei se dezactivează automat când dispozitivul se încarcă."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index b9eab57..c8e093a 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -1092,22 +1092,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Настроить"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Извлечь"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Обзор"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> не найден"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Заново подключите устройство"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Перенос приложения <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Перенос данных"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Перенос завершен"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Перенос данных сюда: <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Не удалось перенести данные"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Данные остались там же, где были"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Подходящих действий не найдено."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Перенаправление мультимедийных данных"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Приложение сможет направлять поток мультимедиа на другие внешние устройства."</string> @@ -1484,6 +1476,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Запрашивать графический ключ для отключения блокировки"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запрашивать пароль для отключения блокировки"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Установлено администратором"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Удалено администратором"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Чтобы продлить время работы устройства от батареи, в режиме энергосбережения снижается производительность, а также ограничивается использование вибрации, геолокации и фоновой передачи данных. Данные, требующие синхронизации, могут обновляться только когда вы откроете приложение.\n\nРежим энергосбережения автоматически отключается во время зарядки устройства."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml index f21d99e..831cadb 100644 --- a/core/res/res/values-si-rLK/strings.xml +++ b/core/res/res/values-si-rLK/strings.xml @@ -1080,22 +1080,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"ස්ථාපනය"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"ගැලවීම"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"ගවේෂණය කරන්න"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> අස්ථානගතයි"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"මෙම උපාංගය යළි ඇතුළු කරන්න"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> ගෙන යමින්"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"දත්ත ගෙන යමින්"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"ගෙන යාම සම්පූර්ණ කරන්න"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"දත්ත <xliff:g id="NAME">%s</xliff:g> වෙත ගෙන යන ලදී"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"දත්ත ගෙන යාමට නොහැකි විය"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"මුල් ස්ථානයෙහි ඉතිරි දත්ත"</string> <string name="activity_list_empty" msgid="1675388330786841066">"ගැලපෙන ක්රියාකාරකම් හමු නොවුණි."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"මාධ්ය ප්රතිදානයේ මාර්ගගත කිරීම"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"වෙනත් බාහිර උපාංග වෙත මාධ්ය ප්රතිදානය යැවීමට යෙදුමට අවසර දෙන්න."</string> @@ -1468,6 +1460,7 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ගැලවීමට පෙර අගුළු අරින රටාව සඳහා අසන්න"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ගැලවීමට පෙර මුරපදය විමසන්න"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"ඔබගේ පරිපාලක විසින් ස්ථාපනය කරන ලද"</string> + <string name="package_updated_device_owner" msgid="8856631322440187071">"ඔබගේ පරිපාලක විසින් යාවත්කාලීන කරන ලදී"</string> <string name="package_deleted_device_owner" msgid="7650577387493101353">"ඔබගේ පරිපාලක විසින් මකන ලද"</string> <string name="battery_saver_description" msgid="1960431123816253034">"බැටරි ආයු කාලය වැඩිදියුණු කිරීමට උදවු කිරීමට, බැටරි සුරැකුම ඔබේ උපාංගයේ ක්රියාකාරීත්වය අඩුකරන අතර කම්පනය, පිහිටීම් සේවා, සහ බොහෝමයක් පසුබිම් දත්ත සීමා කරයි. ඔබ ඒවා විවෘත නොකරන්නේ නම් මිස ඊමේල්, පණිවිඩකරණය, සහ සමමුහුර්ත කිරීම මත රඳා පවතින වෙනත් යෙදුම් යාවත්කාලීන නොවිය හැකිය.\n\nඔබේ උපාංගය ආරෝපණය වන විට බැටරි සුරැකුම ස්වයංක්රියව අක්රිය වේ."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 8e97275..fa79dda 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -1092,22 +1092,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Nastavenie"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Odpojiť"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Preskúmať"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Chýba: <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Opäť vložte toto zariadenie"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Presúva sa aplikácia <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Presúvajú sa údaje"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Presun bol dokončený"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Údaje boli presunuté do úložiska <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Presun údajov zlyhal"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Údaje boli ponechané v pôvodnom umiestnení"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Nenašli sa žiadne zodpovedajúce aktivity."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Smerovanie výstupu médií"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Umožňuje aplikácii smerovať výstup médií do ďalších externých zariadení."</string> @@ -1484,6 +1476,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pred uvoľnením požiadať o bezpečnostný vzor"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pred uvoľnením požiadať o heslo"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Inštalovaný správcom"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Odstránený správcom"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Šetrič batérie znižuje výkonnosť vášho zariadenia a obmedzuje vibrovanie, služby určovania polohy a väčšinu údajov na pozadí, aby tak pomohol predĺžiť výdrž batérie. E-mailová aplikácia, aplikácia na odosielanie správ SMS a MMS a ďalšie aplikácie, ktoré sú založené na synchronizácii, sa pravdepodobne aktualizujú až po ich otvorení.\n\nŠetrič batérie sa automaticky vypne, keď zariadenie začnete nabíjať."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 0ed81d3..a79a0ec 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -1092,22 +1092,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Nastavitev"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Izvrzite"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Raziščite"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Ni shrambe <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Znova vstavite to napravo"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Premikanje aplikacije <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Premikanje podatkov"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Premik je dokončan"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Podatki so premaknjeni v shrambo <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Premik podatkov ni uspel"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Podatki so ostali na izvirni lokaciji"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Ni ustreznih dejavnosti."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Preusmeritev predstavnosti"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Aplikaciji omogoča preusmerjanje predstavnosti v druge zunanje naprave."</string> @@ -1484,6 +1476,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pred odpenjanjem vprašaj za vzorec za odklepanje"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pred odpenjanjem vprašaj za geslo"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Namestil skrbnik"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisal skrbnik"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Varčevanje z energijo akumulatorja podaljša čas njegovega delovanja tako, da zmanjša zmogljivost delovanja naprave in omeji vibriranje, lokacijske storitve ter prenos večine podatkov v ozadju. Aplikacije za e-pošto, sporočanje in drugo, ki uporabljajo sinhroniziranje, se morda ne posodabljajo, razen če jih odprete.\n\nVarčevanje z energijo akumulatorja se samodejno izklopi med polnjenjem akumulatorja naprave."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml index eb2f6e3..ea04ad8 100644 --- a/core/res/res/values-sq-rAL/strings.xml +++ b/core/res/res/values-sq-rAL/strings.xml @@ -129,7 +129,7 @@ <string-array name="wfcOperatorErrorNotificationMessages"> </string-array> <string name="wfcSpnFormat" msgid="8211621332478306568">"%s"</string> - <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Joaktiv"</string> + <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Çaktivizuar"</string> <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferohet Wi-Fi"</string> <string name="wfc_mode_cellular_preferred_summary" msgid="5920549484600758786">"Preferohet rrjeti celular"</string> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Vetëm Wi-Fi"</string> @@ -274,10 +274,8 @@ <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Lejon aplikacionin të marrë dhe përpunojë mesazhe WAP. Kjo do të thotë se aplikacioni mund të monitorojë ose fshijë mesazhe të dërguara në pajisjen tënde, pa t\'i treguar ato."</string> <string name="permlab_getTasks" msgid="6466095396623933906">"gjej aplikacionet në punë"</string> <string name="permdesc_getTasks" msgid="7454215995847658102">"Lejon aplikacionin të gjejë informacione mbi detyrat aktuale dhe të fundit në punë. Kjo mund të lejojë aplikacionin të zbulojë informacione rreth aplikacioneve të përdorura në pajisje."</string> - <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) --> - <skip /> - <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) --> - <skip /> + <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Menaxho pronarët e profilit dhe të pajisjes"</string> + <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Lejo aplikacionet që të caktojnë pronarët e profilit dhe pronarin e pajisjes"</string> <string name="permlab_reorderTasks" msgid="2018575526934422779">"ri-poziciono aplikacionet në punë"</string> <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Lejon aplikacionin të zhvendosë detyra në plan të parë dhe në sfond. Aplikacioni mund ta bëjë këtë pa hyrjen tënde."</string> <string name="permlab_enableCarMode" msgid="5684504058192921098">"aktivizo modalitetin \"në makinë\""</string> @@ -422,7 +420,7 @@ <string name="permdesc_nfc" msgid="7120611819401789907">"Lejon aplikacionin të komunikojë me etiketimet e \"Komunikimit të fushës së afërt (NFC)\", kartat dhe lexuesit."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"çaktivizo kyçjen e ekranit"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Lejon aplikacionin të çaktivizojë kyçjen e tasteve dhe çdo mbrojtje të lidhur me fjalëkalimin. Për shembull, telefoni çaktivizon kyçjen e tasteve kur merr një telefonatë hyrëse, pastaj riaktivizon kyçjen e tasteve kur mbaron telefonata."</string> - <string name="permlab_manageFingerprint" msgid="5640858826254575638">"të qaset te hardueri i gjurmës së gishtit"</string> + <string name="permlab_manageFingerprint" msgid="5640858826254575638">"të menaxhojë harduerin e gjurmës së gishtit"</string> <string name="permdesc_manageFingerprint" msgid="178208705828055464">"E lejon aplikacionin që të aktivizojë metoda për të shtuar dhe për të fshirë shabllonet e gjurmës së gishtit për përdorim."</string> <string name="permlab_useFingerprint" msgid="3150478619915124905">"të përdorë harduerin e gjurmës së gishtit"</string> <string name="permdesc_useFingerprint" msgid="9165097460730684114">"E lejon aplikacinin që të përdorë harduerin e gjurmës së gishtit për verifikimin"</string> @@ -435,7 +433,7 @@ </string-array> <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardueri i gjurmës së gishtit nuk mundësohet."</string> <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Gjurma e gishtit nuk mund të ruhet. Hiq një gjurmë gishti ekzistuese."</string> - <string name="fingerprint_error_timeout" msgid="3927186043737732875">"U arrit vonesa e skadimit për gjurmën e gishtit. Provo përsëri."</string> + <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Koha e veprimit për gjurmën e gishtit skadoi. Provo përsëri."</string> <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operacioni i gjurmës së gishtit u anulua."</string> <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Keni bërë shumë tentativa. Provo përsëri më vonë."</string> <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Provo përsëri."</string> @@ -939,9 +937,9 @@ <string name="new_app_action" msgid="5472756926945440706">"Fillo <xliff:g id="OLD_APP">%1$s</xliff:g>"</string> <string name="new_app_description" msgid="1932143598371537340">"Ndalo aplikacionin e vjetër pa e ruajtur."</string> <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> e ka kaluar kufirin e memories"</string> - <string name="dump_heap_notification_detail" msgid="2075673362317481664">"Hedhja e dëmtimit të grumbullimit është marrë; prek për ta ndarë"</string> - <string name="dump_heap_title" msgid="5864292264307651673">"Të ndahet hedhja e dëmtimit të grumbullimit?"</string> - <string name="dump_heap_text" msgid="4809417337240334941">"Procesi <xliff:g id="PROC">%1$s</xliff:g> ka kaluar kufirin e tij të memories së procesit me <xliff:g id="SIZE">%2$s</xliff:g>. Ofrohet një hedhje e dëmtimit të grumbullimit që ta ndani me zhvilluesit e tij. Trego kujdes: kjo hedhje e dëmtimit të grumbullimit mund të përmbajë çdo informacion tëndin personal ku ka qasje ky aplikacion."</string> + <string name="dump_heap_notification_detail" msgid="2075673362317481664">"Skedarët fiktivë u stivosën; prek për t\'i ndarë"</string> + <string name="dump_heap_title" msgid="5864292264307651673">"Të ndahet stiva e skedarëve fiktivë?"</string> + <string name="dump_heap_text" msgid="4809417337240334941">"Procesi <xliff:g id="PROC">%1$s</xliff:g> ka kaluar kufirin e tij të memories së procesit me <xliff:g id="SIZE">%2$s</xliff:g>. Mundësohet stivimi e skedarëve fiktivë në mënyrë që t\'i ndani me zhvilluesit e tyre. Bëni kujdes pasi stiva e skedarëve fiktivë mund të përmbajë ndonjë informacion tëndin personal ku aplikacioni ka qasje."</string> <string name="sendText" msgid="5209874571959469142">"Zgjidh një veprim për tekstin"</string> <string name="volume_ringtone" msgid="6885421406845734650">"Volumi i ziles"</string> <string name="volume_music" msgid="5421651157138628171">"Volumi i klipeve \"media\""</string> @@ -1080,6 +1078,22 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Konfigurimi"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Nxirr"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Eksploro"</string> + <!-- no translation found for ext_media_missing_title (620980315821543904) --> + <skip /> + <!-- no translation found for ext_media_missing_message (5761133583368750174) --> + <skip /> + <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> + <skip /> + <!-- no translation found for ext_media_move_title (1022809140035962662) --> + <skip /> + <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> + <skip /> + <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> + <skip /> + <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> + <skip /> + <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> + <skip /> <string name="activity_list_empty" msgid="1675388330786841066">"Nuk u gjet asnjë aktivitet që përputhet."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Kalo daljet e medias"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Lejon një aplikacion të kalojë daljet mediatike në pajisje të tjera të jashtme."</string> @@ -1445,7 +1459,7 @@ <string name="managed_profile_label_badge" msgid="2355652472854327647">"Puna <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_toast" msgid="7570091317001980053">"Për t\'i hequr gozhdimin ekranit, prek dhe mbaj shtypur njëkohësisht \"Prapa\" dhe \"Përmbledhje\"."</string> <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Për t\'i hequr gozhdimin ekranit, prek dhe mbaj shtypur \"Përmbledhje\"."</string> - <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Ekrani është i mbërthyer. Anulimi i mbërthimit nuk lejohet nga organizata jote."</string> + <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Ekrani është i gozhduar. Anulimi i mbërthimit nuk lejohet nga organizata jote."</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Ekrani u gozhdua"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"Ekrani u hoq nga gozhdimi"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Kërko PIN-in para se t\'i heqësh gozhdimin"</string> @@ -1475,7 +1489,7 @@ <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Shpalos"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Mos shqetëso"</string> - <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Koha joaktive"</string> + <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"periudha joaktive"</string> <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"Natën gjatë javës"</string> <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"Fundjava"</string> <string name="muted_by" msgid="6147073845094180001">"Lënë në heshtje nga <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string> @@ -1487,7 +1501,7 @@ <string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Kërkesa SS është e modifikuar në kërkesën DIAL."</string> <string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Kërkesa SS është modifikuar në kërkesën USSD."</string> <string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Kërkesa SS është e modifikuar në kërkesën e re SS."</string> - <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Porta periferike USB e Android"</string> + <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Porta periferike USB e Androidit"</string> <string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string> <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Porta periferike USB"</string> <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Opsione të tjera"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index c18d98f..738dccc 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -1085,22 +1085,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Подешавање"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Избаци"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Истражи"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> недостаје"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Уметните уређај поново"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Преноси се <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Подаци се преносе"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Пренос је завршен"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Подаци су пренесени на уређај <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Пренос података није успео"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Подаци су остали на оригиналној локацији"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Није пронађена ниједна подударна активност."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Усмеравање излаза медија"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Дозвољава апликацији да усмерава излаз медија на друге спољне уређаје."</string> @@ -1475,6 +1467,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Тражи шаблон за откључавање пре откачињања"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Тражи лозинку пре откачињања"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Инсталирао је ваш администратор"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Избрисао је ваш адмиистратор"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Да би продужила време трајања батерије, уштеда батерије смањује перформансе уређаја и ограничава вибрацију, услуге локације и већину позадинских података. Имејл, размена порука и друге апликације које се ослањају на синхронизацију можда неће да се ажурирају ако их не отворите.\n\nУштеда батерије се аутоматски искључује када се уређај пуни."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 6981717..dfaa97a 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Konfiguration"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Mata ut"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Utforska"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> saknas"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Sätt i enheten igen"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Flyttar <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Flyttar data"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Flytten är klar"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Data har flyttats till <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Det gick inte att flytta data"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Data kvar på ursprunglig plats"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Det gick inte att hitta några matchande aktiviteter."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Omdirigera medieuppspelning"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Tillåter att appen omdirigerar medieuppspelningar till andra externa enheter."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Be om upplåsningsmönster innan skärmen slutar fästas"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Be om lösenord innan skärmen slutar fästas"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Paketet har installerats av administratören"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Paketet har raderats av administratören"</string> <string name="battery_saver_description" msgid="1960431123816253034">"I batterisparläget reduceras enhetens prestanda så att batteriet ska räcka längre och vibration, platstjänster samt den mesta användningen av bakgrundsdata begränsas. Det kan hända att appar för e-post, sms och annat som kräver synkronisering inte uppdateras förrän du öppnar dem.\n\nBatterisparläget inaktiveras automatiskt när enheten laddas."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index e807ca1..13f6e9c 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Sanidi"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Ondoa"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Chunguza"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> haipo"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Weka tena kifaa hiki"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Inahamisha <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Inahamisha data"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Imekamilisha kuhamisha"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Data ilihamishiwa kwenye <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Haikuweza kuhamisha data"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Data iliachwa katika eneo la awali"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Hakuna shughuli zinazolingana zilizopatikana."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Fuatalia utoaji wa habari"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Inaruhusu programu kufuatilia utoaji wa habari kwa vifaa vingine vya nje."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Omba mchoro wa kufungua kabla hujabandua"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Omba nenosiri kabla hujabandua"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Kilisakinishwa na msimamizi wako"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Kilifutwa na msimamizi wako"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Kusaidia kuboresha muda wa matumizi ya betri, inayookoa betri hupunguza utendaji wa kifaa chako na kupunguza mtetemo, huduma za utambuzi wa mahali, na data nyingi ya chini chini. Barua pepe, ujumbe na programu nyingine zinazotege,ea usawazishaji huenda zisisasishwe usipozifungua.\n\nInayookoa betri hujizima kiotomatiki kifaa chako kinapokuwa kinachaji."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml index f07fcac..b8f8e7a 100644 --- a/core/res/res/values-ta-rIN/strings.xml +++ b/core/res/res/values-ta-rIN/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"அமைவு"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"வெளியேற்று"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"உலாவுக"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> இல்லை"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"சாதனத்தை மீண்டும் செருகவும்"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g>ஐ நகர்த்துகிறது"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"தரவு நகர்த்தப்படுகிறது"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"நகர்த்தப்பட்டது"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"<xliff:g id="NAME">%s</xliff:g>க்குத் தரவு நகர்த்தப்பட்டது"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"தரவை நகர்த்த முடியவில்லை"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"அசல் இடத்திலிருந்து தரவு நகர்த்தப்பட்டது"</string> <string name="activity_list_empty" msgid="1675388330786841066">"பொருந்தும் செயல்பாடுகள் கண்டறியப்படவில்லை."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"மீடியா அவுட்புட்டை வழிசெலுத்துதல்"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"மீடியாவைப் பிற வெளிப்புறச் சாதனங்களுக்கு வெளியீடாக வழிகாட்ட பயன்பாட்டை அனுமதிக்கிறது."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"அகற்றும் முன் திறத்தல் வடிவத்தைக் கேள்"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"அகற்றும் முன் கடவுச்சொல்லைக் கேள்"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"நிர்வாகி நிறுவினார்"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"நிர்வாகி நீக்கிவிட்டார்"</string> <string name="battery_saver_description" msgid="1960431123816253034">"பேட்டரி ஆயுளை மேம்படுத்த, பேட்டரி சேமிப்பான் உங்கள் சாதனத்தின் செயல்திறனைக் குறைத்து, அதிர்வு, இடச் சேவைகள் மற்றும் பெரும்பாலான பின்புலத் தரவு போன்றவற்றைக் கட்டுப்படுத்துகிறது. ஒத்திசைவைச் சார்ந்துள்ள மின்னஞ்சல், செய்தியிடல் மற்றும் பிற பயன்பாடுகளானது அவற்றைத் திறக்கும்வரையில் புதுப்பிக்கப்படாமல் போகக்கூடும்.\n\nஉங்கள் ஃபோன் சார்ஜ் செய்யப்படும்போது, பேட்டரி சேமிப்பான் தானாகவே முடங்கும்."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml index a36c8fe..af113ee 100644 --- a/core/res/res/values-te-rIN/strings.xml +++ b/core/res/res/values-te-rIN/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"సెటప్ చేయి"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"తొలగించు"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"విశ్లేషించు"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> కనుగొనబడటం లేదు"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"ఈ పరికరం తిరిగి చొప్పించండి"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g>ని తరలిస్తోంది"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"డేటాను తరలిస్తోంది"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"తరలింపు పూర్తయింది"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"డేటా <xliff:g id="NAME">%s</xliff:g>కి తరలించబడింది"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"డేటాను తరలించలేకపోయింది"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"డేటా అసలు స్థానంలో అలాగే ఉంది"</string> <string name="activity_list_empty" msgid="1675388330786841066">"సరిపోలే కార్యాచరణలు కనుగొనబడలేదు."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"ప్రసార మాధ్యమ అవుట్పుట్ను మళ్లించడం"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"మీడియా అవుట్పుట్ను ఇతర బాహ్య పరికరాలకు మళ్లించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"అన్పిన్ చేయడానికి ముందు అన్లాక్ నమూనా కోసం అడుగు"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"అన్పిన్ చేయడానికి ముందు పాస్వర్డ్ కోసం అడుగు"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"మీ నిర్వాహకులు ఇన్స్టాల్ చేసారు"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"మీ నిర్వాహకులు తొలగించారు"</string> <string name="battery_saver_description" msgid="1960431123816253034">"బ్యాటరీ జీవితకాలాన్ని మెరుగుపరచడంలో సహాయపడటానికి, బ్యాటరీ సేవర్ మీ పరికరం పనితీరును తగ్గిస్తుంది మరియు వైబ్రేషన్ను, స్థాన సేవలను మరియు ఎక్కువ నేపథ్య డేటాను పరిమితం చేస్తుంది. ఇమెయిల్, మెసేజింగ్ మరియు సమకాలీకరణపై ఆధారపడే ఇతర అనువర్తనాలు మీరు వాటిని తెరిస్తే మినహా నవీకరించబడవు.\n\nమీ పరికరం ఛార్జ్ అవుతున్నప్పుడు బ్యాటరీ సేవర్ స్వయంచాలకంగా ఆఫ్ అవుతుంది."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 84d31a3..e8cf5c2 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"ตั้งค่า"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"นำอุปกรณ์ออก"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"สำรวจ"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"ไม่มี <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"เสียบอุปกรณ์นี้อีกครั้ง"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"กำลังย้าย <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"กำลังย้ายข้อมูล"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"ย้ายเสร็จสมบูรณ์แล้ว"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"ย้ายข้อมูลไปยัง <xliff:g id="NAME">%s</xliff:g> แล้ว"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"ไม่สามารถย้ายข้อมูล"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"ข้อมูลที่เหลืออยู่ในตำแหน่งเดิม"</string> <string name="activity_list_empty" msgid="1675388330786841066">"ไม่พบกิจกรรมที่ตรงกัน"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"กำหนดเส้นทางเอาต์พุตของสื่อ"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"อนุญาตให้แอปพลิเคชันกำหนดเส้นทางเอาต์พุตของสื่อไปยังอุปกรณ์ภายนอกอื่นๆ"</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ขอรูปแบบการปลดล็อกก่อนเลิกตรึง"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ขอรหัสผ่านก่อนเลิกตรึง"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"ติดตั้งโดยผู้ดูแลระบบของคุณ"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"ลบโดยผู้ดูแลระบบของคุณ"</string> <string name="battery_saver_description" msgid="1960431123816253034">"เพื่อช่วยปรับปรุงอายุการใช้งานแบตเตอรี่ โหมดประหยัดแบตเตอรี่จะลดการทำงานของอุปกรณ์และจำกัดการสั่น บริการตำแหน่ง และข้อมูลแบ็กกราวด์ส่วนใหญ่ สำหรับอีเมล การรับส่งข้อความ และแอปอื่นๆ ที่ใช้การซิงค์จะไม่อัปเดตหากคุณไม่เปิดขึ้นมา\n\nโหมดประหยัดแบตเตอรี่จะปิดโดยอัตโนมัติขณะชาร์จอุปกรณ์"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index e343404..87761bb 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"I-setup"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"I-eject"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"I-explore"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Nawawala ang <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Ilagay muli ang device na ito"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Inililipat ang <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Naglilipat ng data"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Nakumpleto na ang paglilipat"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Inilipat ang data sa <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Hindi mailipat ang data"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Iniwan ang data sa orihinal na lokasyon"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Walang nahanap na mga tumutugmang aktibidad."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"I-route ang output ng media"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Pinapayagan ang application na mag-route ng output ng media sa iba pang mga panlabas na device."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Humingi ng pattern sa pag-unlock bago mag-unpin"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Humingi ng password bago mag-unpin"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Na-install ng iyong administrator"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Na-delete ng iyong administrator"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Upang matulungang pagbutihin ang tagal ng baterya, binabawasan ng pangtipid ng baterya ang pagganap ng iyong device at nililimitahan ang pag-vibrate, mga serbisyo ng lokasyon at karamihan sa data ng background. Maaaring hindi mag-update ang email, pagmemensahe at iba pang mga app na umaasa sa pagsi-sync maliban kung buksan mo ang mga iyon.\n\nAwtomatikong nag-o-off ang pangtipid ng baterya kapag nagcha-charge ang iyong device."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index c9166cd..b5fc485 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Kurulum"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Çıkar"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Keşfedin"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> bulunamıyor"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Bu cihazı yeniden yerleştirin"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> taşınıyor"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Veriler taşınıyor"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Taşıma işlemi tamamlandı"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Veriler <xliff:g id="NAME">%s</xliff:g> depolama birimine taşındı"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Veriler taşınamadı"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Orijinal konumda veri kaldı"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Eşleşen hiçbir etkinlik bulunamadı."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Medya çıktısını yönlendir"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Uygulamaya medya çıktısını başka harici cihazlara yönlendirme izni verir."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Sabitlemeyi kaldırmadan önce kilit açma desenini sor"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Sabitlemeyi kaldırmadan önce şifre sor"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Yöneticiniz tarafından yüklendi"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Yöneticiniz tarafından silindi"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Pil tasarrufu özelliği, pil ömrünü iyileştirmeye yardımcı olmak için cihazın performansını düşürür, titreşimi, konum hizmetlerini ve arka plan verilerinin çoğunu sınırlar. Senkronizasyona dayalı olarak çalışan e-posta, mesajlaşma uygulamaları ve diğer uygulamalar, bunları açmadığınız sürece güncellenmeyebilir.\n\nCihazınız şarj olurken pil tasarrufu otomatik olarak kapatılır."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 81c24a4..f792619 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -1092,22 +1092,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Налаштувати"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Відключити"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Переглянути"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"Немає пристрою <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Вийміть і вставте пристрій"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Переміщення додатка <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Переміщення даних"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Дані переміщено"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Дані переміщено на пристрій <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Не вдалося перемістити дані"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Дані не переміщено"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Відповідні дії не знайдено."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Скеровувати вивід медіа-даних"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Дозволяє програмі скеровувати вивід медіа-даних на інші зовнішні пристрої."</string> @@ -1484,6 +1476,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Запитувати ключ розблокування перед відкріпленням"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запитувати пароль перед відкріпленням"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Установив адміністратор"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Видалив адміністратор"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Щоб подовжити час роботи акумулятора, функція заощадження заряду акумулятора знижує продуктивність пристрою, а також обмежує вібрацію, функції служб локації та передавання більшості фонових даних. Електронна пошта, чати й інші додатки, які синхронізуються, можуть не оновлюватися, доки ви їх не відкриєте.\n\nФункція заощадження заряду акумулятора автоматично вимикається під час заряджання пристрою."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml index 03ad6ac..9a2ab9a 100644 --- a/core/res/res/values-ur-rPK/strings.xml +++ b/core/res/res/values-ur-rPK/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"ترتیب دیں"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"خارج کریں"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"دریافت کریں"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> غائب ہے"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"اس آلہ کو دوبارہ داخل کریں"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> کو منتقل کیا جا رہا ہے"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"ڈیٹا منتقل کیا جا رہا ہے…"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"منتقل کرنا مکمل ہوگیا"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"ڈیٹا کو <xliff:g id="NAME">%s</xliff:g> پر منتقل کر دیا گیا"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"ڈیٹا منتقل نہیں کیا جا سکا"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"ڈیٹا اصل جگہ پر باقی ہے"</string> <string name="activity_list_empty" msgid="1675388330786841066">"کوئی مماثل سرگرمیاں نہیں ملیں۔"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"میڈیا آؤٹ پٹ کی سمت طے کریں"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"کسی ایپلیکیشن کو دوسرے خارجی آلات تک میڈیا آؤٹ پٹ کا راستہ بنانے کی اجازت دیتا ہے۔"</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"پن ہٹانے سے پہلے غیر مقفل کرنے کا پیٹرن طلب کریں"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"پن ہٹانے سے پہلے پاس ورڈ طلب کریں"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"آپ کے منتظم کی جانب سے انسٹال کر دیا گیا"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"آپ کے منتظم کی جانب سے حذف کر دیا گیا"</string> <string name="battery_saver_description" msgid="1960431123816253034">"بیٹری کی میعاد بہتر کرنے میں مدد کرنے کیلئے، بیٹری کی بچت آپ کے آلہ کی کارکردگی کم کر دیتی ہے اور وائبریشن، مقام کی سروسز اور پس منظر کا بیشتر ڈیٹا محدود کر دیتی ہے۔ ای میل، پیغام رسانی اور مطابقت پذیری پر مبنی دیگر ایپس ممکن ہے اس وقت تک اپ ڈیٹ نہ ہوں جب تک آپ انہیں نہ کھولیں۔\n\nآپ کا آلہ چارج ہوتے وقت بیٹری کی بچت خود بخود آف ہو جاتی ہے۔"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml index 9706535..c368d51 100644 --- a/core/res/res/values-uz-rUZ/strings.xml +++ b/core/res/res/values-uz-rUZ/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Sozlash"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Chiqarish"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"O‘rganish"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> qurilmasi o‘rnatilmagan"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Ushbu qurilmani qayta kiriting"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> ilovasi ko‘chirilmoqda"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Ma’lumotlar ko‘chirilmoqda"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Ko‘chirish tugadi"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Ma’lumotlar <xliff:g id="NAME">%s</xliff:g> xotirasiga ko‘chirildi"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Ma’lumotlar ko‘chirilmadi"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Ma’lumotlar asl joyida qoldi"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Hech qanday mos faoliyat topilmadi."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Media chiqishni yo‘naltirish"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Ilovaga media chiqish ovozini boshqa tashqi qurilmalarga yo‘naltirish uchun ruxsat beradi."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Bo‘shatishdan oldin chizmali parol so‘ralsin"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Bo‘shatishdan oldin parol so‘ralsin"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Administratoringiz tomonidan o‘rnatilgan"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Administratoringiz tomonidan o‘chirilgan"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Batareya quvvatini uzoqroq vaqtga yetkazish uchun quvvat tejash funksiyasi qurilmangiz unumdorligini kamaytiradi hamda uning tebranishi va orqa fonda internetdan foydalanishini cheklaydi. Sinxronlanishni talab qiladigan e-pochta, xabar almashinuv va boshqa ilovalar esa qachonki ularni ishga tushirganingizda yangilanadi.\n\nQurilma quvvat olayotganda quvvat tejash funksiyasi avtomatik tarzda o‘chadi."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index a1509af..3aae936 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Thiết lập"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Tháo"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Khám phá"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> bị thiếu"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Cắm lại thiết bị này"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Di chuyển <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Di chuyển dữ liệu"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Hoàn tất di chuyển"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Dữ liệu được di chuyển sang <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Không thể di chuyển dữ liệu"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Dữ liệu vẫn ở vị trí ban đầu"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Không tìm thấy hoạt động nào phù hợp."</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Định tuyến thiết bị ra phương tiện"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Cho phép ứng dụng định tuyến thiết bị ra phương tiện đến các thiết bị bên ngoài khác."</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Hỏi hình mở khóa trước khi bỏ ghim"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Hỏi mật khẩu trước khi bỏ ghim"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Được cài đặt bởi quản trị viên của bạn"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Đã bị xóa bởi quản trị viên của bạn"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Để giúp tăng tuổi thọ pin, trình tiết kiệm pin sẽ giảm hiệu suất thiết bị của bạn và hạn chế rung, dịch vụ vị trí và hầu hết dữ liệu nền. Email, nhắn tin và các ứng dụng khác dựa trên đồng bộ hóa có thể không cập nhật nếu bạn không mở chúng.\n\nTrình tiết kiệm pin tự động tắt khi thiết bị của bạn đang sạc."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index bbe3287..14c58f6 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -1466,6 +1466,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"取消时要求绘制解锁图案"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消时要求输入密码"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"已由管理员安装"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"已被管理员删除"</string> <string name="battery_saver_description" msgid="1960431123816253034">"为了延长电池的续航时间,节电助手会降低设备的性能,并限制振动、位置信息服务和大部分后台流量。对于电子邮件、聊天工具等依赖于同步功能的应用,可能要打开这类应用时才能收到新信息。\n\n节电助手会在设备充电时自动关闭。"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index a698848..1635e27 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"設定"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"移除"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"探索"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"找不到<xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"重新插入此裝置"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"正在轉移<xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"正在轉移資料"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"完成轉移"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"資料已轉移至<xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"無法轉移資料"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"資料仍然儲存在原來位置"</string> <string name="activity_list_empty" msgid="1675388330786841066">"找不到相符的活動。"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"轉送媒體輸出"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"允許應用程式將媒體輸出轉送至其他外部裝置。"</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"取消固定時必須畫出解鎖圖案"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消固定時必須輸入密碼"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"已由管理員安裝"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"已由管理員刪除"</string> <string name="battery_saver_description" msgid="1960431123816253034">"節約電池用量模式有助於延長電池壽命,但這會降低裝置效能,並限制震動、定位服務及大部分背景數據傳輸。除非您啟用,否則電郵、短訊及其他需要使用同步功能的應用程式均不會更新。\n\n當裝置充電時,節約電池用量模式會自動關閉。"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 009117a..61d319b 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"設定"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"退出"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"探索"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"找不到 <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"重新插入這部裝置"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"正在移動「<xliff:g id="NAME">%s</xliff:g>」"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"正在移動資料"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"移動完成"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"資料已移動至「<xliff:g id="NAME">%s</xliff:g>」"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"無法移動資料"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"資料留在原來的位置"</string> <string name="activity_list_empty" msgid="1675388330786841066">"找不到相符的活動。"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"轉送媒體輸出"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"允許應用程式將媒體輸出轉送至其他外部裝置。"</string> @@ -1466,6 +1458,8 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"取消固定時必須畫出解鎖圖形"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消固定時必須輸入密碼"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"已由管理員安裝"</string> + <!-- no translation found for package_updated_device_owner (8856631322440187071) --> + <skip /> <string name="package_deleted_device_owner" msgid="7650577387493101353">"已遭管理員刪除"</string> <string name="battery_saver_description" msgid="1960431123816253034">"節約耗電量模式會透過降低裝置效能、震動限制、定位服務限制和大多數背景資料運作限制等方式,延長電池續航力。此外,如果未開啟電子郵件、簡訊和其他需要使用同步功能的應用程式,系統將不會自動更新這些應用程式。\n\n當您為裝置充電時,節約耗電量模式會自動關閉。"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index a719e07..d3f8482 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -1078,22 +1078,14 @@ <string name="ext_media_init_action" msgid="8317198948634872507">"Ukusetha"</string> <string name="ext_media_unmount_action" msgid="1121883233103278199">"Khipha"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Hlola"</string> - <!-- no translation found for ext_media_missing_title (620980315821543904) --> - <skip /> - <!-- no translation found for ext_media_missing_message (5761133583368750174) --> - <skip /> - <!-- no translation found for ext_media_move_specific_title (1471100343872375842) --> - <skip /> - <!-- no translation found for ext_media_move_title (1022809140035962662) --> - <skip /> - <!-- no translation found for ext_media_move_success_title (8575300932957954671) --> - <skip /> - <!-- no translation found for ext_media_move_success_message (4199002148206265426) --> - <skip /> - <!-- no translation found for ext_media_move_failure_title (7613189040358789908) --> - <skip /> - <!-- no translation found for ext_media_move_failure_message (1978096440816403360) --> - <skip /> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> okulahlekile"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Faka kabusha le divayisi"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Ihambisa i-<xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Ihambisa idatha"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Ukuhamba kuphelele"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Idatha iyiswe ku-<xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Ayikwazanga ukuhambisa idatha"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Idatha isele endaweni yoqobo"</string> <string name="activity_list_empty" msgid="1675388330786841066">"Ayikho imisebenzi efanayo etholakele"</string> <string name="permlab_route_media_output" msgid="1642024455750414694">"Yenza umzila wemidiya wokukhiphayo"</string> <string name="permdesc_route_media_output" msgid="4932818749547244346">"Ivumela uhlelo lokusebenza ukwenza umzila wokukhiphayo wemidiya kuya kumadivayisi angaphandle."</string> @@ -1466,6 +1458,7 @@ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Cela iphethini yokuvula ngaphambi kokususa ukuphina"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Cela iphasiwedi ngaphambi kokususa ukuphina"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Ifakwe ngumlawuli wakho"</string> + <string name="package_updated_device_owner" msgid="8856631322440187071">"Ibuyekezwe ngumqondisi wakho"</string> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Isuswe ngumlawuli wakho"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Ukusiza ukuthuthukisa impilo yebhethri, isilondoloze sebhethri sehlisa ukusebenza kwedivayisi yakho futhi sikhawulele ukudlidliza, amasevisi wendawo, nedatha eningi yangasemuva. I-imeyili, imilayezo, nezinye izinhlelo zokusebenza ezincike ekuvumelaniseni zingahle zingabuyekezwa ngaphandle kokuthi uzivule.\n\nIsilondolozi sebhethri siyavaleka ngokuzenzakalelayo uma idivayisi yakho ishaja."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 52b31b2..fe5862b 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -7304,8 +7304,8 @@ <attr name="recognitionService" format="string" /> <attr name="settingsActivity" /> <!-- Flag indicating whether this voice interaction service is capable of handling the - assist gesture. --> - <attr name="supportsAssistGesture" format="boolean" /> + assist action. --> + <attr name="supportsAssist" format="boolean" /> </declare-styleable> <!-- Use <code>voice-enrollment-application</code> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 4631427..59c6e4f 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -842,6 +842,11 @@ via adb. The default value of this attribute is <code>true</code>. --> <attr name="allowBackup" format="boolean" /> + <!-- Applications will set this in their manifest to opt-in to or out of full app data back-up + and restore. Alternatively they can set it to an xml resource within their app that will + be parsed by the BackupAgent to selectively backup files indicated within that xml. --> + <attr name="fullBackupContent" format="reference|boolean" /> + <!-- Indicates that even though the application provides a <code>BackupAgent</code>, only full-data streaming backup operations are to be performed to save the app's data. This lets the app rely on full-data backups while still participating in @@ -1189,6 +1194,7 @@ <attr name="backupAgent" /> <attr name="allowBackup" /> <attr name="fullBackupOnly" /> + <attr name="fullBackupContent" /> <attr name="killAfterRestore" /> <attr name="restoreNeedsApplication" /> <attr name="restoreAnyVersion" /> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 0b8b280..7270b2c 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2138,4 +2138,7 @@ <!-- This config is used to force VoiceInteractionService to start on certain low ram devices. --> <bool name="config_forceEnableVoiceInteractionService">false</bool> + + <!-- This config is ued to determine whether animations are allowed in low power mode. --> + <bool name="config_allowAnimationsInLowPowerMode">false</bool> </resources> diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml index 4b8bd0f..842c72e 100644 --- a/core/res/res/values/ids.xml +++ b/core/res/res/values/ids.xml @@ -101,6 +101,18 @@ <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SCROLL_TO_POSITION}. --> <item type="id" name="accessibilityActionScrollToPosition" /> + <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SCROLL_UP}. --> + <item type="id" name="accessibilityActionScrollUp" /> + + <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SCROLL_LEFT}. --> + <item type="id" name="accessibilityActionScrollLeft" /> + + <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SCROLL_DOWN}. --> + <item type="id" name="accessibilityActionScrollDown" /> + + <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SCROLL_RIGHT}. --> + <item type="id" name="accessibilityActionScrollRight" /> + <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_STYLUS_BUTTON_PRESS}. --> <item type="id" name="accessibilityActionStylusButtonPress" /> </resources> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index cf21a1c..91c3d2e 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2620,6 +2620,7 @@ <public type="attr" name="overflowTintMode" /> <public type="attr" name="navigationTint" /> <public type="attr" name="navigationTintMode" /> + <public type="attr" name="fullBackupContent" /> <public type="style" name="Widget.Material.Button.Colored" /> @@ -2651,6 +2652,10 @@ <public type="id" name="replaceText" /> <public type="id" name="accessibilityActionShowOnScreen" /> <public type="id" name="accessibilityActionScrollToPosition" /> + <public type="id" name="accessibilityActionScrollUp" /> + <public type="id" name="accessibilityActionScrollLeft" /> + <public type="id" name="accessibilityActionScrollDown" /> + <public type="id" name="accessibilityActionScrollRight" /> <public type="id" name="shareText" /> <public type="id" name="accessibilityActionStylusButtonPress" /> @@ -2663,7 +2668,7 @@ <public type="attr" name="autoVerify" /> <public type="attr" name="breakStrategy" /> - <public type="attr" name="supportsAssistGesture" /> + <public type="attr" name="supportsAssist" /> <public type="attr" name="thumbPosition" /> <!-- Placeholder for a removed attribute. Remove this before M release. --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 50d2f80..f8d276f 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -281,6 +281,7 @@ <java-symbol type="bool" name="config_bluetooth_default_profiles" /> <java-symbol type="bool" name="config_enableWifiDisplay" /> <java-symbol type="bool" name="config_forceEnableVoiceInteractionService" /> + <java-symbol type="bool" name="config_allowAnimationsInLowPowerMode" /> <java-symbol type="bool" name="config_useDevInputEventForAudioJack" /> <java-symbol type="bool" name="config_safe_media_volume_enabled" /> <java-symbol type="bool" name="config_camera_sound_forced" /> diff --git a/core/tests/coretests/src/android/app/backup/FullBackupTest.java b/core/tests/coretests/src/android/app/backup/FullBackupTest.java new file mode 100644 index 0000000..8c9c63c --- /dev/null +++ b/core/tests/coretests/src/android/app/backup/FullBackupTest.java @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.backup; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.test.AndroidTestCase; +import android.util.ArrayMap; +import android.util.ArraySet; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +import java.io.File; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class FullBackupTest extends AndroidTestCase { + private XmlPullParserFactory mFactory; + private XmlPullParser mXpp; + private Context mContext; + + Map<String, Set<String>> includeMap; + Set<String> excludesSet; + + @Override + public void setUp() throws Exception { + mFactory = XmlPullParserFactory.newInstance(); + mXpp = mFactory.newPullParser(); + mContext = getContext(); + + includeMap = new ArrayMap(); + excludesSet = new ArraySet(); + } + + public void testparseBackupSchemeFromXml_onlyInclude() throws Exception { + mXpp.setInput(new StringReader( + "<full-backup-content>" + + "<include path=\"onlyInclude.txt\" domain=\"file\"/>" + + "</full-backup-content>")); + + FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext); + bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap); + + assertEquals("Excluding files when there was no <exclude/> tag.", 0, excludesSet.size()); + assertEquals("Unexpected number of <include/>s", 1, includeMap.size()); + + Set<String> fileDomainIncludes = includeMap.get(FullBackup.DATA_TREE_TOKEN); + assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size()); + assertEquals("Invalid path parsed for <include/>", + new File(mContext.getFilesDir(), "onlyInclude.txt").getCanonicalPath(), + fileDomainIncludes.iterator().next()); + } + + public void testparseBackupSchemeFromXml_onlyExclude() throws Exception { + mXpp.setInput(new StringReader( + "<full-backup-content>" + + "<exclude path=\"onlyExclude.txt\" domain=\"file\"/>" + + "</full-backup-content>")); + + FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext); + bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap); + + assertEquals("Including files when there was no <include/> tag.", 0, includeMap.size()); + assertEquals("Unexpected number of <exclude/>s", 1, excludesSet.size()); + assertEquals("Invalid path parsed for <exclude/>", + new File(mContext.getFilesDir(), "onlyExclude.txt").getCanonicalPath(), + excludesSet.iterator().next()); + } + + public void testparseBackupSchemeFromXml_includeAndExclude() throws Exception { + mXpp.setInput(new StringReader( + "<full-backup-content>" + + "<exclude path=\"exclude.txt\" domain=\"file\"/>" + + "<include path=\"include.txt\" domain=\"file\"/>" + + "</full-backup-content>")); + + FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext); + bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap); + + Set<String> fileDomainIncludes = includeMap.get(FullBackup.DATA_TREE_TOKEN); + assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size()); + assertEquals("Invalid path parsed for <include/>", + new File(mContext.getFilesDir(), "include.txt").getCanonicalPath(), + fileDomainIncludes.iterator().next()); + + assertEquals("Unexpected number of <exclude/>s", 1, excludesSet.size()); + assertEquals("Invalid path parsed for <exclude/>", + new File(mContext.getFilesDir(), "exclude.txt").getCanonicalPath(), + excludesSet.iterator().next()); + } + + public void testparseBackupSchemeFromXml_lotsOfIncludesAndExcludes() throws Exception { + mXpp.setInput(new StringReader( + "<full-backup-content>" + + "<exclude path=\"exclude1.txt\" domain=\"file\"/>" + + "<include path=\"include1.txt\" domain=\"file\"/>" + + "<exclude path=\"exclude2.txt\" domain=\"database\"/>" + + "<include path=\"include2.txt\" domain=\"database\"/>" + + "<exclude path=\"exclude3.txt\" domain=\"sharedpref\"/>" + + "<include path=\"include3.txt\" domain=\"sharedpref\"/>" + + "</full-backup-content>")); + + + FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext); + bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap); + + Set<String> fileDomainIncludes = includeMap.get(FullBackup.DATA_TREE_TOKEN); + assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size()); + assertEquals("Invalid path parsed for <include/>", + new File(mContext.getFilesDir(), "include1.txt").getCanonicalPath(), + fileDomainIncludes.iterator().next()); + + Set<String> databaseDomainIncludes = includeMap.get(FullBackup.DATABASE_TREE_TOKEN); + assertEquals("Didn't find expected database domain include.", + 2, databaseDomainIncludes.size()); // two expected here because of "-journal" file + assertTrue("Invalid path parsed for <include/>", + databaseDomainIncludes.contains( + new File(mContext.getDatabasePath("foo").getParentFile(), "include2.txt") + .getCanonicalPath())); + assertTrue("Invalid path parsed for <include/>", + databaseDomainIncludes.contains( + new File( + mContext.getDatabasePath("foo").getParentFile(), + "include2.txt-journal") + .getCanonicalPath())); + + Set<String> sharedPrefDomainIncludes = includeMap.get(FullBackup.SHAREDPREFS_TREE_TOKEN); + assertEquals("Didn't find expected sharedpref domain include.", + 1, sharedPrefDomainIncludes.size()); + assertEquals("Invalid path parsed for <include/>", + new File(mContext.getSharedPrefsFile("foo").getParentFile(), "include3.txt") + .getCanonicalPath(), + sharedPrefDomainIncludes.iterator().next()); + + + assertEquals("Unexpected number of <exclude/>s", 4, excludesSet.size()); + // Sets are annoying to iterate over b/c order isn't enforced - convert to an array and + // sort lexicographically. + List<String> arrayedSet = new ArrayList<String>(excludesSet); + Collections.sort(arrayedSet); + + assertEquals("Invalid path parsed for <exclude/>", + new File(mContext.getDatabasePath("foo").getParentFile(), "exclude2.txt") + .getCanonicalPath(), + arrayedSet.get(0)); + assertEquals("Invalid path parsed for <exclude/>", + new File(mContext.getDatabasePath("foo").getParentFile(), "exclude2.txt-journal") + .getCanonicalPath(), + arrayedSet.get(1)); + assertEquals("Invalid path parsed for <exclude/>", + new File(mContext.getFilesDir(), "exclude1.txt").getCanonicalPath(), + arrayedSet.get(2)); + assertEquals("Invalid path parsed for <exclude/>", + new File(mContext.getSharedPrefsFile("foo").getParentFile(), "exclude3.txt") + .getCanonicalPath(), + arrayedSet.get(3)); + } + + public void testParseBackupSchemeFromXml_invalidXmlFails() throws Exception { + // Invalid root tag. + mXpp.setInput(new StringReader( + "<full-weird-tag>" + + "<exclude path=\"invalidRootTag.txt\" domain=\"file\"/>" + + "</ffull-weird-tag>" )); + + try { + FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext); + bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap); + fail("Invalid root xml tag should throw an XmlPullParserException"); + } catch (XmlPullParserException expected) {} + + // Invalid exclude tag. + mXpp.setInput(new StringReader( + "<full-backup-content>" + + "<excluded path=\"invalidExcludeTag.txt\" domain=\"file\"/>" + + "</full-backup-conten>t" )); + try { + FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext); + bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap); + fail("Misspelled xml exclude tag should throw an XmlPullParserException"); + } catch (XmlPullParserException expected) {} + + // Just for good measure - invalid include tag. + mXpp.setInput(new StringReader( + "<full-backup-content>" + + "<yinclude path=\"invalidIncludeTag.txt\" domain=\"file\"/>" + + "</full-backup-conten>t" )); + try { + FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext); + bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap); + fail("Misspelled xml exclude tag should throw an XmlPullParserException"); + } catch (XmlPullParserException expected) {} + + } + + public void testInvalidPath_doesNotBackup() throws Exception { + mXpp.setInput(new StringReader( + "<full-backup-content>" + + "<exclude path=\"..\" domain=\"file\"/>" + // Invalid use of ".." dir. + "</full-backup-content>" )); + + FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext); + bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap); + + assertEquals("Didn't throw away invalid \"..\" path.", 0, includeMap.size()); + + Set<String> fileDomainIncludes = includeMap.get(FullBackup.DATA_TREE_TOKEN); + assertNull("Didn't throw away invalid \"..\" path.", fileDomainIncludes); + } + public void testDoubleDotInPath_isIgnored() throws Exception { + mXpp.setInput(new StringReader( + "<full-backup-content>" + + "<include path=\"..\" domain=\"file\"/>" + // Invalid use of ".." dir. + "</full-backup-content>" )); + + FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext); + bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap); + + assertEquals("Didn't throw away invalid \"..\" path.", 0, includeMap.size()); + + Set<String> fileDomainIncludes = includeMap.get(FullBackup.DATA_TREE_TOKEN); + assertNull("Didn't throw away invalid \"..\" path.", fileDomainIncludes); + } + + public void testDoubleSlashInPath_isIgnored() throws Exception { + mXpp.setInput(new StringReader( + "<full-backup-content>" + + "<exclude path=\"//hello.txt\" domain=\"file\"/>" + // Invalid use of "//" + "</full-backup-content>" )); + + FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext); + bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap); + + assertEquals("Didn't throw away invalid path containing \"//\".", 0, excludesSet.size()); + } +} |
