From 9ae68f467ec168e584821ddc0148d26e82bdd99d Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Fri, 8 Nov 2019 16:45:16 -0800 Subject: [PATCH 001/219] FocusRequester: fix NPE Fix NPE and potential race condition in FocusRequester.dispatchFocusResultFromExtPolicy where mFocusDispatcher was checked against null, but the method didn't return in that case. Bug: 142278598 Test: Android Auto with phone call and custom focus policy Change-Id: I88447a255132c94f8c2fbf97a1e3ee88f6d2e993 Merged-In: I88447a255132c94f8c2fbf97a1e3ee88f6d2e993 --- .../java/com/android/server/audio/FocusRequester.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/audio/FocusRequester.java b/services/core/java/com/android/server/audio/FocusRequester.java index db55138e446d..7578948adb14 100644 --- a/services/core/java/com/android/server/audio/FocusRequester.java +++ b/services/core/java/com/android/server/audio/FocusRequester.java @@ -416,7 +416,8 @@ public class FocusRequester { } int dispatchFocusChange(int focusChange) { - if (mFocusDispatcher == null) { + final IAudioFocusDispatcher fd = mFocusDispatcher; + if (fd == null) { if (MediaFocusControl.DEBUG) { Log.e(TAG, "dispatchFocusChange: no focus dispatcher"); } return AudioManager.AUDIOFOCUS_REQUEST_FAILED; } @@ -436,7 +437,7 @@ public class FocusRequester { mFocusLossReceived = focusChange; } try { - mFocusDispatcher.dispatchAudioFocusChange(focusChange, mClientId); + fd.dispatchAudioFocusChange(focusChange, mClientId); } catch (android.os.RemoteException e) { Log.e(TAG, "dispatchFocusChange: error talking to focus listener " + mClientId, e); return AudioManager.AUDIOFOCUS_REQUEST_FAILED; @@ -445,16 +446,18 @@ public class FocusRequester { } void dispatchFocusResultFromExtPolicy(int requestResult) { - if (mFocusDispatcher == null) { + final IAudioFocusDispatcher fd = mFocusDispatcher; + if (fd == null) { if (MediaFocusControl.DEBUG) { Log.e(TAG, "dispatchFocusResultFromExtPolicy: no focus dispatcher"); } + return; } if (DEBUG) { Log.v(TAG, "dispatching result" + requestResult + " to " + mClientId); } try { - mFocusDispatcher.dispatchFocusResultFromExtPolicy(requestResult, mClientId); + fd.dispatchFocusResultFromExtPolicy(requestResult, mClientId); } catch (android.os.RemoteException e) { Log.e(TAG, "dispatchFocusResultFromExtPolicy: error talking to focus listener" + mClientId, e); -- GitLab From b6dce0b74f88c396053527438a993091c7daca40 Mon Sep 17 00:00:00 2001 From: davidln Date: Mon, 17 Jun 2019 14:48:11 -0700 Subject: [PATCH 002/219] Concurrent collections for Bluetooth callbacks. This allows callback classes to remove themselves or add additional callbacks in response to state change dispatches. Bug: 129060225 Bug: 144357642 Test: build and deploy, pair multiple devices, switch users Change-Id: I8eed81bbc9c12321ec41b2491d006764e2e483d6 Merged-In: I8eed81bbc9c12321ec41b2491d006764e2e483d6 --- .../bluetooth/BluetoothEventManager.java | 109 +++++++----------- .../bluetooth/CachedBluetoothDevice.java | 17 +-- 2 files changed, 47 insertions(+), 79 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java index 402ce90d6ec5..df30c248c00c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java @@ -35,12 +35,12 @@ import androidx.annotation.VisibleForTesting; import com.android.settingslib.R; -import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; /** * BluetoothEventManager receives broadcasts and callbacks from the Bluetooth @@ -56,7 +56,7 @@ public class BluetoothEventManager { private final Map mHandlerMap; private final BroadcastReceiver mBroadcastReceiver = new BluetoothBroadcastReceiver(); private final BroadcastReceiver mProfileBroadcastReceiver = new BluetoothBroadcastReceiver(); - private final Collection mCallbacks = new ArrayList<>(); + private final Collection mCallbacks = new CopyOnWriteArrayList<>(); private final android.os.Handler mReceiverHandler; private final UserHandle mUserHandle; private final Context mContext; @@ -93,8 +93,10 @@ public class BluetoothEventManager { new ConnectionStateChangedHandler()); // Discovery broadcasts - addHandler(BluetoothAdapter.ACTION_DISCOVERY_STARTED, new ScanningStateChangedHandler(true)); - addHandler(BluetoothAdapter.ACTION_DISCOVERY_FINISHED, new ScanningStateChangedHandler(false)); + addHandler(BluetoothAdapter.ACTION_DISCOVERY_STARTED, + new ScanningStateChangedHandler(true)); + addHandler(BluetoothAdapter.ACTION_DISCOVERY_FINISHED, + new ScanningStateChangedHandler(false)); addHandler(BluetoothDevice.ACTION_FOUND, new DeviceFoundHandler()); addHandler(BluetoothDevice.ACTION_NAME_CHANGED, new NameChangedHandler()); addHandler(BluetoothDevice.ACTION_ALIAS_CHANGED, new NameChangedHandler()); @@ -128,16 +130,12 @@ public class BluetoothEventManager { /** Register to start receiving callbacks for Bluetooth events. */ public void registerCallback(BluetoothCallback callback) { - synchronized (mCallbacks) { - mCallbacks.add(callback); - } + mCallbacks.add(callback); } /** Unregister to stop receiving callbacks for Bluetooth events. */ public void unregisterCallback(BluetoothCallback callback) { - synchronized (mCallbacks) { - mCallbacks.remove(callback); - } + mCallbacks.remove(callback); } @VisibleForTesting @@ -189,63 +187,48 @@ public class BluetoothEventManager { } void dispatchDeviceAdded(CachedBluetoothDevice cachedDevice) { - synchronized (mCallbacks) { - for (BluetoothCallback callback : mCallbacks) { - callback.onDeviceAdded(cachedDevice); - } + for (BluetoothCallback callback : mCallbacks) { + callback.onDeviceAdded(cachedDevice); } } void dispatchDeviceRemoved(CachedBluetoothDevice cachedDevice) { - synchronized (mCallbacks) { - for (BluetoothCallback callback : mCallbacks) { - callback.onDeviceDeleted(cachedDevice); - } + for (BluetoothCallback callback : mCallbacks) { + callback.onDeviceDeleted(cachedDevice); } } void dispatchProfileConnectionStateChanged(CachedBluetoothDevice device, int state, int bluetoothProfile) { - synchronized (mCallbacks) { - for (BluetoothCallback callback : mCallbacks) { - callback.onProfileConnectionStateChanged(device, state, bluetoothProfile); - } + for (BluetoothCallback callback : mCallbacks) { + callback.onProfileConnectionStateChanged(device, state, bluetoothProfile); } } private void dispatchConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { - synchronized (mCallbacks) { - for (BluetoothCallback callback : mCallbacks) { - callback.onConnectionStateChanged(cachedDevice, state); - } + for (BluetoothCallback callback : mCallbacks) { + callback.onConnectionStateChanged(cachedDevice, state); } } private void dispatchAudioModeChanged() { mDeviceManager.dispatchAudioModeChanged(); - synchronized (mCallbacks) { - for (BluetoothCallback callback : mCallbacks) { - callback.onAudioModeChanged(); - } + for (BluetoothCallback callback : mCallbacks) { + callback.onAudioModeChanged(); } } private void dispatchActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) { mDeviceManager.onActiveDeviceChanged(activeDevice, bluetoothProfile); - synchronized (mCallbacks) { - for (BluetoothCallback callback : mCallbacks) { - callback.onActiveDeviceChanged(activeDevice, bluetoothProfile); - } + for (BluetoothCallback callback : mCallbacks) { + callback.onActiveDeviceChanged(activeDevice, bluetoothProfile); } } - private void dispatchAclStateChanged(CachedBluetoothDevice activeDevice, - int state) { - synchronized (mCallbacks) { - for (BluetoothCallback callback : mCallbacks) { - callback.onAclConnectionStateChanged(activeDevice, state); - } + private void dispatchAclStateChanged(CachedBluetoothDevice activeDevice, int state) { + for (BluetoothCallback callback : mCallbacks) { + callback.onAclConnectionStateChanged(activeDevice, state); } } @@ -270,17 +253,14 @@ public class BluetoothEventManager { } private class AdapterStateChangedHandler implements Handler { - public void onReceive(Context context, Intent intent, - BluetoothDevice device) { + public void onReceive(Context context, Intent intent, BluetoothDevice device) { int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); // update local profiles and get paired devices mLocalAdapter.setBluetoothStateInt(state); // send callback to update UI and possibly start scanning - synchronized (mCallbacks) { - for (BluetoothCallback callback : mCallbacks) { - callback.onBluetoothStateChanged(state); - } + for (BluetoothCallback callback : mCallbacks) { + callback.onBluetoothStateChanged(state); } // Inform CachedDeviceManager that the adapter state has changed mDeviceManager.onBluetoothStateChanged(state); @@ -293,12 +273,10 @@ public class BluetoothEventManager { ScanningStateChangedHandler(boolean started) { mStarted = started; } - public void onReceive(Context context, Intent intent, - BluetoothDevice device) { - synchronized (mCallbacks) { - for (BluetoothCallback callback : mCallbacks) { - callback.onScanningStateChanged(mStarted); - } + + public void onReceive(Context context, Intent intent, BluetoothDevice device) { + for (BluetoothCallback callback : mCallbacks) { + callback.onScanningStateChanged(mStarted); } mDeviceManager.onScanningStateChanged(mStarted); } @@ -317,7 +295,7 @@ public class BluetoothEventManager { Log.d(TAG, "DeviceFoundHandler created new CachedBluetoothDevice: " + cachedDevice); } else if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED - &&!cachedDevice.getDevice().isConnected()) { + && !cachedDevice.getDevice().isConnected()) { // Dispatch device add callback to show bonded but // not connected devices in discovery mode dispatchDeviceAdded(cachedDevice); @@ -350,8 +328,7 @@ public class BluetoothEventManager { } private class BondStateChangedHandler implements Handler { - public void onReceive(Context context, Intent intent, - BluetoothDevice device) { + public void onReceive(Context context, Intent intent, BluetoothDevice device) { if (device == null) { Log.e(TAG, "ACTION_BOND_STATE_CHANGED with no EXTRA_DEVICE"); return; @@ -365,10 +342,8 @@ public class BluetoothEventManager { cachedDevice = mDeviceManager.addDevice(device); } - synchronized (mCallbacks) { - for (BluetoothCallback callback : mCallbacks) { - callback.onDeviceBondStateChanged(cachedDevice, bondState); - } + for (BluetoothCallback callback : mCallbacks) { + callback.onDeviceBondStateChanged(cachedDevice, bondState); } cachedDevice.onBondingStateChanged(bondState); @@ -388,12 +363,12 @@ public class BluetoothEventManager { * Called when we have reached the unbonded state. * * @param reason one of the error reasons from - * BluetoothDevice.UNBOND_REASON_* + * BluetoothDevice.UNBOND_REASON_* */ private void showUnbondMessage(Context context, String name, int reason) { int errorMsg; - switch(reason) { + switch (reason) { case BluetoothDevice.UNBOND_REASON_AUTH_FAILED: errorMsg = R.string.bluetooth_pairing_pin_error_message; break; @@ -410,7 +385,8 @@ public class BluetoothEventManager { errorMsg = R.string.bluetooth_pairing_error_message; break; default: - Log.w(TAG, "showUnbondMessage: Not displaying any message for reason: " + reason); + Log.w(TAG, + "showUnbondMessage: Not displaying any message for reason: " + reason); return; } BluetoothUtils.showError(context, name, errorMsg); @@ -418,8 +394,7 @@ public class BluetoothEventManager { } private class ClassChangedHandler implements Handler { - public void onReceive(Context context, Intent intent, - BluetoothDevice device) { + public void onReceive(Context context, Intent intent, BluetoothDevice device) { CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device); if (cachedDevice != null) { cachedDevice.refresh(); @@ -428,8 +403,7 @@ public class BluetoothEventManager { } private class UuidChangedHandler implements Handler { - public void onReceive(Context context, Intent intent, - BluetoothDevice device) { + public void onReceive(Context context, Intent intent, BluetoothDevice device) { CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device); if (cachedDevice != null) { cachedDevice.onUuidChanged(); @@ -438,8 +412,7 @@ public class BluetoothEventManager { } private class BatteryLevelChangedHandler implements Handler { - public void onReceive(Context context, Intent intent, - BluetoothDevice device) { + public void onReceive(Context context, Intent intent, BluetoothDevice device) { CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device); if (cachedDevice != null) { cachedDevice.refresh(); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 8f164f1592d3..98db7c8fb59c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -39,6 +39,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; /** * CachedBluetoothDevice represents a remote Bluetooth device. It contains @@ -75,7 +76,7 @@ public class CachedBluetoothDevice implements Comparable boolean mJustDiscovered; - private final Collection mCallbacks = new ArrayList<>(); + private final Collection mCallbacks = new CopyOnWriteArrayList<>(); /** * Last time a bt profile auto-connect was attempted. @@ -679,22 +680,16 @@ public class CachedBluetoothDevice implements Comparable } public void registerCallback(Callback callback) { - synchronized (mCallbacks) { - mCallbacks.add(callback); - } + mCallbacks.add(callback); } public void unregisterCallback(Callback callback) { - synchronized (mCallbacks) { - mCallbacks.remove(callback); - } + mCallbacks.remove(callback); } void dispatchAttributesChanged() { - synchronized (mCallbacks) { - for (Callback callback : mCallbacks) { - callback.onDeviceAttributesChanged(); - } + for (Callback callback : mCallbacks) { + callback.onDeviceAttributesChanged(); } } -- GitLab From de626c28d7abf02cdf9bd0ed4a3a82d96e4dd423 Mon Sep 17 00:00:00 2001 From: Patrick Baumann Date: Mon, 9 Dec 2019 14:22:32 -0800 Subject: [PATCH 003/219] DO NOT MERGE: Adds artificial package handler latency This change introduces a means of introducing an artificial long task to the package handler to help reproduce timing issues related to it. Bug: 141413692 Test: atest PackageManagerTest Change-Id: I61ddee1fe8b94f5803d981a77babb4bb19e31662 --- .../android/app/ActivityManagerInternal.java | 4 ++- .../content/pm/PackageManagerInternal.java | 12 +++++++++ core/java/android/os/IUserManager.aidl | 1 + .../server/am/ActivityManagerService.java | 22 +++++++++++++++- .../server/pm/PackageManagerService.java | 22 ++++++++++++++-- .../android/server/pm/UserManagerService.java | 25 +++++++++++++++++++ 6 files changed, 82 insertions(+), 4 deletions(-) diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 8508c2c95666..f5f4afb21588 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -29,7 +29,6 @@ import android.content.pm.UserInfo; import android.os.Bundle; import android.os.IBinder; import android.os.TransactionTooLargeException; -import android.view.RemoteAnimationAdapter; import java.util.ArrayList; import java.util.List; @@ -356,4 +355,7 @@ public abstract class ActivityManagerInternal { * Unregisters the specified {@code processObserver}. */ public abstract void unregisterProcessObserver(IProcessObserver processObserver); + + /** Returns true if the given UID is registered as an active instrumentation. */ + public abstract boolean isActiveInstrumentation(int uid); } diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index 672994e79134..3e880f03b222 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -999,4 +999,16 @@ public abstract class PackageManagerInternal { * Migrates legacy obb data to its new location. */ public abstract void migrateLegacyObbData(); + + /** + * Ensures that we block deletion of unused packages on user removal. This is purely for the + * purpose of ensuring that b/141413692 is not reproducible on Q. + */ + public abstract void notifyingOnNextUserRemovalForTest(); + + /** + * Notifies PackageManager of the removal of a user. This is purely for the purpose of ensuring + * that b/141413692 is not reproducible on Q. + */ + public abstract void userRemovedForTest(); } diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index 63641e538b8e..880416abc4f3 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -104,4 +104,5 @@ interface IUserManager { String getUserName(); long getUserStartRealtime(); long getUserUnlockRealtime(); + void notifyOnNextUserRemoveForTest(); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 88c29987d1df..c6cae530e795 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -271,8 +271,8 @@ import android.os.WorkSource; import android.os.storage.IStorageManager; import android.os.storage.StorageManager; import android.provider.DeviceConfig; -import android.provider.Settings; import android.provider.DeviceConfig.Properties; +import android.provider.Settings; import android.server.ServerProtoEnums; import android.sysprop.VoldProperties; import android.text.TextUtils; @@ -8256,6 +8256,21 @@ public class ActivityManagerService extends IActivityManager.Stub } } + private boolean isActiveInstrumentation(int uid) { + synchronized (ActivityManagerService.this) { + for (int i = mActiveInstrumentation.size() - 1; i >= 0; i--) { + final ActiveInstrumentation instrumentation = mActiveInstrumentation.get(i); + for (int j = instrumentation.mRunningProcesses.size() - 1; j >= 0; j--) { + final ProcessRecord process = instrumentation.mRunningProcesses.get(j); + if (process.uid == uid) { + return true; + } + } + } + } + return false; + } + @Override public int getUidProcessState(int uid, String callingPackage) { if (!hasUsageStatsPermission(callingPackage)) { @@ -18507,6 +18522,11 @@ public class ActivityManagerService extends IActivityManager.Stub public void unregisterProcessObserver(IProcessObserver processObserver) { ActivityManagerService.this.unregisterProcessObserver(processObserver); } + + @Override + public boolean isActiveInstrumentation(int uid) { + return ActivityManagerService.this.isActiveInstrumentation(uid); + } } long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 0a2951d147c9..47774b2a13fa 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -208,6 +208,7 @@ import android.os.AsyncTask; import android.os.Binder; import android.os.Build; import android.os.Bundle; +import android.os.ConditionVariable; import android.os.Debug; import android.os.Environment; import android.os.FileUtils; @@ -978,6 +979,8 @@ public class PackageManagerService extends IPackageManager.Stub private Future mPrepareAppDataFuture; + private final ConditionVariable mBlockDeleteOnUserRemoveForTest = new ConditionVariable(true); + private static class IFVerificationParams { PackageParser.Package pkg; boolean replacing; @@ -23652,8 +23655,13 @@ public class PackageManagerService extends IPackageManager.Stub Slog.i(TAG, " Removing package " + packageName); } //end run - mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST, - userHandle, 0)); + mHandler.post(() -> { + if (!mBlockDeleteOnUserRemoveForTest.block(30000 /* 30 seconds*/)) { + mBlockDeleteOnUserRemoveForTest.open(); + } + deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST, + userHandle, 0); + }); } } } @@ -25008,6 +25016,16 @@ public class PackageManagerService extends IPackageManager.Stub Slog.wtf(TAG, e); } } + + @Override + public void notifyingOnNextUserRemovalForTest() { + mBlockDeleteOnUserRemoveForTest.close(); + } + + @Override + public void userRemovedForTest() { + mBlockDeleteOnUserRemoveForTest.open(); + } } @GuardedBy("mPackages") diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 204f186f9e13..e2ebd7336124 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -16,6 +16,7 @@ package com.android.server.pm; +import static android.Manifest.permission.INJECT_EVENTS; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; @@ -39,6 +40,7 @@ import android.content.IntentFilter; import android.content.IntentSender; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.PackageManagerInternal; import android.content.pm.ShortcutServiceInternal; import android.content.pm.UserInfo; import android.content.res.Resources; @@ -124,6 +126,7 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; /** * Service for {@link UserManager}. @@ -246,6 +249,7 @@ public class UserManagerService extends IUserManager.Stub { private final File mUserListFile; private static final IBinder mUserRestriconToken = new Binder(); + private final AtomicBoolean mNotifyPackageManagerOnUserRemoval = new AtomicBoolean(false); /** * Internal non-parcelable wrapper for UserInfo that is not exposed to other system apps. @@ -3134,6 +3138,11 @@ public class UserManagerService extends IUserManager.Stub { mRemovingUserIds.delete(userHandle); } } + if (mNotifyPackageManagerOnUserRemoval.getAndSet(false)) { + final PackageManagerInternal pmInternal = + LocalServices.getService(PackageManagerInternal.class); + pmInternal.userRemovedForTest(); + } } private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId) { @@ -4210,4 +4219,20 @@ public class UserManagerService extends IUserManager.Stub { + " does not match the calling uid " + callingUid); } } + + @Override + public void notifyOnNextUserRemoveForTest() { + mContext.enforceCallingOrSelfPermission(INJECT_EVENTS, "notifyOnNextUserRemoveForTest"); + final ActivityManagerInternal amInternal = + LocalServices.getService(ActivityManagerInternal.class); + if (!amInternal.isActiveInstrumentation(Binder.getCallingUid())) { + return; + } + + this.mNotifyPackageManagerOnUserRemoval.set(true); + + final PackageManagerInternal pmInternal = + LocalServices.getService(PackageManagerInternal.class); + pmInternal.notifyingOnNextUserRemovalForTest(); + } } -- GitLab From c594d702685a5e2a5ef3906c7a484a24c33666bb Mon Sep 17 00:00:00 2001 From: Jim Kaye Date: Tue, 3 Dec 2019 10:14:23 -0800 Subject: [PATCH 004/219] [DO NOT MERGE] Add a configuration to allow disabling auto-suspend If a platform needs to control suspension explicitly, it can set 'config_enableAutoSuspend' to false to disable auto-suspend. Auto-suspend is enabled by default. This is only for Q. Autosuspend is done differently in R. Bug: 143203434 Test: Verified on desktop Automotive hardware Change-Id: Iac17a7d753b8cd5c0259059713fae29d6e5e6fb0 --- core/res/res/values/config.xml | 3 +++ core/res/res/values/symbols.xml | 1 + .../com/android/server/power/PowerManagerService.java | 9 +++++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 4a464656a63a..54684dd3f5d3 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4268,4 +4268,7 @@ false + + true diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index aff7f611f339..09d927401548 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3854,4 +3854,5 @@ + diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index e1b3e4d6fbcf..1cb7880ff81d 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -421,6 +421,8 @@ public final class PowerManagerService extends SystemService // True if doze should not be started until after the screen off transition. private boolean mDozeAfterScreenOff; + private boolean mEnableAutoSuspendConfig; + // The minimum screen off timeout, in milliseconds. private long mMinimumScreenOffTimeoutConfig; @@ -954,6 +956,8 @@ public final class PowerManagerService extends SystemService com.android.internal.R.bool.config_powerDecoupleAutoSuspendModeFromDisplay); mDecoupleHalInteractiveModeFromDisplayConfig = resources.getBoolean( com.android.internal.R.bool.config_powerDecoupleInteractiveModeFromDisplay); + mEnableAutoSuspendConfig = resources.getBoolean( + com.android.internal.R.bool.config_enableAutoSuspend); mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean( com.android.internal.R.bool.config_unplugTurnsOnScreen); mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig = resources.getBoolean( @@ -2625,7 +2629,8 @@ public final class PowerManagerService extends SystemService if (!mDecoupleHalInteractiveModeFromDisplayConfig) { setHalInteractiveModeLocked(false); } - if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) { + if (mEnableAutoSuspendConfig + && !mDecoupleHalAutoSuspendModeFromDisplayConfig) { setHalAutoSuspendModeLocked(true); } } else { @@ -2670,7 +2675,7 @@ public final class PowerManagerService extends SystemService private void updateSuspendBlockerLocked() { final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0); final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked(); - final boolean autoSuspend = !needDisplaySuspendBlocker; + final boolean autoSuspend = mEnableAutoSuspendConfig && !needDisplaySuspendBlocker; final boolean interactive = mDisplayPowerRequest.isBrightOrDim(); // Disable auto-suspend if needed. -- GitLab From ce22265eeda3a96613b9a7bb7dd898c69d295964 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 17 Dec 2019 11:21:02 -0800 Subject: [PATCH 005/219] Revoke 'always' web handler status when not autoverifying If an app has previously used autoVerify to make claims about its status re handling web navigation intents, but is updated such that it no longer makes those claims, step down its "official handler" status as though it had never invoked autoVerify in the first place. Bug: 146204120 Test: manual: as described in bug; observe policy before/after via 'adb shell dumpsys package d' Test: atest CtsOsHostTestCases Change-Id: I58502d1b32d793aba9aa772fa2ad5ac38acca48a Merged-In: I58502d1b32d793aba9aa772fa2ad5ac38acca48a --- .../server/pm/PackageManagerService.java | 44 ++++++++++++++----- .../java/com/android/server/pm/Settings.java | 1 + 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 033c62bf0fc2..5a6168596369 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -17725,36 +17725,48 @@ public class PackageManagerService extends IPackageManager.Stub int count = 0; final String packageName = pkg.packageName; + boolean handlesWebUris = false; + final boolean alreadyVerified; synchronized (mPackages) { // If this is a new install and we see that we've already run verification for this // package, we have nothing to do: it means the state was restored from backup. - if (!replacing) { - IntentFilterVerificationInfo ivi = - mSettings.getIntentFilterVerificationLPr(packageName); - if (ivi != null) { - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.i(TAG, "Package " + packageName+ " already verified: status=" - + ivi.getStatusString()); - } - return; + final IntentFilterVerificationInfo ivi = + mSettings.getIntentFilterVerificationLPr(packageName); + alreadyVerified = (ivi != null); + if (!replacing && alreadyVerified) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Package " + packageName + " already verified: status=" + + ivi.getStatusString()); } + return; } - // If any filters need to be verified, then all need to be. + // If any filters need to be verified, then all need to be. In addition, we need to + // know whether an updating app has any web navigation intent filters, to re- + // examine handling policy even if not re-verifying. boolean needToVerify = false; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { + if (filter.handlesWebUris(true)) { + handlesWebUris = true; + } if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) { Slog.d(TAG, "Intent filter needs verification, so processing all filters"); } needToVerify = true; + // It's safe to break out here because filter.needsVerification() + // can only be true if filter.handlesWebUris(true) returns true, so + // we've already noted that. break; } } } + // Note whether this app publishes any web navigation handling support at all, + // and whether there are any web-nav filters that fit the profile for running + // a verification pass now. if (needToVerify) { final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { @@ -17772,13 +17784,23 @@ public class PackageManagerService extends IPackageManager.Stub } if (count > 0) { + // count > 0 means that we're running a full verification pass if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count + " IntentFilter verification" + (count > 1 ? "s" : "") + " for userId:" + userId); mIntentFilterVerifier.startVerifications(userId); + } else if (alreadyVerified && handlesWebUris) { + // App used autoVerify in the past, no longer does, but still handles web + // navigation starts. + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy"); + } + synchronized (mPackages) { + clearIntentFilterVerificationsLPw(packageName, userId); + } } else { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "No filters or not all autoVerify for " + packageName); + Slog.d(TAG, "No web filters or no prior verify policy for " + packageName); } } } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index a7e38301bb40..6036e7d75433 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1319,6 +1319,7 @@ public final class Settings { return false; } ps.clearDomainVerificationStatusForUser(userId); + ps.setIntentFilterVerificationInfo(null); return true; } -- GitLab From a8fb6dc1671c93b8063c9888339959d9cd9728e9 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 17 Dec 2019 11:21:02 -0800 Subject: [PATCH 006/219] Revoke 'always' web handler status when not autoverifying If an app has previously used autoVerify to make claims about its status re handling web navigation intents, but is updated such that it no longer makes those claims, step down its "official handler" status as though it had never invoked autoVerify in the first place. Bug: 146204120 Test: manual: as described in bug; observe policy before/after via 'adb shell dumpsys package d' Test: atest CtsOsHostTestCases Change-Id: I58502d1b32d793aba9aa772fa2ad5ac38acca48a Merged-In: I58502d1b32d793aba9aa772fa2ad5ac38acca48a --- .../server/pm/PackageManagerService.java | 44 ++++++++++++++----- .../java/com/android/server/pm/Settings.java | 1 + 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 0a2951d147c9..028c2ed11378 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -18078,36 +18078,48 @@ public class PackageManagerService extends IPackageManager.Stub int count = 0; final String packageName = pkg.packageName; + boolean handlesWebUris = false; + final boolean alreadyVerified; synchronized (mPackages) { // If this is a new install and we see that we've already run verification for this // package, we have nothing to do: it means the state was restored from backup. - if (!replacing) { - IntentFilterVerificationInfo ivi = - mSettings.getIntentFilterVerificationLPr(packageName); - if (ivi != null) { - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.i(TAG, "Package " + packageName+ " already verified: status=" - + ivi.getStatusString()); - } - return; + final IntentFilterVerificationInfo ivi = + mSettings.getIntentFilterVerificationLPr(packageName); + alreadyVerified = (ivi != null); + if (!replacing && alreadyVerified) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Package " + packageName + " already verified: status=" + + ivi.getStatusString()); } + return; } - // If any filters need to be verified, then all need to be. + // If any filters need to be verified, then all need to be. In addition, we need to + // know whether an updating app has any web navigation intent filters, to re- + // examine handling policy even if not re-verifying. boolean needToVerify = false; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { + if (filter.handlesWebUris(true)) { + handlesWebUris = true; + } if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) { Slog.d(TAG, "Intent filter needs verification, so processing all filters"); } needToVerify = true; + // It's safe to break out here because filter.needsVerification() + // can only be true if filter.handlesWebUris(true) returns true, so + // we've already noted that. break; } } } + // Note whether this app publishes any web navigation handling support at all, + // and whether there are any web-nav filters that fit the profile for running + // a verification pass now. if (needToVerify) { final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { @@ -18125,13 +18137,23 @@ public class PackageManagerService extends IPackageManager.Stub } if (count > 0) { + // count > 0 means that we're running a full verification pass if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count + " IntentFilter verification" + (count > 1 ? "s" : "") + " for userId:" + userId); mIntentFilterVerifier.startVerifications(userId); + } else if (alreadyVerified && handlesWebUris) { + // App used autoVerify in the past, no longer does, but still handles web + // navigation starts. + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy"); + } + synchronized (mPackages) { + clearIntentFilterVerificationsLPw(packageName, userId); + } } else { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "No filters or not all autoVerify for " + packageName); + Slog.d(TAG, "No web filters or no prior verify policy for " + packageName); } } } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 11a8f4b895f5..46485b5550a6 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1252,6 +1252,7 @@ public final class Settings { return false; } ps.clearDomainVerificationStatusForUser(userId); + ps.setIntentFilterVerificationInfo(null); return true; } -- GitLab From 6cf5f92825df545bd011b7163418f2ea0b337af3 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 17 Dec 2019 11:21:02 -0800 Subject: [PATCH 007/219] Revoke 'always' web handler status when not autoverifying If an app has previously used autoVerify to make claims about its status re handling web navigation intents, but is updated such that it no longer makes those claims, step down its "official handler" status as though it had never invoked autoVerify in the first place. Bug: 146204120 Test: manual: as described in bug; observe policy before/after via 'adb shell dumpsys package d' Test: atest CtsOsHostTestCases Change-Id: I58502d1b32d793aba9aa772fa2ad5ac38acca48a Merged-In: I58502d1b32d793aba9aa772fa2ad5ac38acca48a --- .../server/pm/PackageManagerService.java | 44 ++++++++++++++----- .../java/com/android/server/pm/Settings.java | 1 + 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index ab6c956c6924..efc7fabc0a85 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -18437,35 +18437,47 @@ public class PackageManagerService extends IPackageManager.Stub int count = 0; final String packageName = pkg.packageName; + boolean handlesWebUris = false; + final boolean alreadyVerified; synchronized (mPackages) { // If this is a new install and we see that we've already run verification for this // package, we have nothing to do: it means the state was restored from backup. - if (!replacing) { - IntentFilterVerificationInfo ivi = - mSettings.getIntentFilterVerificationLPr(packageName); - if (ivi != null) { - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.i(TAG, "Package " + packageName+ " already verified: status=" - + ivi.getStatusString()); - } - return; + final IntentFilterVerificationInfo ivi = + mSettings.getIntentFilterVerificationLPr(packageName); + alreadyVerified = (ivi != null); + if (!replacing && alreadyVerified) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Package " + packageName + " already verified: status=" + + ivi.getStatusString()); } + return; } - // If any filters need to be verified, then all need to be. + // If any filters need to be verified, then all need to be. In addition, we need to + // know whether an updating app has any web navigation intent filters, to re- + // examine handling policy even if not re-verifying. boolean needToVerify = false; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { + if (filter.handlesWebUris(true)) { + handlesWebUris = true; + } if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) { Slog.d(TAG, "Intent filter needs verification, so processing all filters"); } needToVerify = true; + // It's safe to break out here because filter.needsVerification() + // can only be true if filter.handlesWebUris(true) returns true, so + // we've already noted that. break; } } } + // Note whether this app publishes any web navigation handling support at all, + // and whether there are any web-nav filters that fit the profile for running + // a verification pass now. if (needToVerify) { final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { @@ -18483,13 +18495,23 @@ public class PackageManagerService extends IPackageManager.Stub } if (count > 0) { + // count > 0 means that we're running a full verification pass if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count + " IntentFilter verification" + (count > 1 ? "s" : "") + " for userId:" + userId); mIntentFilterVerifier.startVerifications(userId); + } else if (alreadyVerified && handlesWebUris) { + // App used autoVerify in the past, no longer does, but still handles web + // navigation starts. + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy"); + } + synchronized (mPackages) { + clearIntentFilterVerificationsLPw(packageName, userId); + } } else { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "No filters or not all autoVerify for " + packageName); + Slog.d(TAG, "No web filters or no prior verify policy for " + packageName); } } } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 45d0c585627b..5ab97a4e9f35 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1377,6 +1377,7 @@ final class Settings { return false; } ps.clearDomainVerificationStatusForUser(userId); + ps.setIntentFilterVerificationInfo(null); return true; } -- GitLab From 9dfd9a5f3333a5d1f176bde97d1fa61cdae1956f Mon Sep 17 00:00:00 2001 From: SongFerngWang Date: Mon, 25 Nov 2019 22:44:12 +0800 Subject: [PATCH 008/219] Supplementary Services(SS) gray out when airplane mode on in Call Settings menu. add carrier config "KEY_SS_DISABLE_WHEN_AIRPLANE_MODE_BOOL". Bug: 141284019 Test: when airplane mode on, all of SS UIs are gray out. Change-Id: I869a267fa5aaebf3b48f20bc70d21d612cd84586 (cherry picked from commit 08972c5b2b8bcb748e5a9b856e589b3d43e1fc69) Merged-In: I869a267fa5aaebf3b48f20bc70d21d612cd84586 --- .../java/android/telephony/CarrierConfigManager.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index b646a93e43f1..1994ccc74b74 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -99,6 +99,17 @@ public class CarrierConfigManager { public static final String KEY_CARRIER_VOLTE_PROVISIONED_BOOL = "carrier_volte_provisioned_bool"; + /** + * Boolean indicating the Supplementary Services(SS) is disable when airplane mode on in the + * Call Settings menu. + * {@code true}: SS is disable when airplane mode on. + * {@code false}: SS is enable when airplane mode on. + * The default value for this key is {@code false} + * @hide + */ + public static final String KEY_DISABLE_SUPPLEMENTARY_SERVICES_IN_AIRPLANE_MODE_BOOL = + "disable_supplementary_services_in_airplane_mode_bool"; + /** * Boolean indicating if the "Call forwarding" item is visible in the Call Settings menu. * true means visible. false means gone. @@ -3255,6 +3266,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_CALL_FORWARDING_VISIBILITY_BOOL, true); sDefaults.putBoolean(KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL, true); sDefaults.putBoolean(KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL, true); + sDefaults.putBoolean(KEY_DISABLE_SUPPLEMENTARY_SERVICES_IN_AIRPLANE_MODE_BOOL, false); sDefaults.putBoolean(KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL, false); sDefaults.putBoolean(KEY_MDN_IS_ADDITIONAL_VOICEMAIL_NUMBER_BOOL, false); sDefaults.putBoolean(KEY_OPERATOR_SELECTION_EXPAND_BOOL, true); -- GitLab From ef5220e5b2a4b90d4260eb058475fdcdf30d861d Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 17 Dec 2019 11:21:02 -0800 Subject: [PATCH 009/219] Revoke 'always' web handler status when not autoverifying If an app has previously used autoVerify to make claims about its status re handling web navigation intents, but is updated such that it no longer makes those claims, step down its "official handler" status as though it had never invoked autoVerify in the first place. Bug: 146204120 Test: manual: as described in bug; observe policy before/after via 'adb shell dumpsys package d' Test: atest CtsOsHostTestCases Change-Id: I58502d1b32d793aba9aa772fa2ad5ac38acca48a Merged-In: I58502d1b32d793aba9aa772fa2ad5ac38acca48a --- .../server/pm/PackageManagerService.java | 44 ++++++++++++++----- .../java/com/android/server/pm/Settings.java | 1 + 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index bf1da5625857..599753b024ce 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -19061,35 +19061,47 @@ public class PackageManagerService extends IPackageManager.Stub int count = 0; final String packageName = pkg.packageName; + boolean handlesWebUris = false; + final boolean alreadyVerified; synchronized (mPackages) { // If this is a new install and we see that we've already run verification for this // package, we have nothing to do: it means the state was restored from backup. - if (!replacing) { - IntentFilterVerificationInfo ivi = - mSettings.getIntentFilterVerificationLPr(packageName); - if (ivi != null) { - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.i(TAG, "Package " + packageName+ " already verified: status=" - + ivi.getStatusString()); - } - return; + final IntentFilterVerificationInfo ivi = + mSettings.getIntentFilterVerificationLPr(packageName); + alreadyVerified = (ivi != null); + if (!replacing && alreadyVerified) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Package " + packageName + " already verified: status=" + + ivi.getStatusString()); } + return; } - // If any filters need to be verified, then all need to be. + // If any filters need to be verified, then all need to be. In addition, we need to + // know whether an updating app has any web navigation intent filters, to re- + // examine handling policy even if not re-verifying. boolean needToVerify = false; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { + if (filter.handlesWebUris(true)) { + handlesWebUris = true; + } if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) { Slog.d(TAG, "Intent filter needs verification, so processing all filters"); } needToVerify = true; + // It's safe to break out here because filter.needsVerification() + // can only be true if filter.handlesWebUris(true) returns true, so + // we've already noted that. break; } } } + // Note whether this app publishes any web navigation handling support at all, + // and whether there are any web-nav filters that fit the profile for running + // a verification pass now. if (needToVerify) { final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { @@ -19107,13 +19119,23 @@ public class PackageManagerService extends IPackageManager.Stub } if (count > 0) { + // count > 0 means that we're running a full verification pass if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count + " IntentFilter verification" + (count > 1 ? "s" : "") + " for userId:" + userId); mIntentFilterVerifier.startVerifications(userId); + } else if (alreadyVerified && handlesWebUris) { + // App used autoVerify in the past, no longer does, but still handles web + // navigation starts. + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy"); + } + synchronized (mPackages) { + clearIntentFilterVerificationsLPw(packageName, userId); + } } else { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "No filters or not all autoVerify for " + packageName); + Slog.d(TAG, "No web filters or no prior verify policy for " + packageName); } } } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 56835f69a3c7..0e1f3c295784 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1380,6 +1380,7 @@ final class Settings { return false; } ps.clearDomainVerificationStatusForUser(userId); + ps.setIntentFilterVerificationInfo(null); return true; } -- GitLab From d2a71cc4b8f11688f85f33507b75d00041c14852 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 17 Dec 2019 11:21:02 -0800 Subject: [PATCH 010/219] Revoke 'always' web handler status when not autoverifying If an app has previously used autoVerify to make claims about its status re handling web navigation intents, but is updated such that it no longer makes those claims, step down its "official handler" status as though it had never invoked autoVerify in the first place. Bug: 146204120 Test: manual: as described in bug; observe policy before/after via 'adb shell dumpsys package d' Test: atest CtsOsHostTestCases Change-Id: I58502d1b32d793aba9aa772fa2ad5ac38acca48a Merged-In: I58502d1b32d793aba9aa772fa2ad5ac38acca48a --- .../server/pm/PackageManagerService.java | 44 ++++++++++++++----- .../java/com/android/server/pm/Settings.java | 1 + 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 04cebb309216..9afaae11b39a 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -18094,36 +18094,48 @@ public class PackageManagerService extends IPackageManager.Stub int count = 0; final String packageName = pkg.packageName; + boolean handlesWebUris = false; + final boolean alreadyVerified; synchronized (mPackages) { // If this is a new install and we see that we've already run verification for this // package, we have nothing to do: it means the state was restored from backup. - if (!replacing) { - IntentFilterVerificationInfo ivi = - mSettings.getIntentFilterVerificationLPr(packageName); - if (ivi != null) { - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.i(TAG, "Package " + packageName+ " already verified: status=" - + ivi.getStatusString()); - } - return; + final IntentFilterVerificationInfo ivi = + mSettings.getIntentFilterVerificationLPr(packageName); + alreadyVerified = (ivi != null); + if (!replacing && alreadyVerified) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Package " + packageName + " already verified: status=" + + ivi.getStatusString()); } + return; } - // If any filters need to be verified, then all need to be. + // If any filters need to be verified, then all need to be. In addition, we need to + // know whether an updating app has any web navigation intent filters, to re- + // examine handling policy even if not re-verifying. boolean needToVerify = false; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { + if (filter.handlesWebUris(true)) { + handlesWebUris = true; + } if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) { Slog.d(TAG, "Intent filter needs verification, so processing all filters"); } needToVerify = true; + // It's safe to break out here because filter.needsVerification() + // can only be true if filter.handlesWebUris(true) returns true, so + // we've already noted that. break; } } } + // Note whether this app publishes any web navigation handling support at all, + // and whether there are any web-nav filters that fit the profile for running + // a verification pass now. if (needToVerify) { final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { @@ -18141,13 +18153,23 @@ public class PackageManagerService extends IPackageManager.Stub } if (count > 0) { + // count > 0 means that we're running a full verification pass if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count + " IntentFilter verification" + (count > 1 ? "s" : "") + " for userId:" + userId); mIntentFilterVerifier.startVerifications(userId); + } else if (alreadyVerified && handlesWebUris) { + // App used autoVerify in the past, no longer does, but still handles web + // navigation starts. + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy"); + } + synchronized (mPackages) { + clearIntentFilterVerificationsLPw(packageName, userId); + } } else { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "No filters or not all autoVerify for " + packageName); + Slog.d(TAG, "No web filters or no prior verify policy for " + packageName); } } } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index d9e4db29de07..169f8cb91e80 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1252,6 +1252,7 @@ public final class Settings { return false; } ps.clearDomainVerificationStatusForUser(userId); + ps.setIntentFilterVerificationInfo(null); return true; } -- GitLab From 611bad95564695d6b5fa87efa89c9a4e1979dc80 Mon Sep 17 00:00:00 2001 From: Christophe Koessler Date: Tue, 17 Dec 2019 16:40:47 -0800 Subject: [PATCH 011/219] Refactor CountryDetectorService Clean-up the test to use Mockito instead of the deprecated AndroidTestCase, also getting rid of 1.5s of Thread.sleep. No logic change. Bug: 141626568 Test: atest CountryDetectorServiceTest Merged-in: Ic0782b1ffcd1dcb30b9f1d91b37521d1f9887f03 Change-Id: Ic0782b1ffcd1dcb30b9f1d91b37521d1f9887f03 (cherry picked from commit 50361687ba6bc20877af43eb5367a5ba3a2911df) --- .../server/CountryDetectorService.java | 76 +++++----- services/tests/servicestests/Android.bp | 1 + .../server/CountryDetectorServiceTest.java | 143 ++++++++++++------ 3 files changed, 129 insertions(+), 91 deletions(-) diff --git a/services/core/java/com/android/server/CountryDetectorService.java b/services/core/java/com/android/server/CountryDetectorService.java index d8a2fe35c7e8..861c731c69e0 100644 --- a/services/core/java/com/android/server/CountryDetectorService.java +++ b/services/core/java/com/android/server/CountryDetectorService.java @@ -16,14 +16,6 @@ package com.android.server; -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.HashMap; - -import com.android.internal.os.BackgroundThread; -import com.android.internal.util.DumpUtils; -import com.android.server.location.ComprehensiveCountryDetector; - import android.content.Context; import android.location.Country; import android.location.CountryListener; @@ -36,17 +28,25 @@ import android.util.PrintWriterPrinter; import android.util.Printer; import android.util.Slog; +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.os.BackgroundThread; +import com.android.internal.util.DumpUtils; +import com.android.server.location.ComprehensiveCountryDetector; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.HashMap; + /** - * This class detects the country that the user is in through - * {@link ComprehensiveCountryDetector}. + * This class detects the country that the user is in through {@link ComprehensiveCountryDetector}. * * @hide */ -public class CountryDetectorService extends ICountryDetector.Stub implements Runnable { +public class CountryDetectorService extends ICountryDetector.Stub { /** - * The class represents the remote listener, it will also removes itself - * from listener list when the remote process was died. + * The class represents the remote listener, it will also removes itself from listener list when + * the remote process was died. */ private final class Receiver implements IBinder.DeathRecipient { private final ICountryListener mListener; @@ -79,9 +79,11 @@ public class CountryDetectorService extends ICountryDetector.Stub implements Run } } - private final static String TAG = "CountryDetector"; + private static final String TAG = "CountryDetector"; - /** Whether to dump the state of the country detector service to bugreports */ + /** + * Whether to dump the state of the country detector service to bugreports + */ private static final boolean DEBUG = false; private final HashMap mReceivers; @@ -92,15 +94,21 @@ public class CountryDetectorService extends ICountryDetector.Stub implements Run private CountryListener mLocationBasedDetectorListener; public CountryDetectorService(Context context) { + this(context, BackgroundThread.getHandler()); + } + + @VisibleForTesting + CountryDetectorService(Context context, Handler handler) { super(); - mReceivers = new HashMap(); + mReceivers = new HashMap<>(); mContext = context; + mHandler = handler; } @Override public Country detectCountry() { if (!mSystemReady) { - return null; // server not yet active + return null; // server not yet active } else { return mCountryDetector.detectCountry(); } @@ -154,9 +162,8 @@ public class CountryDetectorService extends ICountryDetector.Stub implements Run } } - protected void notifyReceivers(Country country) { - synchronized(mReceivers) { + synchronized (mReceivers) { for (Receiver receiver : mReceivers.values()) { try { receiver.getListener().onCountryDetected(country); @@ -170,38 +177,23 @@ public class CountryDetectorService extends ICountryDetector.Stub implements Run void systemRunning() { // Shall we wait for the initialization finish. - BackgroundThread.getHandler().post(this); + mHandler.post( + () -> { + initialize(); + mSystemReady = true; + }); } private void initialize() { mCountryDetector = new ComprehensiveCountryDetector(mContext); - mLocationBasedDetectorListener = new CountryListener() { - public void onCountryDetected(final Country country) { - mHandler.post(new Runnable() { - public void run() { - notifyReceivers(country); - } - }); - } - }; - } - - public void run() { - mHandler = new Handler(); - initialize(); - mSystemReady = true; + mLocationBasedDetectorListener = country -> mHandler.post(() -> notifyReceivers(country)); } protected void setCountryListener(final CountryListener listener) { - mHandler.post(new Runnable() { - @Override - public void run() { - mCountryDetector.setCountryListener(listener); - } - }); + mHandler.post(() -> mCountryDetector.setCountryListener(listener)); } - // For testing + @VisibleForTesting boolean isSystemReady() { return mSystemReady; } diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index 3edbd7ee6eed..d42042d3641d 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -28,6 +28,7 @@ android_test { "services.net", "services.usage", "guava", + "androidx.test.core", "androidx.test.runner", "androidx.test.rules", "mockito-target-minus-junit4", diff --git a/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java index 192c50c7dc19..e9c5ce7127de 100644 --- a/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 The Android Open Source Project + * Copyright (C) 2019 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. @@ -11,28 +11,48 @@ * 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 + * limitations under the License. */ package com.android.server; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.doAnswer; + import android.content.Context; import android.location.Country; import android.location.CountryListener; import android.location.ICountryListener; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; import android.os.RemoteException; -import android.test.AndroidTestCase; -public class CountryDetectorServiceTest extends AndroidTestCase { - private class CountryListenerTester extends ICountryListener.Stub { +import androidx.test.core.app.ApplicationProvider; + +import com.google.common.truth.Expect; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class CountryDetectorServiceTest { + + private static class CountryListenerTester extends ICountryListener.Stub { private Country mCountry; @Override - public void onCountryDetected(Country country) throws RemoteException { + public void onCountryDetected(Country country) { mCountry = country; } - public Country getCountry() { + Country getCountry() { return mCountry; } @@ -41,12 +61,11 @@ public class CountryDetectorServiceTest extends AndroidTestCase { } } - private class CountryDetectorServiceTester extends CountryDetectorService { - + private static class CountryDetectorServiceTester extends CountryDetectorService { private CountryListener mListener; - public CountryDetectorServiceTester(Context context) { - super(context); + CountryDetectorServiceTester(Context context, Handler handler) { + super(context, handler); } @Override @@ -59,51 +78,77 @@ public class CountryDetectorServiceTest extends AndroidTestCase { mListener = listener; } - public boolean isListenerSet() { + boolean isListenerSet() { return mListener != null; } } - public void testAddRemoveListener() throws RemoteException { - CountryDetectorServiceTester serviceTester = new CountryDetectorServiceTester(getContext()); - serviceTester.systemRunning(); - waitForSystemReady(serviceTester); - CountryListenerTester listenerTester = new CountryListenerTester(); - serviceTester.addCountryListener(listenerTester); - assertTrue(serviceTester.isListenerSet()); - serviceTester.removeCountryListener(listenerTester); - assertFalse(serviceTester.isListenerSet()); + @Rule + public final Expect expect = Expect.create(); + @Spy + private Context mContext = ApplicationProvider.getApplicationContext(); + @Spy + private Handler mHandler = new Handler(Looper.myLooper()); + private CountryDetectorServiceTester mCountryDetectorService; + + @BeforeClass + public static void oneTimeInitialization() { + if (Looper.myLooper() == null) { + Looper.prepare(); + } } - public void testNotifyListeners() throws RemoteException { - CountryDetectorServiceTester serviceTester = new CountryDetectorServiceTester(getContext()); - CountryListenerTester listenerTesterA = new CountryListenerTester(); - CountryListenerTester listenerTesterB = new CountryListenerTester(); - Country country = new Country("US", Country.COUNTRY_SOURCE_NETWORK); - serviceTester.systemRunning(); - waitForSystemReady(serviceTester); - serviceTester.addCountryListener(listenerTesterA); - serviceTester.addCountryListener(listenerTesterB); - serviceTester.notifyReceivers(country); - assertTrue(serviceTester.isListenerSet()); - assertTrue(listenerTesterA.isNotified()); - assertTrue(listenerTesterB.isNotified()); - serviceTester.removeCountryListener(listenerTesterA); - serviceTester.removeCountryListener(listenerTesterB); - assertFalse(serviceTester.isListenerSet()); + @Before + public void setUp() { + mCountryDetectorService = new CountryDetectorServiceTester(mContext, mHandler); + + // Immediately invoke run on the Runnable posted to the handler + doAnswer(invocation -> { + Message message = invocation.getArgument(0); + message.getCallback().run(); + return true; + }).when(mHandler).sendMessageAtTime(any(Message.class), anyLong()); } - private void waitForSystemReady(CountryDetectorService service) { - int count = 5; - while (count-- > 0) { - try { - Thread.sleep(500); - } catch (Exception e) { - } - if (service.isSystemReady()) { - return; - } - } - throw new RuntimeException("Wait System Ready timeout"); + @Test + public void countryListener_add_successful() throws RemoteException { + CountryListenerTester countryListener = new CountryListenerTester(); + + mCountryDetectorService.systemRunning(); + expect.that(mCountryDetectorService.isListenerSet()).isFalse(); + mCountryDetectorService.addCountryListener(countryListener); + + expect.that(mCountryDetectorService.isListenerSet()).isTrue(); + } + + @Test + public void countryListener_remove_successful() throws RemoteException { + CountryListenerTester countryListener = new CountryListenerTester(); + + mCountryDetectorService.systemRunning(); + mCountryDetectorService.addCountryListener(countryListener); + expect.that(mCountryDetectorService.isListenerSet()).isTrue(); + mCountryDetectorService.removeCountryListener(countryListener); + + expect.that(mCountryDetectorService.isListenerSet()).isFalse(); + } + + @Test + public void countryListener_notify_successful() throws RemoteException { + CountryListenerTester countryListenerA = new CountryListenerTester(); + CountryListenerTester countryListenerB = new CountryListenerTester(); + Country country = new Country("US", Country.COUNTRY_SOURCE_NETWORK); + + mCountryDetectorService.systemRunning(); + mCountryDetectorService.addCountryListener(countryListenerA); + mCountryDetectorService.addCountryListener(countryListenerB); + expect.that(countryListenerA.isNotified()).isFalse(); + expect.that(countryListenerB.isNotified()).isFalse(); + mCountryDetectorService.notifyReceivers(country); + + expect.that(countryListenerA.isNotified()).isTrue(); + expect.that(countryListenerB.isNotified()).isTrue(); + expect.that(countryListenerA.getCountry().equalsIgnoreSource(country)).isTrue(); + expect.that(countryListenerB.getCountry().equalsIgnoreSource(country)).isTrue(); } } -- GitLab From 3dd716a1303dae79405e2f59e6121bb907f10de0 Mon Sep 17 00:00:00 2001 From: Mohammad Samiul Islam Date: Mon, 16 Sep 2019 11:09:38 +0100 Subject: [PATCH 012/219] Fix ModuleInfoProviderTest by passing correct flag Bug: 140941633 Bug: 147476459 Test: atest ModuleInfoProviderTest Change-Id: Icf93ca7dcf4fc2d7625fe7f9175c59200ae600b6 Merged-In: Icf93ca7dcf4fc2d7625fe7f9175c59200ae600b6 --- .../com/android/server/pm/ModuleInfoProviderTest.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java b/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java index bd3d9ab2220d..3852b9fec001 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java @@ -17,6 +17,7 @@ package com.android.server.pm; import android.content.Context; import android.content.pm.ModuleInfo; +import android.content.pm.PackageManager; import android.test.InstrumentationTestCase; import com.android.frameworks.servicestests.R; @@ -28,7 +29,7 @@ public class ModuleInfoProviderTest extends InstrumentationTestCase { public void testSuccessfulParse() { ModuleInfoProvider provider = getProvider(R.xml.well_formed_metadata); - List mi = provider.getInstalledModules(0); + List mi = provider.getInstalledModules(PackageManager.MATCH_ALL); assertEquals(2, mi.size()); Collections.sort(mi, (ModuleInfo m1, ModuleInfo m2) -> @@ -49,18 +50,18 @@ public class ModuleInfoProviderTest extends InstrumentationTestCase { public void testParseFailure_incorrectTopLevelElement() { ModuleInfoProvider provider = getProvider(R.xml.unparseable_metadata1); - assertEquals(0, provider.getInstalledModules(0).size()); + assertEquals(0, provider.getInstalledModules(PackageManager.MATCH_ALL).size()); } public void testParseFailure_incorrectModuleElement() { ModuleInfoProvider provider = getProvider(R.xml.unparseable_metadata2); - assertEquals(0, provider.getInstalledModules(0).size()); + assertEquals(0, provider.getInstalledModules(PackageManager.MATCH_ALL).size()); } public void testParse_unknownAttributesIgnored() { ModuleInfoProvider provider = getProvider(R.xml.well_formed_metadata); - List mi = provider.getInstalledModules(0); + List mi = provider.getInstalledModules(PackageManager.MATCH_ALL); assertEquals(2, mi.size()); ModuleInfo mi1 = provider.getModuleInfo("com.android.module1", 0); -- GitLab From 17b30481453806548160538dd635b00dbe5eff5b Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sun, 12 Jan 2020 11:33:33 -0800 Subject: [PATCH 013/219] Import translations. DO NOT MERGE Change-Id: I090f0dab1bf477e98afb7146f5fcd4971976b847 Auto-generated-cl: translation import --- packages/PackageInstaller/res/values-ky/strings.xml | 10 +++++----- packages/PackageInstaller/res/values-pl/strings.xml | 2 +- packages/PackageInstaller/res/values-sl/strings.xml | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/PackageInstaller/res/values-ky/strings.xml b/packages/PackageInstaller/res/values-ky/strings.xml index ae47ab14b0cb..8f3f049fcdc3 100644 --- a/packages/PackageInstaller/res/values-ky/strings.xml +++ b/packages/PackageInstaller/res/values-ky/strings.xml @@ -24,8 +24,8 @@ "%1$s орнотулууда…" "Колдонмо орнотулду." "Бул колдонмону орнотоюн деп жатасызбы?" - "Учурдагы колдонмону жаңыртканы жатасызбы? Буга чейин сакталган дайындарыңыз өчүрүлбөйт." - "Учурдагы алдын ала орнотулган колдонмону жаңыртканы жатасызбы? Буга чейин сакталган дайындарыңыз өчүрүлбөйт." + "Учурдагы колдонмону жаңыртканы жатасызбы? Буга чейин сакталган дайын-даректериңиз өчүрүлбөйт." + "Учурдагы алдын ала орнотулган колдонмону жаңыртканы жатасызбы? Буга чейин сакталган дайын-даректериңиз өчүрүлбөйт." "Колдонмо орнотулган жок." "Топтомду орнотууга болбойт." "Башка топтом менен дал келбегендиктен колдонмо орнотулган жок." @@ -83,9 +83,9 @@ "Коопсуздукту сактоо максатында, планшетиңизге бул булактан колдонмолорду орнотууга уруксат жок." "Коопсуздукту сактоо максатында, сыналгыңызга бул булактан колдонмолорду орнотууга уруксат жок." "Коопсуздукту сактоо максатында, телефонуңузга бул булактан колдонмолорду орнотууга уруксат жок." - "Телефонуңуз жана жеке дайындарыңыз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам телефонуңузга кандайдыр бир зыян келтирилсе же дайындарыңызды жоготуп алсаңыз, өзүңүз жооптуу болосуз." - "Планшетиңиз жана жеке дайындарыңыз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам планшетиңизге кандайдыр бир зыян келтирилсе же дайындарыңызды жоготуп алсаңыз, өзүңүз жооптуу болосуз." - "Сыналгыңыз жана жеке дайындарыңыз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам сыналгыңызга кандайдыр бир зыян келтирилсе же дайындарыңызды жоготуп алсаңыз, өзүңүз жооптуу болосуз." + "Телефонуңуз жана жеке дайын-даректериңиз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам телефонуңузга кандайдыр бир зыян келтирилсе же дайын-даректериңизды жоготуп алсаңыз, өзүңүз жооптуу болосуз." + "Планшетиңиз жана жеке дайын-даректериңиз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам планшетиңизге кандайдыр бир зыян келтирилсе же дайын-даректериңизды жоготуп алсаңыз, өзүңүз жооптуу болосуз." + "Сыналгыңыз жана жеке дайын-даректериңиз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам сыналгыңызга кандайдыр бир зыян келтирилсе же дайын-даректериңизды жоготуп алсаңыз, өзүңүз жооптуу болосуз." "Улантуу" "Жөндөөлөр" "Тагынма колдонмолорду орнотуу/чыгаруу" diff --git a/packages/PackageInstaller/res/values-pl/strings.xml b/packages/PackageInstaller/res/values-pl/strings.xml index b08dc559358e..d2426c6c7fa8 100644 --- a/packages/PackageInstaller/res/values-pl/strings.xml +++ b/packages/PackageInstaller/res/values-pl/strings.xml @@ -62,7 +62,7 @@ "Aktywne odinstalowania" "Nieudane odinstalowania" "Odinstalowuję…" - "Odinstalowuję pakiet %1$s…" + "Odinstalowuję %1$s…" "Odinstalowywanie zakończone." "Odinstalowano pakiet %1$s" "Nie udało się odinstalować." diff --git a/packages/PackageInstaller/res/values-sl/strings.xml b/packages/PackageInstaller/res/values-sl/strings.xml index d535dc048cc3..354ce9938bae 100644 --- a/packages/PackageInstaller/res/values-sl/strings.xml +++ b/packages/PackageInstaller/res/values-sl/strings.xml @@ -53,7 +53,7 @@ "Odstrani aplikacijo" "Odstrani posodobitev" "%1$s je del te aplikacije:" - "Ali želite odstraniti to aplikacijo?" + "Ali želite odmestiti to aplikacijo?" "Ali želite odstraniti aplikacijo za ""vse"" uporabnike? Aplikacija in njeni podatki bodo odstranjeni iz ""vseh"" uporabnikov v napravi." "Ali želite to aplikacijo odstraniti za uporabnika %1$s?" "Želite to aplikacijo nadomestiti s tovarniško različico? Odstranjeni bodo vsi podatki." @@ -62,11 +62,11 @@ "Odstranitve v teku" "Neuspele odstranitve" "Odstranjevanje …" - "Odstranjevanje aplikacije %1$s …" + "Odmeščanje aplikacije %1$s …" "Odstranitev je končana." "Aplikacija %1$s je bila odstranjena" "Odstranitev ni uspela." - "Odstranjevanje aplikacije %1$s ni uspelo." + "Odmeščanje aplikacije %1$s ni uspelo." "Aktivne skrbniške aplikacije naprave ni mogoče odstraniti" "Aktivne skrbniške aplikacije za uporabnika %1$s ni mogoče odstraniti" "Aplikacija je obvezna za nekatere uporabnike/profile in je odstranjena za druge." -- GitLab From 27d20fbd19a4df574c1b4ecc0fc777d3e4d87c33 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sun, 12 Jan 2020 11:49:34 -0800 Subject: [PATCH 014/219] Import translations. DO NOT MERGE Change-Id: I193e7ea38b7b5257ac090d593f692dc80795b9ae Auto-generated-cl: translation import --- packages/PrintSpooler/res/values-eu/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/PrintSpooler/res/values-eu/strings.xml b/packages/PrintSpooler/res/values-eu/strings.xml index 459b4d3093ab..7ccccc9ff261 100644 --- a/packages/PrintSpooler/res/values-eu/strings.xml +++ b/packages/PrintSpooler/res/values-eu/strings.xml @@ -32,7 +32,7 @@ "%1$s orriko tartea" "adib., 1-5, 8,11-13" "Inprimatze-aurrebista" - "Aurrebista ikusteko, instalatu PDF ikustailea" + "Aurrebista ikusteko, instalatu PDF dokumentuen ikustailea" "Inprimatzeko aplikazioak matxura izan du" "Inprimatze-lana sortzen" "Gorde PDF gisa" -- GitLab From 4452bafb9352aa89dbae33789fa6566d88cab0b3 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sun, 12 Jan 2020 16:29:37 -0800 Subject: [PATCH 015/219] Import translations. DO NOT MERGE Change-Id: I77ed89b08ff7a8d1fabdbf3071da3b754ce7d06e Auto-generated-cl: translation import --- .../res-keyguard/values-ar/strings.xml | 66 +++++++++---------- packages/SystemUI/res/values-ar/strings.xml | 8 +-- packages/SystemUI/res/values-bn/strings.xml | 2 +- .../SystemUI/res/values-en-rAU/strings.xml | 2 +- .../SystemUI/res/values-en-rCA/strings.xml | 2 +- .../SystemUI/res/values-en-rGB/strings.xml | 2 +- .../SystemUI/res/values-en-rIN/strings.xml | 2 +- packages/SystemUI/res/values-es/strings.xml | 4 +- packages/SystemUI/res/values-eu/strings.xml | 6 +- packages/SystemUI/res/values-fr/strings.xml | 2 +- packages/SystemUI/res/values-hi/strings.xml | 2 +- .../SystemUI/res/values-pt-rPT/strings.xml | 6 +- 12 files changed, 52 insertions(+), 52 deletions(-) diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml index 98f6de739315..414317ff7b52 100644 --- a/packages/SystemUI/res-keyguard/values-ar/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml @@ -50,7 +50,7 @@ "‏تم إيقاف شريحة SIM بشكل دائم.\n اتصل بمقدم خدمة اللاسلكي للحصول على شريحة SIM أخرى." "‏شريحة SIM مؤمّنة." "‏شريحة SIM مؤمّنة برمز PUK." - "‏جارٍ إلغاء تأمين شريحة SIM…" + "‏جارٍ فتح قفل شريحة SIM…" "منطقة رقم التعريف الشخصي" "كلمة مرور الجهاز" "‏منطقة رقم التعريف الشخصي لشريحة SIM" @@ -76,14 +76,14 @@ "ارسم نقشك" "‏أدخل رقم التعريف الشخصي لشريحة SIM." "‏أدخل رقم التعريف الشخصي لشريحة SIM التابعة للمشغّل \"%1$s\"." - "‏%1$s يجب إيقاف eSIM لاستخدام الجهاز دون خدمة جوّال." + "‏%1$s يجب إيقاف eSIM لاستخدام الجهاز بدون خدمة الأجهزة الجوّالة." "أدخل رقم التعريف الشخصي" "أدخل كلمة المرور" "‏شريحة SIM غير مفعّلة الآن. أدخل رمز PUK للمتابعة. اتصل بمشغل شبكة الجوّال للاطلاع على التفاصيل." "‏SIM \"%1$s\" غير مفعّلة الآن. أدخل رمز PUK للمتابعة. واتصل بمشغل شبكة الجوّال لمعرفة التفاصيل." "أدخل رمز رقم التعريف الشخصي المطلوب" "تأكيد رمز رقم التعريف الشخصي المطلوب" - "‏جارٍ إلغاء تأمين شريحة SIM…" + "‏جارٍ فتح قفل شريحة SIM…" "اكتب رمز رقم التعريف الشخصي المكوّن من ٤ إلى ٨ أرقام." "‏يجب أن يتضمن رمز PUK‏ ۸ أرقام أو أكثر." "‏أعد إدخال رمز PUK الصحيح. وستؤدي المحاولات المتكررة إلى إيقاف شريحة SIM نهائيًا." @@ -92,18 +92,18 @@ "لقد كتبت رقم التعريف الشخصي بشكل غير صحيح %1$d مرة. \n\nأعد المحاولة خلال %2$d ثانية." "لقد كتبت كلمة المرور بشكل غير صحيح %1$d مرة. \n\nأعد المحاولة خلال %2$d ثانية." "لقد رسمت نقش فتح القفل بطريقة غير صحيحة %1$d مرة. \n\nأعد المحاولة خلال %2$d ثانية." - "أخطأت في محاولة إلغاء قفل الجهاز اللوحي %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إعادة تعيين هذا الجهاز، ومن ثم يتم حذف جميع بياناته." - "أخطأت في محاولة إلغاء قفل الهاتف %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إعادة تعيين هذا الهاتف، ومن ثم يتم حذف جميع بياناته." - "أخطأت في محاولة إلغاء قفل الجهاز اللوحي %d مرة. ستتم إعادة تعيين هذا الجهاز، ومن ثم يتم حذف جميع بياناته." - "أخطأت في محاولة إلغاء قفل الهاتف %d مرة. ستتم إعادة تعيين هذا الهاتف، ومن ثم يتم حذف جميع بياناته." - "أخطأت في محاولة إلغاء قفل الجهاز اللوحي %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إزالة هذا المستخدم، ومن ثم يتم حذف جميع بيانات المستخدم." - "أخطأت في محاولة إلغاء قفل الهاتف %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إزالة هذا المستخدم، ومن ثم يتم حذف جميع بيانات المستخدم." - "أخطأت في محاولة إلغاء قفل الجهاز اللوحي %d مرة. ستتم إزالة المستخدم، ومن ثم يتم حذف جميع بياناته." - "أخطأت في محاولة إلغاء قفل الهاتف %d مرة. ستتم إزالة المستخدم، ومن ثم يتم حذف جميع بياناته." - "أخطأت في محاولة إلغاء قفل الجهاز اللوحي %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إزالة الملف الشخصي للعمل، ومن ثم يتم حذف جميع بيانات الملف الشخصي." - "أخطأت في محاولة إلغاء قفل الهاتف %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إزالة الملف الشخصي للعمل، ومن ثم يتم حذف جميع بيانات الملف الشخصي." - "أخطأت في محاولة إلغاء قفل الجهاز اللوحي %d مرة. ستتم إزالة الملف الشخصي للعمل، ومن ثم يتم حذف جميع بياناته." - "أخطأت في محاولة إلغاء قفل الهاتف %d مرة. ستتم إزالة الملف الشخصي للعمل، ومن ثم يتم حذف جميع بياناته." + "أخطأت في محاولة فتح قفل الجهاز اللوحي %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إعادة تعيين هذا الجهاز، ومن ثم يتم حذف جميع بياناته." + "أخطأت في محاولة فتح قفل الهاتف %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إعادة تعيين هذا الهاتف، ومن ثم يتم حذف جميع بياناته." + "أخطأت في محاولة فتح قفل الجهاز اللوحي %d مرة. ستتم إعادة تعيين هذا الجهاز، ومن ثم يتم حذف جميع بياناته." + "أخطأت في محاولة فتح قفل الهاتف %d مرة. ستتم إعادة تعيين هذا الهاتف، ومن ثم يتم حذف جميع بياناته." + "أخطأت في محاولة فتح قفل الجهاز اللوحي %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إزالة هذا المستخدم، ومن ثم يتم حذف جميع بيانات المستخدم." + "أخطأت في محاولة فتح قفل الهاتف %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إزالة هذا المستخدم، ومن ثم يتم حذف جميع بيانات المستخدم." + "أخطأت في محاولة فتح قفل الجهاز اللوحي %d مرة. ستتم إزالة المستخدم، ومن ثم يتم حذف جميع بياناته." + "أخطأت في محاولة فتح قفل الهاتف %d مرة. ستتم إزالة المستخدم، ومن ثم يتم حذف جميع بياناته." + "أخطأت في محاولة فتح قفل الجهاز اللوحي %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إزالة الملف الشخصي للعمل، ومن ثم يتم حذف جميع بيانات الملف الشخصي." + "أخطأت في محاولة فتح قفل الهاتف %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إزالة الملف الشخصي للعمل، ومن ثم يتم حذف جميع بيانات الملف الشخصي." + "أخطأت في محاولة فتح قفل الجهاز اللوحي %d مرة. ستتم إزالة الملف الشخصي للعمل، ومن ثم يتم حذف جميع بياناته." + "أخطأت في محاولة فتح قفل الهاتف %d مرة. ستتم إزالة الملف الشخصي للعمل، ومن ثم يتم حذف جميع بياناته." "لقد رسمت نقش فتح القفل بشكل غير صحيح %1$d مرة. بعد إجراء %2$d من المحاولات غير الناجحة الأخرى، ستطالَب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات حساب بريد إلكتروني.\n\n أعد المحاولة خلال %3$d ثانية." "لقد رسمت نقش فتح القفل بشكل غير صحيح %1$d مرة. بعد إجراء %2$d من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام حساب بريد إلكتروني لإلغاء تأمين الهاتف.\n\n أعد المحاولة خلال %3$d ثانية." "‏رمز \"رقم التعريف الشخصي\" لشريحة SIM غير صحيح، ويلزمك الاتصال الآن بمشغّل شبكة الجوّال لإلغاء قفل الجهاز." @@ -142,28 +142,28 @@ "اختار المشرف قفل الجهاز" "تم حظر الجهاز يدويًا" - لم يتم إلغاء تأمين الجهاز لمدة %d ساعة. تأكيد النقش. - لم يتم إلغاء تأمين الجهاز لمدة ساعتين (%d). تأكيد النقش. - لم يتم إلغاء تأمين الجهاز لمدة %d ساعات. تأكيد النقش. - لم يتم إلغاء تأمين الجهاز لمدة %d ساعة. تأكيد النقش. - لم يتم إلغاء تأمين الجهاز لمدة %d ساعة. تأكيد النقش. - لم يتم إلغاء تأمين الجهاز لمدة %d ساعة. تأكيد النقش. + لم يتم فتح قفل الجهاز لمدة %d ساعة. تأكيد النقش. + لم يتم فتح قفل الجهاز لمدة ساعتين (%d). تأكيد النقش. + لم يتم فتح قفل الجهاز لمدة %d ساعات. تأكيد النقش. + لم يتم فتح قفل الجهاز لمدة %d ساعة. تأكيد النقش. + لم يتم فتح قفل الجهاز لمدة %d ساعة. تأكيد النقش. + لم يتم فتح قفل الجهاز لمدة %d ساعة. تأكيد النقش. - لم يتم إلغاء تأمين الجهاز لمدة %d ساعة. تأكيد رقم التعريف الشخصي. - لم يتم إلغاء تأمين الجهاز لمدة ساعتين (%d). تأكيد رقم التعريف الشخصي. - لم يتم إلغاء تأمين الجهاز لمدة %d ساعة. تأكيد رقم التعريف الشخصي. - لم يتم إلغاء تأمين الجهاز لمدة %d ساعة. تأكيد رقم التعريف الشخصي. - لم يتم إلغاء تأمين الجهاز لمدة %d ساعة. تأكيد رقم التعريف الشخصي. - لم يتم إلغاء تأمين الجهاز لمدة %d ساعة. تأكيد رقم التعريف الشخصي. + لم يتم فتح قفل الجهاز لمدة %d ساعة. تأكيد رقم التعريف الشخصي. + لم يتم فتح قفل الجهاز لمدة ساعتين (%d). تأكيد رقم التعريف الشخصي. + لم يتم فتح قفل الجهاز لمدة %d ساعة. تأكيد رقم التعريف الشخصي. + لم يتم فتح قفل الجهاز لمدة %d ساعة. تأكيد رقم التعريف الشخصي. + لم يتم فتح قفل الجهاز لمدة %d ساعة. تأكيد رقم التعريف الشخصي. + لم يتم فتح قفل الجهاز لمدة %d ساعة. تأكيد رقم التعريف الشخصي. - لم يتم إلغاء تأمين الجهاز لمدة %d ساعة. تأكيد كلمة المرور. - لم يتم إلغاء تأمين الجهاز لمدة ساعتين (%d). تأكيد كلمة المرور. - لم يتم إلغاء تأمين الجهاز لمدة %d ساعات. تأكيد كلمة المرور. - لم يتم إلغاء تأمين الجهاز لمدة %d ساعة. تأكيد كلمة المرور. - لم يتم إلغاء تأمين الجهاز لمدة %d ساعة. تأكيد كلمة المرور. - لم يتم إلغاء تأمين الجهاز لمدة %d ساعة. تأكيد كلمة المرور. + لم يتم فتح قفل الجهاز لمدة %d ساعة. تأكيد كلمة المرور. + لم يتم فتح قفل الجهاز لمدة ساعتين (%d). تأكيد كلمة المرور. + لم يتم فتح قفل الجهاز لمدة %d ساعات. تأكيد كلمة المرور. + لم يتم فتح قفل الجهاز لمدة %d ساعة. تأكيد كلمة المرور. + لم يتم فتح قفل الجهاز لمدة %d ساعة. تأكيد كلمة المرور. + لم يتم فتح قفل الجهاز لمدة %d ساعة. تأكيد كلمة المرور. "لم يتم التعرف عليها." "لم يتم التعرّف عليه." diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 1ec9c7283238..5998c56c33b0 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -107,7 +107,7 @@ "الكاميرا" "الهاتف" "المساعد الصوتي" - "إلغاء القفل" + "فتح القفل" "في انتظار بصمة الإصبع" "فتح القفل بدون استخدام بصمة إصبعك" "مسح الوجه" @@ -536,10 +536,10 @@ "أنت متصل بـ %1$s، الذي يمكنه مراقبة أنشطتك الشخصية على الشبكة، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب." "يخضع الملف الشخصي للعمل لإدارة %1$s. تم ربط الملف الشخصي بـ %2$s، الذي يمكنه مراقبة أنشطة شبكتك، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب.\n\nيمكنك الاتصال بالمشرف للحصول على مزيد من المعلومات." "يخضع الملف الشخصي للعمل لإدارة %1$s. تم ربط هذا الملف الشخصي بـ %2$s، الذي يمكنه مراقبة أنشطة شبكتك، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب.\n\nتم ربطك بـ %3$s، الذي يمكنه مراقبة أنشطة شبكتك الشخصية." - "‏إلغاء القفل باستمرار بواسطة TrustAgent" - "سيظل الجهاز مقفلاً إلى أن يتم إلغاء قفله يدويًا" + "‏فتح القفل باستمرار بواسطة TrustAgent" + "سيظل الجهاز مقفلاً إلى أن يتم فتح قفله يدويًا" "الحصول على الإشعارات بشكل أسرع" - "الاطّلاع عليها قبل إلغاء القفل" + "الاطّلاع عليها قبل فتح القفل" "لا، شكرًا" "إعداد" "%1$s. %2$s" diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 6dbd11266805..62d0007b6410 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -876,7 +876,7 @@ "সাধারণ বার্তাগুলি" "স্টোরেজ" "হিন্ট" - "ঝটপট অ্যাপ" + "ইনস্ট্যান্ট অ্যাপ" "%1$s চলছে" "অ্যাপটি ইনস্টল না করে চালু করা হয়েছে।" "অ্যাপটি ইনস্টল না করে চালু করা হয়েছে। আরও জানতে ট্যাপ করুন।" diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index ac9bd2ac82ef..38837ca6824a 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -509,7 +509,7 @@ "%1$s uses %2$s to manage your device." "Your admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information." " " - "Find out more" + "Learn more" "You\'re connected to %1$s, which can monitor your network activity, including emails, apps and websites." " " "Open VPN settings" diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 31bc5004810d..ba7c60948f3e 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -509,7 +509,7 @@ "%1$s uses %2$s to manage your device." "Your admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information." " " - "Find out more" + "Learn more" "You\'re connected to %1$s, which can monitor your network activity, including emails, apps and websites." " " "Open VPN settings" diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index ac9bd2ac82ef..38837ca6824a 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -509,7 +509,7 @@ "%1$s uses %2$s to manage your device." "Your admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information." " " - "Find out more" + "Learn more" "You\'re connected to %1$s, which can monitor your network activity, including emails, apps and websites." " " "Open VPN settings" diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index ac9bd2ac82ef..38837ca6824a 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -509,7 +509,7 @@ "%1$s uses %2$s to manage your device." "Your admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information." " " - "Find out more" + "Learn more" "You\'re connected to %1$s, which can monitor your network activity, including emails, apps and websites." " " "Open VPN settings" diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 4d3240d6a5c9..01200b782b21 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -381,8 +381,8 @@ "Al anochecer" "Hasta el amanecer" "NFC" - "La conexión NFC está inhabilitada" - "La conexión NFC está habilitada" + "El NFC está desactivado" + "El NFC está activado" "Desliza el dedo hacia arriba para cambiar de aplicación" "Arrastra hacia la derecha para cambiar rápidamente de aplicación" "Mostrar u ocultar aplicaciones recientes" diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index aa60d420f79f..4362e8d5b56d 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -55,12 +55,12 @@ "Ikusi" "Ireki %1$s %2$s konektatzen den guztietan" "Ireki %1$s %2$s konektatzen den guztietan" - "USB arazketa onartu?" + "USB bidezko arazketa onartu?" "Ordenagailuaren RSA gakoaren erreferentzia-gako digitala hau da:\n%1$s" "Eman beti ordenagailu honetatik arazteko baimena" "Baimendu" - "Ez da onartzen USB arazketa" - "Gailu honetan saioa hasita daukan erabiltzaileak ezin du aktibatu USB arazketa. Eginbide hori erabiltzeko, aldatu erabiltzaile nagusira." + "Ez da onartzen USB bidezko arazketa" + "Gailu honetan saioa hasita daukan erabiltzaileak ezin du aktibatu USB bidezko arazketa. Eginbide hori erabiltzeko, aldatu erabiltzaile nagusira." "Desgaitu egin da USB ataka" "USB ataka desgaitu egin da gailua likido edo zikinkeriengandik babesteko, eta ez du hautemango osagarririk.\n\nJakinarazpen bat jasoko duzu USB ataka berriz erabiltzeko moduan dagoenean." "USB ataka gaitu da kargagailuak eta osagarriak hautemateko" diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 387d57ef2122..39b3a9179922 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -381,7 +381,7 @@ "Activé la nuit" "Jusqu\'à l\'aube" "NFC" - "La technologie NFC est désactivée" + "NFC désactivée" "La technologie NFC est activée" "Balayer l\'écran vers le haut pour changer d\'application" "Déplacer vers la droite pour changer rapidement d\'application" diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index a90c2e50fef9..9e35f99dbc50 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -876,7 +876,7 @@ "सामान्य संदेश" "जगह" "संकेत" - "इंस्टेंट ऐप" + "झटपट ऐप्लिकेशन" "%1$s चल रहा है" "ऐप्लिकेशन इंस्टॉल किए बिना ही खुल गया है." "ऐप्लिकेशन इंस्टॉल किए बिना ही खुल गया है. ज़्यादा जानने के लिए टैप करें." diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index ca660d76961b..0acd0e56f1c9 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -550,7 +550,7 @@ "Para soltar este ecrã, toque sem soltar nos botões Anterior e Vista geral." "Para soltar este ecrã, toque sem soltar nos botões Anterior e Página inicial." "Para soltar este ecrã, deslize rapidamente para cima sem soltar." - "Compreendi" + "OK" "Não, obrigado" "Ecrã fixo" "Ecrã solto" @@ -614,7 +614,7 @@ "Diversão para alguns, mas não para todos" "O Sintonizador da interface do sistema disponibiliza-lhe formas adicionais ajustar e personalizar a interface do utilizador do Android. Estas funcionalidades experimentais podem ser alteradas, deixar de funcionar ou desaparecer em versões futuras. Prossiga com cuidado." "Estas funcionalidades experimentais podem ser alteradas, deixar de funcionar ou desaparecer em versões futuras. Prossiga com cuidado." - "Compreendi" + "OK" "Parabéns! O Sintonizador da interface do sistema foi adicionado às Definições" "Remover das Definições" "Pretende remover o Sintonizador da interface do sistema das Definições e deixar de utilizar todas as respetivas funcionalidades?" @@ -912,7 +912,7 @@ "Poupança de bateria agendada ativada" "A Poupança de bateria é ativada automaticamente quando o nível de bateria está abaixo de %d%%." "Definições" - "Compreendi" + "OK" "Despejar pilha SysUI" "A aplicação %1$s está a utilizar o(a) %2$s." "As aplicações estão a utilizar o(a) %s." -- GitLab From 0bba8d5ff999a135b7286f6c349ae68d8f9c6053 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Tue, 9 Apr 2019 13:38:07 -0700 Subject: [PATCH 016/219] DO NOT MERGE SetMode: Don't call into PM with AppOps lock held In the setmode paths do not call into package manager with the app-ops lock held. Otherwise we might get dead-locks then someone calls into app-ops manager with the package manager lock held. Test: Booted and saw no errors from the changed code Bug: 124731615 Bug: 146463528 Bug: 146590200 Bug: 147649036 Change-Id: If074bed1bd246a81791a7d9fd656f42f1a755495 (cherry picked from commit ec142a52fe6da0a18a1274249ae452cc5a8669fa) --- .../android/server/appop/AppOpsService.java | 241 +++++++++++------- 1 file changed, 146 insertions(+), 95 deletions(-) diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 3ba31e9ef97a..2949099e305e 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -1105,8 +1105,8 @@ public class AppOpsService extends IAppOpsService.Stub { return Collections.emptyList(); } synchronized (this) { - Ops pkgOps = getOpsRawLocked(uid, resolvedPackageName, false /* edit */, - false /* uidMismatchExpected */); + Ops pkgOps = getOpsRawLocked(uid, resolvedPackageName, false /* isPrivileged */, + false /* edit */); if (pkgOps == null) { return null; } @@ -1203,8 +1203,7 @@ public class AppOpsService extends IAppOpsService.Stub { private void pruneOp(Op op, int uid, String packageName) { if (!op.hasAnyTime()) { - Ops ops = getOpsRawLocked(uid, packageName, false /* edit */, - false /* uidMismatchExpected */); + Ops ops = getOpsRawLocked(uid, packageName, false /* isPrivileged */, false /* edit */); if (ops != null) { ops.remove(op.op); if (ops.size() <= 0) { @@ -1404,11 +1403,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } - @Override - public void setMode(int code, int uid, String packageName, int mode) { - setMode(code, uid, packageName, mode, true, false); - } - /** * Sets the mode for a certain op and uid. * @@ -1416,19 +1410,25 @@ public class AppOpsService extends IAppOpsService.Stub { * @param uid The UID for which to set * @param packageName The package for which to set * @param mode The new mode to set - * @param verifyUid Iff {@code true}, check that the package name belongs to the uid - * @param isPrivileged Whether the package is privileged. (Only used if {@code verifyUid == - * false}) */ - private void setMode(int code, int uid, @NonNull String packageName, int mode, - boolean verifyUid, boolean isPrivileged) { + @Override + public void setMode(int code, int uid, @NonNull String packageName, int mode) { enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid); verifyIncomingOp(code); ArraySet repCbs = null; code = AppOpsManager.opToSwitch(code); + + boolean isPrivileged; + try { + isPrivileged = verifyAndGetIsPrivileged(uid, packageName); + } catch (SecurityException e) { + Slog.e(TAG, "Cannot setMode", e); + return; + } + synchronized (this) { UidState uidState = getUidStateLocked(uid, false); - Op op = getOpLocked(code, uid, packageName, true, verifyUid, isPrivileged); + Op op = getOpLocked(code, uid, packageName, isPrivileged, true); if (op != null) { if (op.mode != mode) { op.mode = mode; @@ -1817,11 +1817,19 @@ public class AppOpsService extends IAppOpsService.Stub { if (isOpRestrictedDueToSuspend(code, packageName, uid)) { return AppOpsManager.MODE_IGNORED; } - synchronized (this) { + + boolean isPrivileged; + try { + isPrivileged = verifyAndGetIsPrivileged(uid, packageName); + } catch (Exception e) { if (verify) { - checkPackage(uid, packageName); + throw e; } - if (isOpRestrictedLocked(uid, code, packageName)) { + return AppOpsManager.MODE_IGNORED; + } + + synchronized (this) { + if (isOpRestrictedLocked(uid, code, packageName, isPrivileged)) { return AppOpsManager.MODE_IGNORED; } code = AppOpsManager.opToSwitch(code); @@ -1831,7 +1839,7 @@ public class AppOpsService extends IAppOpsService.Stub { final int rawMode = uidState.opModes.get(code); return raw ? rawMode : uidState.evalMode(code, rawMode); } - Op op = getOpLocked(code, uid, packageName, false, verify, false); + Op op = getOpLocked(code, uid, packageName, false, false); if (op == null) { return AppOpsManager.opToDefaultMode(code); } @@ -1936,14 +1944,12 @@ public class AppOpsService extends IAppOpsService.Stub { @Override public int checkPackage(int uid, String packageName) { Preconditions.checkNotNull(packageName); - synchronized (this) { - Ops ops = getOpsRawLocked(uid, packageName, true /* edit */, - true /* uidMismatchExpected */); - if (ops != null) { - return AppOpsManager.MODE_ALLOWED; - } else { - return AppOpsManager.MODE_ERRORED; - } + try { + verifyAndGetIsPrivileged(uid, packageName); + + return AppOpsManager.MODE_ALLOWED; + } catch (SecurityException ignored) { + return AppOpsManager.MODE_ERRORED; } } @@ -2006,9 +2012,16 @@ public class AppOpsService extends IAppOpsService.Stub { private int noteOperationUnchecked(int code, int uid, String packageName, int proxyUid, String proxyPackageName, @OpFlags int flags) { + boolean isPrivileged; + try { + isPrivileged = verifyAndGetIsPrivileged(uid, packageName); + } catch (SecurityException e) { + Slog.e(TAG, "Cannot startOperation", e); + return AppOpsManager.MODE_IGNORED; + } + synchronized (this) { - final Ops ops = getOpsRawLocked(uid, packageName, true /* edit */, - false /* uidMismatchExpected */); + final Ops ops = getOpsRawLocked(uid, packageName, isPrivileged, true /* edit */); if (ops == null) { scheduleOpNotedIfNeededLocked(code, uid, packageName, AppOpsManager.MODE_IGNORED); @@ -2017,7 +2030,7 @@ public class AppOpsService extends IAppOpsService.Stub { return AppOpsManager.MODE_ERRORED; } final Op op = getOpLocked(ops, code, true); - if (isOpRestrictedLocked(uid, code, packageName)) { + if (isOpRestrictedLocked(uid, code, packageName, isPrivileged)) { scheduleOpNotedIfNeededLocked(code, uid, packageName, AppOpsManager.MODE_IGNORED); return AppOpsManager.MODE_IGNORED; @@ -2176,16 +2189,25 @@ public class AppOpsService extends IAppOpsService.Stub { return AppOpsManager.MODE_IGNORED; } ClientState client = (ClientState)token; + + boolean isPrivileged; + try { + isPrivileged = verifyAndGetIsPrivileged(uid, packageName); + } catch (SecurityException e) { + Slog.e(TAG, "Cannot startOperation", e); + return AppOpsManager.MODE_IGNORED; + } + synchronized (this) { - final Ops ops = getOpsRawLocked(uid, resolvedPackageName, true /* edit */, - false /* uidMismatchExpected */); + final Ops ops = getOpsRawLocked(uid, resolvedPackageName, isPrivileged, + true /* edit */); if (ops == null) { if (DEBUG) Slog.d(TAG, "startOperation: no op for code " + code + " uid " + uid + " package " + resolvedPackageName); return AppOpsManager.MODE_ERRORED; } final Op op = getOpLocked(ops, code, true); - if (isOpRestrictedLocked(uid, code, resolvedPackageName)) { + if (isOpRestrictedLocked(uid, code, resolvedPackageName, isPrivileged)) { return AppOpsManager.MODE_IGNORED; } final int switchCode = AppOpsManager.opToSwitch(code); @@ -2257,8 +2279,17 @@ public class AppOpsService extends IAppOpsService.Stub { return; } ClientState client = (ClientState) token; + + boolean isPrivileged; + try { + isPrivileged = verifyAndGetIsPrivileged(uid, packageName); + } catch (SecurityException e) { + Slog.e(TAG, "Cannot finishOperation", e); + return; + } + synchronized (this) { - Op op = getOpLocked(code, uid, resolvedPackageName, true, true, false); + Op op = getOpLocked(code, uid, resolvedPackageName, isPrivileged, true); if (op == null) { return; } @@ -2508,8 +2539,76 @@ public class AppOpsService extends IAppOpsService.Stub { uidState.pendingStateCommitTime = 0; } - private Ops getOpsRawLocked(int uid, String packageName, boolean edit, - boolean uidMismatchExpected) { + /** + * Verify that package belongs to uid and return whether the package is privileged. + * + * @param uid The uid the package belongs to + * @param packageName The package the might belong to the uid + * + * @return {@code true} iff the package is privileged + */ + private boolean verifyAndGetIsPrivileged(int uid, String packageName) { + if (uid == Process.ROOT_UID) { + // For backwards compatibility, don't check package name for root UID. + return false; + } + + // Do not check if uid/packageName is already known + synchronized (this) { + UidState uidState = mUidStates.get(uid); + if (uidState != null && uidState.pkgOps != null) { + Ops ops = uidState.pkgOps.get(packageName); + + if (ops != null) { + return ops.isPrivileged; + } + } + } + + boolean isPrivileged = false; + final long ident = Binder.clearCallingIdentity(); + try { + int pkgUid; + + ApplicationInfo appInfo = LocalServices.getService(PackageManagerInternal.class) + .getApplicationInfo(packageName, PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE + | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS + | PackageManager.MATCH_UNINSTALLED_PACKAGES + | PackageManager.MATCH_INSTANT, + Process.SYSTEM_UID, UserHandle.getUserId(uid)); + if (appInfo != null) { + pkgUid = appInfo.uid; + isPrivileged = (appInfo.privateFlags + & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; + } else { + pkgUid = resolveUid(packageName); + if (pkgUid >= 0) { + isPrivileged = false; + } + } + if (pkgUid != uid) { + throw new SecurityException("Specified package " + packageName + " under uid " + uid + + " but it is really " + pkgUid); + } + } finally { + Binder.restoreCallingIdentity(ident); + } + + return isPrivileged; + } + + /** + * Get (and potentially create) ops. + * + * @param uid The uid the package belongs to + * @param packageName The name of the package + * @param isPrivileged If the package is privilidged (ignored if {@code edit} is false) + * @param edit If an ops does not exist, create the ops? + + * @return + */ + private Ops getOpsRawLocked(int uid, String packageName, boolean isPrivileged, boolean edit) { UidState uidState = getUidStateLocked(uid, edit); if (uidState == null) { return null; @@ -2527,47 +2626,6 @@ public class AppOpsService extends IAppOpsService.Stub { if (!edit) { return null; } - boolean isPrivileged = false; - // This is the first time we have seen this package name under this uid, - // so let's make sure it is valid. - if (uid != 0) { - final long ident = Binder.clearCallingIdentity(); - try { - int pkgUid = -1; - try { - ApplicationInfo appInfo = ActivityThread.getPackageManager() - .getApplicationInfo(packageName, - PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, - UserHandle.getUserId(uid)); - if (appInfo != null) { - pkgUid = appInfo.uid; - isPrivileged = (appInfo.privateFlags - & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; - } else { - pkgUid = resolveUid(packageName); - if (pkgUid >= 0) { - isPrivileged = false; - } - } - } catch (RemoteException e) { - Slog.w(TAG, "Could not contact PackageManager", e); - } - if (pkgUid != uid) { - // Oops! The package name is not valid for the uid they are calling - // under. Abort. - if (!uidMismatchExpected) { - RuntimeException ex = new RuntimeException("here"); - ex.fillInStackTrace(); - Slog.w(TAG, "Bad call: specified package " + packageName - + " under uid " + uid + " but it is really " + pkgUid, ex); - } - return null; - } - } finally { - Binder.restoreCallingIdentity(ident); - } - } ops = new Ops(packageName, uidState, isPrivileged); uidState.pkgOps.put(packageName, ops); } @@ -2575,7 +2633,7 @@ public class AppOpsService extends IAppOpsService.Stub { } /** - * Get the state of all ops for a package, don't verify that package belongs to uid. + * Get the state of all ops for a package. * *

Usually callers should use {@link #getOpLocked} and not call this directly. * @@ -2633,23 +2691,15 @@ public class AppOpsService extends IAppOpsService.Stub { * @param code The code of the op * @param uid The uid the of the package * @param packageName The package name for which to get the state for + * @param isPrivileged Whether the package is privileged or not (only used if {@code edit + * == true}) * @param edit Iff {@code true} create the {@link Op} object if not yet created - * @param verifyUid Iff {@code true} check that the package belongs to the uid - * @param isPrivileged Whether the package is privileged or not (only used if {@code verifyUid - * == false}) * * @return The {@link Op state} of the op */ - private @Nullable Op getOpLocked(int code, int uid, @NonNull String packageName, boolean edit, - boolean verifyUid, boolean isPrivileged) { - Ops ops; - - if (verifyUid) { - ops = getOpsRawLocked(uid, packageName, edit, false /* uidMismatchExpected */); - } else { - ops = getOpsRawNoVerifyLocked(uid, packageName, edit, isPrivileged); - } - + private @Nullable Op getOpLocked(int code, int uid, @NonNull String packageName, + boolean isPrivileged, boolean edit) { + Ops ops = getOpsRawNoVerifyLocked(uid, packageName, edit, isPrivileged); if (ops == null) { return null; } @@ -2679,7 +2729,8 @@ public class AppOpsService extends IAppOpsService.Stub { return pmi.isPackageSuspended(packageName, UserHandle.getUserId(uid)); } - private boolean isOpRestrictedLocked(int uid, int code, String packageName) { + private boolean isOpRestrictedLocked(int uid, int code, String packageName, + boolean isPrivileged) { int userHandle = UserHandle.getUserId(uid); final int restrictionSetCount = mOpUserRestrictions.size(); @@ -2691,8 +2742,8 @@ public class AppOpsService extends IAppOpsService.Stub { if (AppOpsManager.opAllowSystemBypassRestriction(code)) { // If we are the system, bypass user restrictions for certain codes synchronized (this) { - Ops ops = getOpsRawLocked(uid, packageName, true /* edit */, - false /* uidMismatchExpected */); + Ops ops = getOpsRawLocked(uid, packageName, isPrivileged, + true /* edit */); if ((ops != null) && ops.isPrivileged) { return false; } @@ -3063,7 +3114,7 @@ public class AppOpsService extends IAppOpsService.Stub { out.attribute(null, "n", Integer.toString(pkg.getUid())); synchronized (this) { Ops ops = getOpsRawLocked(pkg.getUid(), pkg.getPackageName(), - false /* edit */, false /* uidMismatchExpected */); + false /* isPrivileged */, false /* edit */); // Should always be present as the list of PackageOps is generated // from Ops. if (ops != null) { -- GitLab From 1a459638398446938a20b32fa0fbc63ad4bd505f Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Wed, 18 Dec 2019 09:54:09 -0500 Subject: [PATCH 017/219] Prevent sending early termination of appop use If a package starts a particular appop both as active and noted, once one of them is finished (usually noted after 5s), a message will be sent to callbacks indicating the end of the use. However, the app op may still be active. This could result in the removal of indicators prematurely from notifications. This change prevents that from happening by checking if the app op is still in use by that combination uid/package (either active or noted) and not notifying listeners if that's the case. Test: atest AppOpsControllerTest Test: use app from bug report. Observe that notification does not lose the microphone indicator Bug: 144092031 Merged-In: I180e7c257e6171e7686ba7eda9bf02249358ed0 Change-Id: I94473c3ccf1318dac29f067dade91e540e20285e --- .../systemui/appops/AppOpsControllerImpl.java | 51 ++++++- .../systemui/appops/AppOpsControllerTest.java | 138 +++++++++++++++++- 2 files changed, 179 insertions(+), 10 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java index afb8e7421412..bfdda207b5b4 100644 --- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java @@ -193,20 +193,32 @@ public class AppOpsControllerImpl implements AppOpsController, mNotedItems.remove(item); if (DEBUG) Log.w(TAG, "Removed item: " + item.toString()); } - notifySuscribers(code, uid, packageName, false); + boolean active; + // Check if the item is also active + synchronized (mActiveItems) { + active = getAppOpItem(mActiveItems, code, uid, packageName) != null; + } + if (!active) { + notifySuscribers(code, uid, packageName, false); + } } - private void addNoted(int code, int uid, String packageName) { + private boolean addNoted(int code, int uid, String packageName) { AppOpItem item; + boolean createdNew = false; synchronized (mNotedItems) { item = getAppOpItem(mNotedItems, code, uid, packageName); if (item == null) { item = new AppOpItem(code, uid, packageName, System.currentTimeMillis()); mNotedItems.add(item); if (DEBUG) Log.w(TAG, "Added item: " + item.toString()); + createdNew = true; } } + // We should keep this so we make sure it cannot time out. + mBGHandler.removeCallbacksAndMessages(item); mBGHandler.scheduleRemoval(item, NOTED_OP_TIME_DELAY_MS); + return createdNew; } /** @@ -253,23 +265,46 @@ public class AppOpsControllerImpl implements AppOpsController, @Override public void onOpActiveChanged(int code, int uid, String packageName, boolean active) { - if (updateActives(code, uid, packageName, active)) { - notifySuscribers(code, uid, packageName, active); + if (DEBUG) { + Log.w(TAG, String.format("onActiveChanged(%d,%d,%s,%s", code, uid, packageName, + Boolean.toString(active))); + } + boolean activeChanged = updateActives(code, uid, packageName, active); + if (!activeChanged) return; // early return + // Check if the item is also noted, in that case, there's no update. + boolean alsoNoted; + synchronized (mNotedItems) { + alsoNoted = getAppOpItem(mNotedItems, code, uid, packageName) != null; + } + // If active is true, we only send the update if the op is not actively noted (already true) + // If active is false, we only send the update if the op is not actively noted (prevent + // early removal) + if (!alsoNoted) { + mBGHandler.post(() -> notifySuscribers(code, uid, packageName, active)); } } @Override public void onOpNoted(int code, int uid, String packageName, int result) { if (DEBUG) { - Log.w(TAG, "Op: " + code + " with result " + AppOpsManager.MODE_NAMES[result]); + Log.w(TAG, "Noted op: " + code + " with result " + + AppOpsManager.MODE_NAMES[result] + " for package " + packageName); } if (result != AppOpsManager.MODE_ALLOWED) return; - addNoted(code, uid, packageName); - notifySuscribers(code, uid, packageName, true); + boolean notedAdded = addNoted(code, uid, packageName); + if (!notedAdded) return; // early return + boolean alsoActive; + synchronized (mActiveItems) { + alsoActive = getAppOpItem(mActiveItems, code, uid, packageName) != null; + } + if (!alsoActive) { + mBGHandler.post(() -> notifySuscribers(code, uid, packageName, true)); + } } private void notifySuscribers(int code, int uid, String packageName, boolean active) { if (mCallbacksByCode.containsKey(code)) { + if (DEBUG) Log.d(TAG, "Notifying of change in package " + packageName); for (Callback cb: mCallbacksByCode.get(code)) { cb.onActiveStateChanged(code, uid, packageName, active); } @@ -292,7 +327,7 @@ public class AppOpsControllerImpl implements AppOpsController, } - protected final class H extends Handler { + protected class H extends Handler { H(Looper looper) { super(looper); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java index bd7f897dc1c0..df7221e2f663 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java @@ -29,6 +29,8 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static java.lang.Thread.sleep; + import android.app.AppOpsManager; import android.content.pm.PackageManager; import android.os.UserHandle; @@ -37,7 +39,6 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; -import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; import org.junit.Before; @@ -46,6 +47,8 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.List; + @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @@ -64,14 +67,16 @@ public class AppOpsControllerTest extends SysuiTestCase { private AppOpsControllerImpl.H mMockHandler; private AppOpsControllerImpl mController; + private TestableLooper mTestableLooper; @Before public void setUp() { MockitoAnnotations.initMocks(this); + mTestableLooper = TestableLooper.get(this); getContext().addMockSystemService(AppOpsManager.class, mAppOpsManager); - mController = new AppOpsControllerImpl(mContext, Dependency.get(Dependency.BG_LOOPER)); + mController = new AppOpsControllerImpl(mContext, mTestableLooper.getLooper()); } @Test @@ -95,6 +100,7 @@ public class AppOpsControllerTest extends SysuiTestCase { AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED); + mTestableLooper.processAllMessages(); verify(mCallback).onActiveStateChanged(AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); } @@ -104,6 +110,7 @@ public class AppOpsControllerTest extends SysuiTestCase { mController.addCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback); mController.onOpActiveChanged( AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); + mTestableLooper.processAllMessages(); verify(mCallback, never()).onActiveStateChanged( anyInt(), anyInt(), anyString(), anyBoolean()); } @@ -114,6 +121,7 @@ public class AppOpsControllerTest extends SysuiTestCase { mController.removeCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback); mController.onOpActiveChanged( AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); + mTestableLooper.processAllMessages(); verify(mCallback, never()).onActiveStateChanged( anyInt(), anyInt(), anyString(), anyBoolean()); } @@ -124,6 +132,7 @@ public class AppOpsControllerTest extends SysuiTestCase { mController.removeCallback(new int[]{AppOpsManager.OP_CAMERA}, mCallback); mController.onOpActiveChanged( AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); + mTestableLooper.processAllMessages(); verify(mCallback).onActiveStateChanged(AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); } @@ -186,4 +195,129 @@ public class AppOpsControllerTest extends SysuiTestCase { verify(mMockHandler).removeCallbacksAndMessages(null); assertTrue(mController.getActiveAppOps().isEmpty()); } + + @Test + public void noDoubleUpdateOnOpNoted() { + mController.setBGHandler(mMockHandler); + + mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, + AppOpsManager.MODE_ALLOWED); + mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, + AppOpsManager.MODE_ALLOWED); + + // Only one post to notify subscribers + verify(mMockHandler, times(1)).post(any()); + + List list = mController.getActiveAppOps(); + assertEquals(1, list.size()); + } + + @Test + public void onDoubleOPNoted_scheduleTwiceForRemoval() { + mController.setBGHandler(mMockHandler); + + mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, + AppOpsManager.MODE_ALLOWED); + mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, + AppOpsManager.MODE_ALLOWED); + + // Only one post to notify subscribers + verify(mMockHandler, times(2)).scheduleRemoval(any(), anyLong()); + } + + @Test + public void testActiveOpNotRemovedAfterNoted() throws InterruptedException { + // Replaces the timeout delay with 5 ms + AppOpsControllerImpl.H testHandler = mController.new H(mTestableLooper.getLooper()) { + @Override + public void scheduleRemoval(AppOpItem item, long timeToRemoval) { + super.scheduleRemoval(item, 5L); + } + }; + + mController.addCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback); + mController.setBGHandler(testHandler); + + mController.onOpActiveChanged( + AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true); + + mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, + AppOpsManager.MODE_ALLOWED); + + mTestableLooper.processAllMessages(); + List list = mController.getActiveAppOps(); + verify(mCallback).onActiveStateChanged( + AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true); + + // Duplicates are not removed between active and noted + assertEquals(2, list.size()); + + sleep(10L); + + mTestableLooper.processAllMessages(); + + verify(mCallback, never()).onActiveStateChanged( + AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, false); + list = mController.getActiveAppOps(); + assertEquals(1, list.size()); + } + + @Test + public void testNotedNotRemovedAfterActive() { + mController.addCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback); + + mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, + AppOpsManager.MODE_ALLOWED); + + mController.onOpActiveChanged( + AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true); + + mTestableLooper.processAllMessages(); + List list = mController.getActiveAppOps(); + verify(mCallback).onActiveStateChanged( + AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true); + + // Duplicates are not removed between active and noted + assertEquals(2, list.size()); + + mController.onOpActiveChanged( + AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, false); + + mTestableLooper.processAllMessages(); + + verify(mCallback, never()).onActiveStateChanged( + AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, false); + list = mController.getActiveAppOps(); + assertEquals(1, list.size()); + } + + @Test + public void testNotedAndActiveOnlyOneCall() { + mController.addCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback); + + mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, + AppOpsManager.MODE_ALLOWED); + + mController.onOpActiveChanged( + AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true); + + mTestableLooper.processAllMessages(); + verify(mCallback).onActiveStateChanged( + AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true); + } + + @Test + public void testActiveAndNotedOnlyOneCall() { + mController.addCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback); + + mController.onOpActiveChanged( + AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true); + + mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, + AppOpsManager.MODE_ALLOWED); + + mTestableLooper.processAllMessages(); + verify(mCallback).onActiveStateChanged( + AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true); + } } -- GitLab From 73e2690eded5d035de8560aaff60a6f47290305d Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Tue, 7 May 2019 08:57:35 -0700 Subject: [PATCH 018/219] DO NOT MERGE Remove unnecessary internal APIs. Test: Built Bug: 146463528 Bug: 146590200 Bug: 147649036 Change-Id: I5391ac4989d7d5712982f5608f9fc28cf7935b00 --- .../android/app/AppOpsManagerInternal.java | 29 ----------------- .../android/server/appop/AppOpsService.java | 31 ++----------------- 2 files changed, 2 insertions(+), 58 deletions(-) diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java index 08cad04401e9..996939eb9ee1 100644 --- a/core/java/android/app/AppOpsManagerInternal.java +++ b/core/java/android/app/AppOpsManagerInternal.java @@ -16,7 +16,6 @@ package android.app; -import android.annotation.NonNull; import android.util.SparseIntArray; import com.android.internal.util.function.QuadFunction; @@ -76,20 +75,6 @@ public abstract class AppOpsManagerInternal { */ public abstract void setDeviceAndProfileOwners(SparseIntArray owners); - /** - * Sets the app-ops mode for a certain app-op and uid. - * - *

Similar as {@link AppOpsManager#setUidMode} but does not require the package manager to be - * working. Hence this can be used very early during boot. - * - *

Only for internal callers. Does not verify that package name belongs to uid. - * - * @param code The op code to set. - * @param uid The UID for which to set. - * @param mode The new mode to set. - */ - public abstract void setUidMode(int code, int uid, int mode); - /** * Set all {@link #setMode (package) modes} for this uid to the default value. * @@ -97,18 +82,4 @@ public abstract class AppOpsManagerInternal { * @param uid The uid */ public abstract void setAllPkgModesToDefault(int code, int uid); - - /** - * Get the (raw) mode of an app-op. - * - *

Does not verify that package belongs to uid. The caller needs to do that. - * - * @param code The code of the op - * @param uid The uid of the package the op belongs to - * @param packageName The package the op belongs to - * - * @return The mode of the op - */ - public abstract @AppOpsManager.Mode int checkOperationUnchecked(int code, int uid, - @NonNull String packageName); } diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 2949099e305e..1760371597f1 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -1793,14 +1793,6 @@ public class AppOpsService extends IAppOpsService.Stub { return checkOperationUnchecked(code, uid, resolvedPackageName, raw); } - /** - * @see #checkOperationUnchecked(int, int, String, boolean, boolean) - */ - private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName, - boolean raw) { - return checkOperationUnchecked(code, uid, packageName, raw, true); - } - /** * Get the mode of an app-op. * @@ -1808,25 +1800,16 @@ public class AppOpsService extends IAppOpsService.Stub { * @param uid The uid of the package the op belongs to * @param packageName The package the op belongs to * @param raw If the raw state of eval-ed state should be checked. - * @param verify If the code should check the package belongs to the uid * * @return The mode of the op */ private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName, - boolean raw, boolean verify) { + boolean raw) { if (isOpRestrictedDueToSuspend(code, packageName, uid)) { return AppOpsManager.MODE_IGNORED; } - boolean isPrivileged; - try { - isPrivileged = verifyAndGetIsPrivileged(uid, packageName); - } catch (Exception e) { - if (verify) { - throw e; - } - return AppOpsManager.MODE_IGNORED; - } + boolean isPrivileged = verifyAndGetIsPrivileged(uid, packageName); synchronized (this) { if (isOpRestrictedLocked(uid, code, packageName, isPrivileged)) { @@ -4692,19 +4675,9 @@ public class AppOpsService extends IAppOpsService.Stub { } } - @Override - public void setUidMode(int code, int uid, int mode) { - AppOpsService.this.setUidMode(code, uid, mode); - } - @Override public void setAllPkgModesToDefault(int code, int uid) { AppOpsService.this.setAllPkgModesToDefault(code, uid); } - - @Override - public @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName) { - return AppOpsService.this.checkOperationUnchecked(code, uid, packageName, true, false); - } } } -- GitLab From 892ded1e8a56dd622fd2bbddd77c762f0cad8f4e Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 12 Jun 2019 16:31:29 -0700 Subject: [PATCH 019/219] DO NOT MERGE Don't throw exception in AppOpsManager.checkOp In Q we handled the case where the op does not match the package name by returning the default state. NoteOp and StartOp returned errored. Fix up these scenarios. Test: - atest CtsAppOpsTestCases - backported new test to Q to verify the behavior is the same in Q and master Bug: 132885449 Bug: 146463528 Bug: 146590200 Bug: 147649036 Change-Id: I5b94e92af759580f2d2644ece49f159bd006b31c --- .../com/android/server/appop/AppOpsService.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 1760371597f1..3e7188c6e8ec 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -1809,7 +1809,14 @@ public class AppOpsService extends IAppOpsService.Stub { return AppOpsManager.MODE_IGNORED; } - boolean isPrivileged = verifyAndGetIsPrivileged(uid, packageName); + boolean isPrivileged; + + try { + isPrivileged = verifyAndGetIsPrivileged(uid, packageName); + } catch (SecurityException e) { + Slog.e(TAG, "checkOperation", e); + return AppOpsManager.opToDefaultMode(code); + } synchronized (this) { if (isOpRestrictedLocked(uid, code, packageName, isPrivileged)) { @@ -1999,8 +2006,8 @@ public class AppOpsService extends IAppOpsService.Stub { try { isPrivileged = verifyAndGetIsPrivileged(uid, packageName); } catch (SecurityException e) { - Slog.e(TAG, "Cannot startOperation", e); - return AppOpsManager.MODE_IGNORED; + Slog.e(TAG, "noteOperation", e); + return AppOpsManager.MODE_ERRORED; } synchronized (this) { @@ -2177,8 +2184,8 @@ public class AppOpsService extends IAppOpsService.Stub { try { isPrivileged = verifyAndGetIsPrivileged(uid, packageName); } catch (SecurityException e) { - Slog.e(TAG, "Cannot startOperation", e); - return AppOpsManager.MODE_IGNORED; + Slog.e(TAG, "startOperation", e); + return AppOpsManager.MODE_ERRORED; } synchronized (this) { -- GitLab From c6a61a6b0ce93a5ede0842fdaefca73a1bf243a9 Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Wed, 18 Dec 2019 07:01:25 +0100 Subject: [PATCH 020/219] Fix IsolatedUidAllocator for non-primary users. The UID allocator stores complete UIDs, not app IDs. When removing a UID from the range, we should therefore also use the UID, not the app ID. Also added a test to cover this scenario, which passes with this change. Bug: 146313311 Test: atest ActivityManagerTest Change-Id: I1118ec73dcee5987e12f35aabce5cfa8cbe407a1 (cherry picked from commit c9a0df2d88884617b86c09a0ab86363200d6a66d) --- .../java/com/android/server/am/ProcessList.java | 4 +--- .../server/am/ActivityManagerServiceTest.java | 13 ++++++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index fe29a36ec45f..278163b9dfe4 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -422,9 +422,7 @@ public final class ProcessList { @GuardedBy("ProcessList.this.mService") void freeIsolatedUidLocked(int uid) { - // Strip out userId - final int appId = UserHandle.getAppId(uid); - mUidUsed.delete(appId); + mUidUsed.delete(uid); } }; diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java index 3df6976a2cae..2b849e71fdaf 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java @@ -346,10 +346,21 @@ public class ActivityManagerServiceTest { verifyUidRangesNoOverlap(range, range2); verifyIsolatedUidAllocator(range2); - // Free both, then try to allocate the maximum number of UID ranges + // Free both allocator.freeUidRangeLocked(appInfo); allocator.freeUidRangeLocked(appInfo2); + // Verify for a secondary user + ApplicationInfo appInfo3 = new ApplicationInfo(); + appInfo3.processName = "com.android.test.app"; + appInfo3.uid = 1010000; + final IsolatedUidRange range3 = allocator.getOrCreateIsolatedUidRangeLocked( + appInfo3.processName, appInfo3.uid); + validateAppZygoteIsolatedUidRange(range3); + verifyIsolatedUidAllocator(range3); + + allocator.freeUidRangeLocked(appInfo3); + // Try to allocate the maximum number of UID ranges int maxNumUidRanges = (Process.LAST_APP_ZYGOTE_ISOLATED_UID - Process.FIRST_APP_ZYGOTE_ISOLATED_UID + 1) / Process.NUM_UIDS_PER_APP_ZYGOTE; for (int i = 0; i < maxNumUidRanges; i++) { -- GitLab From ad08b5b831d4e7abee46593686f235f45be65b93 Mon Sep 17 00:00:00 2001 From: Evan Laird Date: Wed, 15 Jan 2020 13:59:00 -0500 Subject: [PATCH 021/219] DO NOT MERGE: Use a copy of bt device profile list when updating CachedBluetoothDevice#getProfiles() only returns a Collections.unmodifiableList which isn't thread safe. Use a copy in BluetoothControllerImpl so we can avoid a CME Test: atest SystemUITests Bug: 146828136 Change-Id: I451a746836c67b8b82f26f4f39b5363ac5e0ea79 --- .../android/settingslib/bluetooth/CachedBluetoothDevice.java | 4 ++++ .../systemui/statusbar/policy/BluetoothControllerImpl.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 8f164f1592d3..c7d72f2e3ce4 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -661,6 +661,10 @@ public class CachedBluetoothDevice implements Comparable return Collections.unmodifiableList(mProfiles); } + public List getProfileListCopy() { + return new ArrayList<>(mProfiles); + } + public List getConnectableProfiles() { List connectableProfiles = new ArrayList(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java index 351579a95710..7d562fbdfe61 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java @@ -277,7 +277,7 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa boolean otherProfileConnected = false; for (CachedBluetoothDevice device : getDevices()) { - for (LocalBluetoothProfile profile : device.getProfiles()) { + for (LocalBluetoothProfile profile : device.getProfileListCopy()) { int profileId = profile.getProfileId(); boolean isConnected = device.isConnectedProfile(profile); if (profileId == BluetoothProfile.HEADSET -- GitLab From 05024a1523f796ed740781218cdde5849e4db84c Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 8 May 2019 15:14:09 -0700 Subject: [PATCH 022/219] DO NOT MERGE Fix AppOpsServiceTest - Mock LocalService dependency - Always assume calling app has appropriate permissions Test: atest atest FrameworksMockingServicesTests:com.android.server.appop Fixes: 132274015 Fixes: 147778434 Bug: 146463528 Bug: 146590200 Merged-In: Ie816e0c6c81ecf25d37f05187591ca0d1edf0bc2 Change-Id: Ie816e0c6c81ecf25d37f05187591ca0d1edf0bc2 --- .../com/android/server/appop/TEST_MAPPING | 8 + .../mockingservicestests/AndroidManifest.xml | 1 + .../server/appop/AppOpsServiceTest.java | 167 +++++++++++------- 3 files changed, 114 insertions(+), 62 deletions(-) rename services/tests/{servicestests => mockingservicestests}/src/com/android/server/appop/AppOpsServiceTest.java (76%) diff --git a/services/core/java/com/android/server/appop/TEST_MAPPING b/services/core/java/com/android/server/appop/TEST_MAPPING index a53797dfa9e0..1a5dac503463 100644 --- a/services/core/java/com/android/server/appop/TEST_MAPPING +++ b/services/core/java/com/android/server/appop/TEST_MAPPING @@ -10,6 +10,14 @@ "include-filter": "com.android.server.appop" } ] + }, + { + "name": "FrameworksMockingServicesTests", + "options": [ + { + "include-filter": "com.android.server.appop" + } + ] } ] } diff --git a/services/tests/mockingservicestests/AndroidManifest.xml b/services/tests/mockingservicestests/AndroidManifest.xml index 32d7d026ff10..1200c0c8c7bd 100644 --- a/services/tests/mockingservicestests/AndroidManifest.xml +++ b/services/tests/mockingservicestests/AndroidManifest.xml @@ -20,6 +20,7 @@ + diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java similarity index 76% rename from services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java rename to services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java index 71661452d800..698e491a8926 100644 --- a/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java @@ -25,14 +25,27 @@ import static android.app.AppOpsManager.OP_READ_SMS; import static android.app.AppOpsManager.OP_WIFI_SCAN; import static android.app.AppOpsManager.OP_WRITE_SMS; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; + import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.nullable; + import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.AppOpsManager.OpEntry; import android.app.AppOpsManager.PackageOps; import android.content.Context; +import android.content.pm.PackageManagerInternal; import android.os.Handler; import android.os.HandlerThread; import android.os.Process; @@ -43,12 +56,17 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.dx.mockito.inline.extended.StaticMockitoSession; +import com.android.server.LocalServices; + +import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.quality.Strictness; import java.io.File; import java.util.List; @@ -69,21 +87,46 @@ public class AppOpsServiceTest { // State will be persisted into this XML file. private static final String APP_OPS_FILENAME = "appops-service-test.xml"; + private static final Context sContext = InstrumentationRegistry.getTargetContext(); + private static final String sMyPackageName = sContext.getOpPackageName(); + private File mAppOpsFile; - private Context mContext; private Handler mHandler; - private AppOpsManager mAppOpsManager; private AppOpsService mAppOpsService; - private String mMyPackageName; private int mMyUid; private long mTestStartMillis; + private StaticMockitoSession mMockingSession; + + @Before + public void mockPackageManagerInternalGetApplicationInfo() { + mMockingSession = mockitoSession() + .strictness(Strictness.LENIENT) + .spyStatic(LocalServices.class) + .startMocking(); + + // Mock LocalServices.getService(PackageManagerInternal.class).getApplicationInfo dependency + // needed by AppOpsService + PackageManagerInternal mockPackageManagerInternal = mock(PackageManagerInternal.class); + when(mockPackageManagerInternal.getApplicationInfo(eq(sMyPackageName), anyInt(), anyInt(), + anyInt())).thenReturn(sContext.getApplicationInfo()); + doReturn(mockPackageManagerInternal).when( + () -> LocalServices.getService(PackageManagerInternal.class)); + } + + private void setupAppOpsService() { + mAppOpsService = new AppOpsService(mAppOpsFile, mHandler); + mAppOpsService.mContext = spy(sContext); + + // Always approve all permission checks + doNothing().when(mAppOpsService.mContext).enforcePermission(anyString(), anyInt(), + anyInt(), nullable(String.class)); + } private static String sDefaultAppopHistoryParameters; @Before public void setUp() { - mContext = InstrumentationRegistry.getTargetContext(); - mAppOpsFile = new File(mContext.getFilesDir(), APP_OPS_FILENAME); + mAppOpsFile = new File(sContext.getFilesDir(), APP_OPS_FILENAME); if (mAppOpsFile.exists()) { // Start with a clean state (persisted into XML). mAppOpsFile.delete(); @@ -92,13 +135,10 @@ public class AppOpsServiceTest { HandlerThread handlerThread = new HandlerThread(TAG); handlerThread.start(); mHandler = new Handler(handlerThread.getLooper()); - mMyPackageName = mContext.getOpPackageName(); mMyUid = Process.myUid(); - mAppOpsManager = mContext.getSystemService(AppOpsManager.class); - mAppOpsService = new AppOpsService(mAppOpsFile, mHandler); - mAppOpsService.mHistoricalRegistry.systemReady(mContext.getContentResolver()); - mAppOpsService.mContext = mContext; + setupAppOpsService(); + mAppOpsService.mHistoricalRegistry.systemReady(sContext.getContentResolver()); mTestStartMillis = System.currentTimeMillis(); } @@ -118,6 +158,11 @@ public class AppOpsServiceTest { sDefaultAppopHistoryParameters); } + @After + public void resetStaticMocks() { + mMockingSession.finishMocking(); + } + @Test public void testGetOpsForPackage_noOpsLogged() { assertThat(getLoggedOps()).isNull(); @@ -125,16 +170,16 @@ public class AppOpsServiceTest { @Test public void testNoteOperationAndGetOpsForPackage() { - mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED); - mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, mMyPackageName, MODE_ERRORED); + mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); + mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, sMyPackageName, MODE_ERRORED); // Note an op that's allowed. - mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName); + mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName); List loggedOps = getLoggedOps(); assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED); // Note another op that's not allowed. - mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, mMyPackageName); + mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, sMyPackageName); loggedOps = getLoggedOps(); assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED); assertContainsOp(loggedOps, OP_WRITE_SMS, -1, mTestStartMillis, MODE_ERRORED); @@ -148,17 +193,17 @@ public class AppOpsServiceTest { @Test public void testNoteOperationAndGetOpsForPackage_controlledByDifferentOp() { // This op controls WIFI_SCAN - mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, mMyPackageName, MODE_ALLOWED); + mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, sMyPackageName, MODE_ALLOWED); - assertThat(mAppOpsService.noteOperation(OP_WIFI_SCAN, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_WIFI_SCAN, mMyUid, sMyPackageName)) .isEqualTo(MODE_ALLOWED); assertContainsOp(getLoggedOps(), OP_WIFI_SCAN, mTestStartMillis, -1, MODE_ALLOWED /* default for WIFI_SCAN; this is not changed or used in this test */); // Now set COARSE_LOCATION to ERRORED -> this will make WIFI_SCAN disabled as well. - mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, mMyPackageName, MODE_ERRORED); - assertThat(mAppOpsService.noteOperation(OP_WIFI_SCAN, mMyUid, mMyPackageName)) + mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, sMyPackageName, MODE_ERRORED); + assertThat(mAppOpsService.noteOperation(OP_WIFI_SCAN, mMyUid, sMyPackageName)) .isEqualTo(MODE_ERRORED); assertContainsOp(getLoggedOps(), OP_WIFI_SCAN, mTestStartMillis, mTestStartMillis, @@ -168,15 +213,14 @@ public class AppOpsServiceTest { // Tests the dumping and restoring of the in-memory state to/from XML. @Test public void testStatePersistence() { - mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED); - mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, mMyPackageName, MODE_ERRORED); - mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName); - mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, mMyPackageName); + mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); + mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, sMyPackageName, MODE_ERRORED); + mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName); + mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, sMyPackageName); mAppOpsService.writeState(); // Create a new app ops service, and initialize its state from XML. - mAppOpsService = new AppOpsService(mAppOpsFile, mHandler); - mAppOpsService.mContext = mContext; + setupAppOpsService(); mAppOpsService.readState(); // Query the state of the 2nd service. @@ -188,13 +232,12 @@ public class AppOpsServiceTest { // Tests that ops are persisted during shutdown. @Test public void testShutdown() { - mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED); - mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName); + mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); + mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName); mAppOpsService.shutdown(); // Create a new app ops service, and initialize its state from XML. - mAppOpsService = new AppOpsService(mAppOpsFile, mHandler); - mAppOpsService.mContext = mContext; + setupAppOpsService(); mAppOpsService.readState(); // Query the state of the 2nd service. @@ -204,21 +247,21 @@ public class AppOpsServiceTest { @Test public void testGetOpsForPackage() { - mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED); - mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName); + mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); + mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName); // Query all ops List loggedOps = mAppOpsService.getOpsForPackage( - mMyUid, mMyPackageName, null /* all ops */); + mMyUid, sMyPackageName, null /* all ops */); assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED); // Query specific ops loggedOps = mAppOpsService.getOpsForPackage( - mMyUid, mMyPackageName, new int[]{OP_READ_SMS, OP_WRITE_SMS}); + mMyUid, sMyPackageName, new int[]{OP_READ_SMS, OP_WRITE_SMS}); assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED); // Query unknown UID - loggedOps = mAppOpsService.getOpsForPackage(mMyUid + 1, mMyPackageName, null /* all ops */); + loggedOps = mAppOpsService.getOpsForPackage(mMyUid + 1, sMyPackageName, null /* all ops */); assertThat(loggedOps).isNull(); // Query unknown package name @@ -226,31 +269,31 @@ public class AppOpsServiceTest { assertThat(loggedOps).isNull(); // Query op code that's not been logged - loggedOps = mAppOpsService.getOpsForPackage(mMyUid, mMyPackageName, + loggedOps = mAppOpsService.getOpsForPackage(mMyUid, sMyPackageName, new int[]{OP_WRITE_SMS}); assertThat(loggedOps).isNull(); } @Test public void testPackageRemoved() { - mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED); - mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName); + mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); + mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName); List loggedOps = getLoggedOps(); assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED); - mAppOpsService.packageRemoved(mMyUid, mMyPackageName); + mAppOpsService.packageRemoved(mMyUid, sMyPackageName); assertThat(getLoggedOps()).isNull(); } @Ignore("Historical appops are disabled in Android Q") @Test public void testPackageRemovedHistoricalOps() throws InterruptedException { - mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED); - mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName); + mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); + mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName); AppOpsManager.HistoricalOps historicalOps = new AppOpsManager.HistoricalOps(0, 15000); - historicalOps.increaseAccessCount(OP_READ_SMS, mMyUid, mMyPackageName, + historicalOps.increaseAccessCount(OP_READ_SMS, mMyUid, sMyPackageName, AppOpsManager.UID_STATE_PERSISTENT, 0, 1); mAppOpsService.addHistoricalOps(historicalOps); @@ -263,7 +306,7 @@ public class AppOpsServiceTest { }); // First, do a fetch to ensure it's written - mAppOpsService.getHistoricalOps(mMyUid, mMyPackageName, null, 0, Long.MAX_VALUE, 0, + mAppOpsService.getHistoricalOps(mMyUid, sMyPackageName, null, 0, Long.MAX_VALUE, 0, callback); latchRef.get().await(5, TimeUnit.SECONDS); @@ -271,11 +314,11 @@ public class AppOpsServiceTest { assertThat(resultOpsRef.get().isEmpty()).isFalse(); // Then, check it's deleted on removal - mAppOpsService.packageRemoved(mMyUid, mMyPackageName); + mAppOpsService.packageRemoved(mMyUid, sMyPackageName); latchRef.set(new CountDownLatch(1)); - mAppOpsService.getHistoricalOps(mMyUid, mMyPackageName, null, 0, Long.MAX_VALUE, 0, + mAppOpsService.getHistoricalOps(mMyUid, sMyPackageName, null, 0, Long.MAX_VALUE, 0, callback); latchRef.get().await(5, TimeUnit.SECONDS); @@ -285,8 +328,8 @@ public class AppOpsServiceTest { @Test public void testUidRemoved() { - mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED); - mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName); + mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED); + mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName); List loggedOps = getLoggedOps(); assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED); @@ -297,7 +340,7 @@ public class AppOpsServiceTest { private void setupProcStateTests() { // For the location proc state tests - mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, mMyPackageName, MODE_FOREGROUND); + mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, sMyPackageName, MODE_FOREGROUND); mAppOpsService.mConstants.FG_SERVICE_STATE_SETTLE_TIME = 0; mAppOpsService.mConstants.TOP_STATE_SETTLE_TIME = 0; mAppOpsService.mConstants.BG_STATE_SETTLE_TIME = 0; @@ -308,18 +351,18 @@ public class AppOpsServiceTest { setupProcStateTests(); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); // Second time to make sure that settle time is overcome Thread.sleep(50); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); } @@ -328,11 +371,11 @@ public class AppOpsServiceTest { setupProcStateTests(); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); } @@ -341,12 +384,12 @@ public class AppOpsServiceTest { setupProcStateTests(); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE_LOCATION); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isEqualTo(MODE_ALLOWED); } @@ -355,18 +398,18 @@ public class AppOpsServiceTest { setupProcStateTests(); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE); // Second time to make sure that settle time is overcome Thread.sleep(50); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); } @@ -375,30 +418,30 @@ public class AppOpsServiceTest { setupProcStateTests(); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE_LOCATION); // Second time to make sure that settle time is overcome Thread.sleep(50); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE_LOCATION); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isEqualTo(MODE_ALLOWED); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE); // Second time to make sure that settle time is overcome Thread.sleep(50); mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE); - assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName)) + assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName)) .isNotEqualTo(MODE_ALLOWED); } private List getLoggedOps() { - return mAppOpsService.getOpsForPackage(mMyUid, mMyPackageName, null /* all ops */); + return mAppOpsService.getOpsForPackage(mMyUid, sMyPackageName, null /* all ops */); } private void assertContainsOp(List loggedOps, int opCode, long minMillis, @@ -407,7 +450,7 @@ public class AppOpsServiceTest { boolean opLogged = false; for (PackageOps pkgOps : loggedOps) { assertWithMessage("Unexpected UID").that(mMyUid).isEqualTo(pkgOps.getUid()); - assertWithMessage("Unexpected package name").that(mMyPackageName).isEqualTo( + assertWithMessage("Unexpected package name").that(sMyPackageName).isEqualTo( pkgOps.getPackageName()); for (OpEntry opEntry : pkgOps.getOps()) { -- GitLab From 93320661ca9a23c7b38b3f166d0facf048f2a8a3 Mon Sep 17 00:00:00 2001 From: Ryan Mitchell Date: Wed, 15 Jan 2020 11:43:47 -0800 Subject: [PATCH 023/219] Fix potential double destroy of AssetManager Assume there is a XmlBlock [X] created by a AssetManager [A] ([A] will have mNumRefs = 2). After [A].close is called (mNumRefs = 1) and then both [X] and [A] are going to be GCed, if [A].finalize is called first (nativeDestroy), the later [X].finalize will invoke [A].xmlBlockGone that triggers the second nativeDestroy of [A] and leads to crash. By clearing the mObject in AssetManager.finalize, the decRefsLocked from other paths won't call nativeDestroy again. Bug: 144028297 Test: atest android.security.cts.AssetManagerTest Change-Id: Ia938502d2443f5a6de6a3cabdb7ce1d41d3ff6d1 Merged-In: Ia938502d2443f5a6de6a3cabdb7ce1d41d3ff6d1 --- .../android/content/res/AssetManager.java | 71 ++++++++++--------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index f0adcd6cfb3e..4a187cd774bb 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -68,24 +68,24 @@ public final class AssetManager implements AutoCloseable { private static final String TAG = "AssetManager"; private static final boolean localLOGV = false || false; - + private static final boolean DEBUG_REFS = false; - + private static final Object sSync = new Object(); /*package*/ static AssetManager sSystem = null; private final TypedValue mValue = new TypedValue(); private final long[] mOffsets = new long[2]; - + // For communication with native code. private long mObject; private StringBlock mStringBlocks[] = null; - + private int mNumRefs = 1; private boolean mOpen = true; private HashMap mRefStacks; - + /** * Create a new AssetManager containing only the basic system assets. * Applications will not generally use this method, instead retrieving the @@ -114,7 +114,7 @@ public final class AssetManager implements AutoCloseable { } } } - + private AssetManager(boolean isSystem) { if (DEBUG_REFS) { synchronized (this) { @@ -337,10 +337,10 @@ public final class AssetManager implements AutoCloseable { * Open an asset using ACCESS_STREAMING mode. This provides access to * files that have been bundled with an application as assets -- that is, * files placed in to the "assets" directory. - * + * * @param fileName The name of the asset to open. This name can be * hierarchical. - * + * * @see #open(String, int) * @see #list */ @@ -353,11 +353,11 @@ public final class AssetManager implements AutoCloseable { * read its contents. This provides access to files that have been bundled * with an application as assets -- that is, files placed in to the * "assets" directory. - * + * * @param fileName The name of the asset to open. This name can be * hierarchical. * @param accessMode Desired access mode for retrieving the data. - * + * * @see #ACCESS_UNKNOWN * @see #ACCESS_STREAMING * @see #ACCESS_RANDOM @@ -397,14 +397,14 @@ public final class AssetManager implements AutoCloseable { /** * Return a String array of all the assets at the given path. - * + * * @param path A relative path within the assets, i.e., "docs/home.html". - * + * * @return String[] Array of strings, one for each asset. These file * names are relative to 'path'. You can open the file by * concatenating 'path' and a name in the returned string (via * File) and passing that to open(). - * + * * @see #open */ public native final String[] list(String path) @@ -416,7 +416,7 @@ public final class AssetManager implements AutoCloseable { * provides direct access to all of the files included in an application * package (not only its assets). Applications should not normally use * this. - * + * * @see #open(String) */ public final InputStream openNonAsset(String fileName) throws IOException { @@ -429,7 +429,7 @@ public final class AssetManager implements AutoCloseable { * provides direct access to all of the files included in an application * package (not only its assets). Applications should not normally use * this. - * + * * @see #open(String, int) */ public final InputStream openNonAsset(String fileName, int accessMode) @@ -440,7 +440,7 @@ public final class AssetManager implements AutoCloseable { /** * {@hide} * Open a non-asset in a specified package. Not for use by applications. - * + * * @param cookie Identifier of the package to be opened. * @param fileName Name of the asset to retrieve. */ @@ -452,7 +452,7 @@ public final class AssetManager implements AutoCloseable { /** * {@hide} * Open a non-asset in a specified package. Not for use by applications. - * + * * @param cookie Identifier of the package to be opened. * @param fileName Name of the asset to retrieve. * @param accessMode Desired access mode for retrieving the data. @@ -477,7 +477,7 @@ public final class AssetManager implements AutoCloseable { throws IOException { return openNonAssetFd(0, fileName); } - + public final AssetFileDescriptor openNonAssetFd(int cookie, String fileName) throws IOException { synchronized (this) { @@ -492,20 +492,20 @@ public final class AssetManager implements AutoCloseable { } throw new FileNotFoundException("Asset absolute file: " + fileName); } - + /** * Retrieve a parser for a compiled XML file. - * + * * @param fileName The name of the file to retrieve. */ public final XmlResourceParser openXmlResourceParser(String fileName) throws IOException { return openXmlResourceParser(0, fileName); } - + /** * Retrieve a parser for a compiled XML file. - * + * * @param cookie Identifier of the package to be opened. * @param fileName The name of the file to retrieve. */ @@ -521,7 +521,7 @@ public final class AssetManager implements AutoCloseable { * {@hide} * Retrieve a non-asset as a compiled XML file. Not for use by * applications. - * + * * @param fileName The name of the file to retrieve. */ /*package*/ final XmlBlock openXmlBlockAsset(String fileName) @@ -533,7 +533,7 @@ public final class AssetManager implements AutoCloseable { * {@hide} * Retrieve a non-asset as a compiled XML file. Not for use by * applications. - * + * * @param cookie Identifier of the package to be opened. * @param fileName Name of the asset to retrieve. */ @@ -588,12 +588,18 @@ public final class AssetManager implements AutoCloseable { } } } - destroy(); + + synchronized (this) { + if (mObject != 0) { + destroy(); + mObject = 0; + } + } } finally { super.finalize(); } } - + public final class AssetInputStream extends InputStream { /** * @hide @@ -796,7 +802,7 @@ public final class AssetManager implements AutoCloseable { /*package*/ native final String getResourcePackageName(int resid); /*package*/ native final String getResourceTypeName(int resid); /*package*/ native final String getResourceEntryName(int resid); - + private native final long openAsset(String fileName, int accessMode); private final native ParcelFileDescriptor openAssetFd(String fileName, long[] outOffsets) throws IOException; @@ -856,17 +862,17 @@ public final class AssetManager implements AutoCloseable { * {@hide} */ public native static final int getGlobalAssetCount(); - + /** * {@hide} */ public native static final String getAssetAllocations(); - + /** * {@hide} */ public native static final int getGlobalAssetManagerCount(); - + private native final long newTheme(); private native final void deleteTheme(long theme); /*package*/ native static final void applyThemeStyle(long theme, int styleRes, boolean force); @@ -899,7 +905,7 @@ public final class AssetManager implements AutoCloseable { } mNumRefs++; } - + private final void decRefsLocked(long id) { if (DEBUG_REFS && mRefStacks != null) { mRefStacks.remove(id); @@ -907,8 +913,9 @@ public final class AssetManager implements AutoCloseable { mNumRefs--; //System.out.println("Dec streams: mNumRefs=" + mNumRefs // + " mReleased=" + mReleased); - if (mNumRefs == 0) { + if (mNumRefs == 0 && mObject != 0) { destroy(); + mObject = 0; } } } -- GitLab From f00d7fb3bd217bf236adb936febdb44e59250c78 Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Mon, 22 Jul 2019 14:25:14 -0700 Subject: [PATCH 024/219] Adding atoms for metrics logging Define the atom protos for UpdateEngineUpdateAttemptReported UpdateEngineSuccessfulUpdateReported The fields for both atoms are copied from the already reported Tron counters, except for the source fingerprint. By defining our own proto, we can have a better insight about each update events. It also makes the query easier without the server side work to correlate each counters. Sample output from testdrive shows: data { elapsed_timestamp_nanos: 64932607816092 atom { update_engine_update_attempt_reported { attempt_number: 1 payload_type: FULL duration_boottime_in_minutes: 0 duration_monotonic_in_minutes: 0 payload_size_mib: 510 attempt_result: METADATA_VERIFICATION_FAILED error_code: DOWNLOAD_METADATA_SIGNATURE_MISMATCH fingerprint: "google/walleye/walleye:R/MASTER/eng.xuncha.20190731.151212:userdebug/dev-keys" } } } Bug: 138253582 Bug: 137682371 Test: run statsd_testdrive and check events Merged-In: Ic502acc8831fe4da0b32a826171d10e9c0f9876d (cherry picked from commit 167c3db93401adccc703815a9d71ef057b17e780) Change-Id: Ifa57f23135b4cd63888df2b8f25650be133bb1de --- cmds/statsd/src/atoms.proto | 70 ++++++++++++++++ .../stats/otaupdate/updateengine_enums.proto | 82 +++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 core/proto/android/stats/otaupdate/updateengine_enums.proto diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 1ac37eadae0d..bf89759385cb 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -50,6 +50,7 @@ import "frameworks/base/core/proto/android/stats/intelligence/enums.proto"; import "frameworks/base/core/proto/android/stats/launcher/launcher.proto"; import "frameworks/base/core/proto/android/stats/location/location_enums.proto"; import "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.proto"; +import "frameworks/base/core/proto/android/stats/otaupdate/updateengine_enums.proto"; import "frameworks/base/core/proto/android/stats/storage/storage_enums.proto"; import "frameworks/base/core/proto/android/stats/style/style_enums.proto"; import "frameworks/base/core/proto/android/telecomm/enums.proto"; @@ -322,6 +323,8 @@ message Atom { ExclusionRectStateChanged exclusion_rect_state_changed = 223; BackGesture back_gesture_reported_reported = 224; + UpdateEngineUpdateAttemptReported update_engine_update_attempt_reported = 225; + UpdateEngineSuccessfulUpdateReported update_engine_successful_update_reported = 226; AppCompatibilityChangeReported app_compatibility_change_reported = 228 [(allow_from_any_uid) = true]; PerfettoUploaded perfetto_uploaded = @@ -6983,3 +6986,70 @@ message VmsClientStats { optional int64 dropped_bytes = 9; optional int64 dropped_packets = 10; } + +/** + * Information about an OTA update attempt by update_engine. + * Logged from platform/system/update_engine/metrics_reporter_android.cc + */ +message UpdateEngineUpdateAttemptReported { + // The number of attempts for the update engine to apply a given payload. + optional int32 attempt_number = 1; + + optional android.stats.otaupdate.PayloadType payload_type = 2; + + // The total time in minutes for the update engine to apply a given payload. + // The time is calculated by calling clock_gettime() / CLOCK_BOOTTIME; and + // it's increased when the system is sleeping. + optional int32 duration_boottime_in_minutes = 3; + + // The total time in minutes for the update engine to apply a given payload. + // The time is calculated by calling clock_gettime() / CLOCK_MONOTONIC_RAW; + // and it's not increased when the system is sleeping. + optional int32 duration_monotonic_in_minutes = 4; + + // The size of the payload in MiBs. + optional int32 payload_size_mib = 5; + + // The attempt result reported by the update engine for an OTA update. + optional android.stats.otaupdate.AttemptResult attempt_result = 6; + + // The error code reported by the update engine after an OTA update attempt + // on A/B devices. + optional android.stats.otaupdate.ErrorCode error_code = 7; + + // The build fingerprint of the source system. The value is read from a + // system property when the device takes the update. e.g. + // Android/aosp_sailfish/sailfish:10/QP1A.190425.004/5507117:userdebug/test-keys + optional string source_fingerprint = 8; +} + +/** + * Information about all the attempts the device make before finishing the + * successful update. + * Logged from platform/system/update_engine/metrics_reporter_android.cc + */ +message UpdateEngineSuccessfulUpdateReported { + // The number of attempts for the update engine to apply the payload for a + // successful update. + optional int32 attempt_count = 1; + + optional android.stats.otaupdate.PayloadType payload_type = 2; + + optional int32 payload_size_mib = 3; + + // The total number of bytes downloaded by update_engine since the last + // successful update. + optional int32 total_bytes_downloaded_mib = 4; + + // The ratio in percentage of the over-downloaded bytes compared to the + // total bytes needed to successfully install the update. e.g. 200 if we + // download 200MiB in total for a 100MiB package. + optional int32 download_overhead_percentage = 5; + + // The total time in minutes for the update engine to apply the payload for a + // successful update. + optional int32 total_duration_minutes = 6; + + // The number of reboot of the device during a successful update. + optional int32 reboot_count = 7; +} diff --git a/core/proto/android/stats/otaupdate/updateengine_enums.proto b/core/proto/android/stats/otaupdate/updateengine_enums.proto new file mode 100644 index 000000000000..a6e9919ba606 --- /dev/null +++ b/core/proto/android/stats/otaupdate/updateengine_enums.proto @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2019 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. + */ + +syntax = "proto2"; +package android.stats.otaupdate; + +// The payload type of an OTA update attempt on A/B devices. +enum PayloadType { + FULL = 10000; + DELTA = 10001; +} + +// The attempt result reported by the update engine for an OTA update. +enum AttemptResult { + UPDATE_SUCCEEDED = 10000; + INTERNAL_ERROR = 10001; + PAYLOAD_DOWNLOAD_ERROR = 10002; + METADATA_MALFORMED = 10003; + OPERATION_MALFORMED = 10004; + OPERATION_EXECUTION_ERROR = 10005; + METADATA_VERIFICATION_FAILED = 10006; + PAYLOAD_VERIFICATION_FAILED = 10007; + VERIFICATION_FAILED = 10008; + POSTINSTALL_FAILED = 10009; + ABNORMAL_TERMINATION = 10010; + UPDATE_CANCELED = 10011; + UPDATE_SUCCEEDED_NOT_ACTIVE = 10012; +} + +// The error code reported by the update engine after an OTA update attempt +// on A/B devices. More details in system/update_engine/common/error_code.h +enum ErrorCode { + SUCCESS = 10000; + ERROR = 10001; + FILESYSTEM_COPIER_ERROR = 10004; + POST_INSTALL_RUNNER_ERROR = 10005; + PAYLOAD_MISMATCHED_TYPE_ERROR = 10006; + INSTALL_DEVICE_OPEN_ERROR = 10007; + KERNEL_DEVICE_OPEN_ERROR = 10008; + DOWNLOAD_TRANSFER_ERROR = 10009; + PAYLOAD_HASH_MISMATCH_ERROR = 10010; + PAYLOAD_SIZE_MISMATCH_ERROR = 10011; + DOWNLOAD_PAYLOAD_VERIFICATION_ERROR = 10012; + DOWNLOAD_NEW_PARTITION_INFO_ERROR = 10013; + DOWNLOAD_WRITE_ERROR = 10014; + NEW_ROOTFS_VERIFICATION_ERROR = 10015; + SIGNED_DELTA_PAYLOAD_EXPECTED_ERROR = 10017; + DOWNLOAD_PAYLOAD_PUB_KEY_VERIFICATION_ERROR = 10018; + DOWNLOAD_STATE_INITIALIZATION_ERROR = 10020; + DOWNLOAD_INVALID_METADATA_MAGIC_STRING = 10021; + DOWNLOAD_SIGNATURE_MISSING_IN_MANIFEST = 10022; + DOWNLOAD_MANIFEST_PARSE_ERROR = 10023; + DOWNLOAD_METADATA_SIGNATURE_ERROR = 10024; + DOWNLOAD_METADATA_SIGNATURE_VERIFICATION_ERROR = 10025; + DOWNLOAD_METADATA_SIGNATURE_MISMATCH = 10026; + DOWNLOAD_OPERATION_HASH_VERIFICATION_ERROR = 10027; + DOWNLOAD_OPERATION_EXECUTION_ERROR = 10028; + DOWNLOAD_OPERATION_HASH_MISMATCH = 10029; + DOWNLOAD_INVALID_METADATA_SIZE = 10032; + DOWNLOAD_INVALID_METADATA_SIGNATURE = 10033; + DOWNLOAD_OPERATION_HASH_MISSING_ERROR = 10038; + DOWNLOAD_METADATA_SIGNATURE_MISSING_ERROR = 10039; + UNSUPPORTED_MAJOR_PAYLOAD_VERSION = 10044; + UNSUPPORTED_MINOR_PAYLOAD_VERSION = 10045; + FILESYSTEM_VERIFIER_ERROR = 10047; + USER_CANCELED = 10048; + PAYLOAD_TIMESTAMP_ERROR = 10051; + UPDATED_BUT_NOT_ACTIVE = 10052; +} -- GitLab From 77e6f5ff3ef505d5c659e074413135314e8ceed5 Mon Sep 17 00:00:00 2001 From: Joanne Chung Date: Mon, 19 Aug 2019 14:48:05 +0800 Subject: [PATCH 025/219] Change permissionLevel of ACCESS_SHORTCUTS and UNLIMITED_SHORTCUTS_API_CALLS ACCESS_SHORTCUTS and UNLIMITED_SHORTCUTS_API_CALLS should be granted to an app predictor rather than a text classifier. Bug: 139523153 Test: atest CtsPermission2TestCases Change-Id: I12360b5d5ba3c75bb2dfffd86bd6069b75fbdb53 (cherry picked from commit b6a7851271184b2177a2c5f70163d2691ca26a06) --- core/res/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index aa5141d98cc3..5778d02737b9 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -4467,12 +4467,12 @@ + android:protectionLevel="signature|appPredictor" /> + android:protectionLevel="signature|appPredictor" /> -- GitLab From 0a8a1e9d40a3cdff06150c43c623fa4c415226b6 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Thu, 4 Jul 2019 16:10:08 +0800 Subject: [PATCH 026/219] Fix potential double destroy of AssetManager Assume there is a XmlBlock [X] created by a AssetManager [A] ([A] will have mNumRefs = 2). After [A].close is called (mNumRefs = 1) and then both [X] and [A] are going to be GCed, if [A].finalize is called first (nativeDestroy), the later [X].finalize will invoke [A].xmlBlockGone that triggers the second nativeDestroy of [A] and leads to crash. By clearing the mObject in AssetManager.finalize, the decRefsLocked from other paths won't call nativeDestroy again. Bug: 136721562 Bug: 144028297 Test: atest AssetManagerTest Test: Build and install CorePerfTests adb shell am instrument -w -r --no-hidden-api-checks -e class \ android.app.ResourcesPerfTest#getLayoutAndTravese,android.graphics.perftests.RenderNodePerfTest \ com.android.perftests.core/androidx.test.runner.AndroidJUnitRunner Change-Id: Ia938502d2443f5a6de6a3cabdb7ce1d41d3ff6d1 Merged-In: Ia938502d2443f5a6de6a3cabdb7ce1d41d3ff6d1 --- core/java/android/content/res/AssetManager.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 289534273d13..4ddaa9b4cdf8 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -1050,8 +1050,11 @@ public final class AssetManager implements AutoCloseable { } } - if (mObject != 0) { - nativeDestroy(mObject); + synchronized (this) { + if (mObject != 0) { + nativeDestroy(mObject); + mObject = 0; + } } } -- GitLab From 6f99815dfd949c6208318e4c849de30b6c959dc9 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 18 Jan 2020 10:26:52 -0800 Subject: [PATCH 027/219] Import translations. DO NOT MERGE Change-Id: I38cd73f81ea8fd45fa632a6d3f210cbdaed3361b Auto-generated-cl: translation import --- core/res/res/values-ar/strings.xml | 8 ++++---- core/res/res/values-da/strings.xml | 2 +- core/res/res/values-gu/strings.xml | 4 ++-- core/res/res/values-hy/strings.xml | 2 +- core/res/res/values-ky/strings.xml | 8 ++++---- core/res/res/values-mk/strings.xml | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 5b613d7677fe..954ffd3b50d5 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -334,7 +334,7 @@ "التحكم في تكبير الشاشة" "يمكنك التحكّم في مستوى تكبير/تصغير الشاشة وتحديد الموضع." "تنفيذ إيماءات" - "يمكن النقر والتمرير بسرعة والتصغير وتنفيذ إيماءات أخرى." + "يمكن النقر والتمرير بسرعة والتصغير أو التكبير بإصبعين وتنفيذ إيماءات أخرى." "إيماءات بصمات الإصبع" "يمكن أن تلتقط الإيماءات التي تم تنفيذها على جهاز استشعار بصمات الإصبع في الجهاز." "إيقاف شريط الحالة أو تعديله" @@ -680,7 +680,7 @@ "التحكّم في طريقة ووقت قفل الشاشة" "محو جميع البيانات" "يمكنك محو بيانات الجهاز اللوحي بدون تحذير، وذلك عبر إجراء إعادة الضبط بحسب بيانات المصنع." - "محو بيانات التلفزيون بدون تحذير من خلال إجراء إعادة ضبط البيانات على إعدادات المصنع." + "محو بيانات التلفزيون بدون تحذير من خلال إجراء إعادة ضبط البيانات على الإعدادات الأصلية." "محو بيانات الهاتف بدون تحذير، وذلك من خلال إعادة ضبط البيانات على الإعدادات الأصلية" "محو بيانات المستخدم" "لمحو بيانات هذا المستخدم على هذا الجهاز اللوحي بدون تحذير." @@ -1455,7 +1455,7 @@ "‏انقر لإيقاف تصحيح أخطاء الجهاز عبر USB." "‏اختيار إيقاف تصحيح أخطاء USB." "تم تفعيل وضع \"مفعّل الاختبار\"" - "يمكنك إجراء إعادة ضبط على إعدادات المصنع لإيقاف وضع \"مفعِّل اختبار\"." + "يمكنك إجراء إعادة ضبط على الإعدادات الأصلية لإيقاف وضع \"مفعِّل اختبار\"." "‏السوائل والشوائب في منفذ USB" "‏تمّ إيقاف منفذ USB تلقائيًا. انقُر لمعرفة المزيد من المعلومات." "‏مسموح باستخدام منفذ USB" @@ -1529,7 +1529,7 @@ "للسماح لتطبيق ما بطلب حذف الحِزم." "طلب تجاهل تحسينات البطارية" "للسماح للتطبيق بطلب الإذن لتجاهل تحسينات البطارية في هذا التطبيق." - "اضغط مرتين للتحكم في التكبير/التصغير" + "اضغط مرتين للتحكم في التكبير أو التصغير" "تعذرت إضافة أداة." "تنفيذ" "بحث" diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 1f78ba3bc3c7..f4e4f7377cbf 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -368,7 +368,7 @@ "Denne app kan vises oven på andre apps" "Denne app kan vises oven på andre apps eller andre dele af skærmen. Dette kan forstyrre den normale brug af appen og ændre visningen af andre apps." "kør i baggrunden" - "Denne app kan køre i baggrunden. Dette kan aflade batteriet hurtigere." + "Denne app kan køre i baggrunden. Dette kan dræne batteriet hurtigere." "brug data i baggrunden" "Denne app kan bruge data i baggrunden. Dette kan øge dataforbruget." "sørge for, at appen altid kører" diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index fe6e07610a8e..853d27f2c84b 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -246,7 +246,7 @@ "એરપ્લેન મોડ" "એરપ્લેન મોડ ચાલુ છે." "એરપ્લેન મોડ બંધ છે." - "સેટિંગ્સ" + "સેટિંગ" "સહાય" "વૉઇસ સહાય" "લૉકડાઉન" @@ -1613,7 +1613,7 @@ "ઉપકરણ સાથે કનેક્ટ કરો" "ઉપકરણ પર સ્ક્રીન કાસ્ટ કરો" "ઉપકરણો માટે શોધી રહ્યું છે…" - "સેટિંગ્સ" + "સેટિંગ" "ડિસ્કનેક્ટ કરો" "સ્કેન કરી રહ્યું છે..." "કનેક્ટ કરી રહ્યું છે..." diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index c94afd88425a..401e27428224 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -1923,7 +1923,7 @@ "Հպեք՝ ֆայլերը տեսնելու համար" "Ամրացնել" "Ապամրացնել" - "Հավելվածի տվյալներ" + "Հավելվածի մասին" "−%1$s" "Ցուցադրական օգտատերը գործարկվում է…" "Սարաքը վերակայվում է…" diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index c2ab5705905f..161e4e6cb8f0 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -1452,7 +1452,7 @@ "Аткаруу" "%s менен\nномерди терүү" "%s менен\nбайланыш түзүү" - "Төмөнкү бир же бир нече колдонмо каттоо эсебиңизге азыр жана кийинчерээк кирүү мүмкүнчүлүгүн сурап жатат." + "Төмөнкү бир же бир нече колдонмо аккаунтуңузга азыр жана кийинчерээк кирүү мүмкүнчүлүгүн сурап жатат." "Бул өтүнүчкө уруксат бересизби?" "Жетки талабы" "Уруксат берүү" @@ -1663,9 +1663,9 @@ "Сиз планшетиңизди %d жолу ийгиликсиз бөгөттөн чыгаруу аракетин кылдыңыз. Планшет баштапкы абалына кайтарылат." "Сыналгыңыздын кулпусун ачууда %d_0 жолу туура эмес аракет кылдыңыз. Сыналгыңыз баштапкы абалга келтирилет." "Сиз телефонуңузду %d жолу ийгиликсиз бөгөттөн чыгаруу аракетин кылдыңыз. Телефон баштапкы абалына кайтарылат." - "Графикалык ачкычты %1$d жолу туура эмес көрсөттүңүз. %2$d жолу туура эмес көрсөтүлгөндөн кийин, планшетиңиздин кулпусун ачуу үчүн Google каттоо эсебиңизге кирүүгө туура келет.\n\n%3$d секундадан кийин кайталап көрсөңүз болот." - "Кулпуну ачуу үлгүсүн %1$d жолу туура эмес тарттыңыз. Дагы %2$d жолу туура эмес тартсаңыз, сыналгыңыздын кулпусун электрондук каттоо эсебиңизге кирип ачууга туура келет.\n\n %3$d секундадан кийин дагы аракет кылып көрүңүз." - "Графикалык ачкычты %1$d жолу туура эмес көрсөттүңүз. %2$d жолу туура эмес көрсөтүлгөндөн кийин, телефондун кулпусун ачуу үчүн Google каттоо эсебиңизге кирүүгө туура келет.\n\n%3$d секундадан кийин кайталап көрсөңүз болот." + "Графикалык ачкычты %1$d жолу туура эмес көрсөттүңүз. %2$d жолу туура эмес көрсөтүлгөндөн кийин, планшетиңиздин кулпусун ачуу үчүн Google аккаунтуңузга кирүүгө туура келет.\n\n%3$d секундадан кийин кайталап көрсөңүз болот." + "Кулпуну ачуу үлгүсүн %1$d жолу туура эмес тарттыңыз. Дагы %2$d жолу туура эмес тартсаңыз, сыналгыңыздын кулпусун электрондук аккаунтуңузга кирип ачууга туура келет.\n\n %3$d секундадан кийин дагы аракет кылып көрүңүз." + "Графикалык ачкычты %1$d жолу туура эмес көрсөттүңүз. %2$d жолу туура эмес көрсөтүлгөндөн кийин, телефондун кулпусун ачуу үчүн Google аккаунтуңузга кирүүгө туура келет.\n\n%3$d секундадан кийин кайталап көрсөңүз болот." " — " "Алып салуу" "Сунушталган деңгээлден да катуулатып уккуңуз келеби?\n\nМузыканы узакка чейин катуу уксаңыз, угууңуз начарлап кетиши мүмкүн." diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index fb578b91159a..af73a792ddfd 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -1515,7 +1515,7 @@ "Избриши ги ставките" "Врати ги избришаните" "Не прави ништо засега" - "Избери сметка" + "Изберете сметка" "Додај сметка" "Додај сметка" "Зголеми" -- GitLab From 5b94476ce6bbf93f5ac4216bf70816f19a57abad Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sun, 19 Jan 2020 10:32:43 -0800 Subject: [PATCH 028/219] Import translations. DO NOT MERGE Change-Id: I1df70b7205ca4090d6a9978050049d378fff7cbc Auto-generated-cl: translation import --- packages/SystemUI/res/values-ar/strings.xml | 2 +- packages/SystemUI/res/values-gu/strings.xml | 10 +++++----- packages/SystemUI/res/values-kn/strings.xml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 5998c56c33b0..9548551d6ba6 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -130,7 +130,7 @@ "جارٍ البحث عن وجهك…" "رمز الوجه" "زر تكبير/تصغير للتوافق." - "استخدام التكبير/التصغير لتحويل شاشة صغيرة إلى شاشة أكبر" + "استخدام التكبير أو التصغير لتحويل شاشة صغيرة إلى شاشة أكبر" "تم توصيل البلوتوث." "تم فصل البلوتوث." "ليست هناك بطارية." diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 921c81d72a29..d4fdfb19e3a3 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -37,7 +37,7 @@ "બૅટરી સેવર વિશે" "ચાલુ કરો" "બૅટરી સેવર ચાલુ કરો" - "સેટિંગ્સ" + "સેટિંગ" "વાઇ-ફાઇ" "ઑટો રોટેટ સ્ક્રીન" "મ્યૂટ કરો" @@ -217,7 +217,7 @@ "નોટિફિકેશન શેડ." "ઝડપી સેટિંગ્સ." "લૉક સ્ક્રીન." - "સેટિંગ્સ" + "સેટિંગ" "ઝલક." "કાર્ય લૉક સ્ક્રીન" "બંધ કરો" @@ -288,7 +288,7 @@ "%1$s: %2$s" "સૂચનાઓની સેટિંગ્સ" - "%s સેટિંગ્સ" + "%s સેટિંગ" "સ્ક્રીન આપમેળે ફરશે." "સ્ક્રીન લેન્ડસ્કેપ ઓરિએન્ટેશનમાં લૉક કરેલ છે." "સ્ક્રીન પોટ્રેટ ઓરિએન્ટેશનમાં લૉક કરેલ છે." @@ -326,7 +326,7 @@ "મીડિયા ઉપકરણ" "RSSI" "ફક્ત કટોકટીના કૉલ્સ" - "સેટિંગ્સ" + "સેટિંગ" "સમય" "હું" "વપરાશકર્તા" @@ -876,7 +876,7 @@ "સામાન્ય સંદેશા" "સ્ટોરેજ" "હિન્ટ" - "ઝટપટ ઍપ્લિકેશનો" + "ઝટપટ ઍપ્લિકેશન" "%1$s ચાલી રહી છે" "ઍપ ઇન્સ્ટૉલ કર્યા વિના ખુલી જાય છે." "ઍપ ઇન્સ્ટૉલ કર્યા વિના ખુલી જાય છે. વધુ જાણવા માટે ટૅપ કરો." diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 92e373142d6d..712dca2748c5 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -876,7 +876,7 @@ "ಸಾಮಾನ್ಯ ಸಂದೇಶಗಳು" "ಸಂಗ್ರಹಣೆ" "ಸುಳಿವುಗಳು" - "ತತ್‌ಕ್ಷಣ ಆಪ್‌ಗಳು" + "ಇನ್‌ಸ್ಟಂಟ್ ಆ್ಯಪ್‌ಗಳು" "%1$s ರನ್ ಆಗುತ್ತಿದೆ" "ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡದೆ ಆ್ಯಪ್‌ ತೆರೆಯಲಾಗಿದೆ." "ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡದೆ ಆ್ಯಪ್‌ ತೆರೆಯಲಾಗಿದೆ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ." -- GitLab From 67c89f3e5fa3f3abd81765e00daa3ddaf7ab14b6 Mon Sep 17 00:00:00 2001 From: Mohammad Samiul Islam Date: Tue, 14 Jan 2020 18:33:39 +0000 Subject: [PATCH 029/219] Handle ParcelableException instead of crashing system server Unhandled exception is causing system server to crash. Bug: 146790672 Test: builds successfully Change-Id: Ibfe53ee0309dcec6fd3b24f8b67fcb78f5ce7fd5 Merged-In: Ibfe53ee0309dcec6fd3b24f8b67fcb78f5ce7fd5 --- .../com/android/server/pm/StagingManager.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 9c87c748f867..9913c9846a17 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -40,6 +40,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.ParcelFileDescriptor; +import android.os.ParcelableException; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; @@ -403,29 +404,28 @@ public class StagingManager { } else { params.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION; } - int apkSessionId = mPi.createSession( - params, originalSession.getInstallerPackageName(), - 0 /* UserHandle.SYSTEM */); - PackageInstallerSession apkSession = mPi.getSession(apkSessionId); - try { + int apkSessionId = mPi.createSession( + params, originalSession.getInstallerPackageName(), + 0 /* UserHandle.SYSTEM */); + PackageInstallerSession apkSession = mPi.getSession(apkSessionId); apkSession.open(); for (String apkFilePath : apkFilePaths) { File apkFile = new File(apkFilePath); ParcelFileDescriptor pfd = ParcelFileDescriptor.open(apkFile, ParcelFileDescriptor.MODE_READ_ONLY); - long sizeBytes = pfd.getStatSize(); + long sizeBytes = (pfd == null) ? -1 : pfd.getStatSize(); if (sizeBytes < 0) { Slog.e(TAG, "Unable to get size of: " + apkFilePath); return null; } apkSession.write(apkFile.getName(), 0, sizeBytes, pfd); } - } catch (IOException e) { + return apkSession; + } catch (IOException | ParcelableException e) { Slog.e(TAG, "Failure to install APK staged session " + originalSession.sessionId, e); return null; } - return apkSession; } private boolean commitApkSession(@NonNull PackageInstallerSession apkSession, -- GitLab From c8a7c2bd74b00bfda55788d63303ef693d186e36 Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Tue, 21 Jan 2020 11:25:10 -0500 Subject: [PATCH 030/219] Do not destroy CustomTile when in QSCustomizer Before this CL, TileQueryHelper would create CustomTile when creating tiles for current tiles. This caused them to be destroyed after taking the information and being removed from the maps in TileServices. In this CL, current CustomTile are fixed to only being created by addPackageTiles which knows what to do. Fixes: 148002667 Fixes: 127508346 Test: manual Test: atest TileQueryHelperTest Change-Id: I2c4d3ce6c31449f20670982dad334019cc25469c Merged-In: I2c4d3ce6c31449f20670982dad334019cc25469c (cherry picked from commit 198b0b6ef1e15ca040a67c48f232cdd6efa6c081) --- .../systemui/qs/customize/TileQueryHelper.java | 4 +++- .../qs/customize/TileQueryHelperTest.java | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java index 70062492c162..7a8f497041c1 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java @@ -103,7 +103,9 @@ public class TileQueryHelper { final ArrayList tilesToAdd = new ArrayList<>(); for (String spec : possibleTiles) { - // Only add current and stock tiles that can be created from QSFactoryImpl + // Only add current and stock tiles that can be created from QSFactoryImpl. + // Do not include CustomTile. Those will be created by `addPackageTiles`. + if (spec.startsWith(CustomTile.PREFIX)) continue; final QSTile tile = host.createTile(spec); if (tile == null) { continue; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java index 9e226f693622..2fed441c861e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -79,12 +80,14 @@ public class TileQueryHelperTest extends SysuiTestCase { private static final Set FACTORY_TILES = new ArraySet<>(); private static final String TEST_PKG = "test_pkg"; private static final String TEST_CLS = "test_cls"; + private static final String CUSTOM_TILE = "custom(" + TEST_PKG + "/" + TEST_CLS + ")"; static { FACTORY_TILES.addAll(Arrays.asList( new String[]{"wifi", "bt", "cell", "dnd", "inversion", "airplane", "work", "rotation", "flashlight", "location", "cast", "hotspot", "user", "battery", "saver", "night", "nfc"})); + FACTORY_TILES.add(CUSTOM_TILE); } @Mock @@ -227,6 +230,18 @@ public class TileQueryHelperTest extends SysuiTestCase { assertFalse(specs.contains("other")); } + @Test + public void testCustomTileNotCreated() { + Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.QS_TILES, + CUSTOM_TILE); + mTileQueryHelper.queryTiles(mQSTileHost); + + mBGLooper.processAllMessages(); + waitForIdleSync(Dependency.get(Dependency.MAIN_HANDLER)); + + verify(mQSTileHost, never()).createTile(CUSTOM_TILE); + } + @Test public void testThirdPartyTilesInactive() { ResolveInfo resolveInfo = new ResolveInfo(); -- GitLab From c718e54c27103ba690d99266b1d2f63fbe7f163d Mon Sep 17 00:00:00 2001 From: Michael Groover Date: Wed, 8 Jan 2020 17:42:48 -0800 Subject: [PATCH 031/219] Ensure adb key store is instantiated before revoking grants If adb is not enabled on a device then the adb key store is not instantiated when the AdbDebuggingManager's handler is started as in most cases it will not be needed. However if the user attempts to revoke any previous adb grants when a device is booted with adb disabled it will result in a NPE. This commit ensures the key store is instantiated before attempting to revoke authorizations. Test: atest AdbDebuggingManagerTest Test: Manually invoked 'Revoke USB debugging authorizations' after a boot with adb disabled. Fixes: 145790817 Change-Id: Id00e531c18412be009a211eec80a72867659608f Merged-In: Id00e531c18412be009a211eec80a72867659608f --- .../server/adb/AdbDebuggingManager.java | 5 ++++ .../server/adb/AdbDebuggingManagerTest.java | 24 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java index 4b48ef917744..143474bd5c94 100644 --- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java +++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java @@ -413,6 +413,11 @@ public class AdbDebuggingManager { case MESSAGE_ADB_CLEAR: { Slog.d(TAG, "Received a request to clear the adb authorizations"); mConnectedKeys.clear(); + // If the key store has not yet been instantiated then do so now; this avoids + // the unnecessary creation of the key store when adb is not enabled. + if (mAdbKeyStore == null) { + mAdbKeyStore = new AdbKeyStore(); + } mAdbKeyStore.deleteKeyStore(); cancelJobToUpdateAdbKeyStore(); break; diff --git a/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java b/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java index d4182f3d31e2..5a1ad8655ab0 100644 --- a/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java @@ -672,6 +672,30 @@ public final class AdbDebuggingManagerTest { connectionTime2, mKeyStore.getLastConnectionTime(TEST_KEY_2)); } + @Test + public void testClearAuthorizationsBeforeAdbEnabled() throws Exception { + // The adb key store is not instantiated until adb is enabled; however if the user attempts + // to clear the adb authorizations when adb is disabled after a boot a NullPointerException + // was thrown as deleteKeyStore is invoked against the key store. This test ensures the + // key store can be successfully cleared when adb is disabled. + mHandler = mManager.new AdbDebuggingHandler(FgThread.get().getLooper()); + + clearKeyStore(); + } + + @Test + public void testClearAuthorizationsDeletesKeyFiles() throws Exception { + mAdbKeyFile.createNewFile(); + mAdbKeyXmlFile.createNewFile(); + + clearKeyStore(); + + assertFalse("The adb key file should have been deleted after revocation of the grants", + mAdbKeyFile.exists()); + assertFalse("The adb xml key file should have been deleted after revocation of the grants", + mAdbKeyXmlFile.exists()); + } + /** * Runs an adb test with the provided configuration. * -- GitLab From 4cc695ce4456b02ccba626f95184804a2d35c45c Mon Sep 17 00:00:00 2001 From: Zhen Zhang Date: Mon, 4 Nov 2019 17:03:09 -0800 Subject: [PATCH 032/219] Update mOnDissmissRunnable when Notification gets updated. mOnDissmissRunnable holds reference to StatusBarNotification instance. We should update it when notification gets updated. Bug: 141699084 Test: atest NotifCollectionTest, NotificationDataTest, NotificationEntryManagerTest Change-Id: Iaa4306eedeb144dba480c551808dd431e096314c Merged-In: Iaa4306eedeb144dba480c551808dd431e096314c (cherry picked from commit 52d82f59eab69c944e5e2cdb5f06e91960b76f01) --- .../notification/collection/NotificationRowBinderImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java index 247c31fc80a3..240d567b78c9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java @@ -137,6 +137,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { entry.updateIcons(mContext, sbn); entry.reset(); updateNotification(entry, pmUser, sbn, entry.getRow()); + entry.getRow().setOnDismissRunnable(onDismissRunnable); } else { entry.createIcons(mContext, sbn); new RowInflaterTask().inflate(mContext, parent, entry, -- GitLab From a9feb4602fb611522c4ad4d9b917b0bec1ef15d4 Mon Sep 17 00:00:00 2001 From: Mayank Garg Date: Fri, 10 Jan 2020 00:47:08 -0800 Subject: [PATCH 033/219] Adding option in global setting to control the display message during user switch Bug: 145915635 Bug: 145132885 Test: adb shell settings put global android.car.ENABLE_USER_SWITCH_DEVELOPER_MESSAGE true Merged-In: I70c72d7d74c72a78d919ae34906b6f7b96466ad1 Change-Id: I70c72d7d74c72a78d919ae34906b6f7b96466ad1 (cherry picked from commit e12de0beb45d07aaaaec923e9f009130d5053d2f) --- .../server/am/CarUserSwitchingDialog.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java index ebfc2a011e88..60754fbc5cd3 100644 --- a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java +++ b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java @@ -33,6 +33,7 @@ import android.graphics.RectF; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.UserManager; +import android.provider.Settings; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; @@ -81,8 +82,19 @@ final class CarUserSwitchingDialog extends UserSwitchingDialog { .setImageDrawable(drawable); } - ((TextView) view.findViewById(R.id.user_loading)) - .setText(res.getString(R.string.car_loading_profile)); + TextView msgView = view.findViewById(R.id.user_loading); + + // TODO(b/145132885): use constant from CarSettings + boolean showInfo = "true".equals(Settings.Global.getString( + getContext().getContentResolver(), + "android.car.ENABLE_USER_SWITCH_DEVELOPER_MESSAGE")); + + if (showInfo) { + msgView.setText(res.getString(R.string.car_loading_profile) + " user\n(from " + + mOldUser.id + " to " + mNewUser.id + ")"); + } else { + msgView.setText(res.getString(R.string.car_loading_profile)); + } setView(view); } -- GitLab From eb4f716bf3a0ee3ac8015cde48305aeb82724039 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Thu, 7 Nov 2019 11:37:18 -0500 Subject: [PATCH 034/219] Only suspend package from system or shell Test: manual Bug: 148059175 Change-Id: I50ee768e792266ad2091f1913168e89d5d1463ed Merged-In: I50ee768e792266ad2091f1913168e89d5d1463ed (cherry picked from commit 1c943a2670c1ff499669b42ef72dcd9f07db08c3) (cherry picked from commit adc39de3a148a2058d63bd7a1b8b71ee0a3524ac) --- .../android/server/notification/NotificationManagerService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index b1ea47c6f3b0..06b7c4d45c71 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -7101,6 +7101,7 @@ public class NotificationManagerService extends SystemService { @VisibleForTesting protected void simulatePackageSuspendBroadcast(boolean suspend, String pkg) { + checkCallerIsSystemOrShell(); // only use for testing: mimic receive broadcast that package is (un)suspended // but does not actually (un)suspend the package final Bundle extras = new Bundle(); -- GitLab From 5c31a5c18db13ecb4018b69ea1af6568dd36251e Mon Sep 17 00:00:00 2001 From: Heemin Seog Date: Fri, 24 Jan 2020 16:26:38 -0800 Subject: [PATCH 035/219] DO NOT MERGE Only set the LAYOUT flags if the window is fullscreen This addresses an issue where toasts will be hidden due to the setting of the LAYOUT_HIDE_NAVIGATION flag. Bug: 148180738 Test: manual (adb shell settings put global policy_control "immersive.navigation=*" then try to show a toast with gravity top) Change-Id: Ic47edc5423c4daf373fc3a8bfc30af15cadd6d90 --- .../core/java/com/android/server/wm/PolicyControl.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/PolicyControl.java b/services/core/java/com/android/server/wm/PolicyControl.java index 4c8ce9ebb72c..87c34908d043 100644 --- a/services/core/java/com/android/server/wm/PolicyControl.java +++ b/services/core/java/com/android/server/wm/PolicyControl.java @@ -67,15 +67,19 @@ class PolicyControl { : (attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility); if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) { vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY - | View.SYSTEM_UI_FLAG_FULLSCREEN - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + | View.SYSTEM_UI_FLAG_FULLSCREEN; + if (attrs.isFullscreen()) { + vis |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + } vis &= ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.STATUS_BAR_TRANSLUCENT); } if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(attrs)) { vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; + if (attrs.isFullscreen()) { + vis |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; + } vis &= ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.NAVIGATION_BAR_TRANSLUCENT); } -- GitLab From a3acf85a3badf1caacd09d83d0047c3a32358686 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Fri, 8 Nov 2019 12:16:28 -0800 Subject: [PATCH 036/219] GraphicsEnv: refactor to unify the debuggable logic By default, PR_SET_DUMPABLE is 0 for zygote spawned apps, except in the following circumstances: 1. ro.debuggable=1 (global debuggable enabled, i.e., userdebug or eng builds). 2. android:debuggable="true" in the manifest for an individual application. 3. An app which explicitly calls prctl(PR_SET_DUMPABLE, 1). 4. GraphicsEnv calls prctl(PR_SET_DUMPABLE, 1) in the presence of in the application manifest. So checking both ro.debuggable=1 and PR_GET_DUMPABLE is redundant. Bug: b/144186877, b/148566223 Test: CtsAngleIntegrationHostTestCases Test: CtsRootlessGpuDebugHostTest Change-Id: Ica49254df2c7c090808411935cdeb8efd4e3cb51 Merged-In: Ica49254df2c7c090808411935cdeb8efd4e3cb51 (cherry picked from commit 097a3062b93045d9980d83f903bd4b781505522b) --- core/java/android/os/GraphicsEnvironment.java | 25 +++++-------------- core/jni/android_os_GraphicsEnvironment.cpp | 6 ++--- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index 7a70e93b69d5..31cdf42e3a06 100644 --- a/core/java/android/os/GraphicsEnvironment.java +++ b/core/java/android/os/GraphicsEnvironment.java @@ -172,13 +172,6 @@ public class GraphicsEnvironment { return 0; } - /** - * Check whether application is debuggable - */ - private static boolean isDebuggable(Context context) { - return (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) > 0; - } - /** * Store the layer paths available to the loader. */ @@ -233,7 +226,7 @@ public class GraphicsEnvironment { // 2. ENABLE_GPU_DEBUG_LAYERS is true // 3. Package name is equal to GPU_DEBUG_APP - if (isDebuggable(context) || (getCanLoadSystemLibraries() == 1)) { + if (isDebuggable()) { final int enable = coreSettings.getInt(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0); @@ -414,9 +407,7 @@ public class GraphicsEnvironment { * Check for ANGLE debug package, but only for apps that can load them (dumpable) */ private String getAngleDebugPackage(Context context, Bundle coreSettings) { - final boolean appIsDebuggable = isDebuggable(context); - final boolean deviceIsDebuggable = getCanLoadSystemLibraries() == 1; - if (appIsDebuggable || deviceIsDebuggable) { + if (isDebuggable()) { String debugPackage; if (coreSettings != null) { @@ -451,12 +442,8 @@ public class GraphicsEnvironment { * - devices that are running a userdebug build (ro.debuggable) or can inject libraries for * debugging (PR_SET_DUMPABLE). */ - final boolean appIsDebuggable = isDebuggable(context); - final boolean deviceIsDebuggable = getCanLoadSystemLibraries() == 1; - if (!(appIsDebuggable || deviceIsDebuggable)) { - Log.v(TAG, "Skipping loading temporary rules file: " - + "appIsDebuggable = " + appIsDebuggable + ", " - + "adbRootEnabled = " + deviceIsDebuggable); + if (!isDebuggable()) { + Log.v(TAG, "Skipping loading temporary rules file"); return false; } @@ -725,7 +712,7 @@ public class GraphicsEnvironment { final boolean enablePrereleaseDriver = (ai.metaData != null && ai.metaData.getBoolean(METADATA_DEVELOPER_DRIVER_ENABLE)) - || getCanLoadSystemLibraries() == 1; + || isDebuggable(); // Priority for Game Driver settings global on confliction (Higher priority comes first): // 1. GAME_DRIVER_ALL_APPS @@ -901,7 +888,7 @@ public class GraphicsEnvironment { return ""; } - private static native int getCanLoadSystemLibraries(); + private static native boolean isDebuggable(); private static native void setLayerPaths(ClassLoader classLoader, String layerPaths); private static native void setDebugLayers(String layers); private static native void setDebugLayersGLES(String layers); diff --git a/core/jni/android_os_GraphicsEnvironment.cpp b/core/jni/android_os_GraphicsEnvironment.cpp index be9aee410d40..9ae1a9794395 100644 --- a/core/jni/android_os_GraphicsEnvironment.cpp +++ b/core/jni/android_os_GraphicsEnvironment.cpp @@ -23,8 +23,8 @@ namespace { -int getCanLoadSystemLibraries_native() { - return android::GraphicsEnv::getInstance().getCanLoadSystemLibraries(); +bool isDebuggable_native() { + return android::GraphicsEnv::getInstance().isDebuggable(); } void setDriverPathAndSphalLibraries_native(JNIEnv* env, jobject clazz, jstring path, @@ -90,7 +90,7 @@ void hintActivityLaunch_native(JNIEnv* env, jobject clazz) { } const JNINativeMethod g_methods[] = { - { "getCanLoadSystemLibraries", "()I", reinterpret_cast(getCanLoadSystemLibraries_native) }, + { "isDebuggable", "()Z", reinterpret_cast(isDebuggable_native) }, { "setDriverPathAndSphalLibraries", "(Ljava/lang/String;Ljava/lang/String;)V", reinterpret_cast(setDriverPathAndSphalLibraries_native) }, { "setGpuStats", "(Ljava/lang/String;Ljava/lang/String;JJLjava/lang/String;I)V", reinterpret_cast(setGpuStats_native) }, { "setAngleInfo", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/io/FileDescriptor;JJ)V", reinterpret_cast(setAngleInfo_native) }, -- GitLab From b1a33a8b4fd4b1603c0465a904be29f0c4a07e64 Mon Sep 17 00:00:00 2001 From: Alexey Kuzmin Date: Tue, 7 Jan 2020 11:59:18 +0000 Subject: [PATCH 037/219] Fix serialization issue of ExternalVibration Remove excessive serialization of Audio Attributes Bug: 140417434 Test: atest ExternalVibrationTest#testSerialization Change-Id: Ib7ceaed875889126a53f874eec64fab4817e48d1 --- core/java/android/os/ExternalVibration.java | 1 - .../src/android/os/ExternalVibrationTest.java | 47 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 core/tests/coretests/src/android/os/ExternalVibrationTest.java diff --git a/core/java/android/os/ExternalVibration.java b/core/java/android/os/ExternalVibration.java index 37ca868598f5..041d21fabd6f 100644 --- a/core/java/android/os/ExternalVibration.java +++ b/core/java/android/os/ExternalVibration.java @@ -157,7 +157,6 @@ public class ExternalVibration implements Parcelable { out.writeInt(mUid); out.writeString(mPkg); writeAudioAttributes(mAttrs, out, flags); - out.writeParcelable(mAttrs, flags); out.writeStrongBinder(mController.asBinder()); out.writeStrongBinder(mToken); } diff --git a/core/tests/coretests/src/android/os/ExternalVibrationTest.java b/core/tests/coretests/src/android/os/ExternalVibrationTest.java new file mode 100644 index 000000000000..3b872d5a7ff1 --- /dev/null +++ b/core/tests/coretests/src/android/os/ExternalVibrationTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +import static junit.framework.Assert.assertEquals; + +import static org.mockito.Mockito.mock; + +import android.media.AudioAttributes; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class ExternalVibrationTest { + @Test + public void testSerialization() { + AudioAttributes audio = new AudioAttributes.Builder().build(); + IExternalVibrationController controller = mock(IExternalVibrationController.class); + ExternalVibration original = new ExternalVibration( + 123, // uid + "pkg", + audio, + controller); + Parcel p = Parcel.obtain(); + original.writeToParcel(p, 0); + p.setDataPosition(0); + ExternalVibration restored = ExternalVibration.CREATOR.createFromParcel(p); + assertEquals(original, restored); + } +} + -- GitLab From 0860a5c5c303426073c36763bef28644673ff441 Mon Sep 17 00:00:00 2001 From: Rubin Xu Date: Tue, 5 Nov 2019 10:15:36 +0000 Subject: [PATCH 038/219] RESTRICT AUTOMERGE Update keyguard locked state from TrustManagerService TrustManagerService holds the ground truth about whether a user is locked or not, so update keystore using the information there, instead of doing it from KeyguardStateMonitor. This fixes the issue of work profile locked state not being correctly pushed to keystore. Note: since this change is likely to be backported as a security patch, I'm refraining from doing major refactoring right now. Bug: 141329041 Bug: 144430870 Test: manually with KeyPairSampleApp Change-Id: I3472ece73d573a775345ebcceeeb2cc460374c9b --- keystore/java/android/security/KeyStore.java | 11 +++++ .../policy/keyguard/KeyguardStateMonitor.java | 16 ------- .../server/trust/TrustManagerService.java | 48 +++++++++++++++++++ 3 files changed, 59 insertions(+), 16 deletions(-) diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index fe05c13c999b..6be2da24e630 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -691,6 +691,17 @@ public class KeyStore { return onUserPasswordChanged(UserHandle.getUserId(Process.myUid()), newPassword); } + /** + * Notify keystore about the latest user locked state. This is to support keyguard-bound key. + */ + public void onUserLockedStateChanged(int userHandle, boolean locked) { + try { + mBinder.onKeyguardVisibilityChanged(locked, userHandle); + } catch (RemoteException e) { + Log.w(TAG, "Failed to update user locked state " + userHandle, e); + } + } + public int attestKey( String alias, KeymasterArguments params, KeymasterCertificateChain outChain) { try { diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java index 1cba1c7bed1b..add0b01f1879 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java @@ -19,8 +19,6 @@ package com.android.server.policy.keyguard; import android.app.ActivityManager; import android.content.Context; import android.os.RemoteException; -import android.os.ServiceManager; -import android.security.IKeystoreService; import android.util.Slog; import com.android.internal.policy.IKeyguardService; @@ -53,16 +51,11 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { private final LockPatternUtils mLockPatternUtils; private final StateCallback mCallback; - IKeystoreService mKeystoreService; - public KeyguardStateMonitor(Context context, IKeyguardService service, StateCallback callback) { mLockPatternUtils = new LockPatternUtils(context); mCurrentUserId = ActivityManager.getCurrentUser(); mCallback = callback; - mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager - .getService("android.security.keystore")); - try { service.addStateMonitorCallback(this); } catch (RemoteException e) { @@ -95,11 +88,6 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { mIsShowing = showing; mCallback.onShowingChanged(); - try { - mKeystoreService.onKeyguardVisibilityChanged(showing, mCurrentUserId); - } catch (RemoteException e) { - Slog.e(TAG, "Error informing keystore of screen lock", e); - } } @Override // Binder interface @@ -111,10 +99,6 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { mCurrentUserId = userId; } - private synchronized int getCurrentUser() { - return mCurrentUserId; - } - @Override // Binder interface public void onInputRestrictedStateChanged(boolean inputRestricted) { mInputRestricted = inputRestricted; diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index f9f4bbfc8eb0..0c22f2f1c18a 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -47,6 +47,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; +import android.security.KeyStore; import android.service.trust.TrustAgentService; import android.text.TextUtils; import android.util.ArraySet; @@ -121,6 +122,33 @@ public class TrustManagerService extends SystemService { @GuardedBy("mUserIsTrusted") private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray(); + /** + * Stores the locked state for users on the device. There are three different type of users + * which are handled slightly differently: + *

    + *
  • Users with real keyguard + * These are users who can be switched to ({@link UserInfo#supportsSwitchToByUser()}). Their + * locked state is derived by a combination of user secure state, keyguard state, trust agent + * decision and biometric authentication result. These are updated via + * {@link #refreshDeviceLockedForUser(int)} and result stored in {@link #mDeviceLockedForUser}. + *
  • Managed profiles with unified challenge + * Managed profile with unified challenge always shares the same locked state as their parent, + * so their locked state is not recorded in {@link #mDeviceLockedForUser}. Instead, + * {@link ITrustManager#isDeviceLocked(int)} always resolves their parent user handle and + * queries its locked state instead. + *
  • Managed profiles with separate challenge + * Locked state for profile with separate challenge is determined by other parts of the + * framework (mostly PowerManager) and pushed to TrustManagerService via + * {@link ITrustManager#setDeviceLockedForUser(int, boolean)}. Although in a corner case when + * the profile has a separate but empty challenge, setting its {@link #mDeviceLockedForUser} to + * {@code false} is actually done by {@link #refreshDeviceLockedForUser(int)}. + *
+ * TODO: Rename {@link ITrustManager#setDeviceLockedForUser(int, boolean)} to + * {@code setDeviceLockedForProfile} to better reflect its purpose. Unifying + * {@code setDeviceLockedForProfile} and {@link #setDeviceLockedForUser} would also be nice. + * At the moment they both update {@link #mDeviceLockedForUser} but have slightly different + * side-effects: one notifies trust agents while the other sends out a broadcast. + */ @GuardedBy("mDeviceLockedForUser") private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray(); @@ -410,6 +438,10 @@ public class TrustManagerService extends SystemService { } } + /** + * Update the user's locked state. Only applicable to users with a real keyguard + * ({@link UserInfo#supportsSwitchToByUser}) and unsecured managed profiles. + */ private void refreshDeviceLockedForUser(int userId) { if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) { Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle," @@ -470,6 +502,15 @@ public class TrustManagerService extends SystemService { } if (changed) { dispatchDeviceLocked(userId, locked); + + KeyStore.getInstance().onUserLockedStateChanged(userId, locked); + // Also update the user's profiles who have unified challenge, since they + // share the same unlocked state (see {@link #isDeviceLocked(int)}) + for (int profileHandle : mUserManager.getEnabledProfileIds(userId)) { + if (mLockPatternUtils.isManagedProfileWithUnifiedChallenge(profileHandle)) { + KeyStore.getInstance().onUserLockedStateChanged(profileHandle, locked); + } + } } } @@ -992,6 +1033,10 @@ public class TrustManagerService extends SystemService { return "0x" + Integer.toHexString(i); } + /** + * Changes the lock status for the given user. This is only applicable to managed profiles, + * other users should be handled by Keyguard. + */ @Override public void setDeviceLockedForUser(int userId, boolean locked) { enforceReportPermission(); @@ -1002,6 +1047,9 @@ public class TrustManagerService extends SystemService { synchronized (mDeviceLockedForUser) { mDeviceLockedForUser.put(userId, locked); } + + KeyStore.getInstance().onUserLockedStateChanged(userId, locked); + if (locked) { try { ActivityManager.getService().notifyLockedProfile(userId); -- GitLab From 6a56247200e1a8afc4dacc2497ec384efa200b92 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Tue, 10 Dec 2019 17:34:18 -0800 Subject: [PATCH 039/219] DO NOT MERGE Ensure package names read from config are system packages. Fixes: 145981139 Test: manually tested ensureSystemPackageName() returns null for non-system app Change-Id: I1d23910cbd282f6702785c9dfb059d7be6b0e895 --- .../server/pm/PackageManagerService.java | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 04cebb309216..77415aae22bc 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3127,8 +3127,7 @@ public class PackageManagerService extends IPackageManager.Stub mWellbeingPackage = getWellbeingPackageName(); mDocumenterPackage = getDocumenterPackageName(); - mConfiguratorPackage = - mContext.getString(R.string.config_deviceConfiguratorPackageName); + mConfiguratorPackage = getDeviceConfiguratorPackageName(); mAppPredictionServicePackage = getAppPredictionServicePackageName(); mIncidentReportApproverPackage = getIncidentReportApproverPackageName(); @@ -21118,7 +21117,8 @@ public class PackageManagerService extends IPackageManager.Stub @Override public String getSystemTextClassifierPackageName() { - return mContext.getString(R.string.config_defaultTextClassifierPackage); + return ensureSystemPackageName(mContext.getString( + R.string.config_defaultTextClassifierPackage)); } @Override @@ -21128,7 +21128,7 @@ public class PackageManagerService extends IPackageManager.Stub if (flattenedComponentName != null) { ComponentName componentName = ComponentName.unflattenFromString(flattenedComponentName); if (componentName != null && componentName.getPackageName() != null) { - return componentName.getPackageName(); + return ensureSystemPackageName(componentName.getPackageName()); } } return null; @@ -21153,9 +21153,15 @@ public class PackageManagerService extends IPackageManager.Stub } } + @Nullable + private String getDeviceConfiguratorPackageName() { + return ensureSystemPackageName(mContext.getString( + R.string.config_deviceConfiguratorPackageName)); + } + @Override public String getWellbeingPackageName() { - return mContext.getString(R.string.config_defaultWellbeingPackage); + return ensureSystemPackageName(mContext.getString(R.string.config_defaultWellbeingPackage)); } @Override @@ -21170,7 +21176,7 @@ public class PackageManagerService extends IPackageManager.Stub if (appPredictionServiceComponentName == null) { return null; } - return appPredictionServiceComponentName.getPackageName(); + return ensureSystemPackageName(appPredictionServiceComponentName.getPackageName()); } @Override @@ -21187,11 +21193,23 @@ public class PackageManagerService extends IPackageManager.Stub if (systemCaptionsServiceComponentName == null) { return null; } - return systemCaptionsServiceComponentName.getPackageName(); + return ensureSystemPackageName(systemCaptionsServiceComponentName.getPackageName()); } public String getIncidentReportApproverPackageName() { - return mContext.getString(R.string.config_incidentReportApproverPackage); + return ensureSystemPackageName(mContext.getString( + R.string.config_incidentReportApproverPackage)); + } + + @Nullable + private String ensureSystemPackageName(@Nullable String packageName) { + if (packageName == null) { + return null; + } + if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) { + return null; + } + return packageName; } @Override -- GitLab From 58048eb8a972e107c9b9d137e4121964b3f41b71 Mon Sep 17 00:00:00 2001 From: Dan Sandler Date: Tue, 28 Jan 2020 21:25:53 -0500 Subject: [PATCH 040/219] Separate icon sizes for sharesheet and resolver list. Fixes: 148246479 Test: visual Change-Id: I16d06af155d2eec45d064e73bb45cc9cb6c5f2ca --- core/res/res/layout/resolve_grid_item.xml | 4 ++-- core/res/res/values/dimens.xml | 1 + core/res/res/values/symbols.xml | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/res/res/layout/resolve_grid_item.xml b/core/res/res/layout/resolve_grid_item.xml index 7098c958ce36..6d8682c61df1 100644 --- a/core/res/res/layout/resolve_grid_item.xml +++ b/core/res/res/layout/resolve_grid_item.xml @@ -30,8 +30,8 @@ android:background="?attr/selectableItemBackgroundBorderless"> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 4fdb498451ae..3edfb36982f8 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -764,6 +764,7 @@ 288dp 72dp 32dp + 42dp 8dp 18dp 16dp diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 09d927401548..10e9f9e8caa0 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3809,6 +3809,7 @@ + -- GitLab From 71801c6ac1459c28afe854e8ea633767788d704a Mon Sep 17 00:00:00 2001 From: Eric Berglund Date: Thu, 30 Jan 2020 10:05:54 -0800 Subject: [PATCH 041/219] DO NOT MERGE Unregister notification listener before creating a new one to avoid duplicate Heads Up notifications. Bug: 148530083 Test: manual Change-Id: I3f55b60a390f847b81b2de7da06d12b5725b3b39 --- .../systemui/statusbar/car/CarStatusBar.java | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index 0046c20ab164..0a2d5a08a914 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -41,6 +41,7 @@ import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Looper; +import android.os.RemoteException; import android.util.Log; import android.view.Display; import android.view.GestureDetector; @@ -167,6 +168,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt private FlingAnimationUtils mFlingAnimationUtils; private SwitchToGuestTimer mSwitchToGuestTimer; private NotificationDataManager mNotificationDataManager; + private CarNotificationListener mCarNotificationListener; private NotificationClickHandlerFactory mNotificationClickHandlerFactory; private ScreenLifecycle mScreenLifecycle; private CarAudioManager mCarAudioManager; @@ -643,7 +645,17 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt } }); - CarNotificationListener carNotificationListener = new CarNotificationListener(); + if (mCarNotificationListener != null) { + try { + // If we already had a notification listener we need to unreigster is before + // making a new one + mCarNotificationListener.unregisterAsSystemService(); + } catch (RemoteException e) { + Log.e(TAG, "Error unregistering notification listener."); + } + } + + mCarNotificationListener = new CarNotificationListener(); mCarUxRestrictionManagerWrapper = new CarUxRestrictionManagerWrapper(); mNotificationDataManager = new NotificationDataManager(); @@ -660,7 +672,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt mNotificationClickHandlerFactory, mNotificationDataManager); mNotificationClickHandlerFactory.setNotificationDataManager(mNotificationDataManager); - carNotificationListener.registerAsSystemService(mContext, mCarUxRestrictionManagerWrapper, + mCarNotificationListener.registerAsSystemService(mContext, mCarUxRestrictionManagerWrapper, carHeadsUpNotificationManager, mNotificationDataManager); mNotificationView = mStatusBarWindow.findViewById(R.id.notification_view); @@ -769,7 +781,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt mNotificationViewController = new NotificationViewController( mNotificationView, PreprocessingManager.getInstance(mContext), - carNotificationListener, + mCarNotificationListener, mCarUxRestrictionManagerWrapper, mNotificationDataManager); mNotificationViewController.enable(); @@ -1343,6 +1355,19 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt @Override public void onLocaleListChanged() { + // When locale changes we need to reload the notification panel with the new language + if (mNotificationView == null) { + return; + } + + LayoutParams params = mNotificationView.getLayoutParams(); + int index = mStatusBarWindow.indexOfChild(mNotificationView); + + mStatusBarWindow.removeView(mNotificationView); + + View v = View.inflate(mContext, R.layout.notification_center_activity, null); + mStatusBarWindow.addView(v, index, params); + restartNavBars(); connectNotificationsUI(); } -- GitLab From d9cb95d5c9f781357a726e1d2640563bf6c22d9d Mon Sep 17 00:00:00 2001 From: Calin Juravle Date: Tue, 28 Jan 2020 16:19:52 -0800 Subject: [PATCH 042/219] [framework] Remove boot complete marker ART doesn't load the boot image from /data anymore and the marker is useless. Test: device boots Bug: 143899228 (cherry picked from commit 46a81bdafb0928d2854d7bd920f063dd9de6d61b) Merged-In: I7104b961d2fc2de53ffea4c14cce6b785ff534dd Change-Id: I7104b961d2fc2de53ffea4c14cce6b785ff534dd --- .../server/am/ActivityManagerService.java | 23 ------------------- .../java/com/android/server/pm/Installer.java | 10 -------- 2 files changed, 33 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index cf00210c34d3..6dff3f2ba8f9 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -352,7 +352,6 @@ import com.android.server.contentcapture.ContentCaptureManagerInternal; import com.android.server.firewall.IntentFirewall; import com.android.server.job.JobSchedulerInternal; import com.android.server.pm.Installer; -import com.android.server.pm.Installer.InstallerException; import com.android.server.uri.GrantUri; import com.android.server.uri.UriGrantsManagerInternal; import com.android.server.utils.PriorityDump; @@ -364,8 +363,6 @@ import com.android.server.wm.ActivityTaskManagerService; import com.android.server.wm.WindowManagerService; import com.android.server.wm.WindowProcessController; -import dalvik.system.VMRuntime; - import libcore.util.EmptyArray; import java.io.File; @@ -5201,26 +5198,6 @@ public class ActivityManagerService extends IActivityManager.Stub mCallFinishBooting = false; } - ArraySet completedIsas = new ArraySet(); - for (String abi : Build.SUPPORTED_ABIS) { - ZYGOTE_PROCESS.establishZygoteConnectionForAbi(abi); - final String instructionSet = VMRuntime.getInstructionSet(abi); - if (!completedIsas.contains(instructionSet)) { - try { - mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)); - } catch (InstallerException e) { - if (!VMRuntime.didPruneDalvikCache()) { - // This is technically not the right filter, as different zygotes may - // have made different pruning decisions. But the log is best effort, - // anyways. - Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" + - e.getMessage() +")"); - } - } - completedIsas.add(instructionSet); - } - } - IntentFilter pkgFilter = new IntentFilter(); pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); pkgFilter.addDataScheme("package"); diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java index adcd19e9bb5a..5682093355cc 100644 --- a/services/core/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -431,16 +431,6 @@ public class Installer extends SystemService { } } - public void markBootComplete(String instructionSet) throws InstallerException { - assertValidInstructionSet(instructionSet); - if (!checkBeforeRemote()) return; - try { - mInstalld.markBootComplete(instructionSet); - } catch (Exception e) { - throw InstallerException.from(e); - } - } - public void freeCache(String uuid, long targetFreeBytes, long cacheReservedBytes, int flags) throws InstallerException { if (!checkBeforeRemote()) return; -- GitLab From 692e12085835925d4e34607032e4f290502394fc Mon Sep 17 00:00:00 2001 From: Rhed Jao Date: Thu, 16 Jan 2020 18:38:17 +0800 Subject: [PATCH 043/219] Fixed NPE in package installer session. We updated staged sessions to activation failed state when they aren't in terminal state, and device received ota and reboot. This happend before the StagingManager resumes the sessions when the whole set of parent+child sessions have been restored. A parent session probably cannot find the child session, and a null exception could happen. In this change, we do not destroy child sessions before we destroy the parent session. We only destroy a child session directly if we are sure that its parent session doesn't exist. Bug: 147651771 Test: StagedInstallTest Change-Id: Iac6489a04df35f851aa18a91e1dde2d73928b8ec Merged-in: Iac6489a04df35f851aa18a91e1dde2d73928b8ec (cherry picked from commit 1fc8b36cf38e2632db68e5d15acd3ff83d1f54aa) --- .../com/android/server/pm/PackageInstallerService.java | 9 ++++++--- .../core/java/com/android/server/pm/StagingManager.java | 9 ++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index fd8db4b99be8..d17365db77dd 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -258,12 +258,15 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } // Don't hold mSessions lock when calling restoreSession, since it might trigger an APK // atomic install which needs to query sessions, which requires lock on mSessions. + boolean isDeviceUpgrading = mPm.isDeviceUpgrading(); for (PackageInstallerSession session : stagedSessionsToRestore) { - if (mPm.isDeviceUpgrading() && !session.isStagedAndInTerminalState()) { + if (!session.isStagedAndInTerminalState() && session.hasParentSessionId() + && getSession(session.getParentSessionId()) == null) { session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, - "Build fingerprint has changed"); + "An orphan staged session " + session.sessionId + " is found, " + + "parent " + session.getParentSessionId() + " is missing"); } - mStagingManager.restoreSession(session); + mStagingManager.restoreSession(session, isDeviceUpgrading); } // Broadcasts are not sent while we restore sessions on boot, since no processes would be // ready to listen to them. From now on, we greedily assume that broadcasts requests are diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 9913c9846a17..895d2c5d00bf 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -619,7 +619,7 @@ public class StagingManager { return false; } - void restoreSession(@NonNull PackageInstallerSession session) { + void restoreSession(@NonNull PackageInstallerSession session, boolean isDeviceUpgrading) { PackageInstallerSession sessionToResume = session; synchronized (mStagedSessions) { mStagedSessions.append(session.sessionId, session); @@ -636,6 +636,13 @@ public class StagingManager { } } } + // The preconditions used during pre-reboot verification might have changed when device + // is upgrading. Updated staged sessions to activation failed before we resume the session. + if (isDeviceUpgrading && !sessionToResume.isStagedAndInTerminalState()) { + sessionToResume.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, + "Build fingerprint has changed"); + return; + } checkStateAndResume(sessionToResume); } -- GitLab From 44d1c652ce124eb40101effe300d8655a7869f7b Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Wed, 29 Jan 2020 18:15:05 -0800 Subject: [PATCH 044/219] Update redaction upon profile changes We can't rely on status bar state changes to update the notification list. The current user might not be set yet, causing wrong notifications to become visible. Fixes: 145135488 Test: manual Test: atest NotificationStackScrollLayoutTest Change-Id: I34d1d5f9a751c1d7680a5a5941c39b9fe33a473b Merged-In: I34d1d5f9a751c1d7680a5a5941c39b9fe33a473b --- .../stack/NotificationStackScrollLayout.java | 7 +++++-- .../stack/NotificationStackScrollLayoutTest.java | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index f7b79d175263..918e257fcee0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -566,6 +566,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd mRoundnessManager.setAnimatedChildren(mChildrenToAddAnimated); mRoundnessManager.setOnRoundingChangedCallback(this::invalidate); addOnExpandedHeightListener(mRoundnessManager::setExpanded); + mLockscreenUserManager.addUserChangedListener(userId -> + updateSensitiveness(false /* animated */)); setOutlineProvider(mOutlineProvider); // Blocking helper manager wants to know the expanded state, update as well. @@ -4567,7 +4569,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd } @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) - private void setHideSensitive(boolean hideSensitive, boolean animate) { + private void updateSensitiveness(boolean animate) { + boolean hideSensitive = mLockscreenUserManager.isAnyProfilePublicMode(); if (hideSensitive != mAmbientState.isHideSensitive()) { int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { @@ -5331,7 +5334,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd SysuiStatusBarStateController state = (SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class); - setHideSensitive(publicMode, state.goingToFullShade() /* animate */); + updateSensitiveness(state.goingToFullShade() /* animate */); setDimmed(onKeyguard, state.fromShadeLocked() /* animate */); setExpandingEnabled(!onKeyguard); ActivatableNotificationView activatedChild = getActivatedChild(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index ff835871d822..34163841cc59 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -57,6 +57,8 @@ import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.AmbientPulseManager; import com.android.systemui.statusbar.EmptyShadeView; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; +import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShelf; @@ -117,6 +119,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { @Mock private NotificationIconAreaController mNotificationIconAreaController; @Mock private MetricsLogger mMetricsLogger; @Mock private NotificationRoundnessManager mNotificationRoundnessManager; + @Mock private NotificationLockscreenUserManager mLockscreenUserManager; + private UserChangedListener mUserChangedListener; private TestableNotificationEntryManager mEntryManager; private int mOriginalInterruptionModelSetting; @@ -135,6 +139,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { mDependency.injectTestDependency( NotificationBlockingHelperManager.class, mBlockingHelperManager); + mDependency.injectTestDependency(NotificationLockscreenUserManager.class, + mLockscreenUserManager); mDependency.injectTestDependency(StatusBarStateController.class, mBarState); mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger); mDependency.injectTestDependency(NotificationRemoteInputManager.class, @@ -150,6 +156,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { NotificationShelf notificationShelf = mock(NotificationShelf.class); + ArgumentCaptor userChangedCaptor = ArgumentCaptor + .forClass(UserChangedListener.class); // The actual class under test. You may need to work with this class directly when // testing anonymous class members of mStackScroller, like mMenuEventListener, @@ -171,6 +179,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { mStackScroller.setGroupManager(mGroupManager); mStackScroller.setEmptyShadeView(mEmptyShadeView); mStackScroller.setIconAreaController(mNotificationIconAreaController); + verify(mLockscreenUserManager).addUserChangedListener(userChangedCaptor.capture()); + mUserChangedListener = userChangedCaptor.getValue(); // Stub out functionality that isn't necessary to test. doNothing().when(mBar) @@ -255,6 +265,12 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { verify(mBlockingHelperManager).setNotificationShadeExpanded(100f); } + @Test + public void testOnStatePostChange_verifyIfProfileIsPublic() { + mUserChangedListener.onUserChanged(0); + verify(mLockscreenUserManager).isAnyProfilePublicMode(); + } + @Test public void manageNotifications_visible() { FooterView view = mock(FooterView.class); -- GitLab From f83594ce422bb487eebc6c2a3627de273a6c8fe7 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Tue, 28 Jan 2020 15:09:33 -0800 Subject: [PATCH 045/219] Don't crash system process on empty onTuneFailed This change: - modifies internal programSelectorFromHal to return null instead of throwing NPE on empty input - throws NPE on two of its usages where null is unexpected - *does not* throw NPE on one usage where program selector is optional (onTuneFailed in RadioModule.java) Bug: 147522441 Test: boots, but have no quick way to trigger onTuneFailed(Result::error, {}) Change-Id: I6317da3fbde2bce90079b61bb0839e893e1c4712 (cherry picked from commit dc8a5683a149b4f5ce3d9a9f6198fbe310547dbf) --- .../server/broadcastradio/hal2/Convert.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/broadcastradio/hal2/Convert.java b/services/core/java/com/android/server/broadcastradio/hal2/Convert.java index 9730c9a1a380..ab5bef8b80a7 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/Convert.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/Convert.java @@ -275,8 +275,18 @@ class Convert { return hwSel; } - static @NonNull ProgramSelector programSelectorFromHal( + private static boolean isEmpty( @NonNull android.hardware.broadcastradio.V2_0.ProgramSelector sel) { + if (sel.primaryId.type != 0) return false; + if (sel.primaryId.value != 0) return false; + if (sel.secondaryIds.size() != 0) return false; + return true; + } + + static @Nullable ProgramSelector programSelectorFromHal( + @NonNull android.hardware.broadcastradio.V2_0.ProgramSelector sel) { + if (isEmpty(sel)) return null; + ProgramSelector.Identifier[] secondaryIds = sel.secondaryIds.stream(). map(Convert::programIdentifierFromHal).map(Objects::requireNonNull). toArray(ProgramSelector.Identifier[]::new); @@ -364,7 +374,7 @@ class Convert { collect(Collectors.toList()); return new RadioManager.ProgramInfo( - programSelectorFromHal(info.selector), + Objects.requireNonNull(programSelectorFromHal(info.selector)), programIdentifierFromHal(info.logicallyTunedTo), programIdentifierFromHal(info.physicallyTunedTo), relatedContent, @@ -402,7 +412,7 @@ class Convert { public static @NonNull android.hardware.radio.Announcement announcementFromHal( @NonNull Announcement hwAnnouncement) { return new android.hardware.radio.Announcement( - programSelectorFromHal(hwAnnouncement.selector), + Objects.requireNonNull(programSelectorFromHal(hwAnnouncement.selector)), hwAnnouncement.type, vendorInfoFromHal(hwAnnouncement.vendorInfo) ); -- GitLab From 43c949771924179cc21095ca621bbda383e53d4b Mon Sep 17 00:00:00 2001 From: Kavi Gupta Date: Tue, 11 Jun 2019 09:19:35 -0700 Subject: [PATCH 046/219] Add JVMTI agent to dump/reset JaCoCo coverage information This agent can be attached to an arbitrary Android process with arguments that cause it to either reset or dump the JaCoCo information to a provided directory. Bug: 148178774 Test: manual, used examples in README to test whether it works on a userdebug_coverage build on cuttlefish Change-Id: If6cee20046f790676b8085e1ca84652c063295fa Merged-In: If6cee20046f790676b8085e1ca84652c063295fa (cherry picked from commit 2d84ae7640641c1e931746071a58f13c8a49c61b) --- tools/dump-coverage/Android.bp | 29 ++++ tools/dump-coverage/README.md | 50 ++++++ tools/dump-coverage/dump_coverage.cc | 239 +++++++++++++++++++++++++++ 3 files changed, 318 insertions(+) create mode 100644 tools/dump-coverage/Android.bp create mode 100644 tools/dump-coverage/README.md create mode 100644 tools/dump-coverage/dump_coverage.cc diff --git a/tools/dump-coverage/Android.bp b/tools/dump-coverage/Android.bp new file mode 100644 index 000000000000..4519ce3636bf --- /dev/null +++ b/tools/dump-coverage/Android.bp @@ -0,0 +1,29 @@ +// +// Copyright (C) 2019 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. +// + +// Build variants {target,host} x {32,64} +cc_library { + name: "libdumpcoverage", + srcs: ["dump_coverage.cc"], + header_libs: [ + "libopenjdkjvmti_headers", + ], + + host_supported: true, + shared_libs: [ + "libbase", + ], +} diff --git a/tools/dump-coverage/README.md b/tools/dump-coverage/README.md new file mode 100644 index 000000000000..2bab4bc8c984 --- /dev/null +++ b/tools/dump-coverage/README.md @@ -0,0 +1,50 @@ +# dumpcoverage + +libdumpcoverage.so is a JVMTI agent designed to dump coverage information for a process, where the binaries have been instrumented by JaCoCo. JaCoCo automatically starts recording data on process start, and we need a way to trigger the resetting or dumping of this data. + +The JVMTI agent is used to make the calls to JaCoCo in its process. + +# Usage + +Note that these examples assume you have an instrumented build (userdebug_coverage). Here is, for example, how to dump coverage information regarding the default clock app. First some setup is necessary: + +``` +adb root # necessary to copy files in/out of the /data/data/{package} folder +adb shell 'mkdir /data/data/com.android.deskclock/folder-to-use' +``` + +Then we can run the command to dump the data: + +``` +adb shell 'am attach-agent com.android.deskclock /system/lib/libdumpcoverage.so=dump:/data/data/com.android.deskclock/folder-to-use' +``` + +We can also reset the coverage information with + +``` +adb shell 'am attach-agent com.android.deskclock /system/lib/libdumpcoverage.so=reset' +``` + +then perform more actions, then dump the data again. To get the files, we can get + +``` +adb pull /data/data/com.android.deskclock/folder-to-use ~/path-on-your-computer +``` + +And you should have timestamped `.exec` files on your machine under the folder `~/path-on-your-computer` + +# Details + +In dump mode, the agent makes JNI calls equivalent to + +``` +Agent.getInstance().getExecutionData(/*reset = */ false); +``` + +and then saves the result to a file specified by the passed in directory + +In reset mode, it makes a JNI call equivalent to + +``` +Agent.getInstance().reset(); +``` diff --git a/tools/dump-coverage/dump_coverage.cc b/tools/dump-coverage/dump_coverage.cc new file mode 100644 index 000000000000..3de1865b8018 --- /dev/null +++ b/tools/dump-coverage/dump_coverage.cc @@ -0,0 +1,239 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using std::get; +using std::tuple; +using std::chrono::system_clock; + +namespace dump_coverage { + +#define CHECK_JVMTI(x) CHECK_EQ((x), JVMTI_ERROR_NONE) +#define CHECK_NOTNULL(x) CHECK((x) != nullptr) +#define CHECK_NO_EXCEPTION(env) CHECK(!(env)->ExceptionCheck()); + +static JavaVM* java_vm = nullptr; + +// Get the current JNI environment. +static JNIEnv* GetJNIEnv() { + JNIEnv* env = nullptr; + CHECK_EQ(java_vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6), + JNI_OK); + return env; +} + +// Get the JaCoCo Agent class and an instance of the class, given a JNI +// environment. +// Will crash if the Agent isn't found or if any Java Exception occurs. +static tuple GetJavaAgent(JNIEnv* env) { + jclass java_agent_class = + env->FindClass("org/jacoco/agent/rt/internal/Agent"); + CHECK_NOTNULL(java_agent_class); + + jmethodID java_agent_get_instance = + env->GetStaticMethodID(java_agent_class, "getInstance", + "()Lorg/jacoco/agent/rt/internal/Agent;"); + CHECK_NOTNULL(java_agent_get_instance); + + jobject java_agent_instance = + env->CallStaticObjectMethod(java_agent_class, java_agent_get_instance); + CHECK_NO_EXCEPTION(env); + CHECK_NOTNULL(java_agent_instance); + + return tuple(java_agent_class, java_agent_instance); +} + +// Runs equivalent of Agent.getInstance().getExecutionData(false) and returns +// the result. +// Will crash if the Agent isn't found or if any Java Exception occurs. +static jbyteArray GetExecutionData(JNIEnv* env) { + auto java_agent = GetJavaAgent(env); + jmethodID java_agent_get_execution_data = + env->GetMethodID(get<0>(java_agent), "getExecutionData", "(Z)[B"); + CHECK_NO_EXCEPTION(env); + CHECK_NOTNULL(java_agent_get_execution_data); + + jbyteArray java_result_array = (jbyteArray)env->CallObjectMethod( + get<1>(java_agent), java_agent_get_execution_data, false); + CHECK_NO_EXCEPTION(env); + + return java_result_array; +} + +// Gets the filename to write execution data to +// dirname: the directory in which to place the file +// outputs /YYYY-MM-DD-HH-MM-SS.SSS.exec +static std::string GetFilename(const std::string& dirname) { + system_clock::time_point time_point = system_clock::now(); + auto seconds = std::chrono::time_point_cast(time_point); + auto fractional_time = time_point - seconds; + auto millis = std::chrono::duration_cast(fractional_time); + + std::time_t time = system_clock::to_time_t(time_point); + auto tm = *std::gmtime(&time); + + std::ostringstream oss; + oss + << dirname + << "/" + << std::put_time(&tm, "%Y-%m-%d-%H-%M-%S.") + << std::setfill('0') << std::setw(3) << millis.count() + << ".ec"; + return oss.str(); +} + +// Writes the execution data to a file +// data, length: represent the data, as a sequence of bytes +// dirname: directory name to contain the file +// returns JNI_ERR if there is an error in writing the file, otherwise JNI_OK. +static jint WriteFile(const char* data, int length, const std::string& dirname) { + auto filename = GetFilename(dirname); + + LOG(INFO) << "Writing file of length " << length << " to '" << filename + << "'"; + std::ofstream file(filename, std::ios::binary); + + if (!file.is_open()) { + LOG(ERROR) << "Could not open file: '" << filename << "'"; + return JNI_ERR; + } + file.write(data, length); + file.close(); + + if (!file) { + LOG(ERROR) << "I/O error in reading file"; + return JNI_ERR; + } + + LOG(INFO) << "Done writing file"; + return JNI_OK; +} + +// Grabs execution data and writes it to a file +// dirname: directory name to contain the file +// returns JNI_ERR if there is an error writing the file. +// Will crash if the Agent isn't found or if any Java Exception occurs. +static jint Dump(const std::string& dirname) { + LOG(INFO) << "Dumping file"; + + JNIEnv* env = GetJNIEnv(); + jbyteArray java_result_array = GetExecutionData(env); + CHECK_NOTNULL(java_result_array); + + jbyte* result_ptr = env->GetByteArrayElements(java_result_array, 0); + CHECK_NOTNULL(result_ptr); + + int result_len = env->GetArrayLength(java_result_array); + + return WriteFile((const char*) result_ptr, result_len, dirname); +} + +// Resets execution data, performing the equivalent of +// Agent.getInstance().reset(); +// args: should be empty +// returns JNI_ERR if the arguments are invalid. +// Will crash if the Agent isn't found or if any Java Exception occurs. +static jint Reset(const std::string& args) { + if (args != "") { + LOG(ERROR) << "reset takes no arguments, but received '" << args << "'"; + return JNI_ERR; + } + + JNIEnv* env = GetJNIEnv(); + auto java_agent = GetJavaAgent(env); + + jmethodID java_agent_reset = + env->GetMethodID(get<0>(java_agent), "reset", "()V"); + CHECK_NOTNULL(java_agent_reset); + + env->CallVoidMethod(get<1>(java_agent), java_agent_reset); + CHECK_NO_EXCEPTION(env); + return JNI_OK; +} + +// Given a string of the form ":" returns (, ). +// Given a string that doesn't contain a colon, returns (, ""). +static tuple SplitOnColon(const std::string& options) { + size_t loc_delim = options.find(':'); + std::string command, args; + + if (loc_delim == std::string::npos) { + command = options; + } else { + command = options.substr(0, loc_delim); + args = options.substr(loc_delim + 1, options.length()); + } + return tuple(command, args); +} + +// Parses and executes a command specified by options of the form +// ":" where is either "dump" or "reset". +static jint ParseOptionsAndExecuteCommand(const std::string& options) { + auto split = SplitOnColon(options); + auto command = get<0>(split), args = get<1>(split); + + LOG(INFO) << "command: '" << command << "' args: '" << args << "'"; + + if (command == "dump") { + return Dump(args); + } + + if (command == "reset") { + return Reset(args); + } + + LOG(ERROR) << "Invalid command: expected 'dump' or 'reset' but was '" + << command << "'"; + return JNI_ERR; +} + +static jint AgentStart(JavaVM* vm, char* options) { + android::base::InitLogging(/* argv= */ nullptr); + java_vm = vm; + + return ParseOptionsAndExecuteCommand(options); +} + +// Late attachment (e.g. 'am attach-agent'). +extern "C" JNIEXPORT jint JNICALL +Agent_OnAttach(JavaVM* vm, char* options, void* reserved ATTRIBUTE_UNUSED) { + return AgentStart(vm, options); +} + +// Early attachment. +extern "C" JNIEXPORT jint JNICALL +Agent_OnLoad(JavaVM* jvm ATTRIBUTE_UNUSED, char* options ATTRIBUTE_UNUSED, void* reserved ATTRIBUTE_UNUSED) { + LOG(ERROR) + << "The dumpcoverage agent will not work on load," + << " as it does not have access to the runtime."; + return JNI_ERR; +} + +} // namespace dump_coverage -- GitLab From 3f81e072da4a20d0753787720fac6d014d9e4670 Mon Sep 17 00:00:00 2001 From: Oliver Nguyen Date: Tue, 16 Jul 2019 14:09:38 -0700 Subject: [PATCH 047/219] Change coverage dump to specify the output file instead of directory. Bug: 137857876 Test: manual Change-Id: I2d835856d7a1b6b1ded561eca923f455b39317e4 Merged-In: I2d835856d7a1b6b1ded561eca923f455b39317e4 (cherry picked from commit 05b1c06a91b54321bd2b329916ea0702a020d12e) --- tools/dump-coverage/README.md | 6 ++-- tools/dump-coverage/dump_coverage.cc | 52 +++++----------------------- 2 files changed, 12 insertions(+), 46 deletions(-) diff --git a/tools/dump-coverage/README.md b/tools/dump-coverage/README.md index 2bab4bc8c984..d1c10bc2e520 100644 --- a/tools/dump-coverage/README.md +++ b/tools/dump-coverage/README.md @@ -16,7 +16,7 @@ adb shell 'mkdir /data/data/com.android.deskclock/folder-to-use' Then we can run the command to dump the data: ``` -adb shell 'am attach-agent com.android.deskclock /system/lib/libdumpcoverage.so=dump:/data/data/com.android.deskclock/folder-to-use' +adb shell 'am attach-agent com.android.deskclock /system/lib/libdumpcoverage.so=dump:/data/data/com.android.deskclock/folder-to-use/coverage-file.ec' ``` We can also reset the coverage information with @@ -28,10 +28,10 @@ adb shell 'am attach-agent com.android.deskclock /system/lib/libdumpcoverage.so= then perform more actions, then dump the data again. To get the files, we can get ``` -adb pull /data/data/com.android.deskclock/folder-to-use ~/path-on-your-computer +adb pull /data/data/com.android.deskclock/folder-to-use/coverage-file.ec ~/path-on-your-computer ``` -And you should have timestamped `.exec` files on your machine under the folder `~/path-on-your-computer` +And you should have `coverage-file.ec` on your machine under the folder `~/path-on-your-computer` # Details diff --git a/tools/dump-coverage/dump_coverage.cc b/tools/dump-coverage/dump_coverage.cc index 3de1865b8018..0808e776f190 100644 --- a/tools/dump-coverage/dump_coverage.cc +++ b/tools/dump-coverage/dump_coverage.cc @@ -18,20 +18,10 @@ #include #include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include using std::get; using std::tuple; -using std::chrono::system_clock; namespace dump_coverage { @@ -87,35 +77,11 @@ static jbyteArray GetExecutionData(JNIEnv* env) { return java_result_array; } -// Gets the filename to write execution data to -// dirname: the directory in which to place the file -// outputs /YYYY-MM-DD-HH-MM-SS.SSS.exec -static std::string GetFilename(const std::string& dirname) { - system_clock::time_point time_point = system_clock::now(); - auto seconds = std::chrono::time_point_cast(time_point); - auto fractional_time = time_point - seconds; - auto millis = std::chrono::duration_cast(fractional_time); - - std::time_t time = system_clock::to_time_t(time_point); - auto tm = *std::gmtime(&time); - - std::ostringstream oss; - oss - << dirname - << "/" - << std::put_time(&tm, "%Y-%m-%d-%H-%M-%S.") - << std::setfill('0') << std::setw(3) << millis.count() - << ".ec"; - return oss.str(); -} - -// Writes the execution data to a file -// data, length: represent the data, as a sequence of bytes -// dirname: directory name to contain the file +// Writes the execution data to a file. +// data, length: represent the data, as a sequence of bytes. +// filename: file to write coverage data to. // returns JNI_ERR if there is an error in writing the file, otherwise JNI_OK. -static jint WriteFile(const char* data, int length, const std::string& dirname) { - auto filename = GetFilename(dirname); - +static jint WriteFile(const char* data, int length, const std::string& filename) { LOG(INFO) << "Writing file of length " << length << " to '" << filename << "'"; std::ofstream file(filename, std::ios::binary); @@ -136,11 +102,11 @@ static jint WriteFile(const char* data, int length, const std::string& dirname) return JNI_OK; } -// Grabs execution data and writes it to a file -// dirname: directory name to contain the file +// Grabs execution data and writes it to a file. +// filename: file to write coverage data to. // returns JNI_ERR if there is an error writing the file. // Will crash if the Agent isn't found or if any Java Exception occurs. -static jint Dump(const std::string& dirname) { +static jint Dump(const std::string& filename) { LOG(INFO) << "Dumping file"; JNIEnv* env = GetJNIEnv(); @@ -152,12 +118,12 @@ static jint Dump(const std::string& dirname) { int result_len = env->GetArrayLength(java_result_array); - return WriteFile((const char*) result_ptr, result_len, dirname); + return WriteFile((const char*) result_ptr, result_len, filename); } // Resets execution data, performing the equivalent of // Agent.getInstance().reset(); -// args: should be empty +// args: should be empty. // returns JNI_ERR if the arguments are invalid. // Will crash if the Agent isn't found or if any Java Exception occurs. static jint Reset(const std::string& args) { -- GitLab From 3736484a0d4e92c3436b63d7112ec7db2502c4b0 Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Wed, 29 Jan 2020 18:15:05 -0800 Subject: [PATCH 048/219] Update redaction upon profile changes We can't rely on status bar state changes to update the notification list. The current user might not be set yet, causing wrong notifications to become visible. Fixes: 145135488 Test: manual Test: atest NotificationStackScrollLayoutTest Change-Id: I34d1d5f9a751c1d7680a5a5941c39b9fe33a473b Merged-In: I34d1d5f9a751c1d7680a5a5941c39b9fe33a473b --- .../stack/NotificationStackScrollLayout.java | 7 +++++-- .../stack/NotificationStackScrollLayoutTest.java | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 688e8eb8f2e3..7c49c3f961c9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -566,6 +566,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd mRoundnessManager.setAnimatedChildren(mChildrenToAddAnimated); mRoundnessManager.setOnRoundingChangedCallback(this::invalidate); addOnExpandedHeightChangedListener(mRoundnessManager::setExpanded); + mLockscreenUserManager.addUserChangedListener(userId -> + updateSensitiveness(false /* animated */)); setOutlineProvider(mOutlineProvider); // Blocking helper manager wants to know the expanded state, update as well. @@ -4602,7 +4604,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd } @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) - private void setHideSensitive(boolean hideSensitive, boolean animate) { + private void updateSensitiveness(boolean animate) { + boolean hideSensitive = mLockscreenUserManager.isAnyProfilePublicMode(); if (hideSensitive != mAmbientState.isHideSensitive()) { int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { @@ -5306,7 +5309,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd SysuiStatusBarStateController state = (SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class); - setHideSensitive(publicMode, state.goingToFullShade() /* animate */); + updateSensitiveness(state.goingToFullShade() /* animate */); setDimmed(onKeyguard, state.fromShadeLocked() /* animate */); setExpandingEnabled(!onKeyguard); ActivatableNotificationView activatedChild = getActivatedChild(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index 31054260eb15..7c9537b95319 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -57,6 +57,8 @@ import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.EmptyShadeView; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; +import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShelf; @@ -119,6 +121,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { @Mock private MetricsLogger mMetricsLogger; @Mock private NotificationRoundnessManager mNotificationRoundnessManager; @Mock private KeyguardBypassController mKeyguardBypassController; + @Mock private NotificationLockscreenUserManager mLockscreenUserManager; + private UserChangedListener mUserChangedListener; private TestableNotificationEntryManager mEntryManager; private int mOriginalInterruptionModelSetting; @@ -138,6 +142,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { NotificationBlockingHelperManager.class, mBlockingHelperManager); mDependency.injectTestDependency(SysuiStatusBarStateController.class, mBarState); + mDependency.injectTestDependency(NotificationLockscreenUserManager.class, + mLockscreenUserManager); mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger); mDependency.injectTestDependency(NotificationRemoteInputManager.class, mRemoteInputManager); @@ -152,6 +158,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { NotificationShelf notificationShelf = mock(NotificationShelf.class); + ArgumentCaptor userChangedCaptor = ArgumentCaptor + .forClass(UserChangedListener.class); // The actual class under test. You may need to work with this class directly when // testing anonymous class members of mStackScroller, like mMenuEventListener, @@ -174,6 +182,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { mStackScroller.setGroupManager(mGroupManager); mStackScroller.setEmptyShadeView(mEmptyShadeView); mStackScroller.setIconAreaController(mNotificationIconAreaController); + verify(mLockscreenUserManager).addUserChangedListener(userChangedCaptor.capture()); + mUserChangedListener = userChangedCaptor.getValue(); // Stub out functionality that isn't necessary to test. doNothing().when(mBar) @@ -246,6 +256,12 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { verify(mBlockingHelperManager).setNotificationShadeExpanded(100f); } + @Test + public void testOnStatePostChange_verifyIfProfileIsPublic() { + mUserChangedListener.onUserChanged(0); + verify(mLockscreenUserManager).isAnyProfilePublicMode(); + } + @Test public void manageNotifications_visible() { FooterView view = mock(FooterView.class); -- GitLab From 715c0180eb26c97b9a9ffa95a9a1f8c4d64ff832 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Tue, 24 Sep 2019 09:35:49 -0700 Subject: [PATCH 049/219] Added log statements to some user-switching tasks. NOTE: as user switch is a very low-frequency operation, these logs statements don't need to be guard (to avoid spam). Test: manual verification Bug: 141502467 Bug: 140999054 Bug: 145027829 Change-Id: I7122e45c45a646419b03242c99d90417a29da92a Merged-In: I7122e45c45a646419b03242c99d90417a29da92a (cherry picked from commit ebccffe3b10d8642e7b1d64f183b627f644011a4) (cherry picked from commit b5f0e74302b14dd850b41909052638f24edc15b5) --- .../core/java/com/android/server/am/UserController.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 598a68e90aa8..b8cf27c9698e 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -408,6 +408,7 @@ class UserController implements Handler.Callback { */ private boolean finishUserUnlocking(final UserState uss) { final int userId = uss.mHandle.getIdentifier(); + Slog.d(TAG, "UserController event: finishUserUnlocking(" + userId + ")"); // Only keep marching forward if user is actually unlocked if (!StorageManager.isUserKeyUnlocked(userId)) return false; synchronized (mLock) { @@ -452,6 +453,7 @@ class UserController implements Handler.Callback { */ void finishUserUnlocked(final UserState uss) { final int userId = uss.mHandle.getIdentifier(); + Slog.d(TAG, "UserController event: finishUserUnlocked(" + userId + ")"); // Only keep marching forward if user is actually unlocked if (!StorageManager.isUserKeyUnlocked(userId)) return; synchronized (mLock) { @@ -522,6 +524,7 @@ class UserController implements Handler.Callback { private void finishUserUnlockedCompleted(UserState uss) { final int userId = uss.mHandle.getIdentifier(); + Slog.d(TAG, "UserController event: finishUserUnlockedCompleted(" + userId + ")"); synchronized (mLock) { // Bail if we ended up with a stale user if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return; @@ -739,6 +742,7 @@ class UserController implements Handler.Callback { } void finishUserStopping(final int userId, final UserState uss) { + Slog.d(TAG, "UserController event: finishUserStopping(" + userId + ")"); // On to the next. final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); // This is the result receiver for the final shutdown broadcast. @@ -778,6 +782,7 @@ class UserController implements Handler.Callback { void finishUserStopped(UserState uss) { final int userId = uss.mHandle.getIdentifier(); + Slog.d(TAG, "UserController event: finishUserStopped(" + userId + ")"); final boolean stopped; boolean lockUser = true; final ArrayList stopCallbacks; @@ -1259,7 +1264,7 @@ class UserController implements Handler.Callback { Slog.w(TAG, msg); throw new SecurityException(msg); } - + Slog.i(TAG, "unlocking user " + userId); final long binderToken = Binder.clearCallingIdentity(); try { return unlockUserCleared(userId, token, secret, listener); @@ -1344,6 +1349,7 @@ class UserController implements Handler.Callback { boolean switchUser(final int targetUserId) { enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId); + Slog.i(TAG, "switching to user " + targetUserId); int currentUserId = getCurrentUserId(); UserInfo targetUserInfo = getUserInfo(targetUserId); if (targetUserId == currentUserId) { -- GitLab From eeb7039c236d718929acd2d13774019c0c11fde5 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 29 Jan 2020 12:15:29 -0800 Subject: [PATCH 050/219] Set a shorter timeout for logging a warn on slow IUserSwitchObservers. On automotive, it helps identify slow services. For example: W ActivityManager: User switch delayed: observer #1 WallpaperManagerService sent result after 1608 ms Without this change, the WallpaperManagerService wouldn't be logged because the "give up" timeout is 3000ms. Bug: 145558164 Bug: 144801993 Test: manual verification (see logcat above) Change-Id: I68e3b7220bbac25075e4fd4dad83c3a26b88940c Merged-In: I68e3b7220bbac25075e4fd4dad83c3a26b88940c (cherry picked from commit 48a75cbd675117471f7547c84e00833c32b4a677) --- .../java/com/android/server/am/UserController.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 598a68e90aa8..6807caec1c1b 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -129,6 +129,10 @@ class UserController implements Handler.Callback { // giving up on them and unfreezing the screen. static final int USER_SWITCH_TIMEOUT_MS = 3 * 1000; + // Amount of time we wait for observers to handle a user switch before we log a warning. + // Must be smaller than USER_SWITCH_TIMEOUT_MS. + private static final int USER_SWITCH_WARNING_TIMEOUT_MS = 500; + // ActivityManager thread message constants static final int REPORT_USER_SWITCH_MSG = 10; static final int CONTINUE_USER_SWITCH_MSG = 20; @@ -1486,9 +1490,13 @@ class UserController implements Handler.Callback { synchronized (mLock) { long delay = SystemClock.elapsedRealtime() - dispatchStartedTime; if (delay > USER_SWITCH_TIMEOUT_MS) { - Slog.e(TAG, "User switch timeout: observer " + name + Slog.e(TAG, "User switch timeout: observer " + name + " sent result after " + delay + " ms"); + } else if (delay > USER_SWITCH_WARNING_TIMEOUT_MS) { + Slog.w(TAG, "User switch slowed down by observer " + name + + ": result sent after " + delay + " ms"); } + curWaitingUserSwitchCallbacks.remove(name); // Continue switching if all callbacks have been notified and // user switching session is still valid -- GitLab From c93fa740aa8b3308c6a7b9b83d5bd3e08a4f3c92 Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Wed, 29 Jan 2020 18:15:05 -0800 Subject: [PATCH 051/219] resolve merge conflicts of 01f94b7cc053049a472481f457593d895ad9eca0 to qt-qpr1-dev Bug: None Test: I solemnly swear I tested this conflict resolution. Change-Id: I2d15aaa7402e4e08f1630aa29892ad6cd68bd2b1 Merged-In: I34d1d5f9a751c1d7680a5a5941c39b9fe33a473b --- .../stack/NotificationStackScrollLayout.java | 7 +++++-- .../stack/NotificationStackScrollLayoutTest.java | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 688e8eb8f2e3..7c49c3f961c9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -566,6 +566,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd mRoundnessManager.setAnimatedChildren(mChildrenToAddAnimated); mRoundnessManager.setOnRoundingChangedCallback(this::invalidate); addOnExpandedHeightChangedListener(mRoundnessManager::setExpanded); + mLockscreenUserManager.addUserChangedListener(userId -> + updateSensitiveness(false /* animated */)); setOutlineProvider(mOutlineProvider); // Blocking helper manager wants to know the expanded state, update as well. @@ -4602,7 +4604,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd } @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) - private void setHideSensitive(boolean hideSensitive, boolean animate) { + private void updateSensitiveness(boolean animate) { + boolean hideSensitive = mLockscreenUserManager.isAnyProfilePublicMode(); if (hideSensitive != mAmbientState.isHideSensitive()) { int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { @@ -5306,7 +5309,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd SysuiStatusBarStateController state = (SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class); - setHideSensitive(publicMode, state.goingToFullShade() /* animate */); + updateSensitiveness(state.goingToFullShade() /* animate */); setDimmed(onKeyguard, state.fromShadeLocked() /* animate */); setExpandingEnabled(!onKeyguard); ActivatableNotificationView activatedChild = getActivatedChild(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index 31054260eb15..7c9537b95319 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -57,6 +57,8 @@ import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.EmptyShadeView; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; +import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShelf; @@ -119,6 +121,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { @Mock private MetricsLogger mMetricsLogger; @Mock private NotificationRoundnessManager mNotificationRoundnessManager; @Mock private KeyguardBypassController mKeyguardBypassController; + @Mock private NotificationLockscreenUserManager mLockscreenUserManager; + private UserChangedListener mUserChangedListener; private TestableNotificationEntryManager mEntryManager; private int mOriginalInterruptionModelSetting; @@ -138,6 +142,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { NotificationBlockingHelperManager.class, mBlockingHelperManager); mDependency.injectTestDependency(SysuiStatusBarStateController.class, mBarState); + mDependency.injectTestDependency(NotificationLockscreenUserManager.class, + mLockscreenUserManager); mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger); mDependency.injectTestDependency(NotificationRemoteInputManager.class, mRemoteInputManager); @@ -152,6 +158,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { NotificationShelf notificationShelf = mock(NotificationShelf.class); + ArgumentCaptor userChangedCaptor = ArgumentCaptor + .forClass(UserChangedListener.class); // The actual class under test. You may need to work with this class directly when // testing anonymous class members of mStackScroller, like mMenuEventListener, @@ -174,6 +182,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { mStackScroller.setGroupManager(mGroupManager); mStackScroller.setEmptyShadeView(mEmptyShadeView); mStackScroller.setIconAreaController(mNotificationIconAreaController); + verify(mLockscreenUserManager).addUserChangedListener(userChangedCaptor.capture()); + mUserChangedListener = userChangedCaptor.getValue(); // Stub out functionality that isn't necessary to test. doNothing().when(mBar) @@ -246,6 +256,12 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { verify(mBlockingHelperManager).setNotificationShadeExpanded(100f); } + @Test + public void testOnStatePostChange_verifyIfProfileIsPublic() { + mUserChangedListener.onUserChanged(0); + verify(mLockscreenUserManager).isAnyProfilePublicMode(); + } + @Test public void manageNotifications_visible() { FooterView view = mock(FooterView.class); -- GitLab From 4aced5d9065ebf1abbe35a8bcfb8f3bd105cd77a Mon Sep 17 00:00:00 2001 From: "Chris.CC Lee" Date: Tue, 4 Feb 2020 09:34:48 +0800 Subject: [PATCH 052/219] [DO NOT MERGE] Fix AoD front scrim being opaque at DOZE_PULSING When doze state changed from DOZE to DOZE_PULSING on devices not supporting doze_brightness_sensor_type sensor, there would be no sensor events to update the AoD front scrim. And due to the scrim was set to opaque at DOZE state, most views on the statusbar will be invisible. This patch change the scrim to transparent again at leaving DOZE state. Bug: 148129743 Test: atest DozeScreenBrightnessTest Change-Id: I1cf9d02c9e35dcb3e94cbbc24fec483c51e372d9 --- .../systemui/doze/DozeScreenBrightness.java | 4 ++++ .../systemui/doze/DozeScreenBrightnessTest.java | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java index bd6882c01bbd..c27e633f2a96 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java @@ -161,6 +161,10 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi // again, it will only show after the brightness sensor has stabilized, // avoiding a potential flicker. scrimOpacity = 255; + } else if (!mScreenOff && mLightSensor == null) { + // No light sensor but previous state turned the screen black. Make the scrim + // transparent and below views visible. + scrimOpacity = 0; } else if (brightnessReady) { // Only unblank scrim once brightness is ready. scrimOpacity = computeScrimOpacity(sensorValue); diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java index 392c677b9827..3b760e31b4ac 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java @@ -156,6 +156,20 @@ public class DozeScreenBrightnessTest extends SysuiTestCase { assertEquals(1, mServiceFake.screenBrightness); } + @Test + public void testPulsing_withoutLightSensor_setsAoDDimmingScrimTransparent() throws Exception { + mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager, + null /* sensor */, mHostFake, null /* handler */, + DEFAULT_BRIGHTNESS, SENSOR_TO_BRIGHTNESS, SENSOR_TO_OPACITY, + true /* debuggable */); + mScreen.transitionTo(UNINITIALIZED, INITIALIZED); + mScreen.transitionTo(INITIALIZED, DOZE); + + mScreen.transitionTo(DOZE, DOZE_REQUEST_PULSE); + + assertEquals(0f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); + } + @Test public void testDozingAfterPulsing_pausesLightSensor() throws Exception { mScreen.transitionTo(UNINITIALIZED, INITIALIZED); -- GitLab From b9c4862b8605b653153be29ed902142539f4ffe2 Mon Sep 17 00:00:00 2001 From: Pavel Grafov Date: Wed, 30 Oct 2019 13:29:01 +0000 Subject: [PATCH 053/219] Re-activate backup service after cleaning a profile owner Currently backup service is re-activated unconditionally when clearing a device owner but not profile owner. With this CL it should be re-activate in both cases. NB: there are two bits of state related to backup service: 1. activated or deactivated: This is out of user control, but can be changed by the admin via DPM.setBackupServiceEnabled (this name is a bit misleading here). 2. enabled or disabled: this is controlled by the user via Settings and only available when backup service is activated (see 1.) Bug: 143274029 Bug: 147997438 Test: atest CtsAdminTestCases && adb shell bmgr enabled Test: atest com.android.server.devicepolicy.DevicePolicyManagerTest Merged-In: I6f11642abe544c7df265ed7e2ad466d47796e7f9 Change-Id: I6f11642abe544c7df265ed7e2ad466d47796e7f9 (cherry picked from commit 775b26d8844540680015c5df90f8592c1864a9a8) --- .../DevicePolicyManagerService.java | 15 +++----- .../devicepolicy/DevicePolicyManagerTest.java | 35 ++++++++++++++++--- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 37931be4eb10..c3749c3b0a92 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -8058,15 +8058,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { mSecurityLogMonitor.stop(); setNetworkLoggingActiveInternal(false); deleteTransferOwnershipBundleLocked(userId); - - try { - if (mInjector.getIBackupManager() != null) { - // Reactivate backup service. - mInjector.getIBackupManager().setBackupServiceActive(UserHandle.USER_SYSTEM, true); - } - } catch (RemoteException e) { - throw new IllegalStateException("Failed reactivating backup service.", e); - } + toggleBackupServiceActive(UserHandle.USER_SYSTEM, true); } @Override @@ -8126,7 +8118,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - private void toggleBackupServiceActive(int userId, boolean makeActive) { long ident = mInjector.binderClearCallingIdentity(); try { @@ -8135,7 +8126,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { .setBackupServiceActive(userId, makeActive); } } catch (RemoteException e) { - throw new IllegalStateException("Failed deactivating backup service.", e); + throw new IllegalStateException(String.format("Failed %s backup service.", + makeActive ? "activating" : "deactivating"), e); } finally { mInjector.binderRestoreCallingIdentity(ident); } @@ -8186,6 +8178,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { mOwners.removeProfileOwner(userId); mOwners.writeProfileOwner(userId); deleteTransferOwnershipBundleLocked(userId); + toggleBackupServiceActive(userId, true); } @Override diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 9ae9824da3e2..b9ae23cdfe51 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -909,10 +909,6 @@ public class DevicePolicyManagerTest extends DpmTestBase { verify(getServices().iactivityManager, times(1)).updateDeviceOwner( eq(admin1.getPackageName())); - // TODO We should check if the caller has called clearCallerIdentity(). - verify(getServices().ibackupManager, times(1)).setBackupServiceActive( - eq(UserHandle.USER_SYSTEM), eq(false)); - verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED), MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); @@ -1141,6 +1137,37 @@ public class DevicePolicyManagerTest extends DpmTestBase { // TODO Check other calls. } + public void testDeviceOwnerBackupActivateDeactivate() throws Exception { + mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); + mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); + + // Set admin1 as a DA to the secondary user. + mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; + setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); + dpm.setActiveAdmin(admin1, /* replace =*/ false); + assertTrue(dpm.setDeviceOwner(admin1, "owner-name")); + + verify(getServices().ibackupManager, times(1)).setBackupServiceActive( + eq(UserHandle.USER_SYSTEM), eq(false)); + + dpm.clearDeviceOwnerApp(admin1.getPackageName()); + + verify(getServices().ibackupManager, times(1)).setBackupServiceActive( + eq(UserHandle.USER_SYSTEM), eq(true)); + } + + public void testProfileOwnerBackupActivateDeactivate() throws Exception { + setAsProfileOwner(admin1); + + verify(getServices().ibackupManager, times(1)).setBackupServiceActive( + eq(DpmMockContext.CALLER_USER_HANDLE), eq(false)); + + dpm.clearProfileOwner(admin1); + + verify(getServices().ibackupManager, times(1)).setBackupServiceActive( + eq(DpmMockContext.CALLER_USER_HANDLE), eq(true)); + } + public void testClearDeviceOwner_fromDifferentUser() throws Exception { mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); mContext.callerPermissions.add(permission.MANAGE_USERS); -- GitLab From e693b797bcf0be38f0fc9d878bb5278eacf8b4b1 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Tue, 4 Feb 2020 10:11:12 -0800 Subject: [PATCH 054/219] Call getPackageInfo() with cleared calling identity in ensureSystemPackageName(). Otherwise non-primary users might get a SecurityException. Bug: 145981139 Bug: 148763415 Test: manual Change-Id: I5883e296a0d753e43075cbf0abc5dc4da91e2fca --- .../com/android/server/pm/PackageManagerService.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 035dda2381e0..ca66776239db 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -21231,8 +21231,13 @@ public class PackageManagerService extends IPackageManager.Stub if (packageName == null) { return null; } - if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) { - return null; + long token = Binder.clearCallingIdentity(); + try { + if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) { + return null; + } + } finally { + Binder.restoreCallingIdentity(token); } return packageName; } -- GitLab From 584d73a0b066e01b0877b475c8e2b1a85fcf5328 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Tue, 10 Dec 2019 17:34:18 -0800 Subject: [PATCH 055/219] DO NOT MERGE Ensure package names read from config are system packages. Bug: 145981139 Test: manually tested ensureSystemPackageName() returns null for non-system app Change-Id: I1d23910cbd282f6702785c9dfb059d7be6b0e895 (cherry picked from commit 6a56247200e1a8afc4dacc2497ec384efa200b92) --- .../server/pm/PackageManagerService.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index fc1392ac6b3e..dd86d91517ec 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -20710,7 +20710,29 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public String getSystemTextClassifierPackageName() { - return mContext.getString(R.string.config_defaultTextClassifierPackage); + return ensureSystemPackageName(mContext.getString( + R.string.config_defaultTextClassifierPackage)); + } + + @Nullable + private String ensureSystemPackageName(@Nullable String packageName) { + if (packageName == null) { + return null; + } + long token = Binder.clearCallingIdentity(); + try { + if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) { + PackageInfo packageInfo = getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM); + if (packageInfo != null) { + EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid, + ""); + } + return null; + } + } finally { + Binder.restoreCallingIdentity(token); + } + return packageName; } @Override -- GitLab From 4bf6bc5d50a8c439fe8b67edb1d9dd4a1437f57d Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Tue, 10 Dec 2019 17:34:18 -0800 Subject: [PATCH 056/219] DO NOT MERGE Ensure package names read from config are system packages. Bug: 145981139 Test: manually tested ensureSystemPackageName() returns null for non-system app Change-Id: I1d23910cbd282f6702785c9dfb059d7be6b0e895 Merged-In: I1d23910cbd282f6702785c9dfb059d7be6b0e895 Merged-In: I86c6bfc0a6e28e634e0fd201e424b7ee6882ba2c Merged-In: I5883e296a0d753e43075cbf0abc5dc4da91e2fca (cherry picked from commit 6a56247200e1a8afc4dacc2497ec384efa200b92) --- .../server/pm/PackageManagerService.java | 44 +++++++++++++++---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 161cdb8744f7..289a45b2414b 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3114,8 +3114,7 @@ public class PackageManagerService extends IPackageManager.Stub mWellbeingPackage = getWellbeingPackageName(); mDocumenterPackage = getDocumenterPackageName(); - mConfiguratorPackage = - mContext.getString(R.string.config_deviceConfiguratorPackageName); + mConfiguratorPackage = getDeviceConfiguratorPackageName(); mAppPredictionServicePackage = getAppPredictionServicePackageName(); mIncidentReportApproverPackage = getIncidentReportApproverPackageName(); @@ -21109,7 +21108,8 @@ public class PackageManagerService extends IPackageManager.Stub @Override public String getSystemTextClassifierPackageName() { - return mContext.getString(R.string.config_defaultTextClassifierPackage); + return ensureSystemPackageName(mContext.getString( + R.string.config_defaultTextClassifierPackage)); } @Override @@ -21119,7 +21119,7 @@ public class PackageManagerService extends IPackageManager.Stub if (flattenedComponentName != null) { ComponentName componentName = ComponentName.unflattenFromString(flattenedComponentName); if (componentName != null && componentName.getPackageName() != null) { - return componentName.getPackageName(); + return ensureSystemPackageName(componentName.getPackageName()); } } return null; @@ -21144,9 +21144,15 @@ public class PackageManagerService extends IPackageManager.Stub } } + @Nullable + private String getDeviceConfiguratorPackageName() { + return ensureSystemPackageName(mContext.getString( + R.string.config_deviceConfiguratorPackageName)); + } + @Override public String getWellbeingPackageName() { - return mContext.getString(R.string.config_defaultWellbeingPackage); + return ensureSystemPackageName(mContext.getString(R.string.config_defaultWellbeingPackage)); } @Override @@ -21161,7 +21167,7 @@ public class PackageManagerService extends IPackageManager.Stub if (appPredictionServiceComponentName == null) { return null; } - return appPredictionServiceComponentName.getPackageName(); + return ensureSystemPackageName(appPredictionServiceComponentName.getPackageName()); } @Override @@ -21178,11 +21184,33 @@ public class PackageManagerService extends IPackageManager.Stub if (systemCaptionsServiceComponentName == null) { return null; } - return systemCaptionsServiceComponentName.getPackageName(); + return ensureSystemPackageName(systemCaptionsServiceComponentName.getPackageName()); } public String getIncidentReportApproverPackageName() { - return mContext.getString(R.string.config_incidentReportApproverPackage); + return ensureSystemPackageName(mContext.getString( + R.string.config_incidentReportApproverPackage)); + } + + @Nullable + private String ensureSystemPackageName(@Nullable String packageName) { + if (packageName == null) { + return null; + } + long token = Binder.clearCallingIdentity(); + try { + if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) { + PackageInfo packageInfo = getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM); + if (packageInfo != null) { + EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid, + ""); + } + return null; + } + } finally { + Binder.restoreCallingIdentity(token); + } + return packageName; } @Override -- GitLab From 29e092bf290bacb980a47da22f722c1542197565 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Sat, 25 Jan 2020 06:54:06 -0800 Subject: [PATCH 057/219] Notify all packages is uid-mode is changed Multiple packages might share a UID, but appOpsService might not have cached the uid->package mapping for those yet. Hence the only way to list all packages for a uid is to ask package manager. setUidMode already handled this correctly, hence factor out the code into notifyOpChangedForAllPkgsInUid and reuse it from commitUidStatePendingLocked. Bug: 148180766 Test: (on master) atest CtsAppOpsTestCases:android.app.appops.cts.ForegroundModeTest Change-Id: I99a8f255a60d3523da7eb36a8f2c9426af1a1fea Merged-In: I2d5d6c7aa38d201707349a137c9c29b7987775be --- .../android/server/appop/AppOpsService.java | 54 +++++++++++++------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 3e7188c6e8ec..90d0c3568c13 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -31,6 +31,7 @@ import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE_LOCATION; import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED; import static android.app.AppOpsManager.UID_STATE_PERSISTENT; import static android.app.AppOpsManager.UID_STATE_TOP; +import static android.app.AppOpsManager.WATCH_FOREGROUND_CHANGES; import static android.app.AppOpsManager.modeToName; import static android.app.AppOpsManager.opToName; import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState; @@ -1288,6 +1289,18 @@ public class AppOpsService extends IAppOpsService.Stub { uidState.evalForegroundOps(mOpModeWatchers); } + notifyOpChangedForAllPkgsInUid(code, uid, false); + notifyOpChangedSync(code, uid, null, mode); + } + + /** + * Notify that an op changed for all packages in an uid. + * + * @param code The op that changed + * @param uid The uid the op was changed for + * @param onlyForeground Only notify watchers that watch for foreground changes + */ + private void notifyOpChangedForAllPkgsInUid(int code, int uid, boolean onlyForeground) { String[] uidPackageNames = getPackagesForUid(uid); ArrayMap> callbackSpecs = null; @@ -1297,6 +1310,10 @@ public class AppOpsService extends IAppOpsService.Stub { final int callbackCount = callbacks.size(); for (int i = 0; i < callbackCount; i++) { ModeCallback callback = callbacks.valueAt(i); + if (onlyForeground && (callback.mFlags & WATCH_FOREGROUND_CHANGES) == 0) { + continue; + } + ArraySet changedPackages = new ArraySet<>(); Collections.addAll(changedPackages, uidPackageNames); if (callbackSpecs == null) { @@ -1315,6 +1332,10 @@ public class AppOpsService extends IAppOpsService.Stub { final int callbackCount = callbacks.size(); for (int i = 0; i < callbackCount; i++) { ModeCallback callback = callbacks.valueAt(i); + if (onlyForeground && (callback.mFlags & WATCH_FOREGROUND_CHANGES) == 0) { + continue; + } + ArraySet changedPackages = callbackSpecs.get(callback); if (changedPackages == null) { changedPackages = new ArraySet<>(); @@ -1327,7 +1348,6 @@ public class AppOpsService extends IAppOpsService.Stub { } if (callbackSpecs == null) { - notifyOpChangedSync(code, uid, null, mode); return; } @@ -1349,8 +1369,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } } - - notifyOpChangedSync(code, uid, null, mode); } private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode) { @@ -2496,24 +2514,28 @@ public class AppOpsService extends IAppOpsService.Stub { if (resolvedLastFg == resolvedNowFg) { continue; } - final ArraySet callbacks = mOpModeWatchers.get(code); - if (callbacks != null) { - for (int cbi = callbacks.size() - 1; cbi >= 0; cbi--) { - final ModeCallback callback = callbacks.valueAt(cbi); - if ((callback.mFlags & AppOpsManager.WATCH_FOREGROUND_CHANGES) == 0 - || !callback.isWatchingUid(uidState.uid)) { - continue; - } - boolean doAllPackages = uidState.opModes != null - && uidState.opModes.indexOfKey(code) >= 0 - && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND; - if (uidState.pkgOps != null) { + + if (uidState.opModes != null + && uidState.opModes.indexOfKey(code) >= 0 + && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND) { + mHandler.sendMessage(PooledLambda.obtainMessage( + AppOpsService::notifyOpChangedForAllPkgsInUid, + this, code, uidState.uid, true)); + } else { + final ArraySet callbacks = mOpModeWatchers.get(code); + if (callbacks != null) { + for (int cbi = callbacks.size() - 1; cbi >= 0; cbi--) { + final ModeCallback callback = callbacks.valueAt(cbi); + if ((callback.mFlags & AppOpsManager.WATCH_FOREGROUND_CHANGES) == 0 + || !callback.isWatchingUid(uidState.uid)) { + continue; + } for (int pkgi = uidState.pkgOps.size() - 1; pkgi >= 0; pkgi--) { final Op op = uidState.pkgOps.valueAt(pkgi).get(code); if (op == null) { continue; } - if (doAllPackages || op.mode == AppOpsManager.MODE_FOREGROUND) { + if (op.mode == AppOpsManager.MODE_FOREGROUND) { mHandler.sendMessage(PooledLambda.obtainMessage( AppOpsService::notifyOpChanged, this, callback, code, uidState.uid, -- GitLab From ab9be4fdb63bf30831fd2e05be1315e6c7f067ae Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Sat, 25 Jan 2020 06:57:04 -0800 Subject: [PATCH 058/219] Force update uid state when pending uid state is applied Before the state was update lazily when someone interacted with appopsmanager. Since Q the the uid state might change depending on the procState and hence we might need to trigger the opChanged callbacks when the procState is applied. Bug: 148180766 Test: (on master) atest CtsAppOpsTestCases:android.app.appops.cts.ForegroundModeTest Change-Id: I99720a372db6e79eaba30e4563c09e009cffe86f Merged-In: Id974769a4e9d89c01890b7557dd93f8444a3908f --- .../android/server/appop/AppOpsService.java | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 90d0c3568c13..a5ad42f17912 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -36,6 +36,8 @@ import static android.app.AppOpsManager.modeToName; import static android.app.AppOpsManager.opToName; import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState; +import static java.lang.Long.max; + import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; @@ -934,6 +936,19 @@ public class AppOpsService extends IAppOpsService.Stub { } } + /** + * Update the pending state for the uid + * + * @param currentTime The current elapsed real time + * @param uid The uid that has a pending state + */ + private void updatePendingState(long currentTime, int uid) { + synchronized (this) { + mLastRealtime = max(currentTime, mLastRealtime); + updatePendingStateIfNeededLocked(mUidStates.get(uid)); + } + } + public void updateUidProcState(int uid, int procState) { synchronized (this) { final UidState uidState = getUidStateLocked(uid, true); @@ -959,7 +974,12 @@ public class AppOpsService extends IAppOpsService.Stub { } else { settleTime = mConstants.BG_STATE_SETTLE_TIME; } - uidState.pendingStateCommitTime = SystemClock.elapsedRealtime() + settleTime; + final long commitTime = SystemClock.elapsedRealtime() + settleTime; + uidState.pendingStateCommitTime = commitTime; + + mHandler.sendMessageDelayed( + PooledLambda.obtainMessage(AppOpsService::updatePendingState, this, + commitTime + 1, uid), settleTime + 1); } if (uidState.startNesting != 0) { // There is some actively running operation... need to find it @@ -2485,6 +2505,18 @@ public class AppOpsService extends IAppOpsService.Stub { uidState = new UidState(uid); mUidStates.put(uid, uidState); } else { + updatePendingStateIfNeededLocked(uidState); + } + return uidState; + } + + /** + * Check if the pending state should be updated and do so if needed + * + * @param uidState The uidState that might have a pending state + */ + private void updatePendingStateIfNeededLocked(@NonNull UidState uidState) { + if (uidState != null) { if (uidState.pendingStateCommitTime != 0) { if (uidState.pendingStateCommitTime < mLastRealtime) { commitUidPendingStateLocked(uidState); @@ -2496,7 +2528,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } } - return uidState; } private void commitUidPendingStateLocked(UidState uidState) { -- GitLab From a79b6ba5c59dc6aaa8adbe1ffa3ee4b761f45e7f Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Mon, 19 Aug 2019 16:16:20 -0700 Subject: [PATCH 059/219] DO NOT MERGE - Kill apps outright for API contract violations ...rather than relying on in-app code to perform the shutdown. Backport of security fix. Bug: 128649910 Bug: 140108616 Test: manual Test: atest OsHostTests#testForegroundServiceBadNotification Change-Id: I94d9de50bb03c33666471e3dbd9c721e9278f7cb Merged-In: I94d9de50bb03c33666471e3dbd9c721e9278f7cb --- core/java/android/app/IActivityManager.aidl | 3 ++- .../com/android/server/am/ActiveServices.java | 11 +++++++- .../server/am/ActivityManagerService.java | 5 ++-- .../am/ActivityManagerShellCommand.java | 2 +- .../java/com/android/server/am/AppErrors.java | 26 ++++++++++++++----- .../com/android/server/am/ServiceRecord.java | 7 +++-- .../NotificationManagerService.java | 14 ++++++++++ 7 files changed, 52 insertions(+), 16 deletions(-) diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index b192021f821b..3f7f3b73c417 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -278,7 +278,8 @@ interface IActivityManager { boolean isImmersive(in IBinder token); void setImmersive(in IBinder token, boolean immersive); boolean isTopActivityImmersive(); - void crashApplication(int uid, int initialPid, in String packageName, int userId, in String message); + void crashApplication(int uid, int initialPid, in String packageName, int userId, + in String message, boolean force); String getProviderMimeType(in Uri uri, int userId); IBinder newUriPermissionOwner(in String name); void grantUriPermissionFromOwner(in IBinder owner, int fromUid, in String targetPkg, diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index ca715b51a328..b49d07f3e46c 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -787,6 +787,15 @@ public final class ActiveServices { } } + void killMisbehavingService(ServiceRecord r, + int appUid, int appPid, String localPackageName) { + synchronized (mAm) { + stopServiceLocked(r); + mAm.crashApplication(appUid, appPid, localPackageName, -1, + "Bad notification for startForeground", true /*force*/); + } + } + IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) { ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(), Binder.getCallingUid(), @@ -3655,7 +3664,7 @@ public final class ActiveServices { void serviceForegroundCrash(ProcessRecord app, CharSequence serviceRecord) { mAm.crashApplication(app.uid, app.pid, app.info.packageName, app.userId, "Context.startForegroundService() did not then call Service.startForeground(): " - + serviceRecord); + + serviceRecord, false /*force*/); } void scheduleServiceTimeoutLocked(ProcessRecord proc) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 7c57c43533af..3dea717a9982 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5773,7 +5773,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void crashApplication(int uid, int initialPid, String packageName, int userId, - String message) { + String message, boolean force) { if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: crashApplication() from pid=" @@ -5785,7 +5785,8 @@ public class ActivityManagerService extends IActivityManager.Stub } synchronized(this) { - mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message); + mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, + message, force); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index ccbc8ed32a9c..adb7056408ba 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -987,7 +987,7 @@ final class ActivityManagerShellCommand extends ShellCommand { } catch (NumberFormatException e) { packageName = arg; } - mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash"); + mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash", false); return 0; } diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index f0e2876b4761..0b8fca9d8e71 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -314,20 +314,24 @@ class AppErrors { } void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) { - app.crashing = false; - app.crashingReport = null; - app.notResponding = false; - app.notRespondingReport = null; if (app.anrDialog == fromDialog) { app.anrDialog = null; } if (app.waitDialog == fromDialog) { app.waitDialog = null; } + killAppImmediateLocked(app, "user-terminated", "user request after error"); + } + + private void killAppImmediateLocked(ProcessRecord app, String reason, String killReason) { + app.crashing = false; + app.crashingReport = null; + app.notResponding = false; + app.notRespondingReport = null; if (app.pid > 0 && app.pid != MY_PID) { - handleAppCrashLocked(app, "user-terminated" /*reason*/, + handleAppCrashLocked(app, reason, null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/); - app.kill("user request after error", true); + app.kill(killReason, true); } } @@ -341,7 +345,7 @@ class AppErrors { * @param message */ void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId, - String message) { + String message, boolean force) { ProcessRecord proc = null; // Figure out which process to kill. We don't trust that initialPid @@ -374,6 +378,14 @@ class AppErrors { } proc.scheduleCrash(message); + if (force) { + // If the app is responsive, the scheduled crash will happen as expected + // and then the delayed summary kill will be a no-op. + final ProcessRecord p = proc; + mService.mHandler.postDelayed( + () -> killAppImmediateLocked(p, "forced", "killed for invalid state"), + 5000L); + } } /** diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 4d89d015b669..925a4d97fa32 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -584,6 +584,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN final String localPackageName = packageName; final int localForegroundId = foregroundId; final Notification _foregroundNoti = foregroundNoti; + final ServiceRecord record = this; ams.mHandler.post(new Runnable() { public void run() { NotificationManagerInternal nm = LocalServices.getService( @@ -682,10 +683,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN Slog.w(TAG, "Error showing notification for service", e); // If it gave us a garbage notification, it doesn't // get to be foreground. - ams.setServiceForeground(name, ServiceRecord.this, - 0, null, 0); - ams.crashApplication(appUid, appPid, localPackageName, -1, - "Bad notification for startForeground: " + e); + ams.mServices.killMisbehavingService(record, + appUid, appPid, localPackageName); } } }); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index b1ea47c6f3b0..c4647096f61c 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -798,8 +798,22 @@ public class NotificationManagerService extends SystemService { @Override public void onNotificationError(int callingUid, int callingPid, String pkg, String tag, int id, int uid, int initialPid, String message, int userId) { + final boolean fgService; + synchronized (mNotificationLock) { + NotificationRecord r = findNotificationLocked(pkg, tag, id, userId); + fgService = r != null && (r.getNotification().flags & FLAG_FOREGROUND_SERVICE) != 0; + } cancelNotification(callingUid, callingPid, pkg, tag, id, 0, 0, false, userId, REASON_ERROR, null); + if (fgService) { + // Still crash for foreground services, preventing the not-crash behaviour abused + // by apps to give us a garbage notification and silently start a fg service. + Binder.withCleanCallingIdentity( + () -> mAm.crashApplication(uid, initialPid, pkg, -1, + "Bad notification(tag=" + tag + ", id=" + id + ") posted from package " + + pkg + ", crashing app(uid=" + uid + ", pid=" + initialPid + "): " + + message, true /* force */)); + } } @Override -- GitLab From 6b14ea266e9c5d72db901272f9c8e6e0ef0a51f3 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Fri, 31 Jan 2020 16:25:45 -0800 Subject: [PATCH 060/219] Add SafetyNet logging for package names read from config. Bug: 145981139 Test: manual Change-Id: I86c6bfc0a6e28e634e0fd201e424b7ee6882ba2c --- .../java/com/android/server/pm/PackageManagerService.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index ca66776239db..8ee925e182e4 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -21234,6 +21234,11 @@ public class PackageManagerService extends IPackageManager.Stub long token = Binder.clearCallingIdentity(); try { if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) { + PackageInfo packageInfo = getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM); + if (packageInfo != null) { + EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid, + ""); + } return null; } } finally { -- GitLab From ed30689e2190b19641db6cef664eb32d2f7cf0e0 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 5 Dec 2019 09:55:36 -0800 Subject: [PATCH 061/219] DO NOT MERGE - Use TimingsTraceLog on SystemServiceManager and VoiceInteractionManagerService. (NOTE: this change is manually cherry-picked from master - master has the same trace calls, but they were introduced by larger changes) Bug: 145626101 Bug: 145027829 Test: manual verification Change-Id: I5cae10c9c7e5ed6f733c72659643708dfa826fc7 --- .../android/server/SystemServiceManager.java | 41 ++++++++++++------- .../VoiceInteractionManagerService.java | 25 ++++++++++- 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java index c5b4966ddcf2..3df585e4b866 100644 --- a/services/core/java/com/android/server/SystemServiceManager.java +++ b/services/core/java/com/android/server/SystemServiceManager.java @@ -22,6 +22,7 @@ import android.os.Environment; import android.os.SystemClock; import android.os.Trace; import android.util.Slog; +import android.util.TimingsTraceLog; import java.io.File; import java.lang.reflect.Constructor; @@ -178,12 +179,13 @@ public class SystemServiceManager { } public void startUser(final int userHandle) { + final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER); + t.traceBegin("ssm.startUser-" + userHandle); Slog.i(TAG, "Calling onStartUser u" + userHandle); final int serviceLen = mServices.size(); for (int i = 0; i < serviceLen; i++) { final SystemService service = mServices.get(i); - Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onStartUser " - + service.getClass().getName()); + t.traceBegin("onStartUser-" + userHandle + " " + service.getClass().getName()); long time = SystemClock.elapsedRealtime(); try { service.onStartUser(userHandle); @@ -192,17 +194,19 @@ public class SystemServiceManager { + " to service " + service.getClass().getName(), ex); } warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStartUser "); - Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + t.traceEnd(); } + t.traceEnd(); } public void unlockUser(final int userHandle) { + final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER); + t.traceBegin("ssm.unlockUser-" + userHandle); Slog.i(TAG, "Calling onUnlockUser u" + userHandle); final int serviceLen = mServices.size(); for (int i = 0; i < serviceLen; i++) { final SystemService service = mServices.get(i); - Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onUnlockUser " - + service.getClass().getName()); + t.traceBegin("onUnlockUser-" + userHandle + " " + service.getClass().getName()); long time = SystemClock.elapsedRealtime(); try { service.onUnlockUser(userHandle); @@ -211,17 +215,19 @@ public class SystemServiceManager { + " to service " + service.getClass().getName(), ex); } warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onUnlockUser "); - Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + t.traceEnd(); } + t.traceEnd(); } public void switchUser(final int userHandle) { + final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER); + t.traceBegin("ssm.switchUser-" + userHandle); Slog.i(TAG, "Calling switchUser u" + userHandle); final int serviceLen = mServices.size(); for (int i = 0; i < serviceLen; i++) { final SystemService service = mServices.get(i); - Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onSwitchUser " - + service.getClass().getName()); + t.traceBegin("onSwitchUser-" + userHandle + " " + service.getClass().getName()); long time = SystemClock.elapsedRealtime(); try { service.onSwitchUser(userHandle); @@ -230,17 +236,19 @@ public class SystemServiceManager { + " to service " + service.getClass().getName(), ex); } warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onSwitchUser"); - Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + t.traceEnd(); } + t.traceEnd(); } public void stopUser(final int userHandle) { + final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER); + t.traceBegin("ssm.stopUser-" + userHandle); Slog.i(TAG, "Calling onStopUser u" + userHandle); final int serviceLen = mServices.size(); for (int i = 0; i < serviceLen; i++) { final SystemService service = mServices.get(i); - Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onStopUser " - + service.getClass().getName()); + t.traceBegin("onStopUser-" + userHandle + " " + service.getClass().getName()); long time = SystemClock.elapsedRealtime(); try { service.onStopUser(userHandle); @@ -249,17 +257,19 @@ public class SystemServiceManager { + " to service " + service.getClass().getName(), ex); } warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStopUser"); - Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + t.traceEnd(); } + t.traceEnd(); } public void cleanupUser(final int userHandle) { + final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER); + t.traceBegin("ssm.cleanupUser-" + userHandle); Slog.i(TAG, "Calling onCleanupUser u" + userHandle); final int serviceLen = mServices.size(); for (int i = 0; i < serviceLen; i++) { final SystemService service = mServices.get(i); - Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onCleanupUser " - + service.getClass().getName()); + t.traceBegin("onCleanupUser-" + userHandle + " " + service.getClass().getName()); long time = SystemClock.elapsedRealtime(); try { service.onCleanupUser(userHandle); @@ -268,8 +278,9 @@ public class SystemServiceManager { + " to service " + service.getClass().getName(), ex); } warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onCleanupUser"); - Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + t.traceEnd(); } + t.traceEnd(); } /** Sets the safe mode flag for services to query. */ diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index 46d7509b43ca..0b1c07b9ee43 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -20,6 +20,7 @@ import android.Manifest; import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.AppGlobals; @@ -51,6 +52,7 @@ import android.os.Parcel; import android.os.RemoteCallback; import android.os.RemoteCallbackList; import android.os.RemoteException; +import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; @@ -65,6 +67,7 @@ import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; import android.util.Slog; +import android.util.TimingsTraceLog; import com.android.internal.app.IVoiceActionCheckCallback; import com.android.internal.app.IVoiceInteractionManagerService; @@ -269,7 +272,17 @@ public class VoiceInteractionManagerService extends SystemService { } } - public void initForUser(int userHandle) { + public void initForUser(@UserIdInt int userHandle) { + final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER); + t.traceBegin("initForUser(" + userHandle + ")"); + try { + initForUserNoTracing(userHandle); + } finally { + t.traceEnd(); + } + } + + private void initForUserNoTracing(@UserIdInt int userHandle) { if (DEBUG) Slog.d(TAG, "**************** initForUser user=" + userHandle); String curInteractorStr = Settings.Secure.getStringForUser( mContext.getContentResolver(), @@ -426,6 +439,16 @@ public class VoiceInteractionManagerService extends SystemService { } void switchImplementationIfNeededLocked(boolean force) { + final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER); + t.traceBegin("switchImplementation(" + mCurUser + ")"); + try { + switchImplementationIfNeededNoTracingLocked(force); + } finally { + t.traceEnd(); + } + } + + void switchImplementationIfNeededNoTracingLocked(boolean force) { if (!mSafeMode) { String curService = Settings.Secure.getStringForUser( mResolver, Settings.Secure.VOICE_INTERACTION_SERVICE, mCurUser); -- GitLab From f35f2913f88610764efb8b4ac2db6bbf393326ee Mon Sep 17 00:00:00 2001 From: Tobias Thierer Date: Wed, 8 May 2019 22:00:38 +0100 Subject: [PATCH 062/219] Parcel only the canonical Uri.Part representation, not both. Before this CL, Uri.AbstractPart's implementation of Parcelable was parceling and unparceling both the encoded and the decoded representation. A Uri with inconsistent decoded/encoded representation of its Parts would have remained inconsistent across parcel/unparcel cycles. For example, such a Uri's uri.getDecodedAuthority() might have returned "good.com" while url.getEncodedAuthority() (used e.g. for toString()) returned "evil.com". After this CL, AbstractPart's constructor allows at most one of the representations to be set (exception: NULL and EMPTY); this means that no Part instance with inconsistent values can be constructed via the constructor (e.g. by unparceling parceled data). The historical parcel representation of a Part with both values present can no longer be unparceled, which is safe because Parcel does not guarantee backwards compatibility (the parceled form must not be persisted across Android version upgrades). When parceling, only one of the values is now stored, namely the (canonical) one that was passed to the constructor. Fixes: 124526860 Test: atest FrameworksCoreTests:android.net.UriTest Test: Checked that if run before this CL, the added tests would fail with a failure along the lines of: ComparisonFailure: expected: but was: or (if the first assertion was commented out): ComparisonFailure: expected:<[b].com> but was:<[a].com> Change-Id: I2bc2008e49de5a66641ecdbd8e5354dfa647269d Merged-In: I2bc2008e49de5a66641ecdbd8e5354dfa647269d (cherry picked from commit c9afa38f974317b6b0e28410bbc3426a41791660) --- core/java/android/net/Uri.java | 61 +++++++++++-------- .../coretests/src/android/net/UriTest.java | 60 ++++++++++++++++++ 2 files changed, 94 insertions(+), 27 deletions(-) diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java index c3166e91fac7..8cf182b41566 100644 --- a/core/java/android/net/Uri.java +++ b/core/java/android/net/Uri.java @@ -1987,17 +1987,26 @@ public abstract class Uri implements Parcelable, Comparable { * Enum which indicates which representation of a given part we have. */ static class Representation { - static final int BOTH = 0; static final int ENCODED = 1; static final int DECODED = 2; } volatile String encoded; volatile String decoded; + private final int mCanonicalRepresentation; AbstractPart(String encoded, String decoded) { - this.encoded = encoded; - this.decoded = decoded; + if (encoded != NOT_CACHED) { + this.mCanonicalRepresentation = Representation.ENCODED; + this.encoded = encoded; + this.decoded = NOT_CACHED; + } else if (decoded != NOT_CACHED) { + this.mCanonicalRepresentation = Representation.DECODED; + this.encoded = NOT_CACHED; + this.decoded = decoded; + } else { + throw new IllegalArgumentException("Neither encoded nor decoded"); + } } abstract String getEncoded(); @@ -2009,25 +2018,21 @@ public abstract class Uri implements Parcelable, Comparable { } final void writeTo(Parcel parcel) { - @SuppressWarnings("StringEquality") - boolean hasEncoded = encoded != NOT_CACHED; - - @SuppressWarnings("StringEquality") - boolean hasDecoded = decoded != NOT_CACHED; - - if (hasEncoded && hasDecoded) { - parcel.writeInt(Representation.BOTH); - parcel.writeString(encoded); - parcel.writeString(decoded); - } else if (hasEncoded) { - parcel.writeInt(Representation.ENCODED); - parcel.writeString(encoded); - } else if (hasDecoded) { - parcel.writeInt(Representation.DECODED); - parcel.writeString(decoded); + final String canonicalValue; + if (mCanonicalRepresentation == Representation.ENCODED) { + canonicalValue = encoded; + } else if (mCanonicalRepresentation == Representation.DECODED) { + canonicalValue = decoded; } else { - throw new IllegalArgumentException("Neither encoded nor decoded"); + throw new IllegalArgumentException("Unknown representation: " + + mCanonicalRepresentation); + } + if (canonicalValue == NOT_CACHED) { + throw new AssertionError("Canonical value not cached (" + + mCanonicalRepresentation + ")"); } + parcel.writeInt(mCanonicalRepresentation); + parcel.writeString(canonicalValue); } } @@ -2059,13 +2064,12 @@ public abstract class Uri implements Parcelable, Comparable { static Part readFrom(Parcel parcel) { int representation = parcel.readInt(); + String value = parcel.readString(); switch (representation) { - case Representation.BOTH: - return from(parcel.readString(), parcel.readString()); case Representation.ENCODED: - return fromEncoded(parcel.readString()); + return fromEncoded(value); case Representation.DECODED: - return fromDecoded(parcel.readString()); + return fromDecoded(value); default: throw new IllegalArgumentException("Unknown representation: " + representation); @@ -2127,6 +2131,11 @@ public abstract class Uri implements Parcelable, Comparable { private static class EmptyPart extends Part { public EmptyPart(String value) { super(value, value); + if (value != null && !value.isEmpty()) { + throw new IllegalArgumentException("Expected empty value, got: " + value); + } + // Avoid having to re-calculate the non-canonical value. + encoded = decoded = value; } @Override @@ -2245,14 +2254,12 @@ public abstract class Uri implements Parcelable, Comparable { static PathPart readFrom(Parcel parcel) { int representation = parcel.readInt(); switch (representation) { - case Representation.BOTH: - return from(parcel.readString(), parcel.readString()); case Representation.ENCODED: return fromEncoded(parcel.readString()); case Representation.DECODED: return fromDecoded(parcel.readString()); default: - throw new IllegalArgumentException("Bad representation: " + representation); + throw new IllegalArgumentException("Unknown representation: " + representation); } } diff --git a/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java index a71000bd220c..f20220c4ab9b 100644 --- a/core/tests/coretests/src/android/net/UriTest.java +++ b/core/tests/coretests/src/android/net/UriTest.java @@ -24,6 +24,9 @@ import androidx.test.filters.SmallTest; import junit.framework.TestCase; import java.io.File; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Arrays; import java.util.Iterator; import java.util.List; @@ -816,6 +819,63 @@ public class UriTest extends TestCase { Uri.parse("content://com.example/path%2Fpath"))); } + + /** + * Check that calling Part(String, String) with inconsistent Strings does not lead + * to the Part's encoded vs. decoded values being inconsistent. + */ + public void testPart_consistentEncodedVsDecoded() throws Exception { + Object authority = createPart(Class.forName("android.net.Uri$Part"), "a.com", "b.com"); + Object path = createPart(Class.forName("android.net.Uri$PathPart"), "/foo/a", "/foo/b"); + Uri uri = makeHierarchicalUri(authority, path); + // In these cases, decoding/encoding the encoded/decoded representation yields the same + // String, so we can just assert equality. + // assertEquals(uri.getPath(), uri.getEncodedPath()); + assertEquals(uri.getAuthority(), uri.getEncodedAuthority()); + + // When both encoded and decoded strings are given, the encoded one is preferred. + assertEquals("a.com", uri.getAuthority()); + assertEquals("/foo/a", uri.getPath()); + } + + private Object createPart(Class partClass, String encoded, String decoded) throws Exception { + Constructor partConstructor = partClass.getDeclaredConstructor(String.class, String.class); + partConstructor.setAccessible(true); + return partConstructor.newInstance(encoded, decoded); + } + + private static Uri makeHierarchicalUri(Object authority, Object path) throws Exception { + Class hierarchicalUriClass = Class.forName("android.net.Uri$HierarchicalUri"); + Constructor hierarchicalUriConstructor = hierarchicalUriClass.getDeclaredConstructors()[0]; + hierarchicalUriConstructor.setAccessible(true); + return (Uri) hierarchicalUriConstructor.newInstance("https", authority, path, null, null); + } + + /** Attempting to unparcel a legacy parcel format of Uri.{,Path}Part should fail. */ + public void testUnparcelLegacyPart_fails() throws Exception { + assertUnparcelLegacyPart_fails(Class.forName("android.net.Uri$Part")); + assertUnparcelLegacyPart_fails(Class.forName("android.net.Uri$PathPart")); + } + + private static void assertUnparcelLegacyPart_fails(Class partClass) throws Exception { + Parcel parcel = Parcel.obtain(); + parcel.writeInt(0 /* BOTH */); + parcel.writeString("encoded"); + parcel.writeString("decoded"); + parcel.setDataPosition(0); + + Method readFromMethod = partClass.getDeclaredMethod("readFrom", Parcel.class); + readFromMethod.setAccessible(true); + try { + readFromMethod.invoke(null, parcel); + fail(); + } catch (InvocationTargetException expected) { + Throwable targetException = expected.getTargetException(); + // Check that the exception was thrown for the correct reason. + assertEquals("Unknown representation: 0", targetException.getMessage()); + } + } + public void testToSafeString() { checkToSafeString("tel:xxxxxx", "tel:Google"); checkToSafeString("tel:xxxxxxxxxx", "tel:1234567890"); -- GitLab From 38567a6051bbc38041048fa36f5e83ac00adba70 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Mon, 19 Aug 2019 16:16:20 -0700 Subject: [PATCH 063/219] DO NOT MERGE - Kill apps outright for API contract violations ...rather than relying on in-app code to perform the shutdown. Bug: 128649910 Bug: 140108616 Test: manual Test: atest OsHostTests#testForegroundServiceBadNotification Change-Id: I94d9de50bb03c33666471e3dbd9c721e9278f7cb Merged-In: I94d9de50bb03c33666471e3dbd9c721e9278f7cb --- core/java/android/app/IActivityManager.aidl | 3 ++- .../com/android/server/am/ActiveServices.java | 11 +++++++- .../server/am/ActivityManagerService.java | 5 ++-- .../am/ActivityManagerShellCommand.java | 2 +- .../java/com/android/server/am/AppErrors.java | 26 ++++++++++++++----- .../com/android/server/am/ServiceRecord.java | 7 +++-- .../NotificationManagerService.java | 14 ++++++++++ 7 files changed, 52 insertions(+), 16 deletions(-) diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 48ca71690a1b..c0c63555b10a 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -287,7 +287,8 @@ interface IActivityManager { void handleApplicationStrictModeViolation(in IBinder app, int penaltyMask, in StrictMode.ViolationInfo crashInfo); boolean isTopActivityImmersive(); - void crashApplication(int uid, int initialPid, in String packageName, int userId, in String message); + void crashApplication(int uid, int initialPid, in String packageName, int userId, + in String message, boolean force); @UnsupportedAppUsage String getProviderMimeType(in Uri uri, int userId); // Cause the specified process to dump the specified heap. diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 7bc2e6d647be..5d72828964c7 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -829,6 +829,15 @@ public final class ActiveServices { } } + void killMisbehavingService(ServiceRecord r, + int appUid, int appPid, String localPackageName) { + synchronized (mAm) { + stopServiceLocked(r); + mAm.crashApplication(appUid, appPid, localPackageName, -1, + "Bad notification for startForeground", true /*force*/); + } + } + IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) { ServiceLookupResult r = retrieveServiceLocked(service, null, resolvedType, callingPackage, Binder.getCallingPid(), Binder.getCallingUid(), @@ -3918,7 +3927,7 @@ public final class ActiveServices { void serviceForegroundCrash(ProcessRecord app, CharSequence serviceRecord) { mAm.crashApplication(app.uid, app.pid, app.info.packageName, app.userId, "Context.startForegroundService() did not then call Service.startForeground(): " - + serviceRecord); + + serviceRecord, false /*force*/); } void scheduleServiceTimeoutLocked(ProcessRecord proc) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index c6cae530e795..81d636ea832f 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -3568,7 +3568,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void crashApplication(int uid, int initialPid, String packageName, int userId, - String message) { + String message, boolean force) { if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: crashApplication() from pid=" @@ -3580,7 +3580,8 @@ public class ActivityManagerService extends IActivityManager.Stub } synchronized(this) { - mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message); + mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, + message, force); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index cba9674d7360..8f16ed4768de 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -1051,7 +1051,7 @@ final class ActivityManagerShellCommand extends ShellCommand { } catch (NumberFormatException e) { packageName = arg; } - mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash"); + mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash", false); return 0; } diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index 1ff6f4dac724..6a29c75b702a 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -314,20 +314,24 @@ class AppErrors { } void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) { - app.setCrashing(false); - app.crashingReport = null; - app.setNotResponding(false); - app.notRespondingReport = null; if (app.anrDialog == fromDialog) { app.anrDialog = null; } if (app.waitDialog == fromDialog) { app.waitDialog = null; } + killAppImmediateLocked(app, "user-terminated", "user request after error"); + } + + private void killAppImmediateLocked(ProcessRecord app, String reason, String killReason) { + app.setCrashing(false); + app.crashingReport = null; + app.setNotResponding(false); + app.notRespondingReport = null; if (app.pid > 0 && app.pid != MY_PID) { - handleAppCrashLocked(app, "user-terminated" /*reason*/, + handleAppCrashLocked(app, reason, null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/); - app.kill("user request after error", true); + app.kill(killReason, true); } } @@ -341,7 +345,7 @@ class AppErrors { * @param message */ void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId, - String message) { + String message, boolean force) { ProcessRecord proc = null; // Figure out which process to kill. We don't trust that initialPid @@ -374,6 +378,14 @@ class AppErrors { } proc.scheduleCrash(message); + if (force) { + // If the app is responsive, the scheduled crash will happen as expected + // and then the delayed summary kill will be a no-op. + final ProcessRecord p = proc; + mService.mHandler.postDelayed( + () -> killAppImmediateLocked(p, "forced", "killed for invalid state"), + 5000L); + } } /** diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index dee8e3b285a7..c408695bcb66 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -798,6 +798,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN final String localPackageName = packageName; final int localForegroundId = foregroundId; final Notification _foregroundNoti = foregroundNoti; + final ServiceRecord record = this; ams.mHandler.post(new Runnable() { public void run() { NotificationManagerInternal nm = LocalServices.getService( @@ -896,10 +897,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN Slog.w(TAG, "Error showing notification for service", e); // If it gave us a garbage notification, it doesn't // get to be foreground. - ams.setServiceForeground(instanceName, ServiceRecord.this, - 0, null, 0, 0); - ams.crashApplication(appUid, appPid, localPackageName, -1, - "Bad notification for startForeground: " + e); + ams.mServices.killMisbehavingService(record, + appUid, appPid, localPackageName); } } }); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 928747ecf14c..1eaafd4a8de1 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -892,8 +892,22 @@ public class NotificationManagerService extends SystemService { @Override public void onNotificationError(int callingUid, int callingPid, String pkg, String tag, int id, int uid, int initialPid, String message, int userId) { + final boolean fgService; + synchronized (mNotificationLock) { + NotificationRecord r = findNotificationLocked(pkg, tag, id, userId); + fgService = r != null && (r.getNotification().flags & FLAG_FOREGROUND_SERVICE) != 0; + } cancelNotification(callingUid, callingPid, pkg, tag, id, 0, 0, false, userId, REASON_ERROR, null); + if (fgService) { + // Still crash for foreground services, preventing the not-crash behaviour abused + // by apps to give us a garbage notification and silently start a fg service. + Binder.withCleanCallingIdentity( + () -> mAm.crashApplication(uid, initialPid, pkg, -1, + "Bad notification(tag=" + tag + ", id=" + id + ") posted from package " + + pkg + ", crashing app(uid=" + uid + ", pid=" + initialPid + "): " + + message, true /* force */)); + } } @Override -- GitLab From c4808d9a4b846b612a3d2a377a096ca92b66736b Mon Sep 17 00:00:00 2001 From: Aarthi Balachander Date: Mon, 27 Aug 2018 11:03:59 -0700 Subject: [PATCH 064/219] Make switching dialog full screen and change "Loading" text color. Bug: 148318514 Bug: 111928877, 112242211 Test: Tested on device Change-Id: Iaa45b8e7581f2a19106a6e734432fe2cda661a33 (cherry picked from commit 88def57a6d97271013c0ca996950ff33939e7013) --- core/res/res/layout/car_user_switching_dialog.xml | 13 +++++-------- .../android/server/am/CarUserSwitchingDialog.java | 3 --- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/core/res/res/layout/car_user_switching_dialog.xml b/core/res/res/layout/car_user_switching_dialog.xml index 7ce35df3613a..d7274348bd16 100644 --- a/core/res/res/layout/car_user_switching_dialog.xml +++ b/core/res/res/layout/car_user_switching_dialog.xml @@ -16,25 +16,22 @@ --> + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + android:layout_centerHorizontal="true"/> + android:gravity="center"/> \ No newline at end of file diff --git a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java index 60754fbc5cd3..a6811e3070b2 100644 --- a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java +++ b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java @@ -30,7 +30,6 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; -import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.UserManager; import android.provider.Settings; @@ -57,8 +56,6 @@ final class CarUserSwitchingDialog extends UserSwitchingDialog { String switchingToSystemUserMessage) { super(service, context, oldUser, newUser, aboveSystem, switchingFromSystemUserMessage, switchingToSystemUserMessage); - - getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); } @Override -- GitLab From fb23ff98d90936bbae0d8f8ee3cd4465d9659680 Mon Sep 17 00:00:00 2001 From: Heemin Seog Date: Wed, 5 Feb 2020 17:35:19 -0800 Subject: [PATCH 065/219] Add null check for handler on Clock view On reboot, we've encountered an issue where the handler returns null, causing a null pointer exception in the broadcast receiver. In this CL, we add a null check and an error message to prevent a sysui crash. Bug: 148869042 Test: build, reboot a few times Change-Id: Iac7f3a538be9a53d4a76926523aa2a3f4f22723d Merged-In: Ie8a2627004876cf35291d52bd3686a5014498f52 --- .../systemui/statusbar/policy/Clock.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java index c2c3f81527e8..371de7439f8f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java @@ -34,6 +34,7 @@ import android.text.format.DateFormat; import android.text.style.CharacterStyle; import android.text.style.RelativeSizeSpan; import android.util.AttributeSet; +import android.util.Log; import android.view.Display; import android.view.View; import android.widget.TextView; @@ -67,6 +68,7 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C DarkReceiver, ConfigurationListener { public static final String CLOCK_SECONDS = "clock_seconds"; + private static final String TAG = "StatusBarClock"; private static final String CLOCK_SUPER_PARCELABLE = "clock_super_parcelable"; private static final String CURRENT_USER_ID = "current_user_id"; private static final String VISIBLE_BY_POLICY = "visible_by_policy"; @@ -228,9 +230,18 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); + Handler handler = getHandler(); + if (handler == null) { + Log.e(TAG, + "Received intent, but handler is null - still attached to window? Window " + + "token: " + + getWindowToken()); + return; + } + if (action.equals(Intent.ACTION_TIMEZONE_CHANGED)) { String tz = intent.getStringExtra("time-zone"); - getHandler().post(() -> { + handler.post(() -> { mCalendar = Calendar.getInstance(TimeZone.getTimeZone(tz)); if (mClockFormat != null) { mClockFormat.setTimeZone(mCalendar.getTimeZone()); @@ -238,14 +249,14 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C }); } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { final Locale newLocale = getResources().getConfiguration().locale; - getHandler().post(() -> { + handler.post(() -> { if (!newLocale.equals(mLocale)) { mLocale = newLocale; mClockFormatString = ""; // force refresh } }); } - getHandler().post(() -> updateClock()); + handler.post(() -> updateClock()); } }; -- GitLab From a5fb0829d5aae26a5164fb132838a451d4cf8214 Mon Sep 17 00:00:00 2001 From: Dmitry Dementyev Date: Fri, 13 Dec 2019 16:19:50 -0800 Subject: [PATCH 066/219] Remove hidden shared account methods from AccountManager.java Bug: 145207098,145206763,145206842 Test: CTS Change-Id: I0d07e0e6c4377eff5756ee938c5b43ad632249df (cherry picked from commit b6907622f78a09966c14bc753ff48753eb3d8b76) --- .../java/android/accounts/AccountManager.java | 29 ------------------- .../android/accounts/IAccountManager.aidl | 3 -- .../accounts/AccountManagerService.java | 3 -- 3 files changed, 35 deletions(-) diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index f4e465ab3adb..0f10c3980021 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -1942,35 +1942,6 @@ public class AccountManager { }.start(); } - /** - * @hide - * Removes the shared account. - * @param account the account to remove - * @param user the user to remove the account from - * @return - */ - public boolean removeSharedAccount(final Account account, UserHandle user) { - try { - boolean val = mService.removeSharedAccountAsUser(account, user.getIdentifier()); - return val; - } catch (RemoteException re) { - throw re.rethrowFromSystemServer(); - } - } - - /** - * @hide - * @param user - * @return - */ - public Account[] getSharedAccounts(UserHandle user) { - try { - return mService.getSharedAccountsAsUser(user.getIdentifier()); - } catch (RemoteException re) { - throw re.rethrowFromSystemServer(); - } - } - /** * Confirms that the user knows the password for an account to make extra * sure they are the owner of the account. The user-entered password can diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl index 4cf0a2089fe5..012713891d11 100644 --- a/core/java/android/accounts/IAccountManager.aidl +++ b/core/java/android/accounts/IAccountManager.aidl @@ -80,14 +80,11 @@ interface IAccountManager { String authTokenType); /* Shared accounts */ - Account[] getSharedAccountsAsUser(int userId); - boolean removeSharedAccountAsUser(in Account account, int userId); void addSharedAccountsFromParentUser(int parentUserId, int userId, String opPackageName); /* Account renaming. */ void renameAccount(in IAccountManagerResponse response, in Account accountToRename, String newName); String getPreviousName(in Account account); - boolean renameSharedAccountAsUser(in Account accountToRename, String newName, int userId); /* Add account in two steps. */ void startAddAccountSession(in IAccountManagerResponse response, String accountType, diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 0d2882216f08..c732521bb7cd 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -4404,7 +4404,6 @@ public class AccountManagerService return true; } - @Override public boolean renameSharedAccountAsUser(Account account, String newName, int userId) { userId = handleIncomingUser(userId); UserAccounts accounts = getUserAccounts(userId); @@ -4420,7 +4419,6 @@ public class AccountManagerService return r > 0; } - @Override public boolean removeSharedAccountAsUser(Account account, int userId) { return removeSharedAccountAsUser(account, userId, getCallingUid()); } @@ -4438,7 +4436,6 @@ public class AccountManagerService return deleted; } - @Override public Account[] getSharedAccountsAsUser(int userId) { userId = handleIncomingUser(userId); UserAccounts accounts = getUserAccounts(userId); -- GitLab From 874c974f73839da761177a4e0a53b7f4a7d29288 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Mon, 3 Feb 2020 18:35:13 -0800 Subject: [PATCH 067/219] DO NOT MERGE - Kill apps outright for API contract violations ...rather than relying on in-app code to perform the shutdown. Backport of security fix. Bug: 128649910 Bug: 140108616 Test: manual Test: atest OsHostTests#testForegroundServiceBadNotification Change-Id: I94d9de50bb03c33666471e3dbd9c721e9278f7cb Merged-In: I94d9de50bb03c33666471e3dbd9c721e9278f7cb --- core/java/android/app/IActivityManager.aidl | 3 ++- .../com/android/server/am/ActiveServices.java | 12 ++++++++- .../server/am/ActivityManagerService.java | 5 ++-- .../am/ActivityManagerShellCommand.java | 2 +- .../java/com/android/server/am/AppErrors.java | 26 ++++++++++++++----- .../com/android/server/am/ServiceRecord.java | 7 +++-- .../NotificationManagerService.java | 23 +++++++++------- 7 files changed, 53 insertions(+), 25 deletions(-) diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 18117481b0ea..d29a332ae197 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -266,7 +266,8 @@ interface IActivityManager { boolean isImmersive(in IBinder token); void setImmersive(in IBinder token, boolean immersive); boolean isTopActivityImmersive(); - void crashApplication(int uid, int initialPid, in String packageName, int userId, in String message); + void crashApplication(int uid, int initialPid, in String packageName, int userId, + in String message, boolean force); String getProviderMimeType(in Uri uri, int userId); IBinder newUriPermissionOwner(in String name); void grantUriPermissionFromOwner(in IBinder owner, int fromUid, in String targetPkg, diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 9d823a726afe..8e0bf6fada37 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -653,6 +653,15 @@ public final class ActiveServices { } } + void killMisbehavingService(ServiceRecord r, + int appUid, int appPid, String localPackageName) { + synchronized (mAm) { + stopServiceLocked(r); + mAm.crashApplication(appUid, appPid, localPackageName, -1, + "Bad notification for startForeground", true /*force*/); + } + } + IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) { ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(), Binder.getCallingUid(), @@ -3391,7 +3400,8 @@ public final class ActiveServices { void serviceForegroundCrash(ProcessRecord app) { mAm.crashApplication(app.uid, app.pid, app.info.packageName, app.userId, - "Context.startForegroundService() did not then call Service.startForeground()"); + "Context.startForegroundService() did not then call Service.startForeground()", + false /*force*/); } void scheduleServiceTimeoutLocked(ProcessRecord proc) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index b4c18b13947c..0d9fc03208db 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5141,7 +5141,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void crashApplication(int uid, int initialPid, String packageName, int userId, - String message) { + String message, boolean force) { if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: crashApplication() from pid=" @@ -5153,7 +5153,8 @@ public class ActivityManagerService extends IActivityManager.Stub } synchronized(this) { - mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message); + mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, + message, force); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 8488e526eba9..9575fddf04f2 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -921,7 +921,7 @@ final class ActivityManagerShellCommand extends ShellCommand { } catch (NumberFormatException e) { packageName = arg; } - mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash"); + mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash", false); return 0; } diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index a842724c3177..a7954bbd624d 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -243,20 +243,24 @@ class AppErrors { } void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) { - app.crashing = false; - app.crashingReport = null; - app.notResponding = false; - app.notRespondingReport = null; if (app.anrDialog == fromDialog) { app.anrDialog = null; } if (app.waitDialog == fromDialog) { app.waitDialog = null; } + killAppImmediateLocked(app, "user-terminated", "user request after error"); + } + + private void killAppImmediateLocked(ProcessRecord app, String reason, String killReason) { + app.crashing = false; + app.crashingReport = null; + app.notResponding = false; + app.notRespondingReport = null; if (app.pid > 0 && app.pid != MY_PID) { - handleAppCrashLocked(app, "user-terminated" /*reason*/, + handleAppCrashLocked(app, reason, null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/); - app.kill("user request after error", true); + app.kill(killReason, true); } } @@ -270,7 +274,7 @@ class AppErrors { * @param message */ void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId, - String message) { + String message, boolean force) { ProcessRecord proc = null; // Figure out which process to kill. We don't trust that initialPid @@ -303,6 +307,14 @@ class AppErrors { } proc.scheduleCrash(message); + if (force) { + // If the app is responsive, the scheduled crash will happen as expected + // and then the delayed summary kill will be a no-op. + final ProcessRecord p = proc; + mService.mHandler.postDelayed( + () -> killAppImmediateLocked(p, "forced", "killed for invalid state"), + 5000L); + } } /** diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 16995e50fdbf..f87ba716926e 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -453,6 +453,7 @@ final class ServiceRecord extends Binder { final String localPackageName = packageName; final int localForegroundId = foregroundId; final Notification _foregroundNoti = foregroundNoti; + final ServiceRecord record = this; ams.mHandler.post(new Runnable() { public void run() { NotificationManagerInternal nm = LocalServices.getService( @@ -551,10 +552,8 @@ final class ServiceRecord extends Binder { Slog.w(TAG, "Error showing notification for service", e); // If it gave us a garbage notification, it doesn't // get to be foreground. - ams.setServiceForeground(name, ServiceRecord.this, - 0, null, 0); - ams.crashApplication(appUid, appPid, localPackageName, -1, - "Bad notification for startForeground: " + e); + ams.mServices.killMisbehavingService(record, + appUid, appPid, localPackageName); } } }); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 5df6083bb223..797ce37af560 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -714,18 +714,23 @@ public class NotificationManagerService extends SystemService { @Override public void onNotificationError(int callingUid, int callingPid, String pkg, String tag, int id, int uid, int initialPid, String message, int userId) { - Slog.d(TAG, "onNotification error pkg=" + pkg + " tag=" + tag + " id=" + id - + "; will crashApplication(uid=" + uid + ", pid=" + initialPid + ")"); + final boolean fgService; + synchronized (mNotificationLock) { + NotificationRecord r = findNotificationLocked(pkg, tag, id, userId); + fgService = r != null + && (r.getNotification().flags&Notification.FLAG_FOREGROUND_SERVICE) != 0; + } cancelNotification(callingUid, callingPid, pkg, tag, id, 0, 0, false, userId, REASON_ERROR, null); - long ident = Binder.clearCallingIdentity(); - try { - ActivityManager.getService().crashApplication(uid, initialPid, pkg, -1, - "Bad notification posted from package " + pkg - + ": " + message); - } catch (RemoteException e) { + if (fgService) { + // Still crash for foreground services, preventing the not-crash behaviour abused + // by apps to give us a garbage notification and silently start a fg service. + Binder.withCleanCallingIdentity( + () -> mAm.crashApplication(uid, initialPid, pkg, -1, + "Bad notification(tag=" + tag + ", id=" + id + ") posted from package " + + pkg + ", crashing app(uid=" + uid + ", pid=" + initialPid + "): " + + message, true /* force */)); } - Binder.restoreCallingIdentity(ident); } @Override -- GitLab From f656f6d2c1f3ff50b2c4c71d04c1b0924d176c08 Mon Sep 17 00:00:00 2001 From: Wilson Wu Date: Thu, 26 Dec 2019 16:17:56 +0800 Subject: [PATCH 068/219] Use the main thread to update alignment indication The alignment status is reported from WLC-HAL level and runs on another thread. It may cause CalledFromWrongThreadException, if use that thread to update UI directly. Bug: 146770234 Test: atest SystemUITests:KeyguardIndicationControllerTest Change-Id: I89bf1c188d6ba094106e059f1590c9eaf3703bb8 (cherry picked from commit 0e72713fdf3e065ec4d1e8ca5c4f14dfcc74ebb6) Merged-In: I89bf1c188d6ba094106e059f1590c9eaf3703bb8 --- .../KeyguardIndicationController.java | 3 +- .../KeyguardIndicationControllerTest.java | 50 +++++++++++-------- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 8ee7305d99c5..4256976249b1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -166,7 +166,8 @@ public class KeyguardIndicationController implements StateListener, mStatusBarStateController = statusBarStateController; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mDockManager = dockManager; - mDockManager.addAlignmentStateListener(this::handleAlignStateChanged); + mDockManager.addAlignmentStateListener( + alignState -> mHandler.post(() -> handleAlignStateChanged(alignState))); // lock icon is not used on all form factors. if (mLockIcon != null) { mLockIcon.setOnLongClickListener(this::handleLockLongClick); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java index 2fe51d35c490..8592fd1e9be2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java @@ -223,12 +223,14 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { @Test public void onAlignmentStateChanged_showsSlowChargingIndication() { - createController(); - verify(mDockManager).addAlignmentStateListener(mAlignmentListener.capture()); - mController.setVisible(true); + mInstrumentation.runOnMainSync(() -> { + createController(); + verify(mDockManager).addAlignmentStateListener(mAlignmentListener.capture()); + mController.setVisible(true); - mAlignmentListener.getValue().onAlignmentStateChanged( - DockManager.ALIGN_STATE_POOR); + mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_POOR); + }); + mInstrumentation.waitForIdleSync(); assertThat(mTextView.getText()).isEqualTo( mContext.getResources().getString(R.string.dock_alignment_slow_charging)); @@ -238,11 +240,14 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { @Test public void onAlignmentStateChanged_showsNotChargingIndication() { - createController(); - verify(mDockManager).addAlignmentStateListener(mAlignmentListener.capture()); - mController.setVisible(true); + mInstrumentation.runOnMainSync(() -> { + createController(); + verify(mDockManager).addAlignmentStateListener(mAlignmentListener.capture()); + mController.setVisible(true); - mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_TERRIBLE); + mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_TERRIBLE); + }); + mInstrumentation.waitForIdleSync(); assertThat(mTextView.getText()).isEqualTo( mContext.getResources().getString(R.string.dock_alignment_not_charging)); @@ -252,13 +257,15 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { @Test public void onAlignmentStateChanged_whileDozing_showsSlowChargingIndication() { - createController(); - verify(mDockManager).addAlignmentStateListener(mAlignmentListener.capture()); - mController.setVisible(true); - mController.setDozing(true); + mInstrumentation.runOnMainSync(() -> { + createController(); + verify(mDockManager).addAlignmentStateListener(mAlignmentListener.capture()); + mController.setVisible(true); + mController.setDozing(true); - mAlignmentListener.getValue().onAlignmentStateChanged( - DockManager.ALIGN_STATE_POOR); + mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_POOR); + }); + mInstrumentation.waitForIdleSync(); assertThat(mTextView.getText()).isEqualTo( mContext.getResources().getString(R.string.dock_alignment_slow_charging)); @@ -268,12 +275,15 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { @Test public void onAlignmentStateChanged_whileDozing_showsNotChargingIndication() { - createController(); - verify(mDockManager).addAlignmentStateListener(mAlignmentListener.capture()); - mController.setVisible(true); - mController.setDozing(true); + mInstrumentation.runOnMainSync(() -> { + createController(); + verify(mDockManager).addAlignmentStateListener(mAlignmentListener.capture()); + mController.setVisible(true); + mController.setDozing(true); - mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_TERRIBLE); + mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_TERRIBLE); + }); + mInstrumentation.waitForIdleSync(); assertThat(mTextView.getText()).isEqualTo( mContext.getResources().getString(R.string.dock_alignment_not_charging)); -- GitLab From aff8e2d83d86abcfdef645712f77215fb3e239e9 Mon Sep 17 00:00:00 2001 From: Ryan Mitchell Date: Fri, 23 Aug 2019 11:45:04 -0700 Subject: [PATCH 069/219] Fix security issue in DynamicRefTable::load. A crafted resources arsc could cause libandroidfw to read data out of bounds of the resources arsc. This change updates the logic to calculate whether the ref table chunk is large enough to hold the number of entries specified in the header. Bug: 129475100 Test: adb shell push ResTableTest data Test: adb shell push poc.arsc data Test: ./ResTableTest poc.arsc Change-Id: Ifbaad87bdbcb7eecf554ef362e0118f53532a22a (cherry picked from commit 8da1c38b69e947885fcec50cda46c5472ddb6746) --- libs/androidfw/ResourceTypes.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 2ad2e76cc696..8a035dbbc0f5 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -6902,9 +6902,8 @@ std::unique_ptr DynamicRefTable::clone() const { status_t DynamicRefTable::load(const ResTable_lib_header* const header) { const uint32_t entryCount = dtohl(header->count); - const uint32_t sizeOfEntries = sizeof(ResTable_lib_entry) * entryCount; const uint32_t expectedSize = dtohl(header->header.size) - dtohl(header->header.headerSize); - if (sizeOfEntries > expectedSize) { + if (entryCount > (expectedSize / sizeof(ResTable_lib_entry))) { ALOGE("ResTable_lib_header size %u is too small to fit %u entries (x %u).", expectedSize, entryCount, (uint32_t)sizeof(ResTable_lib_entry)); return UNKNOWN_ERROR; -- GitLab From 85382ce4d285d251cdc4643bb65cef5289034bc3 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Tue, 14 Jan 2020 10:09:36 -0800 Subject: [PATCH 070/219] Disabled some DEBUG constants. Bug: 138939803 Bug: 142965266 Bug: 148457657 Test: echo 'in TH we trust!' Change-Id: Ie3112fa1965d9b03bc142924ca17cf27dd6aa44d (cherry picked from commit e966b8e76d26283163721620528eea0bfd77b43c) --- core/java/android/app/DisabledWallpaperManager.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/core/java/android/app/DisabledWallpaperManager.java b/core/java/android/app/DisabledWallpaperManager.java index 518594191e6c..7151f900c5af 100644 --- a/core/java/android/app/DisabledWallpaperManager.java +++ b/core/java/android/app/DisabledWallpaperManager.java @@ -41,8 +41,7 @@ final class DisabledWallpaperManager extends WallpaperManager { // Don't need to worry about synchronization private static DisabledWallpaperManager sInstance; - // TODO(b/138939803): STOPSHIP changed to false and/or remove it - private static final boolean DEBUG = true; + private static final boolean DEBUG = false; @NonNull static DisabledWallpaperManager getInstance() { @@ -66,10 +65,6 @@ final class DisabledWallpaperManager extends WallpaperManager { return false; } - // TODO(b/138939803): STOPSHIP methods below should not be necessary, - // callers should check if isWallpaperSupported(), consider removing them to keep this class - // simpler - private static T unsupported() { if (DEBUG) Log.w(TAG, "unsupported method called; returning null", new Exception()); return null; -- GitLab From a0e531aa71b49d8d696fb9b73559833a76890710 Mon Sep 17 00:00:00 2001 From: Amin Shaikh Date: Tue, 2 Jul 2019 09:45:58 -0400 Subject: [PATCH 071/219] Fix flaky sysui crash in devicehealthchecks test. Upgrade tuner on the main thread to avoid ConcurrentModificationException. Fixes: 133847620 Bug: 148794872 Test: mp droid Change-Id: I15ef66a19eeac2c6baf652d83e6a90669834f203 Merged-In: I15ef66a19eeac2c6baf652d83e6a90669834f203 --- .../com/android/systemui/tuner/TunerServiceImpl.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java index 6185063e7966..aa4dcc0ca2ae 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java @@ -15,7 +15,7 @@ */ package com.android.systemui.tuner; -import static com.android.systemui.Dependency.BG_HANDLER_NAME; +import static com.android.systemui.Dependency.MAIN_HANDLER_NAME; import android.app.ActivityManager; import android.content.ContentResolver; @@ -82,7 +82,7 @@ public class TunerServiceImpl extends TunerService { /** */ @Inject - public TunerServiceImpl(Context context, @Named(BG_HANDLER_NAME) Handler bgHandler, + public TunerServiceImpl(Context context, @Named(MAIN_HANDLER_NAME) Handler mainHandler, LeakDetector leakDetector) { mContext = context; mContentResolver = mContext.getContentResolver(); @@ -91,7 +91,7 @@ public class TunerServiceImpl extends TunerService { for (UserInfo user : UserManager.get(mContext).getUsers()) { mCurrentUser = user.getUserHandle().getIdentifier(); if (getValue(TUNER_VERSION, 0) != CURRENT_TUNER_VERSION) { - upgradeTuner(getValue(TUNER_VERSION, 0), CURRENT_TUNER_VERSION, bgHandler); + upgradeTuner(getValue(TUNER_VERSION, 0), CURRENT_TUNER_VERSION, mainHandler); } } @@ -112,7 +112,7 @@ public class TunerServiceImpl extends TunerService { mUserTracker.stopTracking(); } - private void upgradeTuner(int oldVersion, int newVersion, Handler bgHandler) { + private void upgradeTuner(int oldVersion, int newVersion, Handler mainHandler) { if (oldVersion < 1) { String blacklistStr = getValue(StatusBarIconController.ICON_BLACKLIST); if (blacklistStr != null) { @@ -134,7 +134,7 @@ public class TunerServiceImpl extends TunerService { if (oldVersion < 4) { // Delay this so that we can wait for everything to be registered first. final int user = mCurrentUser; - bgHandler.postDelayed( + mainHandler.postDelayed( () -> clearAllFromUser(user), 5000); } setValue(TUNER_VERSION, newVersion); -- GitLab From f8c0b315240c5949fbbe755af1c2a2e4006e7210 Mon Sep 17 00:00:00 2001 From: Yan Zhu Date: Wed, 11 Dec 2019 09:14:44 -0800 Subject: [PATCH 072/219] DO NOT MERGE - Enable blacklist for headless system user - Get all packages for system user - Reuse split system user's logic to blacklist packages when headless system user is enabled - Add new method in UserManager to get headless sytem user mode (same as in master) Bug: 145626101 Test: edit device's sysconfig file, use tag: system-user-blacklisted-app to blacklist app make services && adb sync system && adb reboot cts test Change-Id: I98d1bc33e7dd59ffa3ac6426f95af708671138da (cherry picked from commit 9c4cf4945d57d45e429bc7d33bf6ffa68eb0838c) --- core/java/android/os/UserManager.java | 10 ++++ .../server/pm/PackageManagerService.java | 47 +++++++++++-------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 45842926ff1d..da41478e91a6 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -1274,6 +1274,16 @@ public class UserManager { return RoSystemProperties.FW_SYSTEM_USER_SPLIT; } + /** + * @hide + * @return Whether the device is running in a headless system user mode. It means the headless + * user (system user) runs system services and system UI, but is not associated with any real + * person. Secondary users can be created to be associated with real person. + */ + public static boolean isHeadlessSystemUserMode() { + return RoSystemProperties.MULTIUSER_HEADLESS_SYSTEM_USER; + } + /** * @return Whether guest user is always ephemeral * @hide diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index ca66776239db..fc43dc3a2016 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -2321,32 +2321,41 @@ public class PackageManagerService extends IPackageManager.Stub } private void enableSystemUserPackages() { - if (!UserManager.isSplitSystemUser()) { + boolean isHeadlessSystemUserMode = UserManager.isHeadlessSystemUserMode(); + if (!isHeadlessSystemUserMode && !UserManager.isSplitSystemUser()) { return; } - // For system user, enable apps based on the following conditions: - // - app is whitelisted or belong to one of these groups: - // -- system app which has no launcher icons - // -- system app which has INTERACT_ACROSS_USERS permission - // -- system IME app - // - app is not in the blacklist - AppsQueryHelper queryHelper = new AppsQueryHelper(this); + Set enableApps = new ArraySet<>(); - enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS - | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM - | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); - ArraySet wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); - enableApps.addAll(wlApps); - enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER, - /* systemAppsOnly */ false, UserHandle.SYSTEM)); - ArraySet blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); - enableApps.removeAll(blApps); - Log.i(TAG, "Applications installed for system user: " + enableApps); + AppsQueryHelper queryHelper = new AppsQueryHelper(this); List allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false, UserHandle.SYSTEM); + + if (isHeadlessSystemUserMode) { + enableApps.addAll(allAps); + } else { + // For split system user, select apps based on the following conditions: + // -- system app which has no launcher icons + // -- system app which has INTERACT_ACROSS_USERS permission + // -- system IME app + enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS + | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM + | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); + enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER, + /* systemAppsOnly */ false, UserHandle.SYSTEM)); + + // Apply whitelist for split system user + ArraySet wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); + enableApps.addAll(wlApps); + } + // Apply blacklist for split system user/headless system user + ArraySet blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); + enableApps.removeAll(blApps); + Log.i(TAG, "Blacklisted packages: " + blApps); + final int allAppsSize = allAps.size(); synchronized (mPackages) { - for (int i = 0; i < allAppsSize; i++) { + for (int i = 0; i < allAppsSize; i++) { String pName = allAps.get(i); PackageSetting pkgSetting = mSettings.mPackages.get(pName); // Should not happen, but we shouldn't be failing if it does -- GitLab From 81ce02f510b18974ade9ac5a377426e5ceba7f72 Mon Sep 17 00:00:00 2001 From: Yan Zhu Date: Tue, 17 Dec 2019 14:00:16 -0800 Subject: [PATCH 073/219] DO NOT MERGE - Add flag to turn on/off the headless user specific blacklist/whitelist Bug: 145626101 Test: manual: set config_systemUserPackagesBlacklistSupported build and flash Verify with: 1. adb shell dumpsys package packages 2. adb logcat | grep "blacklist" Change-Id: I5b45fc86e4c5008933bf361d5bb32a2c17259655 (cherry picked from commit d1c59ec220e95f881feefb55eb099b6f602d4e05) --- core/res/res/values/config.xml | 3 +++ core/res/res/values/symbols.xml | 1 + .../server/pm/PackageManagerService.java | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 10c727154814..12058c15458e 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1692,6 +1692,9 @@ This feature should be disabled for most devices. --> 0 + + false + false + true + + + com.android.server.location.ComprehensiveCountryDetector diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 29f90fb192c5..1c387baf7826 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3689,6 +3689,8 @@ + + diff --git a/services/core/java/com/android/server/CountryDetectorService.java b/services/core/java/com/android/server/CountryDetectorService.java index 861c731c69e0..b0132d35fa3b 100644 --- a/services/core/java/com/android/server/CountryDetectorService.java +++ b/services/core/java/com/android/server/CountryDetectorService.java @@ -24,21 +24,29 @@ import android.location.ICountryListener; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; +import android.text.TextUtils; import android.util.PrintWriterPrinter; import android.util.Printer; import android.util.Slog; +import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.BackgroundThread; import com.android.internal.util.DumpUtils; import com.android.server.location.ComprehensiveCountryDetector; +import com.android.server.location.CountryDetectorBase; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.lang.reflect.InvocationTargetException; import java.util.HashMap; /** - * This class detects the country that the user is in through {@link ComprehensiveCountryDetector}. + * This class detects the country that the user is in. The default country detection is made through + * {@link com.android.server.location.ComprehensiveCountryDetector}. It is possible to overlay the + * detection algorithm by overlaying the attribute R.string.config_customCountryDetector with the + * custom class name to use instead. The custom class must extend + * {@link com.android.server.location.CountryDetectorBase} * * @hide */ @@ -88,7 +96,7 @@ public class CountryDetectorService extends ICountryDetector.Stub { private final HashMap mReceivers; private final Context mContext; - private ComprehensiveCountryDetector mCountryDetector; + private CountryDetectorBase mCountryDetector; private boolean mSystemReady; private Handler mHandler; private CountryListener mLocationBasedDetectorListener; @@ -184,8 +192,17 @@ public class CountryDetectorService extends ICountryDetector.Stub { }); } - private void initialize() { - mCountryDetector = new ComprehensiveCountryDetector(mContext); + @VisibleForTesting + void initialize() { + final String customCountryClass = mContext.getString(R.string.config_customCountryDetector); + if (!TextUtils.isEmpty(customCountryClass)) { + mCountryDetector = loadCustomCountryDetectorIfAvailable(customCountryClass); + } + + if (mCountryDetector == null) { + Slog.d(TAG, "Using default country detector"); + mCountryDetector = new ComprehensiveCountryDetector(mContext); + } mLocationBasedDetectorListener = country -> mHandler.post(() -> notifyReceivers(country)); } @@ -193,11 +210,33 @@ public class CountryDetectorService extends ICountryDetector.Stub { mHandler.post(() -> mCountryDetector.setCountryListener(listener)); } + @VisibleForTesting + CountryDetectorBase getCountryDetector() { + return mCountryDetector; + } + @VisibleForTesting boolean isSystemReady() { return mSystemReady; } + private CountryDetectorBase loadCustomCountryDetectorIfAvailable( + final String customCountryClass) { + CountryDetectorBase customCountryDetector = null; + + Slog.d(TAG, "Using custom country detector class: " + customCountryClass); + try { + customCountryDetector = Class.forName(customCountryClass).asSubclass( + CountryDetectorBase.class).getConstructor(Context.class).newInstance( + mContext); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException + | NoSuchMethodException | InvocationTargetException e) { + Slog.e(TAG, "Could not instantiate the custom country detector class"); + } + + return customCountryDetector; + } + @SuppressWarnings("unused") @Override protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { @@ -206,9 +245,10 @@ public class CountryDetectorService extends ICountryDetector.Stub { try { final Printer p = new PrintWriterPrinter(fout); p.println("CountryDetectorService state:"); + p.println("Country detector class=" + mCountryDetector.getClass().getName()); p.println(" Number of listeners=" + mReceivers.keySet().size()); if (mCountryDetector == null) { - p.println(" ComprehensiveCountryDetector not initialized"); + p.println(" CountryDetector not initialized"); } else { p.println(" " + mCountryDetector.toString()); } diff --git a/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java index e9c5ce7127de..d5483ffa5445 100644 --- a/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java @@ -19,8 +19,11 @@ package com.android.server; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; import android.content.Context; +import android.content.res.Resources; import android.location.Country; import android.location.CountryListener; import android.location.ICountryListener; @@ -31,6 +34,10 @@ import android.os.RemoteException; import androidx.test.core.app.ApplicationProvider; +import com.android.internal.R; +import com.android.server.location.ComprehensiveCountryDetector; +import com.android.server.location.CustomCountryDetectorTestClass; + import com.google.common.truth.Expect; import org.junit.Before; @@ -38,12 +45,18 @@ import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class CountryDetectorServiceTest { + private static final String VALID_CUSTOM_TEST_CLASS = + "com.android.server.location.CustomCountryDetectorTestClass"; + private static final String INVALID_CUSTOM_TEST_CLASS = + "com.android.server.location.MissingCountryDetectorTestClass"; + private static class CountryListenerTester extends ICountryListener.Stub { private Country mCountry; @@ -83,12 +96,11 @@ public class CountryDetectorServiceTest { } } - @Rule - public final Expect expect = Expect.create(); - @Spy - private Context mContext = ApplicationProvider.getApplicationContext(); - @Spy - private Handler mHandler = new Handler(Looper.myLooper()); + @Rule public final Expect expect = Expect.create(); + @Spy private Context mContext = ApplicationProvider.getApplicationContext(); + @Spy private Handler mHandler = new Handler(Looper.myLooper()); + @Mock private Resources mResources; + private CountryDetectorServiceTester mCountryDetectorService; @BeforeClass @@ -108,10 +120,12 @@ public class CountryDetectorServiceTest { message.getCallback().run(); return true; }).when(mHandler).sendMessageAtTime(any(Message.class), anyLong()); + + doReturn(mResources).when(mContext).getResources(); } @Test - public void countryListener_add_successful() throws RemoteException { + public void addCountryListener_validListener_listenerAdded() throws RemoteException { CountryListenerTester countryListener = new CountryListenerTester(); mCountryDetectorService.systemRunning(); @@ -122,7 +136,7 @@ public class CountryDetectorServiceTest { } @Test - public void countryListener_remove_successful() throws RemoteException { + public void removeCountryListener_validListener_listenerRemoved() throws RemoteException { CountryListenerTester countryListener = new CountryListenerTester(); mCountryDetectorService.systemRunning(); @@ -133,8 +147,31 @@ public class CountryDetectorServiceTest { expect.that(mCountryDetectorService.isListenerSet()).isFalse(); } + @Test(expected = RemoteException.class) + public void addCountryListener_serviceNotReady_throwsException() throws RemoteException { + CountryListenerTester countryListener = new CountryListenerTester(); + + expect.that(mCountryDetectorService.isSystemReady()).isFalse(); + mCountryDetectorService.addCountryListener(countryListener); + } + + @Test(expected = RemoteException.class) + public void removeCountryListener_serviceNotReady_throwsException() throws RemoteException { + CountryListenerTester countryListener = new CountryListenerTester(); + + expect.that(mCountryDetectorService.isSystemReady()).isFalse(); + mCountryDetectorService.removeCountryListener(countryListener); + } + @Test - public void countryListener_notify_successful() throws RemoteException { + public void detectCountry_serviceNotReady_returnNull() { + expect.that(mCountryDetectorService.isSystemReady()).isFalse(); + + expect.that(mCountryDetectorService.detectCountry()).isNull(); + } + + @Test + public void notifyReceivers_twoListenersRegistered_bothNotified() throws RemoteException { CountryListenerTester countryListenerA = new CountryListenerTester(); CountryListenerTester countryListenerB = new CountryListenerTester(); Country country = new Country("US", Country.COUNTRY_SOURCE_NETWORK); @@ -151,4 +188,26 @@ public class CountryDetectorServiceTest { expect.that(countryListenerA.getCountry().equalsIgnoreSource(country)).isTrue(); expect.that(countryListenerB.getCountry().equalsIgnoreSource(country)).isTrue(); } + + @Test + public void initialize_deviceWithCustomDetector_useCustomDetectorClass() { + when(mResources.getString(R.string.config_customCountryDetector)) + .thenReturn(VALID_CUSTOM_TEST_CLASS); + + mCountryDetectorService.initialize(); + + expect.that(mCountryDetectorService.getCountryDetector()) + .isInstanceOf(CustomCountryDetectorTestClass.class); + } + + @Test + public void initialize_deviceWithInvalidCustomDetector_useDefaultDetector() { + when(mResources.getString(R.string.config_customCountryDetector)) + .thenReturn(INVALID_CUSTOM_TEST_CLASS); + + mCountryDetectorService.initialize(); + + expect.that(mCountryDetectorService.getCountryDetector()) + .isInstanceOf(ComprehensiveCountryDetector.class); + } } diff --git a/services/tests/servicestests/src/com/android/server/location/CustomCountryDetectorTestClass.java b/services/tests/servicestests/src/com/android/server/location/CustomCountryDetectorTestClass.java new file mode 100644 index 000000000000..e159012f1b54 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/location/CustomCountryDetectorTestClass.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.location; + +import android.content.Context; +import android.location.Country; + +public class CustomCountryDetectorTestClass extends CountryDetectorBase { + public CustomCountryDetectorTestClass(Context ctx) { + super(ctx); + } + + @Override + public Country detectCountry() { + return null; + } + + @Override + public void stop() { + + } +} -- GitLab From d445aaf1e2e4c9e98f03d0726cd513a34952a693 Mon Sep 17 00:00:00 2001 From: kwaky Date: Wed, 5 Feb 2020 12:51:46 -0800 Subject: [PATCH 077/219] Add null check for voiceInteractorComponentName. Voice Assistant can be disabled on a user-level. Adding this null check prevents crash for when Assistant is enabled for the system in general but disabled for a specific user. Bug: 149112015 Test: Manual -- Change config_disableLockscreenByDefault to true to emulate the environment in which Volvo observed the bug. Verify that switching to user0 through adb shell switch-user 0 causes the same crash. Verify that the crash does not happen with the new null check. Change-Id: I5b8ede1e5bd8c1bc047bc6d6220b425dea8f50ea Merged-in: I5b8ede1e5bd8c1bc047bc6d6220b425dea8f50ea --- .../systemui/statusbar/phone/KeyguardBottomAreaView.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index 80d36a1a4e54..c3244a4431d9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -641,9 +641,10 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL if (previewBefore != null) { mPreviewContainer.removeView(previewBefore); } - if (mLeftIsVoiceAssist) { - mLeftPreview = mPreviewInflater.inflatePreviewFromService( - mAssistManager.getVoiceInteractorComponentName()); + ComponentName voiceInteractorComponentName = + mAssistManager.getVoiceInteractorComponentName(); + if (mLeftIsVoiceAssist && voiceInteractorComponentName != null) { + mLeftPreview = mPreviewInflater.inflatePreviewFromService(voiceInteractorComponentName); } else { mLeftPreview = mPreviewInflater.inflatePreview(mLeftButton.getIntent()); } -- GitLab From 6073f3c58b4b7585bc446c49cb1fa86f438d307c Mon Sep 17 00:00:00 2001 From: kwaky Date: Thu, 6 Feb 2020 13:45:57 -0800 Subject: [PATCH 078/219] DO NOT MERGE Adjust NotificationView bottom margin based on whether Keyboard is shown. If the Keyboard is shown, then margin bottom is 0. Otherwise, the margin is the height of the NavBar. Bug: 149022190 Test: Manual. Verify that NotificationView's margin adjusts based on whether keyboard or IME is shown. Change-Id: I96c50a4d773dfac9b57ab1c15cfc59d315da4605 --- .../res/layout/notification_center_activity.xml | 3 ++- .../com/android/systemui/statusbar/car/CarStatusBar.java | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/CarSystemUI/res/layout/notification_center_activity.xml b/packages/CarSystemUI/res/layout/notification_center_activity.xml index 0af74c4462a6..e5cc08a3b601 100644 --- a/packages/CarSystemUI/res/layout/notification_center_activity.xml +++ b/packages/CarSystemUI/res/layout/notification_center_activity.xml @@ -20,7 +20,8 @@ android:id="@+id/notification_view" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/notification_shade_background_color"> + android:background="@color/notification_shade_background_color" + android:visibility="invisible"> Date: Tue, 17 Dec 2019 00:33:18 +0800 Subject: [PATCH 079/219] Remove framework code that has moved to frameworks/libs/net Add srcs to framework and change import path. Remove the codes which are moved to frameworks/libs/net. Bug: 139268426 Bug: 135998869 Bug: 138306002 Bug: 143925787 Test: atest FrameworksNetTests atest FrameworksTelephonyTests atest ./frameworks/opt/net/wifi/tests/wifitests/runtests.sh Change-Id: I067cdc404e5a63947c19cb75069a39ae42faa3c8 Merged-In: Ieb8927f9af7f87a5ae038bd6c7daeb3d70117fef --- core/java/android/net/LinkProperties.java | 76 ++---------------- core/java/android/net/MacAddress.java | 79 ++----------------- core/java/android/net/NetworkUtils.java | 10 --- core/java/android/net/RouteInfo.java | 17 +--- .../android/server/ConnectivityService.java | 2 +- .../java/android/net/LinkPropertiesTest.java | 2 +- .../net/java/android/net/MacAddressTest.java | 12 +-- .../android/net/wifi/WifiConfiguration.java | 5 +- .../net/wifi/WifiConfigurationTest.java | 6 +- 9 files changed, 31 insertions(+), 178 deletions(-) diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index d25ee0e69e88..732ceb560cab 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -21,6 +21,8 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.net.util.LinkPropertiesUtils; +import android.net.util.LinkPropertiesUtils.CompareResult; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -90,36 +92,6 @@ public final class LinkProperties implements Parcelable { // Indexed by interface name to allow modification and to prevent duplicates being added. private Hashtable mStackedLinks = new Hashtable<>(); - /** - * @hide - */ - public static class CompareResult { - public final List removed = new ArrayList<>(); - public final List added = new ArrayList<>(); - - public CompareResult() {} - - public CompareResult(Collection oldItems, Collection newItems) { - if (oldItems != null) { - removed.addAll(oldItems); - } - if (newItems != null) { - for (T newItem : newItems) { - if (!removed.remove(newItem)) { - added.add(newItem); - } - } - } - } - - @Override - public String toString() { - return "removed=[" + TextUtils.join(",", removed) - + "] added=[" + TextUtils.join(",", added) - + "]"; - } - } - /** * @hide */ @@ -1326,7 +1298,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalInterfaceName(@NonNull LinkProperties target) { - return TextUtils.equals(getInterfaceName(), target.getInterfaceName()); + return LinkPropertiesUtils.isIdenticalInterfaceName(target, this); } /** @@ -1349,10 +1321,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalAddresses(@NonNull LinkProperties target) { - Collection targetAddresses = target.getAddresses(); - Collection sourceAddresses = getAddresses(); - return (sourceAddresses.size() == targetAddresses.size()) ? - sourceAddresses.containsAll(targetAddresses) : false; + return LinkPropertiesUtils.isIdenticalAddresses(target, this); } /** @@ -1364,15 +1333,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalDnses(@NonNull LinkProperties target) { - Collection targetDnses = target.getDnsServers(); - String targetDomains = target.getDomains(); - if (mDomains == null) { - if (targetDomains != null) return false; - } else { - if (!mDomains.equals(targetDomains)) return false; - } - return (mDnses.size() == targetDnses.size()) ? - mDnses.containsAll(targetDnses) : false; + return LinkPropertiesUtils.isIdenticalDnses(target, this); } /** @@ -1425,9 +1386,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalRoutes(@NonNull LinkProperties target) { - Collection targetRoutes = target.getRoutes(); - return (mRoutes.size() == targetRoutes.size()) ? - mRoutes.containsAll(targetRoutes) : false; + return LinkPropertiesUtils.isIdenticalRoutes(target, this); } /** @@ -1439,8 +1398,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public boolean isIdenticalHttpProxy(@NonNull LinkProperties target) { - return getHttpProxy() == null ? target.getHttpProxy() == null : - getHttpProxy().equals(target.getHttpProxy()); + return LinkPropertiesUtils.isIdenticalHttpProxy(target, this); } /** @@ -1662,26 +1620,6 @@ public final class LinkProperties implements Parcelable { && isIdenticalCaptivePortalData(target); } - /** - * Compares the addresses in this LinkProperties with another - * LinkProperties, examining only addresses on the base link. - * - * @param target a LinkProperties with the new list of addresses - * @return the differences between the addresses. - * @hide - */ - public @NonNull CompareResult compareAddresses(@Nullable LinkProperties target) { - /* - * Duplicate the LinkAddresses into removed, we will be removing - * address which are common between mLinkAddresses and target - * leaving the addresses that are different. And address which - * are in target but not in mLinkAddresses are placed in the - * addedAddresses. - */ - return new CompareResult<>(mLinkAddresses, - target != null ? target.getLinkAddresses() : null); - } - /** * Compares the DNS addresses in this LinkProperties with another * LinkProperties, examining only DNS addresses on the base link. diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java index 74c9aac05b41..0e10c42e61db 100644 --- a/core/java/android/net/MacAddress.java +++ b/core/java/android/net/MacAddress.java @@ -20,11 +20,11 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.net.util.MacAddressUtils; import android.net.wifi.WifiInfo; import android.os.Parcel; import android.os.Parcelable; -import com.android.internal.util.BitUtils; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; @@ -33,7 +33,6 @@ import java.net.Inet6Address; import java.net.UnknownHostException; import java.security.SecureRandom; import java.util.Arrays; -import java.util.Random; /** * Representation of a MAC address. @@ -109,20 +108,12 @@ public final class MacAddress implements Parcelable { if (equals(BROADCAST_ADDRESS)) { return TYPE_BROADCAST; } - if (isMulticastAddress()) { + if ((mAddr & MULTICAST_MASK) != 0) { return TYPE_MULTICAST; } return TYPE_UNICAST; } - /** - * @return true if this MacAddress is a multicast address. - * @hide - */ - public boolean isMulticastAddress() { - return (mAddr & MULTICAST_MASK) != 0; - } - /** * @return true if this MacAddress is a locally assigned address. */ @@ -192,7 +183,7 @@ public final class MacAddress implements Parcelable { * @hide */ public static boolean isMacAddress(byte[] addr) { - return addr != null && addr.length == ETHER_ADDR_LEN; + return MacAddressUtils.isMacAddress(addr); } /** @@ -261,26 +252,11 @@ public final class MacAddress implements Parcelable { } private static byte[] byteAddrFromLongAddr(long addr) { - byte[] bytes = new byte[ETHER_ADDR_LEN]; - int index = ETHER_ADDR_LEN; - while (index-- > 0) { - bytes[index] = (byte) addr; - addr = addr >> 8; - } - return bytes; + return MacAddressUtils.byteAddrFromLongAddr(addr); } private static long longAddrFromByteAddr(byte[] addr) { - Preconditions.checkNotNull(addr); - if (!isMacAddress(addr)) { - throw new IllegalArgumentException( - Arrays.toString(addr) + " was not a valid MAC address"); - } - long longAddr = 0; - for (byte b : addr) { - longAddr = (longAddr << 8) + BitUtils.uint8(b); - } - return longAddr; + return MacAddressUtils.longAddrFromByteAddr(addr); } // Internal conversion function equivalent to longAddrFromByteAddr(byteAddrFromStringAddr(addr)) @@ -350,50 +326,7 @@ public final class MacAddress implements Parcelable { * @hide */ public static @NonNull MacAddress createRandomUnicastAddressWithGoogleBase() { - return createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom()); - } - - /** - * Returns a generated MAC address whose 46 bits, excluding the locally assigned bit and the - * unicast bit, are randomly selected. - * - * The locally assigned bit is always set to 1. The multicast bit is always set to 0. - * - * @return a random locally assigned, unicast MacAddress. - * - * @hide - */ - public static @NonNull MacAddress createRandomUnicastAddress() { - return createRandomUnicastAddress(null, new SecureRandom()); - } - - /** - * Returns a randomly generated MAC address using the given Random object and the same - * OUI values as the given MacAddress. - * - * The locally assigned bit is always set to 1. The multicast bit is always set to 0. - * - * @param base a base MacAddress whose OUI is used for generating the random address. - * If base == null then the OUI will also be randomized. - * @param r a standard Java Random object used for generating the random address. - * @return a random locally assigned MacAddress. - * - * @hide - */ - public static @NonNull MacAddress createRandomUnicastAddress(MacAddress base, Random r) { - long addr; - if (base == null) { - addr = r.nextLong() & VALID_LONG_MASK; - } else { - addr = (base.mAddr & OUI_MASK) | (NIC_MASK & r.nextLong()); - } - addr |= LOCALLY_ASSIGNED_MASK; - addr &= ~MULTICAST_MASK; - MacAddress mac = new MacAddress(addr); - if (mac.equals(DEFAULT_MAC_ADDRESS)) { - return createRandomUnicastAddress(base, r); - } - return mac; + return MacAddressUtils.createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom()); } // Convenience function for working around the lack of byte literals. diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java index 08cc4e24b245..779f7bc91e8f 100644 --- a/core/java/android/net/NetworkUtils.java +++ b/core/java/android/net/NetworkUtils.java @@ -31,7 +31,6 @@ import android.util.Pair; import java.io.FileDescriptor; import java.math.BigInteger; import java.net.Inet4Address; -import java.net.Inet6Address; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; @@ -312,15 +311,6 @@ public class NetworkUtils { return new Pair(address, prefixLength); } - /** - * Check if IP address type is consistent between two InetAddress. - * @return true if both are the same type. False otherwise. - */ - public static boolean addressTypeMatches(InetAddress left, InetAddress right) { - return (((left instanceof Inet4Address) && (right instanceof Inet4Address)) || - ((left instanceof Inet6Address) && (right instanceof Inet6Address))); - } - /** * Convert a 32 char hex string into a Inet6Address. * throws a runtime exception if the string isn't 32 chars, isn't hex or can't be diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java index 67bad532cd0d..2b9e9fe81b1b 100644 --- a/core/java/android/net/RouteInfo.java +++ b/core/java/android/net/RouteInfo.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.net.util.NetUtils; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -483,21 +484,7 @@ public final class RouteInfo implements Parcelable { @UnsupportedAppUsage @Nullable public static RouteInfo selectBestRoute(Collection routes, InetAddress dest) { - if ((routes == null) || (dest == null)) return null; - - RouteInfo bestRoute = null; - // pick a longest prefix match under same address type - for (RouteInfo route : routes) { - if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) { - if ((bestRoute != null) && - (bestRoute.mDestination.getPrefixLength() >= - route.mDestination.getPrefixLength())) { - continue; - } - if (route.matches(dest)) bestRoute = route; - } - } - return bestRoute; + return NetUtils.selectBestRoute(routes, dest); } /** diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index f06d50021288..376dd667bf38 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -89,7 +89,6 @@ import android.net.InetAddresses; import android.net.IpMemoryStore; import android.net.IpPrefix; import android.net.LinkProperties; -import android.net.LinkProperties.CompareResult; import android.net.MatchAllNetworkSpecifier; import android.net.NattSocketKeepalive; import android.net.Network; @@ -124,6 +123,7 @@ import android.net.metrics.IpConnectivityLog; import android.net.metrics.NetworkEvent; import android.net.netlink.InetDiagMessage; import android.net.shared.PrivateDnsConfig; +import android.net.util.LinkPropertiesUtils.CompareResult; import android.net.util.MultinetworkPolicyTracker; import android.net.util.NetdService; import android.os.Binder; diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java index 3f311c951c7e..f25fd4daf829 100644 --- a/tests/net/common/java/android/net/LinkPropertiesTest.java +++ b/tests/net/common/java/android/net/LinkPropertiesTest.java @@ -27,8 +27,8 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import android.net.LinkProperties.CompareResult; import android.net.LinkProperties.ProvisioningChange; +import android.net.util.LinkPropertiesUtils.CompareResult; import android.system.OsConstants; import android.util.ArraySet; diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java index daf187d01533..91c9a2a38036 100644 --- a/tests/net/java/android/net/MacAddressTest.java +++ b/tests/net/java/android/net/MacAddressTest.java @@ -22,6 +22,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.net.util.MacAddressUtils; + import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -122,11 +124,11 @@ public class MacAddressTest { for (MacAddress mac : multicastAddresses) { String msg = mac.toString() + " expected to be a multicast address"; - assertTrue(msg, mac.isMulticastAddress()); + assertTrue(msg, MacAddressUtils.isMulticastAddress(mac)); } for (MacAddress mac : unicastAddresses) { String msg = mac.toString() + " expected not to be a multicast address"; - assertFalse(msg, mac.isMulticastAddress()); + assertFalse(msg, MacAddressUtils.isMulticastAddress(mac)); } } @@ -156,7 +158,7 @@ public class MacAddressTest { public void testMacAddressConversions() { final int iterations = 10000; for (int i = 0; i < iterations; i++) { - MacAddress mac = MacAddress.createRandomUnicastAddress(); + MacAddress mac = MacAddressUtils.createRandomUnicastAddress(); String stringRepr = mac.toString(); byte[] bytesRepr = mac.toByteArray(); @@ -188,7 +190,7 @@ public class MacAddressTest { final String expectedLocalOui = "26:5f:78"; final MacAddress base = MacAddress.fromString(anotherOui + ":0:0:0"); for (int i = 0; i < iterations; i++) { - MacAddress mac = MacAddress.createRandomUnicastAddress(base, r); + MacAddress mac = MacAddressUtils.createRandomUnicastAddress(base, r); String stringRepr = mac.toString(); assertTrue(stringRepr + " expected to be a locally assigned address", @@ -199,7 +201,7 @@ public class MacAddressTest { } for (int i = 0; i < iterations; i++) { - MacAddress mac = MacAddress.createRandomUnicastAddress(); + MacAddress mac = MacAddressUtils.createRandomUnicastAddress(); String stringRepr = mac.toString(); assertTrue(stringRepr + " expected to be a locally assigned address", diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 933dded815b9..ce49ab1208b0 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -28,6 +28,7 @@ import android.net.NetworkSpecifier; import android.net.ProxyInfo; import android.net.StaticIpConfiguration; import android.net.Uri; +import android.net.util.MacAddressUtils; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -1037,7 +1038,7 @@ public class WifiConfiguration implements Parcelable { * @return true if mac is good to use */ public static boolean isValidMacAddressForRandomization(MacAddress mac) { - return mac != null && !mac.isMulticastAddress() && mac.isLocallyAssigned() + return mac != null && !MacAddressUtils.isMulticastAddress(mac) && mac.isLocallyAssigned() && !MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS).equals(mac); } @@ -1051,7 +1052,7 @@ public class WifiConfiguration implements Parcelable { int randomMacGenerationCount = 0; while (!isValidMacAddressForRandomization(mRandomizedMacAddress) && randomMacGenerationCount < MAXIMUM_RANDOM_MAC_GENERATION_RETRY) { - mRandomizedMacAddress = MacAddress.createRandomUnicastAddress(); + mRandomizedMacAddress = MacAddressUtils.createRandomUnicastAddress(); randomMacGenerationCount++; } diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index ba9fc786afe7..f3e8351587bc 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import android.net.MacAddress; +import android.net.util.MacAddressUtils; import android.net.wifi.WifiConfiguration.KeyMgmt; import android.net.wifi.WifiConfiguration.NetworkSelectionStatus; import android.os.Parcel; @@ -62,7 +63,8 @@ public class WifiConfigurationTest { config.updateIdentifier = "1234"; config.fromWifiNetworkSpecifier = true; config.fromWifiNetworkSuggestion = true; - MacAddress macBeforeParcel = config.getOrCreateRandomizedMacAddress(); + config.setRandomizedMacAddress(MacAddressUtils.createRandomUnicastAddress()); + MacAddress macBeforeParcel = config.getRandomizedMacAddress(); Parcel parcelW = Parcel.obtain(); config.writeToParcel(parcelW, 0); byte[] bytes = parcelW.marshall(); @@ -211,7 +213,7 @@ public class WifiConfigurationTest { MacAddress defaultMac = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); assertEquals(defaultMac, config.getRandomizedMacAddress()); - MacAddress macToChangeInto = MacAddress.createRandomUnicastAddress(); + MacAddress macToChangeInto = MacAddressUtils.createRandomUnicastAddress(); config.setRandomizedMacAddress(macToChangeInto); MacAddress macAfterChange = config.getRandomizedMacAddress(); -- GitLab From ec879fa0f2198aad607c9ef46e31d8f89c281059 Mon Sep 17 00:00:00 2001 From: Ahan Wu Date: Fri, 22 Nov 2019 15:54:56 +0800 Subject: [PATCH 080/219] Fix potential NPE while releasing worker thread of ImageWallpaper We nullify mWorker right in ImageWallpaper#destroy(), we might get NPE if postRender is invoked later. Thus, we add null check to avoid NPE. Bug: 144039509 Bug: 146167292 Test: atest com.android.systemui Test: atest CtsMultiUserHostTestCases Change-Id: I209673bdac7dcfee765006568583b5a9d6037b95 Merged-In: I243274af54538fc89268c448aa2c5a95f63c7ae3 --- .../src/com/android/systemui/ImageWallpaper.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java index c0c14fb01222..319d1177622d 100644 --- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java @@ -121,12 +121,13 @@ public class ImageWallpaper extends WallpaperService { @Override public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) { + if (mWorker == null) return; mWorker.getThreadHandler().post(() -> mRenderer.updateOffsets(xOffset, yOffset)); } @Override public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) { - if (!mNeedTransition) return; + if (mWorker == null || !mNeedTransition) return; if (DEBUG) { Log.d(TAG, "onAmbientModeChanged: inAmbient=" + inAmbientMode + ", duration=" + animationDuration); @@ -174,6 +175,7 @@ public class ImageWallpaper extends WallpaperService { @Override public void onSurfaceCreated(SurfaceHolder holder) { + if (mWorker == null) return; mWorker.getThreadHandler().post(() -> { mEglHelper.init(holder); mRenderer.onSurfaceCreated(); @@ -182,6 +184,7 @@ public class ImageWallpaper extends WallpaperService { @Override public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { + if (mWorker == null) return; mWorker.getThreadHandler().post(() -> { if (DEBUG) { Log.d(TAG, "onSurfaceChanged: w=" + width + ", h=" + height); @@ -194,6 +197,7 @@ public class ImageWallpaper extends WallpaperService { @Override public void onSurfaceRedrawNeeded(SurfaceHolder holder) { + if (mWorker == null) return; mWorker.getThreadHandler().post(() -> { if (DEBUG) { Log.d(TAG, "onSurfaceRedrawNeeded: mNeedRedraw=" + mNeedRedraw); @@ -222,7 +226,7 @@ public class ImageWallpaper extends WallpaperService { @Override public void onStatePostChange() { // When back to home, we try to release EGL, which is preserved in lock screen or aod. - if (mController.getState() == StatusBarState.SHADE) { + if (mWorker != null && mController.getState() == StatusBarState.SHADE) { mWorker.getThreadHandler().post(this::scheduleFinishRendering); } } @@ -327,10 +331,12 @@ public class ImageWallpaper extends WallpaperService { } private void cancelFinishRenderingTask() { + if (mWorker == null) return; mWorker.getThreadHandler().removeCallbacks(mFinishRenderingTask); } private void scheduleFinishRendering() { + if (mWorker == null) return; cancelFinishRenderingTask(); mWorker.getThreadHandler().postDelayed(mFinishRenderingTask, DELAY_FINISH_RENDERING); } -- GitLab From c26e4fa64f75ee3224026a284741a197a1e1ed0c Mon Sep 17 00:00:00 2001 From: kwaky Date: Mon, 27 Jan 2020 16:03:19 -0800 Subject: [PATCH 081/219] Add vertical type check to prevent non-Automotive Androids from force displaying system bars. Force displaying system bars can cause app screen compatibility issues in non-Automotive Android. Bug: 148407132 Test: CTS Test + Unit Tests Change-Id: Ia433572650760e3b85954724c63084dca769eaa0 Merged-In: Ia433572650760e3b85954724c63084dca769eaa0 --- .../server/wm/WindowManagerService.java | 6 ++ services/tests/wmtests/AndroidManifest.xml | 1 + .../server/wm/WindowManagerServiceTests.java | 59 +++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f67b4fe78f58..529936a6c899 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -5702,6 +5702,12 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void setForceShowSystemBars(boolean show) { + boolean isAutomotive = mContext.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_AUTOMOTIVE); + if (!isAutomotive) { + throw new UnsupportedOperationException("Force showing system bars is only supported" + + "for Automotive use cases."); + } if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Caller does not hold permission " diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml index 8c4544249b5c..123bb079dbbb 100644 --- a/services/tests/wmtests/AndroidManifest.xml +++ b/services/tests/wmtests/AndroidManifest.xml @@ -37,6 +37,7 @@ + Date: Tue, 18 Feb 2020 12:21:15 -0500 Subject: [PATCH 082/219] Add cutout support in QSDetail Add padding from cornerCutoutMargins. Test: manual on device with and without cutout Fixes: 147708367 Change-Id: I21a9b71c34664982b4e14dd4372638e405a5046e Merged-In: I665c8c76a2a057e9a30bce7c28fdbe7a249bb5c2 --- .../src/com/android/systemui/qs/QSDetail.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java index 496aa0e572ae..837f90ec23c6 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java @@ -25,9 +25,12 @@ import android.content.Intent; import android.content.res.Configuration; import android.graphics.drawable.Animatable; import android.util.AttributeSet; +import android.util.Pair; import android.util.SparseArray; +import android.view.DisplayCutout; import android.view.View; import android.view.ViewGroup; +import android.view.WindowInsets; import android.view.accessibility.AccessibilityEvent; import android.widget.ImageView; import android.widget.LinearLayout; @@ -42,6 +45,7 @@ import com.android.systemui.SysUiServiceProvider; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.phone.PhoneStatusBarView; public class QSDetail extends LinearLayout { @@ -142,6 +146,25 @@ public class QSDetail extends LinearLayout { } } + @Override + public WindowInsets onApplyWindowInsets(WindowInsets insets) { + DisplayCutout cutout = insets.getDisplayCutout(); + Pair padding = PhoneStatusBarView.cornerCutoutMargins( + cutout, getDisplay()); + if (padding == null) { + mQsDetailHeader.setPaddingRelative( + getResources().getDimensionPixelSize(R.dimen.qs_detail_header_padding), + getPaddingTop(), + getResources().getDimensionPixelSize(R.dimen.qs_detail_header_padding), + getPaddingBottom() + ); + } else { + mQsDetailHeader.setPadding(padding.first, getPaddingTop(), + padding.second, getPaddingBottom()); + } + return super.onApplyWindowInsets(insets); + } + private void updateDetailText() { mDetailDoneButton.setText(R.string.quick_settings_done); mDetailSettingsButton.setText(R.string.quick_settings_more_settings); -- GitLab From 3cc9758323cb6779a02618cb9bf2015e7b4f9fba Mon Sep 17 00:00:00 2001 From: kwaky Date: Tue, 18 Feb 2020 14:52:10 -0800 Subject: [PATCH 083/219] DO NOT MERGE Reflect the selection state that reflects the current task stack upon restarting the Navigation Bar. Previously, while restarting the Navigation Bar, we omitted the step where we apply the selection state that reflects the current task stack. This omission caused CarFacetButtons to lose their selection state on certain events, such as the day/night toggle. Bug: 148211695 Test: Manual -- Verify that the selection state is preserved between day/night toggle. adb shell dumpsys activity service com.android.car/.CarService day-night-mode day adb shell dumpsys activity service com.android.car/.CarService day-night-mode night Change-Id: Ic07b8b66aa531436ce4f23d56bb3c11a79b7cb46 --- .../com/android/systemui/statusbar/car/CarStatusBar.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index e0f398742ebc..4e1f552f7f99 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -486,6 +486,15 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt // CarFacetButtonController was reset therefore we need to re-add the status bar elements // to the controller. mCarFacetButtonController.addAllFacetButtons(mStatusBarWindow); + + // Upon restarting the Navigation Bar, CarFacetButtonController should immediately apply the + // selection state that reflects the current task stack. + try { + mCarFacetButtonController.taskChanged( + ActivityTaskManager.getService().getAllStackInfos()); + } catch (Exception e) { + Log.e(TAG, "Getting StackInfo from activity manager failed", e); + } } private void addTemperatureViewToController(View v) { -- GitLab From 07af69531c817fda7f57a655f960cf00c73e71c6 Mon Sep 17 00:00:00 2001 From: Lin Guo Date: Sat, 15 Jun 2019 14:19:48 -0700 Subject: [PATCH 084/219] DO NOT MERGE Dismiss system dialog This fixed the keypad remains ON when switch facet issue. BUG: 130573446, 149228466 Test: Manual Change-Id: Ia449fb41a03bc02498471ded660d573d5b1ad141 (cherry picked from commit 82298783683ebe82a5847dfd35fc8b3528709930) (cherry picked from commit ebff32a5d61cdf6f6812588ab4e60ba869dad306) --- .../android/systemui/statusbar/car/CarFacetButton.java | 8 +++++++- .../systemui/statusbar/car/CarNavigationButton.java | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java index 90d20ba19d0e..01b153c979ee 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java @@ -125,13 +125,19 @@ public class CarFacetButton extends LinearLayout { /** Defines the behavior of a button click. */ protected OnClickListener getButtonClickListener(Intent toSend) { - return v -> mContext.startActivityAsUser(toSend, UserHandle.CURRENT); + return v -> { + mContext.startActivityAsUser(toSend, UserHandle.CURRENT); + mContext.sendBroadcastAsUser( + new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), UserHandle.CURRENT); + }; } /** Defines the behavior of a long click. */ protected OnLongClickListener getButtonLongClickListener(Intent toSend) { return v -> { mContext.startActivityAsUser(toSend, UserHandle.CURRENT); + mContext.sendBroadcastAsUser( + new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), UserHandle.CURRENT); return true; }; } diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java index bdf23c56797b..afca2701aa5d 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java @@ -112,6 +112,9 @@ public class CarNavigationButton extends com.android.keyguard.AlphaOptimizedImag try { if (mBroadcastIntent) { mContext.sendBroadcastAsUser(toSend, UserHandle.CURRENT); + mContext.sendBroadcastAsUser( + new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), + UserHandle.CURRENT); return; } mContext.startActivityAsUser(toSend, UserHandle.CURRENT); -- GitLab From 0d3a5aa2aa16fb469a6f10042e53c6dc61c09437 Mon Sep 17 00:00:00 2001 From: Malcolm Chen Date: Tue, 4 Feb 2020 19:01:25 -0800 Subject: [PATCH 085/219] Add carrier config to skip validation if recently validate. Bug: 148611362 Test: unittest Change-Id: I4f4e1f698bf883e6eaf80959f3592562015c70f5 Merged-In: I4f4e1f698bf883e6eaf80959f3592562015c70f5 --- .../telephony/CarrierConfigManager.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 1994ccc74b74..81042f4a34bf 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -3150,6 +3150,25 @@ public class CarrierConfigManager { public static final String KEY_SUBSCRIPTION_GROUP_UUID_STRING = "subscription_group_uuid_string"; + /** + * Data switch validation minimal gap time, in milliseconds. + * + * Which means, if the same subscription on the same network (based on MCC+MNC+TAC+subId) + * was recently validated (within this time gap), and Telephony receives a request to switch to + * it again, Telephony will skip the validation part and switch to it as soon as connection + * is setup, as if it's already validated. + * + * If the network was validated within the gap but the latest validation result is false, the + * validation will not be skipped. + * + * If not set or set to 0, validation will never be skipped. + * The max acceptable value of this config is 24 hours. + * + * @hide + */ + public static final String KEY_DATA_SWITCH_VALIDATION_MIN_GAP_LONG = + "data_switch_validation_min_gap_LONG"; + /** * A boolean property indicating whether this subscription should be managed as an opportunistic * subscription. @@ -3628,6 +3647,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_SUPPORT_WPS_OVER_IMS_BOOL, true); sDefaults.putStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY, null); sDefaults.putLong(KEY_DATA_SWITCH_VALIDATION_TIMEOUT_LONG, 2000); + sDefaults.putLong(KEY_DATA_SWITCH_VALIDATION_MIN_GAP_LONG, 0); } /** -- GitLab From cbfe702556fea02b6a2d467419cb719274c154fc Mon Sep 17 00:00:00 2001 From: Eric Berglund Date: Mon, 10 Feb 2020 12:35:29 -0800 Subject: [PATCH 086/219] DO NOT MERGE Hold onto NotificationListener when reconnecting notifications UI. Bug: 149342387 Test: manual Change-Id: I1bc4046ce1e6792699eaa87b9d50cfaa231e806f --- .../systemui/statusbar/car/CarStatusBar.java | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index e0f398742ebc..4b4b73dae91e 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -41,7 +41,6 @@ import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Looper; -import android.os.RemoteException; import android.util.Log; import android.view.Display; import android.view.GestureDetector; @@ -645,20 +644,22 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt } }); - if (mCarNotificationListener != null) { - try { - // If we already had a notification listener we need to unreigster is before - // making a new one - mCarNotificationListener.unregisterAsSystemService(); - } catch (RemoteException e) { - Log.e(TAG, "Error unregistering notification listener."); - } - } - - mCarNotificationListener = new CarNotificationListener(); mCarUxRestrictionManagerWrapper = new CarUxRestrictionManagerWrapper(); - mNotificationDataManager = new NotificationDataManager(); + if (mCarNotificationListener == null) { + // Only make and register a listener if we don't already have one since + // #connectNotificationsUI can be called multiple times on locale change. + mCarNotificationListener = new CarNotificationListener(); + mNotificationDataManager = new NotificationDataManager(); + + CarHeadsUpNotificationManager carHeadsUpNotificationManager = + new CarSystemUIHeadsUpNotificationManager(mContext, + mNotificationClickHandlerFactory, mNotificationDataManager); + mCarNotificationListener.registerAsSystemService(mContext, + mCarUxRestrictionManagerWrapper, + carHeadsUpNotificationManager, mNotificationDataManager); + } + mNotificationDataManager.setOnUnseenCountUpdateListener(() -> { if (mNavigationBarView != null && mNotificationDataManager != null) { onUseenCountUpdate(mNotificationDataManager.getUnseenNotificationCount()); @@ -667,13 +668,8 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt mEnableHeadsUpNotificationWhenNotificationShadeOpen = mContext.getResources().getBoolean( R.bool.config_enableHeadsUpNotificationWhenNotificationShadeOpen); - CarHeadsUpNotificationManager carHeadsUpNotificationManager = - new CarSystemUIHeadsUpNotificationManager(mContext, - mNotificationClickHandlerFactory, mNotificationDataManager); - mNotificationClickHandlerFactory.setNotificationDataManager(mNotificationDataManager); - mCarNotificationListener.registerAsSystemService(mContext, mCarUxRestrictionManagerWrapper, - carHeadsUpNotificationManager, mNotificationDataManager); + mNotificationClickHandlerFactory.setNotificationDataManager(mNotificationDataManager); mNotificationView = mStatusBarWindow.findViewById(R.id.notification_view); View glassPane = mStatusBarWindow.findViewById(R.id.glass_pane); -- GitLab From 7c7f3dc678ab43bfb45cef6a14bd4959b120b8d9 Mon Sep 17 00:00:00 2001 From: Jay Aliomer Date: Tue, 18 Feb 2020 11:48:29 -0500 Subject: [PATCH 087/219] Back porting Dark theme bug fixes from R Applying theme on start update system properties on startup to apply the updates Fixes: 149441632 Fixes: 149385662 Test: UiModeManager tests Change-Id: I7f71e27a43eb24be833b3003340653fefc75d0cc Merged-In: I0bee6517b39216146681097262cf55c7192b0131 --- .../android/server/UiModeManagerService.java | 128 +++++++++++------- .../server/UiModeManagerServiceTest.java | 5 +- 2 files changed, 85 insertions(+), 48 deletions(-) diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java index 978cc577f1eb..17742b7f634f 100644 --- a/services/core/java/com/android/server/UiModeManagerService.java +++ b/services/core/java/com/android/server/UiModeManagerService.java @@ -16,6 +16,7 @@ package com.android.server; +import android.annotation.IntRange; import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityManager; @@ -41,6 +42,7 @@ import android.os.Handler; import android.os.PowerManager; import android.os.PowerManager.ServiceType; import android.os.PowerManagerInternal; +import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; @@ -67,6 +69,10 @@ import com.android.server.wm.WindowManagerInternal; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.Map; + +import static android.app.UiModeManager.MODE_NIGHT_AUTO; +import static android.app.UiModeManager.MODE_NIGHT_YES; final class UiModeManagerService extends SystemService { private static final String TAG = UiModeManager.class.getSimpleName(); @@ -124,6 +130,7 @@ final class UiModeManagerService extends SystemService { private NotificationManager mNotificationManager; private StatusBarManager mStatusBarManager; private WindowManagerInternal mWindowManager; + private PowerManager mPowerManager; private PowerManager.WakeLock mWakeLock; @@ -136,11 +143,12 @@ final class UiModeManagerService extends SystemService { @VisibleForTesting protected UiModeManagerService(Context context, WindowManagerInternal wm, PowerManager.WakeLock wl, TwilightManager tm, - boolean setupWizardComplete) { + PowerManager pm, boolean setupWizardComplete) { super(context); mWindowManager = wm; mWakeLock = wl; mTwilightManager = tm; + mPowerManager = pm; mSetupWizardComplete = setupWizardComplete; } @@ -261,14 +269,19 @@ final class UiModeManagerService extends SystemService { private final ContentObserver mDarkThemeObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange, Uri uri) { - int mode = Secure.getIntForUser(getContext().getContentResolver(), Secure.UI_NIGHT_MODE, - mNightMode, 0); - mode = mode == UiModeManager.MODE_NIGHT_AUTO - ? UiModeManager.MODE_NIGHT_YES : mode; - SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME, Integer.toString(mode)); + updateSystemProperties(); } }; + private void updateSystemProperties() { + int mode = Secure.getIntForUser(getContext().getContentResolver(), Secure.UI_NIGHT_MODE, + mNightMode, 0); + if (mode == MODE_NIGHT_AUTO) { + mode = MODE_NIGHT_YES; + } + SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME, Integer.toString(mode)); + } + @Override public void onSwitchUser(int userHandle) { super.onSwitchUser(userHandle); @@ -280,9 +293,9 @@ final class UiModeManagerService extends SystemService { public void onStart() { final Context context = getContext(); - final PowerManager powerManager = + mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - mWakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG); + mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG); mWindowManager = LocalServices.getService(WindowManagerInternal.class); // If setup isn't complete for this user listen for completion so we can unblock @@ -349,6 +362,7 @@ final class UiModeManagerService extends SystemService { context.getContentResolver().registerContentObserver(Secure.getUriFor(Secure.UI_NIGHT_MODE), false, mDarkThemeObserver, 0); + mHandler.post(() -> updateSystemProperties()); } @VisibleForTesting @@ -406,6 +420,7 @@ final class UiModeManagerService extends SystemService { } private void registerScreenOffEvent() { + if (mPowerSave) return; mWaitForScreenOff = true; final IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF); @@ -510,7 +525,9 @@ final class UiModeManagerService extends SystemService { persistNightMode(user); } // on screen off will update configuration instead - if (mNightMode != UiModeManager.MODE_NIGHT_AUTO || mCar) { + if ((mNightMode != MODE_NIGHT_AUTO) + || shouldApplyAutomaticChangesImmediately()) { + unregisterScreenOffEvent(); updateLocked(0, 0); } else { registerScreenOffEvent(); @@ -587,19 +604,20 @@ final class UiModeManagerService extends SystemService { synchronized (mLock) { pw.println("Current UI Mode Service state:"); pw.print(" mDockState="); pw.print(mDockState); - pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState); + pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState); pw.print(" mNightMode="); pw.print(mNightMode); pw.print(" ("); - pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") "); - pw.print(" mNightModeLocked="); pw.print(mNightModeLocked); - pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled); - pw.print(" mComputedNightMode="); pw.print(mComputedNightMode); - pw.print(" mCarModeEnableFlags="); pw.print(mCarModeEnableFlags); - pw.print(" mEnableCarDockLaunch="); pw.println(mEnableCarDockLaunch); + pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") "); + pw.print(" mNightModeLocked="); pw.print(mNightModeLocked); + pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled); + pw.print(" mComputedNightMode="); pw.print(mComputedNightMode); + pw.print(" mCarModeEnableFlags="); pw.print(mCarModeEnableFlags); + pw.print(" mEnableCarDockLaunch="); pw.println(mEnableCarDockLaunch); pw.print(" mCurUiMode=0x"); pw.print(Integer.toHexString(mCurUiMode)); - pw.print(" mUiModeLocked="); pw.print(mUiModeLocked); - pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode)); + pw.print(" mUiModeLocked="); pw.print(mUiModeLocked); + pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode)); pw.print(" mHoldingConfiguration="); pw.print(mHoldingConfiguration); - pw.print(" mSystemReady="); pw.println(mSystemReady); + pw.print(" mSystemReady="); pw.println(mSystemReady); + if (mTwilightManager != null) { // We may not have a TwilightManager. pw.print(" mTwilightService.getLastTwilightState()="); @@ -615,7 +633,6 @@ final class UiModeManagerService extends SystemService { mTwilightManager = getLocalService(TwilightManager.class); mSystemReady = true; mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR; - updateComputedNightModeLocked(); registerVrStateListener(); updateLocked(0, 0); } @@ -683,40 +700,56 @@ final class UiModeManagerService extends SystemService { uiMode = Configuration.UI_MODE_TYPE_VR_HEADSET; } - if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) { + if (mNightMode == MODE_NIGHT_YES || mNightMode == UiModeManager.MODE_NIGHT_NO) { + mComputedNightMode = mNightMode == MODE_NIGHT_YES; + } + + if (mNightMode == MODE_NIGHT_AUTO) { + boolean activateNightMode = mComputedNightMode; if (mTwilightManager != null) { mTwilightManager.registerListener(mTwilightListener, mHandler); + final TwilightState lastState = mTwilightManager.getLastTwilightState(); + activateNightMode = lastState == null ? mComputedNightMode : lastState.isNight(); } - updateComputedNightModeLocked(); - uiMode |= mComputedNightMode ? Configuration.UI_MODE_NIGHT_YES - : Configuration.UI_MODE_NIGHT_NO; + + updateComputedNightModeLocked(activateNightMode); } else { if (mTwilightManager != null) { mTwilightManager.unregisterListener(mTwilightListener); } - uiMode |= mNightMode << 4; } // Override night mode in power save mode if not in car mode if (mPowerSave && !mCarModeEnabled) { uiMode &= ~Configuration.UI_MODE_NIGHT_NO; uiMode |= Configuration.UI_MODE_NIGHT_YES; + } else { + uiMode = getComputedUiModeConfiguration(uiMode); } if (LOG) { Slog.d(TAG, - "updateConfigurationLocked: mDockState=" + mDockState + "updateConfigurationLocked: mDockState=" + mDockState + "; mCarMode=" + mCarModeEnabled + "; mNightMode=" + mNightMode + "; uiMode=" + uiMode); } mCurUiMode = uiMode; - if (!mHoldingConfiguration || !mWaitForScreenOff) { + if (!mHoldingConfiguration && (!mWaitForScreenOff || mPowerSave)) { mConfiguration.uiMode = uiMode; } } + @UiModeManager.NightMode + private int getComputedUiModeConfiguration(@UiModeManager.NightMode int uiMode) { + uiMode |= mComputedNightMode ? Configuration.UI_MODE_NIGHT_YES + : Configuration.UI_MODE_NIGHT_NO; + uiMode &= mComputedNightMode ? ~Configuration.UI_MODE_NIGHT_NO + : ~Configuration.UI_MODE_NIGHT_YES; + return uiMode; + } + private void applyConfigurationExternallyLocked() { if (mSetUiMode != mConfiguration.uiMode) { mSetUiMode = mConfiguration.uiMode; @@ -724,10 +757,16 @@ final class UiModeManagerService extends SystemService { ActivityTaskManager.getService().updateConfiguration(mConfiguration); } catch (RemoteException e) { Slog.w(TAG, "Failure communicating with activity manager", e); + } catch (SecurityException e) { + Slog.e(TAG, "Activity does not have the ", e); } } } + private boolean shouldApplyAutomaticChangesImmediately() { + return mCar || !mPowerManager.isInteractive(); + } + void updateLocked(int enableFlags, int disableFlags) { String action = null; String oldAction = null; @@ -958,26 +997,21 @@ final class UiModeManagerService extends SystemService { } } - private void updateComputedNightModeLocked() { - if (mTwilightManager != null) { - TwilightState state = mTwilightManager.getLastTwilightState(); - if (state != null) { - mComputedNightMode = state.isNight(); - } - if (mNightModeOverride == UiModeManager.MODE_NIGHT_YES && !mComputedNightMode) { - mComputedNightMode = true; - return; - } - if (mNightModeOverride == UiModeManager.MODE_NIGHT_NO && mComputedNightMode) { - mComputedNightMode = false; - return; - } - - mNightModeOverride = mNightMode; - final int user = UserHandle.getCallingUserId(); - Secure.putIntForUser(getContext().getContentResolver(), - OVERRIDE_NIGHT_MODE, mNightModeOverride, user); + private void updateComputedNightModeLocked(boolean activate) { + mComputedNightMode = activate; + if (mNightModeOverride == UiModeManager.MODE_NIGHT_YES && !mComputedNightMode) { + mComputedNightMode = true; + return; + } + if (mNightModeOverride == UiModeManager.MODE_NIGHT_NO && mComputedNightMode) { + mComputedNightMode = false; + return; } + + mNightModeOverride = mNightMode; + final int user = UserHandle.getCallingUserId(); + Secure.putIntForUser(getContext().getContentResolver(), + OVERRIDE_NIGHT_MODE, mNightModeOverride, user); } private void registerVrStateListener() { @@ -1098,7 +1132,7 @@ final class UiModeManagerService extends SystemService { final boolean isIt = (mConfiguration.uiMode & Configuration.UI_MODE_NIGHT_YES) != 0; if (LOG) { Slog.d(TAG, - "LocalService.isNightMode(): mNightMode=" + mNightMode + "LocalService.isNightMode(): mNightMode=" + mNightMode + "; mComputedNightMode=" + mComputedNightMode + "; uiMode=" + mConfiguration.uiMode + "; isIt=" + isIt); diff --git a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java index 338f837b9b44..3fce5ebc8432 100644 --- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java @@ -24,6 +24,7 @@ import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; import android.os.PowerManager; +import android.os.PowerManagerInternal; import android.os.RemoteException; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -66,12 +67,14 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { TwilightManager mTwilightManager; @Mock PowerManager.WakeLock mWakeLock; + @Mock + PowerManager mPowerManager; private Set mScreenOffRecievers; @Before public void setUp() { mUiManagerService = new UiModeManagerService(mContext, mWindowManager, mWakeLock, - mTwilightManager, true); + mTwilightManager, mPowerManager, true); mScreenOffRecievers = new HashSet<>(); mService = mUiManagerService.getService(); when(mContext.checkCallingOrSelfPermission(anyString())) -- GitLab From f9418dbb2c2469dd271e4aebefda5b6a4b485f3a Mon Sep 17 00:00:00 2001 From: Rubin Xu Date: Tue, 5 Nov 2019 10:15:36 +0000 Subject: [PATCH 088/219] RESTRICT AUTOMERGE Update keyguard locked state from TrustManagerService TrustManagerService holds the ground truth about whether a user is locked or not, so update keystore using the information there, instead of doing it from KeyguardStateMonitor. This fixes the issue of work profile locked state not being correctly pushed to keystore. Note: since this change is likely to be backported as a security patch, I'm refraining from doing major refactoring right now. Bug: 141329041 Bug: 144430870 Test: manually with KeyPairSampleApp Change-Id: I3472ece73d573a775345ebcceeeb2cc460374c9b --- keystore/java/android/security/KeyStore.java | 11 +++++ .../policy/keyguard/KeyguardStateMonitor.java | 28 ----------- .../server/trust/TrustManagerService.java | 48 +++++++++++++++++++ 3 files changed, 59 insertions(+), 28 deletions(-) diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index 646aa13664c4..9866c3053714 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -1067,6 +1067,17 @@ public class KeyStore { return onUserPasswordChanged(UserHandle.getUserId(Process.myUid()), newPassword); } + /** + * Notify keystore about the latest user locked state. This is to support keyguard-bound key. + */ + public void onUserLockedStateChanged(int userHandle, boolean locked) { + try { + mBinder.onKeyguardVisibilityChanged(locked, userHandle); + } catch (RemoteException e) { + Log.w(TAG, "Failed to update user locked state " + userHandle, e); + } + } + private class KeyAttestationCallbackResult { private KeystoreResponse keystoreResponse; private KeymasterCertificateChain certificateChain; diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java index f78d2639df1a..add0b01f1879 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java @@ -19,8 +19,6 @@ package com.android.server.policy.keyguard; import android.app.ActivityManager; import android.content.Context; import android.os.RemoteException; -import android.os.ServiceManager; -import android.security.keystore.IKeystoreService; import android.util.Slog; import com.android.internal.policy.IKeyguardService; @@ -53,16 +51,11 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { private final LockPatternUtils mLockPatternUtils; private final StateCallback mCallback; - IKeystoreService mKeystoreService; - public KeyguardStateMonitor(Context context, IKeyguardService service, StateCallback callback) { mLockPatternUtils = new LockPatternUtils(context); mCurrentUserId = ActivityManager.getCurrentUser(); mCallback = callback; - mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager - .getService("android.security.keystore")); - try { service.addStateMonitorCallback(this); } catch (RemoteException e) { @@ -95,23 +88,6 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { mIsShowing = showing; mCallback.onShowingChanged(); - int retry = 2; - while (retry > 0) { - try { - mKeystoreService.onKeyguardVisibilityChanged(showing, mCurrentUserId); - break; - } catch (RemoteException e) { - if (retry == 2) { - Slog.w(TAG, "Error informing keystore of screen lock. Keystore may have died" - + " -> refreshing service token and retrying"); - mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager - .getService("android.security.keystore")); - } else { - Slog.e(TAG, "Error informing keystore of screen lock after retrying once", e); - } - --retry; - } - } } @Override // Binder interface @@ -123,10 +99,6 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { mCurrentUserId = userId; } - private synchronized int getCurrentUser() { - return mCurrentUserId; - } - @Override // Binder interface public void onInputRestrictedStateChanged(boolean inputRestricted) { mInputRestricted = inputRestricted; diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index 7408dd40b5ca..5f5cd3c46117 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -53,6 +53,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; +import android.security.KeyStore; import android.service.trust.TrustAgentService; import android.text.TextUtils; import android.util.ArrayMap; @@ -135,6 +136,33 @@ public class TrustManagerService extends SystemService { @GuardedBy("mUserIsTrusted") private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray(); + /** + * Stores the locked state for users on the device. There are three different type of users + * which are handled slightly differently: + *
    + *
  • Users with real keyguard + * These are users who can be switched to ({@link UserInfo#supportsSwitchToByUser()}). Their + * locked state is derived by a combination of user secure state, keyguard state, trust agent + * decision and biometric authentication result. These are updated via + * {@link #refreshDeviceLockedForUser(int)} and result stored in {@link #mDeviceLockedForUser}. + *
  • Managed profiles with unified challenge + * Managed profile with unified challenge always shares the same locked state as their parent, + * so their locked state is not recorded in {@link #mDeviceLockedForUser}. Instead, + * {@link ITrustManager#isDeviceLocked(int)} always resolves their parent user handle and + * queries its locked state instead. + *
  • Managed profiles with separate challenge + * Locked state for profile with separate challenge is determined by other parts of the + * framework (mostly PowerManager) and pushed to TrustManagerService via + * {@link ITrustManager#setDeviceLockedForUser(int, boolean)}. Although in a corner case when + * the profile has a separate but empty challenge, setting its {@link #mDeviceLockedForUser} to + * {@code false} is actually done by {@link #refreshDeviceLockedForUser(int)}. + *
+ * TODO: Rename {@link ITrustManager#setDeviceLockedForUser(int, boolean)} to + * {@code setDeviceLockedForProfile} to better reflect its purpose. Unifying + * {@code setDeviceLockedForProfile} and {@link #setDeviceLockedForUser} would also be nice. + * At the moment they both update {@link #mDeviceLockedForUser} but have slightly different + * side-effects: one notifies trust agents while the other sends out a broadcast. + */ @GuardedBy("mDeviceLockedForUser") private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray(); @@ -601,6 +629,10 @@ public class TrustManagerService extends SystemService { } } + /** + * Update the user's locked state. Only applicable to users with a real keyguard + * ({@link UserInfo#supportsSwitchToByUser}) and unsecured managed profiles. + */ private void refreshDeviceLockedForUser(int userId) { if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) { Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle," @@ -661,6 +693,15 @@ public class TrustManagerService extends SystemService { } if (changed) { dispatchDeviceLocked(userId, locked); + + KeyStore.getInstance().onUserLockedStateChanged(userId, locked); + // Also update the user's profiles who have unified challenge, since they + // share the same unlocked state (see {@link #isDeviceLocked(int)}) + for (int profileHandle : mUserManager.getEnabledProfileIds(userId)) { + if (mLockPatternUtils.isManagedProfileWithUnifiedChallenge(profileHandle)) { + KeyStore.getInstance().onUserLockedStateChanged(profileHandle, locked); + } + } } } @@ -1194,6 +1235,10 @@ public class TrustManagerService extends SystemService { return "0x" + Integer.toHexString(i); } + /** + * Changes the lock status for the given user. This is only applicable to managed profiles, + * other users should be handled by Keyguard. + */ @Override public void setDeviceLockedForUser(int userId, boolean locked) { enforceReportPermission(); @@ -1204,6 +1249,9 @@ public class TrustManagerService extends SystemService { synchronized (mDeviceLockedForUser) { mDeviceLockedForUser.put(userId, locked); } + + KeyStore.getInstance().onUserLockedStateChanged(userId, locked); + if (locked) { try { ActivityManager.getService().notifyLockedProfile(userId); -- GitLab From 25400fdcb92305814e1ee614f05947e51b502375 Mon Sep 17 00:00:00 2001 From: Abhijoy Saha Date: Tue, 18 Feb 2020 12:54:33 -0800 Subject: [PATCH 089/219] DO NOT MERGE Have volume UI dismiss on home button press. Register a receiver that listens for Intent.ACTION_CLOSE_SYSTEM_DIALOGS and dismisses the volume UI when such an intent is received. Bug: 149228466 Test: Manual Change-Id: Iabb706b1d4cc54cb84f228aad95bfdb7e6f75851 --- .../systemui/volume/CarVolumeDialogImpl.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java index f91c90ec636f..b87844ea74a1 100644 --- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java +++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java @@ -26,8 +26,11 @@ import android.app.KeyguardManager; import android.car.Car; import android.car.Car.CarServiceLifecycleListener; import android.car.media.CarAudioManager; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.Color; @@ -39,6 +42,7 @@ import android.os.Debug; import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.os.UserHandle; import android.util.AttributeSet; import android.util.Log; import android.util.SparseArray; @@ -175,6 +179,17 @@ public class CarVolumeDialogImpl implements VolumeDialog { mCarAudioManager.registerCarVolumeCallback(mVolumeChangeCallback); }; + private final BroadcastReceiver mHomeButtonPressedBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (!intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) { + return; + } + + dismiss(Events.DISMISS_REASON_VOLUME_CONTROLLER); + } + }; + public CarVolumeDialogImpl(Context context) { mContext = context; mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); @@ -204,6 +219,10 @@ public class CarVolumeDialogImpl implements VolumeDialog { public void init(int windowType, Callback callback) { initDialog(); + mContext.registerReceiverAsUser(mHomeButtonPressedBroadcastReceiver, UserHandle.CURRENT, + new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), /* broadcastPermission= */ + null, /* scheduler= */ null); + ((CarSystemUIFactory) SystemUIFactory.getInstance()).getCarServiceProvider(mContext) .addListener(mCarServiceLifecycleListener); } @@ -212,6 +231,8 @@ public class CarVolumeDialogImpl implements VolumeDialog { public void destroy() { mHandler.removeCallbacksAndMessages(/* token= */ null); + mContext.unregisterReceiver(mHomeButtonPressedBroadcastReceiver); + cleanupAudioManager(); } -- GitLab From cb45d588e15243d28af595442383fe21bd567b10 Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Thu, 13 Feb 2020 16:15:39 -0500 Subject: [PATCH 090/219] RESTRICT AUTOMERGE Use Alternative Prox Sensor for Falsing This allows new phones to use a sensor with a different theshold when attempting to determine the devices proximity to surfaces. Bug: 149420648 Test: manual Change-Id: Iee8568f7d9f58359dc1e72fd195a42abeaf2ddf3 --- packages/SystemUI/res/values/config.xml | 8 ++++ .../android/systemui/doze/DozeSensors.java | 18 ++++---- .../android/systemui/doze/DozeTriggers.java | 13 +++--- .../systemui/util/ProximitySensor.java | 43 +++++++++++++++---- 4 files changed, 60 insertions(+), 22 deletions(-) diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 78318cb7e858..87461bbccf12 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -201,6 +201,14 @@ always-on display) --> + + @string/doze_brightness_sensor_type + + + + 0 + 130 diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java index 026a62528c8d..b7c8f707b850 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java @@ -43,11 +43,11 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; -import com.android.systemui.R; import com.android.systemui.plugins.SensorManagerPlugin; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.util.AlarmTimeout; import com.android.systemui.util.AsyncSensorManager; +import com.android.systemui.util.ProximitySensor; import com.android.systemui.util.wakelock.WakeLock; import java.io.PrintWriter; @@ -288,6 +288,7 @@ public class DozeSensors { final AlarmTimeout mCooldownTimer; final AlwaysOnDisplayPolicy mPolicy; final Sensor mSensor; + private final float mSensorThreshold; final boolean mUsingBrightnessSensor; public ProxSensor(AlwaysOnDisplayPolicy policy) { @@ -297,11 +298,14 @@ public class DozeSensors { // The default prox sensor can be noisy, so let's use a prox gated brightness sensor // if available. - Sensor sensor = DozeSensors.findSensorWithType(mSensorManager, - mContext.getString(R.string.doze_brightness_sensor_type)); + Sensor sensor = ProximitySensor.findCustomProxSensor(mContext, mSensorManager); mUsingBrightnessSensor = sensor != null; - if (sensor == null) { + if (mUsingBrightnessSensor) { + mSensorThreshold = ProximitySensor.getBrightnessSensorThreshold( + mContext.getResources()); + } else { sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); + mSensorThreshold = sensor.getMaximumRange(); } mSensor = sensor; } @@ -343,11 +347,9 @@ public class DozeSensors { if (DEBUG) Log.d(TAG, "onSensorChanged " + event); if (mUsingBrightnessSensor) { - // The custom brightness sensor is gated by the proximity sensor and will return 0 - // whenever prox is covered. - mCurrentlyFar = event.values[0] > 0; + mCurrentlyFar = event.values[0] > mSensorThreshold; } else { - mCurrentlyFar = event.values[0] >= event.sensor.getMaximumRange(); + mCurrentlyFar = event.values[0] >= mSensorThreshold; } mProxCallback.accept(mCurrentlyFar); diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index 6199a0deb31f..c7a133dc530a 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -41,10 +41,10 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.Preconditions; import com.android.systemui.Dependency; -import com.android.systemui.R; import com.android.systemui.dock.DockManager; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.util.Assert; +import com.android.systemui.util.ProximitySensor; import com.android.systemui.util.wakelock.WakeLock; import java.io.PrintWriter; @@ -431,15 +431,18 @@ public class DozeTriggers implements DozeMachine.Part { private boolean mFinished; private float mMaxRange; private boolean mUsingBrightnessSensor; + private float mSensorThreshold; protected abstract void onProximityResult(int result); public void check() { Preconditions.checkState(!mFinished && !mRegistered); - Sensor sensor = DozeSensors.findSensorWithType(mSensorManager, - mContext.getString(R.string.doze_brightness_sensor_type)); + Sensor sensor = ProximitySensor.findCustomProxSensor(mContext, mSensorManager); mUsingBrightnessSensor = sensor != null; - if (sensor == null) { + if (mUsingBrightnessSensor) { + mSensorThreshold = ProximitySensor.getBrightnessSensorThreshold( + mContext.getResources()); + } else { sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); } if (sensor == null) { @@ -473,7 +476,7 @@ public class DozeTriggers implements DozeMachine.Part { if (mUsingBrightnessSensor) { // The custom brightness sensor is gated by the proximity sensor and will // return 0 whenever prox is covered. - isNear = event.values[0] == 0; + isNear = event.values[0] <= mSensorThreshold; } else { isNear = event.values[0] < mMaxRange; } diff --git a/packages/SystemUI/src/com/android/systemui/util/ProximitySensor.java b/packages/SystemUI/src/com/android/systemui/util/ProximitySensor.java index a905eba1f0ed..4cd38febc5dd 100644 --- a/packages/SystemUI/src/com/android/systemui/util/ProximitySensor.java +++ b/packages/SystemUI/src/com/android/systemui/util/ProximitySensor.java @@ -17,6 +17,7 @@ package com.android.systemui.util; import android.content.Context; +import android.content.res.Resources; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; @@ -40,7 +41,7 @@ public class ProximitySensor { private final Sensor mSensor; private final AsyncSensorManager mSensorManager; private final boolean mUsingBrightnessSensor; - private final float mMaxRange; + private final float mThreshold; private SensorEventListener mSensorEventListener = new SensorEventListener() { @Override @@ -59,7 +60,7 @@ public class ProximitySensor { @Inject public ProximitySensor(Context context, AsyncSensorManager sensorManager) { mSensorManager = sensorManager; - Sensor sensor = findBrightnessSensor(context, sensorManager); + Sensor sensor = findCustomProxSensor(context, sensorManager); if (sensor == null) { mUsingBrightnessSensor = false; @@ -69,9 +70,13 @@ public class ProximitySensor { } mSensor = sensor; if (mSensor != null) { - mMaxRange = mSensor.getMaximumRange(); + if (mUsingBrightnessSensor) { + mThreshold = getBrightnessSensorThreshold(context.getResources()); + } else { + mThreshold = mSensor.getMaximumRange(); + } } else { - mMaxRange = 0; + mThreshold = 0; } } @@ -79,8 +84,18 @@ public class ProximitySensor { mTag = tag; } - private Sensor findBrightnessSensor(Context context, SensorManager sensorManager) { - String sensorType = context.getString(R.string.doze_brightness_sensor_type); + /** + * Returns a brightness sensor that can be used for proximity purposes. + * + * @deprecated This method exists for legacy purposes. Use the containing class directly. + */ + @Deprecated + public static Sensor findCustomProxSensor(Context context, SensorManager sensorManager) { + String sensorType = context.getString(R.string.proximity_sensor_type); + if (sensorType.isEmpty()) { + return null; + } + List sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL); Sensor sensor = null; for (Sensor s : sensorList) { @@ -93,6 +108,16 @@ public class ProximitySensor { return sensor; } + /** + * Returns a threshold value that can be used along with {@link #findCustomProxSensor} + * + * @deprecated This method exists for legacy purposes. Use the containing class directly. + */ + @Deprecated + public static float getBrightnessSensorThreshold(Resources resources) { + return resources.getFloat(R.dimen.proximity_sensor_threshold); + } + /** * Returns {@code false} if a Proximity sensor is not available. */ @@ -141,11 +166,11 @@ public class ProximitySensor { } private void onSensorEvent(SensorEvent event) { - boolean near = event.values[0] < mMaxRange; if (mUsingBrightnessSensor) { - near = event.values[0] == 0; + mNear = event.values[0] <= mThreshold; + } else { + mNear = event.values[0] < mThreshold; } - mNear = near; mListeners.forEach(proximitySensorListener -> proximitySensorListener.onProximitySensorEvent( new ProximityEvent(mNear, event.timestamp))); -- GitLab From fbf32a013d7821ee3cf75b64fa40876f8ca6bf4a Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 16 Jan 2020 12:17:17 -0800 Subject: [PATCH 091/219] DO NOT MERGE: RELAND: NetworkRequest: Embed requestor uid & packageName Add the requestorUid & requestorPackageName fields to NetworkCapabilities. This is populated by CS when a new network request is received. These 2 requestor fields are also optionally used for network matching. All of the regular app initiated requests will have the requestor uid and package name set by connectivity service. Network agents can optionally set the requestorUid and requestorPackageName to restrict the network created only to the app that requested the network. This will help removing the necessity for the various specifiers to embed the uid & package name info in the specifier for network matching. Note: NetworkSpecifier.assertValidFromUid() is deprecated & removed in favor of setting the uid/package name on the agent to restrict the network to a certain app (useful for wifi peer to peer API & wifi aware). Bug: 144102365 Test: Verified that wifi network request related CTS verifier tests pass. Test: Device boots up and connects to wifi networks Merged-In: I207c446108afdac7ee2c25e6bbcbc37c4e3f6529 Change-Id: I58775e82aa7725aac5aa27ca9d2b5ee8f0be4242 --- api/current.txt | 2 +- api/system-current.txt | 7 +- .../java/android/net/ConnectivityManager.java | 14 +- .../android/net/IConnectivityManager.aidl | 9 +- .../java/android/net/NetworkCapabilities.java | 161 +++++++++++++++++- core/java/android/net/NetworkRequest.java | 26 +++ core/java/android/net/NetworkSpecifier.java | 17 -- .../android/server/ConnectivityService.java | 54 +++--- .../android/net/NetworkCapabilitiesTest.java | 16 +- .../android/net/ConnectivityManagerTest.java | 12 +- .../server/ConnectivityServiceTest.java | 31 +--- .../net/wifi/WifiNetworkAgentSpecifier.java | 6 - .../net/wifi/WifiNetworkSpecifier.java | 8 - .../aware/WifiAwareAgentNetworkSpecifier.java | 6 - .../wifi/aware/WifiAwareNetworkSpecifier.java | 8 - .../wifi/WifiNetworkAgentSpecifierTest.java | 10 -- .../WifiAwareAgentNetworkSpecifierTest.java | 11 -- 17 files changed, 263 insertions(+), 135 deletions(-) diff --git a/api/current.txt b/api/current.txt index 7a06cb7e9093..b0878d7c5c62 100644 --- a/api/current.txt +++ b/api/current.txt @@ -29162,7 +29162,7 @@ package android.net { method @NonNull public android.net.NetworkCapabilities setLinkDownstreamBandwidthKbps(int); method @NonNull public android.net.NetworkCapabilities setLinkUpstreamBandwidthKbps(int); method @NonNull public android.net.NetworkCapabilities setNetworkSpecifier(@NonNull android.net.NetworkSpecifier); - method public void setOwnerUid(int); + method @NonNull public android.net.NetworkCapabilities setOwnerUid(int); method @NonNull public android.net.NetworkCapabilities setSignalStrength(int); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; diff --git a/api/system-current.txt b/api/system-current.txt index ef5c838faa25..971ea08651b4 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4656,7 +4656,9 @@ package android.net { method @Nullable public String getSSID(); method @NonNull public int[] getTransportTypes(); method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities); - method public void setAdministratorUids(@NonNull java.util.List); + method @NonNull public android.net.NetworkCapabilities setAdministratorUids(@NonNull java.util.List); + method @NonNull public android.net.NetworkCapabilities setRequestorPackageName(@NonNull String); + method @NonNull public android.net.NetworkCapabilities setRequestorUid(int); method @NonNull public android.net.NetworkCapabilities setSSID(@Nullable String); method @NonNull public android.net.NetworkCapabilities setTransportInfo(@NonNull android.net.TransportInfo); field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16 @@ -4708,6 +4710,8 @@ package android.net { } public class NetworkRequest implements android.os.Parcelable { + method @Nullable public String getRequestorPackageName(); + method public int getRequestorUid(); method public boolean satisfiedBy(@Nullable android.net.NetworkCapabilities); } @@ -4742,7 +4746,6 @@ package android.net { } public abstract class NetworkSpecifier { - method public void assertValidFromUid(int); method @Nullable public android.net.NetworkSpecifier redact(); method public abstract boolean satisfiedBy(@Nullable android.net.NetworkSpecifier); } diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 6d8565025fd4..f1b5d3298b9b 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -3747,6 +3747,7 @@ public class ConnectivityManager { checkCallbackNotNull(callback); Preconditions.checkArgument(action == REQUEST || need != null, "null NetworkCapabilities"); final NetworkRequest request; + final String callingPackageName = mContext.getOpPackageName(); try { synchronized(sCallbacks) { if (callback.networkRequest != null @@ -3758,10 +3759,11 @@ public class ConnectivityManager { Messenger messenger = new Messenger(handler); Binder binder = new Binder(); if (action == LISTEN) { - request = mService.listenForNetwork(need, messenger, binder); + request = mService.listenForNetwork( + need, messenger, binder, callingPackageName); } else { request = mService.requestNetwork( - need, messenger, timeoutMs, binder, legacyType); + need, messenger, timeoutMs, binder, legacyType, callingPackageName); } if (request != null) { sCallbacks.put(request, callback); @@ -4034,8 +4036,10 @@ public class ConnectivityManager { @NonNull PendingIntent operation) { printStackTrace(); checkPendingIntentNotNull(operation); + final String callingPackageName = mContext.getOpPackageName(); try { - mService.pendingRequestForNetwork(request.networkCapabilities, operation); + mService.pendingRequestForNetwork( + request.networkCapabilities, operation, callingPackageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } catch (ServiceSpecificException e) { @@ -4147,8 +4151,10 @@ public class ConnectivityManager { @NonNull PendingIntent operation) { printStackTrace(); checkPendingIntentNotNull(operation); + final String callingPackageName = mContext.getOpPackageName(); try { - mService.pendingListenForNetwork(request.networkCapabilities, operation); + mService.pendingListenForNetwork( + request.networkCapabilities, operation, callingPackageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } catch (ServiceSpecificException e) { diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index c871c456dc66..3a55461a77d2 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -166,18 +166,19 @@ interface IConnectivityManager in int factorySerialNumber); NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, - in Messenger messenger, int timeoutSec, in IBinder binder, int legacy); + in Messenger messenger, int timeoutSec, in IBinder binder, int legacy, + String callingPackageName); NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities, - in PendingIntent operation); + in PendingIntent operation, String callingPackageName); void releasePendingNetworkRequest(in PendingIntent operation); NetworkRequest listenForNetwork(in NetworkCapabilities networkCapabilities, - in Messenger messenger, in IBinder binder); + in Messenger messenger, in IBinder binder, String callingPackageName); void pendingListenForNetwork(in NetworkCapabilities networkCapabilities, - in PendingIntent operation); + in PendingIntent operation, String callingPackageName); void releaseNetworkRequest(in NetworkRequest networkRequest); diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 38f7390abffd..ef4a9e5f3b5d 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -27,6 +27,7 @@ import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.Process; +import android.text.TextUtils; import android.util.ArraySet; import android.util.proto.ProtoOutputStream; @@ -63,6 +64,16 @@ public final class NetworkCapabilities implements Parcelable { // Set to true when private DNS is broken. private boolean mPrivateDnsBroken; + /** + * Uid of the app making the request. + */ + private int mRequestorUid; + + /** + * Package name of the app making the request. + */ + private String mRequestorPackageName; + public NetworkCapabilities() { clearAll(); mNetworkCapabilities = DEFAULT_CAPABILITIES; @@ -89,6 +100,8 @@ public final class NetworkCapabilities implements Parcelable { mOwnerUid = Process.INVALID_UID; mSSID = null; mPrivateDnsBroken = false; + mRequestorUid = Process.INVALID_UID; + mRequestorPackageName = null; } /** @@ -109,6 +122,8 @@ public final class NetworkCapabilities implements Parcelable { mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities; mSSID = nc.mSSID; mPrivateDnsBroken = nc.mPrivateDnsBroken; + mRequestorUid = nc.mRequestorUid; + mRequestorPackageName = nc.mRequestorPackageName; } /** @@ -810,7 +825,7 @@ public final class NetworkCapabilities implements Parcelable { } /** - * UID of the app that owns this network, or INVALID_UID if none/unknown. + * UID of the app that owns this network, or Process#INVALID_UID if none/unknown. * *

This field keeps track of the UID of the app that created this network and is in charge of * its lifecycle. This could be the UID of apps such as the Wifi network suggestor, the running @@ -821,8 +836,9 @@ public final class NetworkCapabilities implements Parcelable { /** * Set the UID of the owner app. */ - public void setOwnerUid(final int uid) { + public @NonNull NetworkCapabilities setOwnerUid(final int uid) { mOwnerUid = uid; + return this; } /** @@ -865,9 +881,11 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ @SystemApi - public void setAdministratorUids(@NonNull final List administratorUids) { + public @NonNull NetworkCapabilities setAdministratorUids( + @NonNull final List administratorUids) { mAdministratorUids.clear(); mAdministratorUids.addAll(administratorUids); + return this; } /** @@ -1385,6 +1403,7 @@ public final class NetworkCapabilities implements Parcelable { combineSignalStrength(nc); combineUids(nc); combineSSIDs(nc); + combineRequestor(nc); } /** @@ -1404,7 +1423,8 @@ public final class NetworkCapabilities implements Parcelable { && satisfiedBySpecifier(nc) && (onlyImmutable || satisfiedBySignalStrength(nc)) && (onlyImmutable || satisfiedByUids(nc)) - && (onlyImmutable || satisfiedBySSID(nc))); + && (onlyImmutable || satisfiedBySSID(nc))) + && (onlyImmutable || satisfiedByRequestor(nc)); } /** @@ -1488,7 +1508,7 @@ public final class NetworkCapabilities implements Parcelable { public boolean equals(@Nullable Object obj) { if (obj == null || (obj instanceof NetworkCapabilities == false)) return false; NetworkCapabilities that = (NetworkCapabilities) obj; - return (equalsNetCapabilities(that) + return equalsNetCapabilities(that) && equalsTransportTypes(that) && equalsLinkBandwidths(that) && equalsSignalStrength(that) @@ -1496,7 +1516,8 @@ public final class NetworkCapabilities implements Parcelable { && equalsTransportInfo(that) && equalsUids(that) && equalsSSID(that) - && equalsPrivateDnsBroken(that)); + && equalsPrivateDnsBroken(that) + && equalsRequestor(that); } @Override @@ -1514,7 +1535,9 @@ public final class NetworkCapabilities implements Parcelable { + Objects.hashCode(mUids) * 31 + Objects.hashCode(mSSID) * 37 + Objects.hashCode(mTransportInfo) * 41 - + Objects.hashCode(mPrivateDnsBroken) * 43; + + Objects.hashCode(mPrivateDnsBroken) * 43 + + Objects.hashCode(mRequestorUid) * 47 + + Objects.hashCode(mRequestorPackageName) * 53; } @Override @@ -1537,6 +1560,8 @@ public final class NetworkCapabilities implements Parcelable { dest.writeBoolean(mPrivateDnsBroken); dest.writeList(mAdministratorUids); dest.writeInt(mOwnerUid); + dest.writeInt(mRequestorUid); + dest.writeString(mRequestorPackageName); } public static final @android.annotation.NonNull Creator CREATOR = @@ -1559,6 +1584,8 @@ public final class NetworkCapabilities implements Parcelable { netCap.mPrivateDnsBroken = in.readBoolean(); netCap.setAdministratorUids(in.readArrayList(null)); netCap.mOwnerUid = in.readInt(); + netCap.mRequestorUid = in.readInt(); + netCap.mRequestorPackageName = in.readString(); return netCap; } @Override @@ -1624,6 +1651,9 @@ public final class NetworkCapabilities implements Parcelable { sb.append(" Private DNS is broken"); } + sb.append(" RequestorUid: ").append(mRequestorUid); + sb.append(" RequestorPackageName: ").append(mRequestorPackageName); + sb.append("]"); return sb.toString(); } @@ -1632,6 +1662,7 @@ public final class NetworkCapabilities implements Parcelable { private interface NameOf { String nameOf(int value); } + /** * @hide */ @@ -1799,4 +1830,120 @@ public final class NetworkCapabilities implements Parcelable { private boolean equalsPrivateDnsBroken(NetworkCapabilities nc) { return mPrivateDnsBroken == nc.mPrivateDnsBroken; } + + /** + * Set the uid of the app making the request. + * + * Note: This works only for {@link NetworkAgent} instances. Any capabilities passed in + * via the public {@link ConnectivityManager} API's will have this field overwritten. + * + * @param uid UID of the app. + * @hide + */ + @SystemApi + public @NonNull NetworkCapabilities setRequestorUid(int uid) { + mRequestorUid = uid; + return this; + } + + /** + * @return the uid of the app making the request. + * + * Note: This could return {@link Process#INVALID_UID} if the {@link NetworkRequest} + * object was not obtained from {@link ConnectivityManager}. + * @hide + */ + public int getRequestorUid() { + return mRequestorUid; + } + + /** + * Set the package name of the app making the request. + * + * Note: This works only for {@link NetworkAgent} instances. Any capabilities passed in + * via the public {@link ConnectivityManager} API's will have this field overwritten. + * + * @param packageName package name of the app. + * @hide + */ + @SystemApi + public @NonNull NetworkCapabilities setRequestorPackageName(@NonNull String packageName) { + mRequestorPackageName = packageName; + return this; + } + + /** + * @return the package name of the app making the request. + * + * Note: This could return {@code null} if the {@link NetworkRequest} object was not obtained + * from {@link ConnectivityManager}. + * @hide + */ + @Nullable + public String getRequestorPackageName() { + return mRequestorPackageName; + } + + /** + * Set the uid and package name of the app making the request. + * + * Note: This is intended to be only invoked from within connectivitiy service. + * + * @param uid UID of the app. + * @param packageName package name of the app. + * @hide + */ + public @NonNull NetworkCapabilities setRequestorUidAndPackageName( + int uid, @NonNull String packageName) { + return setRequestorUid(uid).setRequestorPackageName(packageName); + } + + /** + * Test whether the passed NetworkCapabilities satisfies the requestor restrictions of this + * capabilities. + * + * This method is called on the NetworkCapabilities embedded in a request with the + * capabilities of an available network. If the available network, sets a specific + * requestor (by uid and optionally package name), then this will only match a request from the + * same app. If either of the capabilities have an unset uid or package name, then it matches + * everything. + *

+ * nc is assumed nonnull. Else, NPE. + */ + private boolean satisfiedByRequestor(NetworkCapabilities nc) { + // No uid set, matches everything. + if (mRequestorUid == Process.INVALID_UID || nc.mRequestorUid == Process.INVALID_UID) { + return true; + } + // uids don't match. + if (mRequestorUid != nc.mRequestorUid) return false; + // No package names set, matches everything + if (null == nc.mRequestorPackageName || null == mRequestorPackageName) return true; + // check for package name match. + return TextUtils.equals(mRequestorPackageName, nc.mRequestorPackageName); + } + + /** + * Combine requestor info of the capabilities. + *

+ * This is only legal if either the requestor info of this object is reset, or both info are + * equal. + * nc is assumed nonnull. + */ + private void combineRequestor(@NonNull NetworkCapabilities nc) { + if (mRequestorUid != Process.INVALID_UID && mRequestorUid != nc.mOwnerUid) { + throw new IllegalStateException("Can't combine two uids"); + } + if (mRequestorPackageName != null + && !mRequestorPackageName.equals(nc.mRequestorPackageName)) { + throw new IllegalStateException("Can't combine two package names"); + } + setRequestorUid(nc.mRequestorUid); + setRequestorPackageName(nc.mRequestorPackageName); + } + + private boolean equalsRequestor(NetworkCapabilities nc) { + return mRequestorUid == nc.mRequestorUid + && TextUtils.equals(mRequestorPackageName, nc.mRequestorPackageName); + } } diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java index ee4379a85b6b..b0bf64ecec56 100644 --- a/core/java/android/net/NetworkRequest.java +++ b/core/java/android/net/NetworkRequest.java @@ -380,6 +380,7 @@ public class NetworkRequest implements Parcelable { dest.writeInt(requestId); dest.writeString(type.name()); } + public static final @android.annotation.NonNull Creator CREATOR = new Creator() { public NetworkRequest createFromParcel(Parcel in) { @@ -494,6 +495,31 @@ public class NetworkRequest implements Parcelable { return networkCapabilities.getNetworkSpecifier(); } + /** + * @return the uid of the app making the request. + * + * Note: This could return {@link Process#INVALID_UID} if the {@link NetworkRequest} object was + * not obtained from {@link ConnectivityManager}. + * @hide + */ + @SystemApi + public int getRequestorUid() { + return networkCapabilities.getRequestorUid(); + } + + /** + * @return the package name of the app making the request. + * + * Note: This could return {@code null} if the {@link NetworkRequest} object was not obtained + * from {@link ConnectivityManager}. + * @hide + */ + @SystemApi + @Nullable + public String getRequestorPackageName() { + return networkCapabilities.getRequestorPackageName(); + } + public String toString() { return "NetworkRequest [ " + type + " id=" + requestId + (legacyType != ConnectivityManager.TYPE_NONE ? ", legacyType=" + legacyType : "") + diff --git a/core/java/android/net/NetworkSpecifier.java b/core/java/android/net/NetworkSpecifier.java index cf31d217c967..2dd0c4e207fe 100644 --- a/core/java/android/net/NetworkSpecifier.java +++ b/core/java/android/net/NetworkSpecifier.java @@ -37,23 +37,6 @@ public abstract class NetworkSpecifier { @SystemApi public abstract boolean satisfiedBy(@Nullable NetworkSpecifier other); - /** - * Optional method which can be overridden by concrete implementations of NetworkSpecifier to - * check a self-reported UID. A concrete implementation may contain a UID which would be self- - * reported by the caller (since NetworkSpecifier implementations should be non-mutable). This - * function is called by ConnectivityService and is passed the actual UID of the caller - - * allowing the verification of the self-reported UID. In cases of mismatch the implementation - * should throw a SecurityException. - * - * @param requestorUid The UID of the requestor as obtained from its binder. - * - * @hide - */ - @SystemApi - public void assertValidFromUid(int requestorUid) { - // empty - } - /** * Optional method which can be overridden by concrete implementations of NetworkSpecifier to * perform any redaction of information from the NetworkSpecifier, e.g. if it contains diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index e91918ac6dbb..52a2ca974d40 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -615,7 +615,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private Set mWolSupportedInterfaces; - private TelephonyManager mTelephonyManager; + private final TelephonyManager mTelephonyManager; private final AppOpsManager mAppOpsManager; private final LocationPermissionChecker mLocationPermissionChecker; @@ -966,6 +966,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mDeps = checkNotNull(deps, "missing Dependencies"); mSystemProperties = mDeps.getSystemProperties(); mNetIdManager = mDeps.makeNetIdManager(); + mContext = checkNotNull(context, "missing Context"); mMetricsLog = logger; mDefaultRequest = createDefaultInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST); @@ -995,7 +996,6 @@ public class ConnectivityService extends IConnectivityManager.Stub mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS); - mContext = checkNotNull(context, "missing Context"); mNMS = checkNotNull(netManager, "missing INetworkManagementService"); mStatsService = checkNotNull(statsService, "missing INetworkStatsService"); mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager"); @@ -1175,6 +1175,7 @@ public class ConnectivityService extends IConnectivityManager.Stub int transportType, NetworkRequest.Type type) { final NetworkCapabilities netCap = new NetworkCapabilities(); netCap.addCapability(NET_CAPABILITY_INTERNET); + netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); if (transportType > -1) { netCap.addTransportType(transportType); } @@ -1705,10 +1706,12 @@ public class ConnectivityService extends IConnectivityManager.Stub return newLp; } - private void restrictRequestUidsForCaller(NetworkCapabilities nc) { + private void restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc, + int callerUid, String callerPackageName) { if (!checkSettingsPermission()) { - nc.setSingleUid(Binder.getCallingUid()); + nc.setSingleUid(callerUid); } + nc.setRequestorUidAndPackageName(callerUid, callerPackageName); nc.setAdministratorUids(Collections.EMPTY_LIST); // Clear owner UID; this can never come from an app. @@ -5334,7 +5337,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // This checks that the passed capabilities either do not request a // specific SSID/SignalStrength, or the calling app has permission to do so. private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc, - int callerPid, int callerUid) { + int callerPid, int callerUid, String callerPackageName) { if (null != nc.getSSID() && !checkSettingsPermission(callerPid, callerUid)) { throw new SecurityException("Insufficient permissions to request a specific SSID"); } @@ -5344,6 +5347,7 @@ public class ConnectivityService extends IConnectivityManager.Stub throw new SecurityException( "Insufficient permissions to request a specific signal strength"); } + mAppOpsManager.checkPackage(callerUid, callerPackageName); } private ArrayList getSignalStrengthThresholds(NetworkAgentInfo nai) { @@ -5390,7 +5394,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return; } MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(ns); - ns.assertValidFromUid(Binder.getCallingUid()); } private void ensureValid(NetworkCapabilities nc) { @@ -5402,7 +5405,9 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities, - Messenger messenger, int timeoutMs, IBinder binder, int legacyType) { + Messenger messenger, int timeoutMs, IBinder binder, int legacyType, + @NonNull String callingPackageName) { + final int callingUid = Binder.getCallingUid(); final NetworkRequest.Type type = (networkCapabilities == null) ? NetworkRequest.Type.TRACK_DEFAULT : NetworkRequest.Type.REQUEST; @@ -5410,7 +5415,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // the default network request. This allows callers to keep track of // the system default network. if (type == NetworkRequest.Type.TRACK_DEFAULT) { - networkCapabilities = createDefaultNetworkCapabilitiesForUid(Binder.getCallingUid()); + networkCapabilities = createDefaultNetworkCapabilitiesForUid(callingUid); enforceAccessPermission(); } else { networkCapabilities = new NetworkCapabilities(networkCapabilities); @@ -5422,13 +5427,14 @@ public class ConnectivityService extends IConnectivityManager.Stub } ensureRequestableCapabilities(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, - Binder.getCallingPid(), Binder.getCallingUid()); + Binder.getCallingPid(), callingUid, callingPackageName); // Set the UID range for this request to the single UID of the requester, or to an empty // set of UIDs if the caller has the appropriate permission and UIDs have not been set. // This will overwrite any allowed UIDs in the requested capabilities. Though there // are no visible methods to set the UIDs, an app could use reflection to try and get // networks for other apps so it's essential that the UIDs are overwritten. - restrictRequestUidsForCaller(networkCapabilities); + restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities, + callingUid, callingPackageName); if (timeoutMs < 0) { throw new IllegalArgumentException("Bad timeout specified"); @@ -5503,16 +5509,18 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities, - PendingIntent operation) { + PendingIntent operation, @NonNull String callingPackageName) { checkNotNull(operation, "PendingIntent cannot be null."); + final int callingUid = Binder.getCallingUid(); networkCapabilities = new NetworkCapabilities(networkCapabilities); enforceNetworkRequestPermissions(networkCapabilities); enforceMeteredApnPolicy(networkCapabilities); ensureRequestableCapabilities(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, - Binder.getCallingPid(), Binder.getCallingUid()); + Binder.getCallingPid(), callingUid, callingPackageName); ensureValidNetworkSpecifier(networkCapabilities); - restrictRequestUidsForCaller(networkCapabilities); + restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities, + callingUid, callingPackageName); NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.REQUEST); @@ -5560,15 +5568,16 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities, - Messenger messenger, IBinder binder) { + Messenger messenger, IBinder binder, @NonNull String callingPackageName) { + final int callingUid = Binder.getCallingUid(); if (!hasWifiNetworkListenPermission(networkCapabilities)) { enforceAccessPermission(); } NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, - Binder.getCallingPid(), Binder.getCallingUid()); - restrictRequestUidsForCaller(nc); + Binder.getCallingPid(), callingUid, callingPackageName); + restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName); // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get // onLost and onAvailable callbacks when networks move in and out of the background. @@ -5588,17 +5597,17 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public void pendingListenForNetwork(NetworkCapabilities networkCapabilities, - PendingIntent operation) { + PendingIntent operation, @NonNull String callingPackageName) { checkNotNull(operation, "PendingIntent cannot be null."); + final int callingUid = Binder.getCallingUid(); if (!hasWifiNetworkListenPermission(networkCapabilities)) { enforceAccessPermission(); } ensureValid(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, - Binder.getCallingPid(), Binder.getCallingUid()); - + Binder.getCallingPid(), callingUid, callingPackageName); final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); - restrictRequestUidsForCaller(nc); + restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName); NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.LISTEN); @@ -7897,12 +7906,13 @@ public class ConnectivityService extends IConnectivityManager.Stub throw new IllegalArgumentException("ConnectivityManager.TYPE_* are deprecated." + " Please use NetworkCapabilities instead."); } - mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackageName); + final int callingUid = Binder.getCallingUid(); + mAppOpsManager.checkPackage(callingUid, callingPackageName); // This NetworkCapabilities is only used for matching to Networks. Clear out its owner uid // and administrator uids to be safe. final NetworkCapabilities nc = new NetworkCapabilities(request.networkCapabilities); - restrictRequestUidsForCaller(nc); + restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName); final NetworkRequest requestWithId = new NetworkRequest( diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java index 3e4f3d818840..efea91ab91f0 100644 --- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java +++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java @@ -272,9 +272,23 @@ public class NetworkCapabilitiesTest { netCap.setOwnerUid(123); assertParcelingIsLossless(netCap); netCap.setSSID(TEST_SSID); - assertParcelSane(netCap, 13); + assertParcelSane(netCap, 15); } + @Test + public void testParcelNetworkCapabilitiesWithRequestorUidAndPackageName() { + final NetworkCapabilities netCap = new NetworkCapabilities() + .addCapability(NET_CAPABILITY_INTERNET) + .setRequestorUid(9304) + .setRequestorPackageName("com.android.test") + .addCapability(NET_CAPABILITY_EIMS) + .addCapability(NET_CAPABILITY_NOT_METERED); + assertParcelingIsLossless(netCap); + netCap.setSSID(TEST_SSID); + assertParcelSane(netCap, 15); + } + + @Test public void testOemPaid() { NetworkCapabilities nc = new NetworkCapabilities(); diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java index 7ede14428a4f..d6bf334ee56a 100644 --- a/tests/net/java/android/net/ConnectivityManagerTest.java +++ b/tests/net/java/android/net/ConnectivityManagerTest.java @@ -212,7 +212,8 @@ public class ConnectivityManagerTest { ArgumentCaptor captor = ArgumentCaptor.forClass(Messenger.class); // register callback - when(mService.requestNetwork(any(), captor.capture(), anyInt(), any(), anyInt())) + when(mService.requestNetwork( + any(), captor.capture(), anyInt(), any(), anyInt(), any())) .thenReturn(request); manager.requestNetwork(request, callback, handler); @@ -240,7 +241,8 @@ public class ConnectivityManagerTest { ArgumentCaptor captor = ArgumentCaptor.forClass(Messenger.class); // register callback - when(mService.requestNetwork(any(), captor.capture(), anyInt(), any(), anyInt())) + when(mService.requestNetwork( + any(), captor.capture(), anyInt(), any(), anyInt(), any())) .thenReturn(req1); manager.requestNetwork(req1, callback, handler); @@ -258,7 +260,8 @@ public class ConnectivityManagerTest { verify(callback, timeout(100).times(0)).onLosing(any(), anyInt()); // callback can be registered again - when(mService.requestNetwork(any(), captor.capture(), anyInt(), any(), anyInt())) + when(mService.requestNetwork( + any(), captor.capture(), anyInt(), any(), anyInt(), any())) .thenReturn(req2); manager.requestNetwork(req2, callback, handler); @@ -282,7 +285,8 @@ public class ConnectivityManagerTest { info.targetSdkVersion = VERSION_CODES.N_MR1 + 1; when(mCtx.getApplicationInfo()).thenReturn(info); - when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt())).thenReturn(request); + when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt(), any())) + .thenReturn(request); Handler handler = new Handler(Looper.getMainLooper()); manager.requestNetwork(request, callback, handler); diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index a906805d3a0c..77147c8a35af 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -108,6 +108,7 @@ import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -311,6 +312,7 @@ public class ConnectivityServiceTest { private static final String MOBILE_IFNAME = "test_rmnet_data0"; private static final String WIFI_IFNAME = "test_wlan0"; private static final String WIFI_WOL_IFNAME = "test_wlan_wol"; + private static final String TEST_PACKAGE_NAME = "com.android.test.package"; private static final String[] EMPTY_STRING_ARRAY = new String[0]; private MockContext mServiceContext; @@ -666,7 +668,7 @@ public class ConnectivityServiceTest { if (mNmValidationRedirectUrl != null) { mNmCallbacks.showProvisioningNotification( - "test_provisioning_notif_action", "com.android.test.package"); + "test_provisioning_notif_action", TEST_PACKAGE_NAME); mNmProvNotificationRequested = true; } } @@ -3039,7 +3041,7 @@ public class ConnectivityServiceTest { networkCapabilities.addTransportType(TRANSPORT_WIFI) .setNetworkSpecifier(new MatchAllNetworkSpecifier()); mService.requestNetwork(networkCapabilities, null, 0, null, - ConnectivityManager.TYPE_WIFI); + ConnectivityManager.TYPE_WIFI, TEST_PACKAGE_NAME); }); class NonParcelableSpecifier extends NetworkSpecifier { @@ -3078,31 +3080,12 @@ public class ConnectivityServiceTest { } @Test - public void testNetworkSpecifierUidSpoofSecurityException() throws Exception { - class UidAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable { - @Override - public boolean satisfiedBy(NetworkSpecifier other) { - return true; - } - - @Override - public void assertValidFromUid(int requestorUid) { - throw new SecurityException("failure"); - } - - @Override - public int describeContents() { return 0; } - @Override - public void writeToParcel(Parcel dest, int flags) {} - } - + public void testNetworkRequestUidSpoofSecurityException() throws Exception { mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); mWiFiNetworkAgent.connect(false); - - UidAwareNetworkSpecifier networkSpecifier = new UidAwareNetworkSpecifier(); - NetworkRequest networkRequest = newWifiRequestBuilder().setNetworkSpecifier( - networkSpecifier).build(); + NetworkRequest networkRequest = newWifiRequestBuilder().build(); TestNetworkCallback networkCallback = new TestNetworkCallback(); + doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString()); assertThrows(SecurityException.class, () -> { mCm.requestNetwork(networkRequest, networkCallback); }); diff --git a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java index 24aa23aec7ae..20fbc9f61a17 100644 --- a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java +++ b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java @@ -199,12 +199,6 @@ public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements return sb.toString(); } - @Override - public void assertValidFromUid(int requestorUid) { - throw new IllegalStateException("WifiNetworkAgentSpecifier should never be used " - + "for requests."); - } - @Override public NetworkSpecifier redact() { return null; diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java index 6c2d7ff882d3..e1d3c434acdb 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java @@ -598,12 +598,4 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc // not make much sense! return equals(other); } - - /** @hide */ - @Override - public void assertValidFromUid(int requestorUid) { - if (this.requestorUid != requestorUid) { - throw new SecurityException("mismatched UIDs"); - } - } } diff --git a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java index 9164d04885b3..282fda8e1b14 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java @@ -143,12 +143,6 @@ public class WifiAwareAgentNetworkSpecifier extends NetworkSpecifier implements return mNetworkSpecifiers.contains(nsBytes); } - @Override - public void assertValidFromUid(int requestorUid) { - throw new SecurityException( - "WifiAwareAgentNetworkSpecifier should not be used in network requests"); - } - @Override public NetworkSpecifier redact() { return null; diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java index 0511f2411647..ad656e1476b2 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java @@ -289,14 +289,6 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements return sb.toString(); } - /** @hide */ - @Override - public void assertValidFromUid(int requestorUid) { - if (this.requestorUid != requestorUid) { - throw new SecurityException("mismatched UIDs"); - } - } - /** * A builder class for a Wi-Fi Aware network specifier to set up an Aware connection with a * peer. diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java index e6eece85cb19..38040ea08eba 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java @@ -70,16 +70,6 @@ public class WifiNetworkAgentSpecifierTest { assertEquals(specifier, parcelSpecifier); } - /** - * Validate that the NetworkAgentSpecifier cannot be used in a {@link NetworkRequest} by apps. - */ - @Test(expected = IllegalStateException.class) - public void testWifiNetworkAgentSpecifierNotUsedInNetworkRequest() { - WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier(); - - specifier.assertValidFromUid(TEST_UID); - } - /** * Validate NetworkAgentSpecifier equals with itself. * a) Create network agent specifier 1 for WPA_PSK network diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java index c3b62854f12c..ef9c6a389db7 100644 --- a/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java +++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java @@ -162,17 +162,6 @@ public class WifiAwareAgentNetworkSpecifierTest { collector.checkThat("Match unexpected", oldNs.satisfiedBy(newNs), equalTo(false)); } - /** - * Validate that agent network specifier cannot be used as in network requests - i.e. that - * throws an exception when queried for UID validity. - */ - @Test(expected = SecurityException.class) - public void testNoUsageInRequest() { - WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier(); - - dut.assertValidFromUid(0); - } - // utilities /** -- GitLab From dd12316b0d6795f4d952110a04890c231dfa6da3 Mon Sep 17 00:00:00 2001 From: Bill Lin Date: Tue, 18 Feb 2020 15:00:39 +0800 Subject: [PATCH 092/219] Add DEBUG flag for rounded corner and display cutout path There wasn't a good approach for engineers to distignlish bounds between H/W display component and S/W anti-aliasing. Allow enable color to review the anti-aliasing effect. Test: adb root; adb shell setprop debug.screenshot_rounded_corners true; Test: adb shell pidof com.android.systemui |xargs -i adb shell kill -9 {} Test: check visual following above steps Test: atest SystemUITests Test: atest ScreenDecorationsTest Change-Id: I87f04b50945e1500babdf9fa7ba9cdb37010fde8 Merged-In: I87f04b50945e1500babdf9fa7ba9cdb37010fde8 --- .../SystemUI/src/com/android/systemui/ScreenDecorations.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index f38b4f259c88..6f597e83bda8 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -105,6 +105,7 @@ public class ScreenDecorations extends SystemUI implements Tunable, private static final boolean DEBUG_SCREENSHOT_ROUNDED_CORNERS = SystemProperties.getBoolean("debug.screenshot_rounded_corners", false); private static final boolean VERBOSE = false; + private static final boolean DEBUG_COLOR = DEBUG_SCREENSHOT_ROUNDED_CORNERS; private DisplayManager mDisplayManager; private DisplayManager.DisplayListener mDisplayListener; @@ -457,6 +458,9 @@ public class ScreenDecorations extends SystemUI implements Tunable, private void updateColorInversion(int colorsInvertedValue) { int tint = colorsInvertedValue != 0 ? Color.WHITE : Color.BLACK; + if (DEBUG_COLOR) { + tint = Color.RED; + } ColorStateList tintList = ColorStateList.valueOf(tint); ((ImageView) mOverlay.findViewById(R.id.left)).setImageTintList(tintList); ((ImageView) mOverlay.findViewById(R.id.right)).setImageTintList(tintList); -- GitLab From b85c9eaa2478ba8a4ca37a2e7628984fbd88ada1 Mon Sep 17 00:00:00 2001 From: Beverly Date: Thu, 20 Feb 2020 13:45:36 -0500 Subject: [PATCH 093/219] DO NOT MERGE Set background drawable on status_bar_container Put the background drawable on status_bar_container instead of status_bar because we always want the status bar background to fill the entire container. status_bar receives new margins when corner display cutouts are enabled which may prevent status_bar from taking up the entire status_bar_container space. Test: atest SystemUITests Bug: 148355955 Change-Id: Ic7e0c0a79908d2a58d4595d239062435253edfda --- packages/SystemUI/res/layout/status_bar.xml | 1 - .../SystemUI/res/layout/super_status_bar.xml | 3 ++- .../phone/PhoneStatusBarTransitions.java | 22 +++++++++---------- .../statusbar/phone/PhoneStatusBarView.java | 7 ------ .../systemui/statusbar/phone/StatusBar.java | 14 ++++++------ .../statusbar/phone/StatusBarWindowView.java | 9 ++++++-- 6 files changed, 26 insertions(+), 30 deletions(-) diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml index 4fae3c500a45..f8db97dbf800 100644 --- a/packages/SystemUI/res/layout/status_bar.xml +++ b/packages/SystemUI/res/layout/status_bar.xml @@ -24,7 +24,6 @@ android:layout_width="match_parent" android:layout_height="@dimen/status_bar_height" android:id="@+id/status_bar" - android:background="@drawable/system_bar_background" android:orientation="vertical" android:focusable="false" android:descendantFocusability="afterDescendants" diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml index a91493003bb5..9d56e08bc555 100644 --- a/packages/SystemUI/res/layout/super_status_bar.xml +++ b/packages/SystemUI/res/layout/super_status_bar.xml @@ -54,7 +54,8 @@ + android:layout_height="wrap_content" + android:background="@drawable/system_bar_background" /> Date: Fri, 14 Feb 2020 15:08:13 +0800 Subject: [PATCH 094/219] DO NOT MERGE Respect rounded.xml size in ScreenDecorations Suppose vendors will customize rounded.xml with corresponding multiple radius path and size, ScreenDecorations should not resize it by rounded_corner_radius in case jagged edges problem Test: atest SystemUITests Test: atest ScreenDecorationsTest Bug: 145707162 Bug: 148912090 Change-Id: Ie33526214072ad324ca00a10074ad212dfbf4258 --- packages/SystemUI/res/values/config.xml | 3 + .../android/systemui/ScreenDecorations.java | 24 +++++-- .../systemui/ScreenDecorationsTest.java | 65 +++++++++++++++++++ 3 files changed, 86 insertions(+), 6 deletions(-) diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 78318cb7e858..7fd9d3c7e1e8 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -480,4 +480,7 @@ -1 + + false + diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index f38b4f259c88..953e9f54ba28 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -45,6 +45,7 @@ import android.graphics.Path; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.Region; +import android.graphics.drawable.VectorDrawable; import android.hardware.display.DisplayManager; import android.os.Handler; import android.os.HandlerThread; @@ -129,6 +130,7 @@ public class ScreenDecorations extends SystemUI implements Tunable, private boolean mAssistHintBlocked = false; private boolean mIsReceivingNavBarColor = false; private boolean mInGesturalMode; + private boolean mIsRoundedCornerMultipleRadius; /** * Converts a set of {@link Rect}s into a {@link Region} @@ -323,6 +325,8 @@ public class ScreenDecorations extends SystemUI implements Tunable, private void startOnScreenDecorationsThread() { mRotation = RotationUtils.getExactRotation(mContext); mWindowManager = mContext.getSystemService(WindowManager.class); + mIsRoundedCornerMultipleRadius = mContext.getResources().getBoolean( + R.bool.config_roundedCornerMultipleRadius); updateRoundedCornerRadii(); if (hasRoundedCorners() || shouldDrawCutout() || shouldHostHandles()) { setupDecorations(); @@ -528,17 +532,24 @@ public class ScreenDecorations extends SystemUI implements Tunable, com.android.internal.R.dimen.rounded_corner_radius_top); final int newRoundedDefaultBottom = mContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.rounded_corner_radius_bottom); - final boolean roundedCornersChanged = mRoundedDefault != newRoundedDefault || mRoundedDefaultBottom != newRoundedDefaultBottom || mRoundedDefaultTop != newRoundedDefaultTop; if (roundedCornersChanged) { - mRoundedDefault = newRoundedDefault; - mRoundedDefaultTop = newRoundedDefaultTop; - mRoundedDefaultBottom = newRoundedDefaultBottom; - onTuningChanged(SIZE, null); + // If config_roundedCornerMultipleRadius set as true, ScreenDecorations respect the + // max(width, height) size of drawable/rounded.xml instead of rounded_corner_radius + if (mIsRoundedCornerMultipleRadius) { + final VectorDrawable d = (VectorDrawable) mContext.getDrawable(R.drawable.rounded); + mRoundedDefault = Math.max(d.getIntrinsicWidth(), d.getIntrinsicHeight()); + mRoundedDefaultTop = mRoundedDefaultBottom = mRoundedDefault; + } else { + mRoundedDefault = newRoundedDefault; + mRoundedDefaultTop = newRoundedDefaultTop; + mRoundedDefaultBottom = newRoundedDefaultBottom; + } } + onTuningChanged(SIZE, null); } private void updateViews() { @@ -637,7 +648,8 @@ public class ScreenDecorations extends SystemUI implements Tunable, } private boolean hasRoundedCorners() { - return mRoundedDefault > 0 || mRoundedDefaultBottom > 0 || mRoundedDefaultTop > 0; + return mRoundedDefault > 0 || mRoundedDefaultBottom > 0 || mRoundedDefaultTop > 0 + || mIsRoundedCornerMultipleRadius; } private boolean shouldDrawCutout() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java index 3b5e12c4ef96..11b256a4da01 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java @@ -20,6 +20,8 @@ import static com.android.systemui.ScreenDecorations.rectsToRegion; import static com.android.systemui.tuner.TunablePadding.FLAG_END; import static com.android.systemui.tuner.TunablePadding.FLAG_START; +import static com.google.common.truth.Truth.assertThat; + import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; @@ -38,6 +40,7 @@ import static org.mockito.Mockito.when; import android.app.Fragment; import android.content.res.Configuration; import android.graphics.Rect; +import android.graphics.drawable.VectorDrawable; import android.os.Handler; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -148,6 +151,8 @@ public class ScreenDecorationsTest extends SysuiTestCase { com.android.internal.R.dimen.rounded_corner_radius_bottom, 0); mContext.getOrCreateTestableResources() .addOverride(dimen.rounded_corner_content_padding, 0); + mContext.getOrCreateTestableResources() + .addOverride(R.bool.config_roundedCornerMultipleRadius, false); mScreenDecorations.start(); // No views added. @@ -166,6 +171,55 @@ public class ScreenDecorationsTest extends SysuiTestCase { com.android.internal.R.dimen.rounded_corner_radius, 20); mContext.getOrCreateTestableResources() .addOverride(dimen.rounded_corner_content_padding, 20); + mContext.getOrCreateTestableResources() + .addOverride(R.bool.config_roundedCornerMultipleRadius, false); + + mScreenDecorations.start(); + // Add 2 windows for rounded corners (top and bottom). + verify(mWindowManager, times(2)).addView(any(), any()); + + // Add 2 tag listeners for each of the fragments that are needed. + verify(mFragmentHostManager, times(2)).addTagListener(any(), any()); + // One tunable. + verify(mTunerService, times(1)).addTunable(any(), any()); + // One TunablePadding. + verify(mTunablePaddingService, times(1)).add(any(), anyString(), anyInt(), anyInt()); + } + + @Test + public void testRoundingRadius() { + final int testRadius = 1; + mContext.getOrCreateTestableResources().addOverride( + com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false); + mContext.getOrCreateTestableResources().addOverride( + com.android.internal.R.dimen.rounded_corner_radius, testRadius); + mContext.getOrCreateTestableResources().addOverride( + com.android.internal.R.dimen.rounded_corner_radius_top, testRadius); + mContext.getOrCreateTestableResources().addOverride( + com.android.internal.R.dimen.rounded_corner_radius_bottom, testRadius); + mContext.getOrCreateTestableResources() + .addOverride(R.bool.config_roundedCornerMultipleRadius, false); + + mScreenDecorations.start(); + // Size of corner view should same as rounded_corner_radius{_top|_bottom} + assertThat(mScreenDecorations.mRoundedDefault).isEqualTo(testRadius); + assertThat(mScreenDecorations.mRoundedDefaultTop).isEqualTo(testRadius); + assertThat(mScreenDecorations.mRoundedDefaultBottom).isEqualTo(testRadius); + } + + @Test + public void testRoundingMultipleRadius() { + final VectorDrawable d = (VectorDrawable) mContext.getDrawable(R.drawable.rounded); + final int multipleRadiusSize = Math.max(d.getIntrinsicWidth(), d.getIntrinsicHeight()); + + mContext.getOrCreateTestableResources().addOverride( + com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false); + mContext.getOrCreateTestableResources().addOverride( + com.android.internal.R.dimen.rounded_corner_radius, 9999); + mContext.getOrCreateTestableResources() + .addOverride(dimen.rounded_corner_content_padding, 9999); + mContext.getOrCreateTestableResources() + .addOverride(R.bool.config_roundedCornerMultipleRadius, true); mScreenDecorations.start(); // Add 2 windows for rounded corners (top and bottom). @@ -177,6 +231,10 @@ public class ScreenDecorationsTest extends SysuiTestCase { verify(mTunerService, times(1)).addTunable(any(), any()); // One TunablePadding. verify(mTunablePaddingService, times(1)).add(any(), anyString(), anyInt(), anyInt()); + // Size of corner view should exactly match max(width, height) of R.drawable.rounded + assertThat(mScreenDecorations.mRoundedDefault).isEqualTo(multipleRadiusSize); + assertThat(mScreenDecorations.mRoundedDefaultTop).isEqualTo(multipleRadiusSize); + assertThat(mScreenDecorations.mRoundedDefaultBottom).isEqualTo(multipleRadiusSize); } @Test @@ -224,6 +282,9 @@ public class ScreenDecorationsTest extends SysuiTestCase { com.android.internal.R.dimen.rounded_corner_radius_bottom, 0); mContext.getOrCreateTestableResources() .addOverride(dimen.rounded_corner_content_padding, 0); + mContext.getOrCreateTestableResources() + .addOverride(R.bool.config_roundedCornerMultipleRadius, false); + when(mNavigationModeController.addListener(any())).thenReturn( WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL); @@ -245,6 +306,8 @@ public class ScreenDecorationsTest extends SysuiTestCase { com.android.internal.R.dimen.rounded_corner_radius_bottom, 0); mContext.getOrCreateTestableResources() .addOverride(dimen.rounded_corner_content_padding, 0); + mContext.getOrCreateTestableResources() + .addOverride(R.bool.config_roundedCornerMultipleRadius, false); when(mNavigationModeController.addListener(any())).thenReturn( WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON); @@ -296,6 +359,8 @@ public class ScreenDecorationsTest extends SysuiTestCase { com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false); mContext.getOrCreateTestableResources().addOverride( com.android.internal.R.dimen.rounded_corner_radius, 20); + mContext.getOrCreateTestableResources() + .addOverride(R.bool.config_roundedCornerMultipleRadius, false); mScreenDecorations.start(); assertEquals(mScreenDecorations.mRoundedDefault, 20); -- GitLab From ba42f4a80a0a3d5419a01e7820a88a1690d21a57 Mon Sep 17 00:00:00 2001 From: Heemin Seog Date: Thu, 20 Feb 2020 16:22:21 -0800 Subject: [PATCH 095/219] DO NOT MERGE Fix Autohide functionality Make sure that opening the notification panel doesn't result in a "blip" in the nav bar visibility Bug: 147427386 Bug: 149021759 Bug: 149115608 Test: on hawk adb shell settings put global policy_control "immersive.navigation=*" swipe up from bottom of screen - make sure it autohides pull down notification panel - make sure the panel doesn't blip on sdk_gphone_x86 - atest SystemUITests Change-Id: I4b5244e5ff26fb23e687cd46bc105d4fb8251bc6 --- .../systemui/statusbar/car/CarStatusBar.java | 84 +++++++++++++++++++ .../statusbar/phone/AutoHideController.java | 17 ++-- .../statusbar/phone/AutoHideElement.java | 32 +++++++ .../phone/NavigationBarFragment.java | 10 ++- .../systemui/statusbar/phone/StatusBar.java | 8 ++ 5 files changed, 143 insertions(+), 8 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideElement.java diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index e0f398742ebc..228111aeabcb 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -16,6 +16,9 @@ package com.android.systemui.statusbar.car; +import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE; +import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; @@ -99,6 +102,8 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; +import com.android.systemui.statusbar.phone.AutoHideElement; +import com.android.systemui.statusbar.phone.BarTransitions; import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment; import com.android.systemui.statusbar.phone.LightBarController; import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper; @@ -122,6 +127,7 @@ import java.util.Map; */ public class CarStatusBar extends StatusBar implements CarBatteryController.BatteryViewHandler { private static final String TAG = "CarStatusBar"; + private static final int MODE_INVALID = -1; // used to calculate how fast to open or close the window private static final float DEFAULT_FLING_VELOCITY = 0; // max time a fling animation takes @@ -268,6 +274,9 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt } }; + private int mNavigationBarMode; + private BarTransitions mNavBarTransitions; + @Override public void start() { // Non blocking call to connect to car service. Call this early so that we'll be connected @@ -382,6 +391,18 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt Log.wtf(TAG, " mVolumeChangeCallback failed to connect to car ", e); } }); + + mAutoHideController.setNavigationBar(new AutoHideElement() { + @Override + public void synchronizeState() { + checkNavBarModes(); + } + + @Override + public boolean isSemiTransparent() { + return mNavigationBarMode == MODE_SEMI_TRANSPARENT; + } + }); } @Override @@ -421,6 +442,65 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt mUserSwitcherController = Dependency.get(UserSwitcherController.class); } + @Override + public void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis, + int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds, + boolean navbarColorManagedByIme) { + // Ensure we store the systemUiVisibility flags before the super call overwrites it. + int oldVal = getSystemUiVisibility(); + + super.setSystemUiVisibility(displayId, vis, fullscreenStackVis, dockedStackVis, mask, + fullscreenStackBounds, dockedStackBounds, navbarColorManagedByIme); + + if (displayId != getDisplayId()) { + return; + } + + int newVal = (oldVal & ~mask) | (vis & mask); + + // update navigation bar mode + int nbMode = mNavigationBarWindow == null ? MODE_INVALID : computeNavBarMode(oldVal, + newVal); + boolean nbModeChanged = nbMode != MODE_INVALID; + if (nbModeChanged) { + if (mNavigationBarMode != nbMode) { + mNavigationBarMode = nbMode; + checkNavBarModes(); + } + mAutoHideController.touchAutoHide(); + } + + mLightBarController.onNavigationVisibilityChanged( + vis, mask, nbModeChanged, mNavigationBarMode, navbarColorManagedByIme); + } + + @BarTransitions.TransitionMode + private int computeNavBarMode(int oldVis, int newVis) { + int oldMode = navBarMode(oldVis); + int newMode = navBarMode(newVis); + if (oldMode == newMode) { + return -1; // no mode change + } + return newMode; + } + + @BarTransitions.TransitionMode + private int navBarMode(int vis) { + if ((vis & View.NAVIGATION_BAR_TRANSIENT) != 0) { + return MODE_SEMI_TRANSPARENT; + } else { + return MODE_OPAQUE; + } + } + + /** + * Checks current navigation bar mode and make transitions. + */ + private void checkNavBarModes() { + boolean anim = isDeviceInteractive() && mBottomNavBarVisible; + mNavBarTransitions.transitionTo(mNavigationBarMode, anim); + } + @Override protected void setUpQuickSettingsTilePanel() { // ignore. @@ -920,7 +1000,9 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt mNotificationViewController.setIsInForeground(false); // let the status bar know that the panel is closed setPanelExpanded(false); + mAutoHideController.userAutoHide(); } else { + mAutoHideController.cancelAutoHide(); mNotificationViewController.setIsInForeground(true); // let the status bar know that the panel is open mNotificationView.setVisibleNotificationsAsSeen(); @@ -995,6 +1077,8 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt if (mShowBottom) { mNavigationBarWindow = (ViewGroup) View.inflate(mContext, R.layout.navigation_bar_window, null); + mNavBarTransitions = new BarTransitions(mNavigationBarWindow, + R.drawable.nav_background); } if (mShowLeft) { mLeftNavigationBarWindow = (ViewGroup) View.inflate(mContext, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java index 5912cd7b6433..1042b61ab4f7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java @@ -47,7 +47,7 @@ public class AutoHideController implements CommandQueue.Callbacks { private final NotificationRemoteInputManager mRemoteInputManager; private final CommandQueue mCommandQueue; private StatusBar mStatusBar; - private NavigationBarFragment mNavigationBar; + private AutoHideElement mNavigationBar; @VisibleForTesting int mDisplayId; @@ -85,11 +85,11 @@ public class AutoHideController implements CommandQueue.Callbacks { } } - void setStatusBar(StatusBar statusBar) { + public void setStatusBar(StatusBar statusBar) { mStatusBar = statusBar; } - void setNavigationBar(NavigationBarFragment navigationBar) { + public void setNavigationBar(AutoHideElement navigationBar) { mNavigationBar = navigationBar; } @@ -158,7 +158,8 @@ public class AutoHideController implements CommandQueue.Callbacks { mAutoHideSuspended = (mSystemUiVisibility & getTransientMask()) != 0; } - void touchAutoHide() { + /** Schedule auto hide if necessary otherwise cancel any pending runnables. */ + public void touchAutoHide() { // update transient bar auto hide if ((hasStatusBar() && mStatusBar.getStatusBarMode() == MODE_SEMI_TRANSPARENT) || hasNavigationBar() && mNavigationBar.isSemiTransparent()) { @@ -172,13 +173,14 @@ public class AutoHideController implements CommandQueue.Callbacks { if (hasStatusBar()) { return () -> mStatusBar.checkBarModes(); } else if (hasNavigationBar()) { - return () -> mNavigationBar.checkNavBarModes(); + return () -> mNavigationBar.synchronizeState(); } else { return null; } } - private void cancelAutoHide() { + /** Remove any scheduled auto hide runnables. */ + public void cancelAutoHide() { mAutoHideSuspended = false; mHandler.removeCallbacks(mAutoHide); } @@ -202,7 +204,8 @@ public class AutoHideController implements CommandQueue.Callbacks { } } - private void userAutoHide() { + /** Schedule auto hide. */ + public void userAutoHide() { cancelAutoHide(); mHandler.postDelayed(mAutoHide, 350); // longer than app gesture -> flag clear } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideElement.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideElement.java new file mode 100644 index 000000000000..8849519ba477 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideElement.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.phone; + +/** An interface for a UI element controlled by the {@link AutoHideController}. */ +public interface AutoHideElement { + /** + * Synchronizes the UI State of this {@link AutoHideElement}. This method is posted as a + * {@link Runnable} on the main thread. + */ + void synchronizeState(); + + /** + * Returns {@code true} if the {@link AutoHideElement} is in a + * {@link BarTransitions#MODE_SEMI_TRANSPARENT} state. + */ + boolean isSemiTransparent(); +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index 9a5f35a979eb..cd27c827fce5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -120,7 +120,7 @@ import javax.inject.Inject; * on clicks and view states of the nav bar. */ public class NavigationBarFragment extends LifecycleFragment implements Callbacks, - NavigationModeController.ModeChangedListener { + NavigationModeController.ModeChangedListener, AutoHideElement { public static final String TAG = "NavigationBar"; private static final boolean DEBUG = false; @@ -970,10 +970,18 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback mAutoHideController.setNavigationBar(this); } + // AutoHideElement + @Override public boolean isSemiTransparent() { return mNavigationBarMode == MODE_SEMI_TRANSPARENT; } + // AutoHideElement + @Override + public void synchronizeState() { + checkNavBarModes(); + } + private void checkBarModes() { // We only have status bar on default display now. if (mIsOnDefaultDisplay) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index c6dee5e9bdf5..7cae81b1996a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -2205,6 +2205,14 @@ public class StatusBar extends SystemUI implements DemoMode, navbarColorManagedByIme); } + protected final int getSystemUiVisibility() { + return mSystemUiVisibility; + } + + protected final int getDisplayId() { + return mDisplayId; + } + @Override public void showWirelessChargingAnimation(int batteryLevel) { if (mDozing || mKeyguardManager.isKeyguardLocked()) { -- GitLab From 48d8d370f3d1dac06719ca6a52bda5f45a1a533a Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Wed, 19 Feb 2020 15:13:56 +0800 Subject: [PATCH 096/219] RESTRICT AUTOMERGE Create separated tasks for different apps from startActivities Assume there are 2 applications A, B with different uids. There are 4 activities A1, A2, B1, B2 with default task affinity and launch mode. After A1 called startActivities(B1, A2, B2): Original : Task(A1, B1, A2, B2) This Change: Task(A1, B1), Task(A2, B2) In other words, the source caller cannot launch its activity above the activity of other application in the same task, and it can still launch activity of other application in its task. Bug: 145669109 Test: atest StartActivityTests# \ testStartActivitiesWithDiffUidNotInSameTask Change-Id: I97bd875146a52f62b8fe82235487ccefb2955e8e --- .../server/am/ActivityStartController.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java index c926503da27d..240f01d159a7 100644 --- a/services/core/java/com/android/server/am/ActivityStartController.java +++ b/services/core/java/com/android/server/am/ActivityStartController.java @@ -334,6 +334,9 @@ public class ActivityStartController { } else { callingPid = callingUid = -1; } + boolean forceNewTask = false; + final int filterCallingUid = ActivityStarter.computeResolveFilterUid( + callingUid, realCallingUid, UserHandle.USER_NULL); final long origId = Binder.clearCallingIdentity(); try { synchronized (mService) { @@ -353,11 +356,13 @@ public class ActivityStartController { // Don't modify the client's object! intent = new Intent(intent); + if (forceNewTask) { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + } // Collect information about the target of the Intent. ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 0, - null, userId, ActivityStarter.computeResolveFilterUid( - callingUid, realCallingUid, UserHandle.USER_NULL)); + null, userId, filterCallingUid); // TODO: New, check if this is correct aInfo = mService.getActivityInfoForUser(aInfo, userId); @@ -397,7 +402,17 @@ public class ActivityStartController { return res; } - resultTo = outActivity[0] != null ? outActivity[0].appToken : null; + final ActivityRecord started = outActivity[0]; + if (started != null && started.getUid() == filterCallingUid) { + // Only the started activity which has the same uid as the source caller can + // be the caller of next activity. + resultTo = started.appToken; + forceNewTask = false; + } else { + // Different apps not adjacent to the caller are forced to be new task. + resultTo = null; + forceNewTask = true; + } } } } finally { -- GitLab From b06dc6aa5b0a118cc8c836b64f661c7aa89a6631 Mon Sep 17 00:00:00 2001 From: Joshua Duong Date: Mon, 3 Dec 2018 15:21:46 -0800 Subject: [PATCH 097/219] [adbwifi] Make AdbManager changes for adb over WiFi. This CL has a couple of notable changes: - Add communication layer between adbd, system server, and Settings UI - Add system notification (Wireless debugging connected) when at least one device is connected. - Add trusted networks (BSSID) to the keystore. - Changed the keystore format to: - Currently, trusted networks don't have a expiration time. Also, only way to clear it is by blowing up the keystore (revoke permissions). - Add pairing mechanism: - Using libadbwifi_pairing_connection C++ library to pair a device using SPAKE2 protocol over TLS. - Register MDNS service for client discovery. - Removed ability to ctl.start/stop adbd from UsbDeviceManager - AdbService now controls when to do this Bug: 111434128, 119490154, 119492574 Test: Manual. From developer options: 1) USB debugging off, WiFi Debugging off - Ensure both transports are disabled by trying to connect via WiFi and USB. 2) USB debugging on, WiFi Debugging off - Connections via USB are available, WiFi is disabled 3) USB debugging off, WiFi Debugging on - Connections via WiFi are available (IP + port), USB is not available 4) USB debugging on, WiFi Debugging on - Check both transports work Change-Id: I9f87679d195da99a55b6faf7131da1f1af65fe01 Exempt-From-Owner-Approval: approved in aosp master (cherry picked from commit a5969b5a1d9fe08783c32ea23bead56252a74383) --- proto/src/system_messages.proto | 4 + .../server/adb/AdbDebuggingManager.java | 1267 ++++++++++++++++- .../com/android/server/adb/AdbService.java | 146 +- services/core/jni/Android.bp | 3 + ...android_server_adb_AdbDebuggingManager.cpp | 168 +++ services/core/jni/onload.cpp | 2 + .../android/server/usb/UsbDeviceManager.java | 27 +- 7 files changed, 1517 insertions(+), 100 deletions(-) create mode 100644 services/core/jni/com_android_server_adb_AdbDebuggingManager.cpp diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto index ef071a43aa3e..2c7ea31043a2 100644 --- a/proto/src/system_messages.proto +++ b/proto/src/system_messages.proto @@ -230,6 +230,10 @@ message SystemMessage { // Package: android NOTE_TEST_HARNESS_MODE_ENABLED = 54; + // Display the Android Debug Protocol status + // Package: android + NOTE_ADB_WIFI_ACTIVE = 62; + // ADD_NEW_IDS_ABOVE_THIS_LINE // Legacy IDs with arbitrary values appear below // Legacy IDs existed as stable non-conflicting constants prior to the O release diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java index 7cbb515fd03d..8a3f11206abe 100644 --- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java +++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java @@ -20,19 +20,36 @@ import static com.android.internal.util.dump.DumpUtils.writeStringIfNotNull; import android.annotation.TestApi; import android.app.ActivityManager; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; import android.content.ActivityNotFoundException; +import android.content.BroadcastReceiver; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.content.res.Resources; import android.database.ContentObserver; +import android.debug.AdbManager; import android.debug.AdbProtoEnums; import android.debug.AdbTransportType; +import android.debug.PairDevice; +import android.net.ConnectivityManager; import android.net.LocalSocket; import android.net.LocalSocketAddress; +import android.net.NetworkInfo; import android.net.Uri; +import android.net.nsd.NsdManager; +import android.net.nsd.NsdServiceInfo; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.os.Bundle; import android.os.Environment; import android.os.FileUtils; import android.os.Handler; @@ -52,6 +69,8 @@ import android.util.Xml; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; +import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; import com.android.internal.util.dump.DualDumpOutputStream; @@ -71,6 +90,8 @@ import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; +import java.security.SecureRandom; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -79,6 +100,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; /** * Provides communication to the Android Debug Bridge daemon to allow, deny, or clear public keysi @@ -87,6 +109,7 @@ import java.util.Set; public class AdbDebuggingManager { private static final String TAG = "AdbDebuggingManager"; private static final boolean DEBUG = false; + private static final boolean MDNS_DEBUG = false; private static final String ADBD_SOCKET = "adbd"; private static final String ADB_DIRECTORY = "misc/adb"; @@ -98,19 +121,39 @@ public class AdbDebuggingManager { private static final int BUFFER_SIZE = 65536; private final Context mContext; + private final ContentResolver mContentResolver; private final Handler mHandler; private AdbDebuggingThread mThread; - private boolean mAdbEnabled = false; + private boolean mAdbUsbEnabled = false; + private boolean mAdbWifiEnabled = false; private String mFingerprints; - private final List mConnectedKeys; + // A key can be used more than once (e.g. USB, wifi), so need to keep a refcount + private final Map mConnectedKeys; private String mConfirmComponent; private final File mTestUserKeyFile; + private static final String WIFI_PERSISTENT_CONFIG_PROPERTY = + "persist.adb.tls_server.enable"; + private static final String WIFI_PERSISTENT_GUID = + "persist.adb.wifi.guid"; + private static final int PAIRING_CODE_LENGTH = 6; + private PairingThread mPairingThread = null; + // A list of keys connected via wifi + private final Set mWifiConnectedKeys; + // The current info of the adbwifi connection. + private AdbConnectionInfo mAdbConnectionInfo; + // Polls for a tls port property when adb wifi is enabled + private AdbConnectionPortPoller mConnectionPortPoller; + private final PortListenerImpl mPortListener = new PortListenerImpl(); + public AdbDebuggingManager(Context context) { mHandler = new AdbDebuggingHandler(FgThread.get().getLooper()); mContext = context; + mContentResolver = mContext.getContentResolver(); mTestUserKeyFile = null; - mConnectedKeys = new ArrayList<>(1); + mConnectedKeys = new HashMap(); + mWifiConnectedKeys = new HashSet(); + mAdbConnectionInfo = new AdbConnectionInfo(); } /** @@ -121,9 +164,178 @@ public class AdbDebuggingManager { protected AdbDebuggingManager(Context context, String confirmComponent, File testUserKeyFile) { mHandler = new AdbDebuggingHandler(FgThread.get().getLooper()); mContext = context; + mContentResolver = mContext.getContentResolver(); mConfirmComponent = confirmComponent; mTestUserKeyFile = testUserKeyFile; - mConnectedKeys = new ArrayList<>(); + mConnectedKeys = new HashMap(); + mWifiConnectedKeys = new HashSet(); + mAdbConnectionInfo = new AdbConnectionInfo(); + } + + class PairingThread extends Thread implements NsdManager.RegistrationListener { + private NsdManager mNsdManager; + private String mPublicKey; + private String mPairingCode; + private String mGuid; + private String mServiceName; + private final String mServiceType = "_adb_secure_pairing._tcp."; + private int mPort; + + private native int native_pairing_start(String guid, String password); + private native void native_pairing_cancel(); + private native boolean native_pairing_wait(); + + PairingThread(String pairingCode, String serviceName) { + super(TAG); + mPairingCode = pairingCode; + mGuid = SystemProperties.get(WIFI_PERSISTENT_GUID); + mServiceName = serviceName; + if (serviceName == null || serviceName.isEmpty()) { + mServiceName = mGuid; + } + mPort = -1; + mNsdManager = (NsdManager) mContext.getSystemService(Context.NSD_SERVICE); + } + + @Override + public void run() { + if (mGuid.isEmpty()) { + Slog.e(TAG, "adbwifi guid was not set"); + return; + } + mPort = native_pairing_start(mGuid, mPairingCode); + if (mPort <= 0 || mPort > 65535) { + Slog.e(TAG, "Unable to start pairing server"); + return; + } + + // Register the mdns service + NsdServiceInfo serviceInfo = new NsdServiceInfo(); + serviceInfo.setServiceName(mServiceName); + serviceInfo.setServiceType(mServiceType); + serviceInfo.setPort(mPort); + mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, this); + + // Send pairing port to UI + Message msg = mHandler.obtainMessage( + AdbDebuggingHandler.MSG_RESPONSE_PAIRING_PORT); + msg.obj = mPort; + mHandler.sendMessage(msg); + + boolean paired = native_pairing_wait(); + if (DEBUG) { + if (mPublicKey != null) { + Slog.i(TAG, "Pairing succeeded key=" + mPublicKey); + } else { + Slog.i(TAG, "Pairing failed"); + } + } + + mNsdManager.unregisterService(this); + + Bundle bundle = new Bundle(); + bundle.putString("publicKey", paired ? mPublicKey : null); + Message message = Message.obtain(mHandler, + AdbDebuggingHandler.MSG_RESPONSE_PAIRING_RESULT, + bundle); + mHandler.sendMessage(message); + } + + public void cancelPairing() { + native_pairing_cancel(); + } + + @Override + public void onServiceRegistered(NsdServiceInfo serviceInfo) { + if (MDNS_DEBUG) Slog.i(TAG, "Registered pairing service: " + serviceInfo); + } + + @Override + public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { + Slog.e(TAG, "Failed to register pairing service(err=" + errorCode + + "): " + serviceInfo); + cancelPairing(); + } + + @Override + public void onServiceUnregistered(NsdServiceInfo serviceInfo) { + if (MDNS_DEBUG) Slog.i(TAG, "Unregistered pairing service: " + serviceInfo); + } + + @Override + public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { + Slog.w(TAG, "Failed to unregister pairing service(err=" + errorCode + + "): " + serviceInfo); + } + } + + interface AdbConnectionPortListener { + void onPortReceived(int port); + } + + /** + * This class will poll for a period of time for adbd to write the port + * it connected to. + * + * TODO(joshuaduong): The port is being sent via system property because the adbd socket + * (AdbDebuggingManager) is not created when ro.adb.secure=0. Thus, we must communicate the + * port through different means. A better fix would be to always start AdbDebuggingManager, but + * it needs to adjust accordingly on whether ro.adb.secure is set. + */ + static class AdbConnectionPortPoller extends Thread { + private final String mAdbPortProp = "service.adb.tls.port"; + private AdbConnectionPortListener mListener; + private final int mDurationSecs = 10; + private AtomicBoolean mCanceled = new AtomicBoolean(false); + + AdbConnectionPortPoller(AdbConnectionPortListener listener) { + mListener = listener; + } + + @Override + public void run() { + if (DEBUG) Slog.d(TAG, "Starting adb port property poller"); + // Once adbwifi is enabled, we poll the service.adb.tls.port + // system property until we get the port, or -1 on failure. + // Let's also limit the polling to 10 seconds, just in case + // something went wrong. + for (int i = 0; i < mDurationSecs; ++i) { + if (mCanceled.get()) { + return; + } + + // If the property is set to -1, then that means adbd has failed + // to start the server. Otherwise we should have a valid port. + int port = SystemProperties.getInt(mAdbPortProp, Integer.MAX_VALUE); + if (port == -1 || (port > 0 && port <= 65535)) { + mListener.onPortReceived(port); + return; + } + SystemClock.sleep(1000); + } + Slog.w(TAG, "Failed to receive adb connection port"); + mListener.onPortReceived(-1); + } + + public void cancelAndWait() { + mCanceled.set(true); + if (this.isAlive()) { + try { + this.join(); + } catch (InterruptedException e) { + } + } + } + } + + class PortListenerImpl implements AdbConnectionPortListener { + public void onPortReceived(int port) { + Message msg = mHandler.obtainMessage(port > 0 + ? AdbDebuggingHandler.MSG_SERVER_CONNECTED + : AdbDebuggingHandler.MSG_SERVER_DISCONNECTED); + msg.obj = port; + mHandler.sendMessage(msg); + } } class AdbDebuggingThread extends Thread { @@ -213,6 +425,46 @@ public class AdbDebuggingManager { AdbDebuggingHandler.MESSAGE_ADB_CONNECTED_KEY); msg.obj = key; mHandler.sendMessage(msg); + } else if (buffer[0] == 'W' && buffer[1] == 'E') { + // adbd_auth.h and AdbTransportType.aidl need to be kept in + // sync. + byte transportType = buffer[2]; + String key = new String(Arrays.copyOfRange(buffer, 3, count)); + if (transportType == AdbTransportType.USB) { + Slog.d(TAG, "Received USB TLS connected key message: " + key); + Message msg = mHandler.obtainMessage( + AdbDebuggingHandler.MESSAGE_ADB_CONNECTED_KEY); + msg.obj = key; + mHandler.sendMessage(msg); + } else if (transportType == AdbTransportType.WIFI) { + Slog.d(TAG, "Received WIFI TLS connected key message: " + key); + Message msg = mHandler.obtainMessage( + AdbDebuggingHandler.MSG_WIFI_DEVICE_CONNECTED); + msg.obj = key; + mHandler.sendMessage(msg); + } else { + Slog.e(TAG, "Got unknown transport type from adbd (" + transportType + + ")"); + } + } else if (buffer[0] == 'W' && buffer[1] == 'F') { + byte transportType = buffer[2]; + String key = new String(Arrays.copyOfRange(buffer, 3, count)); + if (transportType == AdbTransportType.USB) { + Slog.d(TAG, "Received USB TLS disconnect message: " + key); + Message msg = mHandler.obtainMessage( + AdbDebuggingHandler.MESSAGE_ADB_DISCONNECT); + msg.obj = key; + mHandler.sendMessage(msg); + } else if (transportType == AdbTransportType.WIFI) { + Slog.d(TAG, "Received WIFI TLS disconnect key message: " + key); + Message msg = mHandler.obtainMessage( + AdbDebuggingHandler.MSG_WIFI_DEVICE_DISCONNECTED); + msg.obj = key; + mHandler.sendMessage(msg); + } else { + Slog.e(TAG, "Got unknown transport type from adbd (" + transportType + + ")"); + } } else { Slog.e(TAG, "Wrong message: " + (new String(Arrays.copyOfRange(buffer, 0, 2)))); @@ -268,7 +520,156 @@ public class AdbDebuggingManager { } } + class AdbConnectionInfo { + private String mBssid; + private String mSsid; + private int mPort; + + AdbConnectionInfo() { + mBssid = ""; + mSsid = ""; + mPort = -1; + } + + AdbConnectionInfo(String bssid, String ssid) { + mBssid = bssid; + mSsid = ssid; + } + + AdbConnectionInfo(AdbConnectionInfo other) { + mBssid = other.mBssid; + mSsid = other.mSsid; + mPort = other.mPort; + } + + public String getBSSID() { + return mBssid; + } + + public String getSSID() { + return mSsid; + } + + public int getPort() { + return mPort; + } + + public void setPort(int port) { + mPort = port; + } + + public void clear() { + mBssid = ""; + mSsid = ""; + mPort = -1; + } + } + + private void setAdbConnectionInfo(AdbConnectionInfo info) { + synchronized (mAdbConnectionInfo) { + if (info == null) { + mAdbConnectionInfo.clear(); + return; + } + mAdbConnectionInfo = info; + } + } + + private AdbConnectionInfo getAdbConnectionInfo() { + synchronized (mAdbConnectionInfo) { + return new AdbConnectionInfo(mAdbConnectionInfo); + } + } + class AdbDebuggingHandler extends Handler { + private NotificationManager mNotificationManager; + private boolean mAdbNotificationShown; + + private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + // We only care about when wifi is disabled, and when there is a wifi network + // change. + if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) { + int state = intent.getIntExtra( + WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_DISABLED); + if (state == WifiManager.WIFI_STATE_DISABLED) { + Slog.i(TAG, "Wifi disabled. Disabling adbwifi."); + Settings.Global.putInt(mContentResolver, + Settings.Global.ADB_WIFI_ENABLED, 0); + } + } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) { + // We only care about wifi type connections + NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra( + WifiManager.EXTRA_NETWORK_INFO); + if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) { + // Check for network disconnect + if (!networkInfo.isConnected()) { + Slog.i(TAG, "Network disconnected. Disabling adbwifi."); + Settings.Global.putInt(mContentResolver, + Settings.Global.ADB_WIFI_ENABLED, 0); + return; + } + + WifiManager wifiManager = + (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + WifiInfo wifiInfo = wifiManager.getConnectionInfo(); + if (wifiInfo == null || wifiInfo.getNetworkId() == -1) { + Slog.i(TAG, "Not connected to any wireless network." + + " Not enabling adbwifi."); + Settings.Global.putInt(mContentResolver, + Settings.Global.ADB_WIFI_ENABLED, 0); + } + + // Check for network change + String bssid = wifiInfo.getBSSID(); + if (bssid == null || bssid.isEmpty()) { + Slog.e(TAG, "Unable to get the wifi ap's BSSID. Disabling adbwifi."); + Settings.Global.putInt(mContentResolver, + Settings.Global.ADB_WIFI_ENABLED, 0); + } + synchronized (mAdbConnectionInfo) { + if (!bssid.equals(mAdbConnectionInfo.getBSSID())) { + Slog.i(TAG, "Detected wifi network change. Disabling adbwifi."); + Settings.Global.putInt(mContentResolver, + Settings.Global.ADB_WIFI_ENABLED, 0); + } + } + } + } + } + }; + + private static final String ADB_NOTIFICATION_CHANNEL_ID_TV = "usbdevicemanager.adb.tv"; + + private boolean isTv() { + return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK); + } + + private void setupNotifications() { + if (mNotificationManager != null) { + return; + } + mNotificationManager = (NotificationManager) + mContext.getSystemService(Context.NOTIFICATION_SERVICE); + if (mNotificationManager == null) { + Slog.e(TAG, "Unable to setup notifications for wireless debugging"); + return; + } + + // Ensure that the notification channels are set up + if (isTv()) { + // TV-specific notification channel + mNotificationManager.createNotificationChannel( + new NotificationChannel(ADB_NOTIFICATION_CHANNEL_ID_TV, + mContext.getString( + com.android.internal.R.string + .adb_debugging_notification_channel_tv), + NotificationManager.IMPORTANCE_HIGH)); + } + } + // The default time to schedule the job to keep the keystore updated with a currently // connected key as well as to removed expired keys. static final long UPDATE_KEYSTORE_JOB_INTERVAL = 86400000; @@ -288,8 +689,50 @@ public class AdbDebuggingManager { static final int MESSAGE_ADB_UPDATE_KEYSTORE = 9; static final int MESSAGE_ADB_CONNECTED_KEY = 10; + // === Messages from the UI ============== + // UI asks adbd to enable adbdwifi + static final int MSG_ADBDWIFI_ENABLE = 11; + // UI asks adbd to disable adbdwifi + static final int MSG_ADBDWIFI_DISABLE = 12; + // Cancel pairing + static final int MSG_PAIRING_CANCEL = 14; + // Enable pairing by pairing code + static final int MSG_PAIR_PAIRING_CODE = 15; + // Enable pairing by QR code + static final int MSG_PAIR_QR_CODE = 16; + // UI asks to unpair (forget) a device. + static final int MSG_REQ_UNPAIR = 17; + // User allows debugging on the current network + static final int MSG_ADBWIFI_ALLOW = 18; + // User denies debugging on the current network + static final int MSG_ADBWIFI_DENY = 19; + + // === Messages from the PairingThread =========== + // Result of the pairing + static final int MSG_RESPONSE_PAIRING_RESULT = 20; + // The port opened for pairing + static final int MSG_RESPONSE_PAIRING_PORT = 21; + + // === Messages from adbd ================ + // Notifies us a wifi device connected. + static final int MSG_WIFI_DEVICE_CONNECTED = 22; + // Notifies us a wifi device disconnected. + static final int MSG_WIFI_DEVICE_DISCONNECTED = 23; + // Notifies us the TLS server is connected and listening + static final int MSG_SERVER_CONNECTED = 24; + // Notifies us the TLS server is disconnected + static final int MSG_SERVER_DISCONNECTED = 25; + + // === Messages we can send to adbd =========== + static final String MSG_DISCONNECT_DEVICE = "DD"; + static final String MSG_DISABLE_ADBDWIFI = "DA"; + private AdbKeyStore mAdbKeyStore; + // Usb, Wi-Fi transports can be enabled together or separately, so don't break the framework + // connection unless all transport types are disconnected. + private int mAdbEnabledRefCount = 0; + private ContentObserver mAuthTimeObserver = new ContentObserver(this) { @Override public void onChange(boolean selfChange, Uri uri) { @@ -314,44 +757,111 @@ public class AdbDebuggingManager { mAdbKeyStore = adbKeyStore; } + // Show when at least one device is connected. + public void showAdbConnectedNotification(boolean show) { + final int id = SystemMessage.NOTE_ADB_WIFI_ACTIVE; + final int titleRes = com.android.internal.R.string.adbwifi_active_notification_title; + if (show == mAdbNotificationShown) { + return; + } + setupNotifications(); + if (!mAdbNotificationShown) { + Resources r = mContext.getResources(); + CharSequence title = r.getText(titleRes); + CharSequence message = r.getText( + com.android.internal.R.string.adbwifi_active_notification_message); + + Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_CLEAR_TASK); + PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, + intent, 0, null, UserHandle.CURRENT); + + Notification notification = + new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER) + .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) + .setWhen(0) + .setOngoing(true) + .setTicker(title) + .setDefaults(0) // please be quiet + .setColor(mContext.getColor( + com.android.internal.R.color + .system_notification_accent_color)) + .setContentTitle(title) + .setContentText(message) + .setContentIntent(pi) + .setVisibility(Notification.VISIBILITY_PUBLIC) + .extend(new Notification.TvExtender() + .setChannelId(ADB_NOTIFICATION_CHANNEL_ID_TV)) + .build(); + mAdbNotificationShown = true; + mNotificationManager.notifyAsUser(null, id, notification, + UserHandle.ALL); + } else { + mAdbNotificationShown = false; + mNotificationManager.cancelAsUser(null, id, UserHandle.ALL); + } + } + + private void startAdbDebuggingThread() { + ++mAdbEnabledRefCount; + if (DEBUG) Slog.i(TAG, "startAdbDebuggingThread ref=" + mAdbEnabledRefCount); + if (mAdbEnabledRefCount > 1) { + return; + } + + registerForAuthTimeChanges(); + mThread = new AdbDebuggingThread(); + mThread.start(); + + mAdbKeyStore.updateKeyStore(); + scheduleJobToUpdateAdbKeyStore(); + } + + private void stopAdbDebuggingThread() { + --mAdbEnabledRefCount; + if (DEBUG) Slog.i(TAG, "stopAdbDebuggingThread ref=" + mAdbEnabledRefCount); + if (mAdbEnabledRefCount > 0) { + return; + } + + if (mThread != null) { + mThread.stopListening(); + mThread = null; + } + + if (!mConnectedKeys.isEmpty()) { + for (Map.Entry entry : mConnectedKeys.entrySet()) { + mAdbKeyStore.setLastConnectionTime(entry.getKey(), + System.currentTimeMillis()); + } + sendPersistKeyStoreMessage(); + mConnectedKeys.clear(); + mWifiConnectedKeys.clear(); + } + scheduleJobToUpdateAdbKeyStore(); + } + public void handleMessage(Message msg) { + if (mAdbKeyStore == null) { + mAdbKeyStore = new AdbKeyStore(); + } + switch (msg.what) { case MESSAGE_ADB_ENABLED: - if (mAdbEnabled) { + if (mAdbUsbEnabled) { break; } - registerForAuthTimeChanges(); - mAdbEnabled = true; - - mThread = new AdbDebuggingThread(); - mThread.start(); - - mAdbKeyStore = new AdbKeyStore(); - mAdbKeyStore.updateKeyStore(); - scheduleJobToUpdateAdbKeyStore(); + startAdbDebuggingThread(); + mAdbUsbEnabled = true; break; case MESSAGE_ADB_DISABLED: - if (!mAdbEnabled) { + if (!mAdbUsbEnabled) { break; } - - mAdbEnabled = false; - - if (mThread != null) { - mThread.stopListening(); - mThread = null; - } - - if (!mConnectedKeys.isEmpty()) { - for (String connectedKey : mConnectedKeys) { - mAdbKeyStore.setLastConnectionTime(connectedKey, - System.currentTimeMillis()); - } - sendPersistKeyStoreMessage(); - mConnectedKeys.clear(); - } - scheduleJobToUpdateAdbKeyStore(); + stopAdbDebuggingThread(); + mAdbUsbEnabled = false; break; case MESSAGE_ADB_ALLOW: { @@ -367,8 +877,8 @@ public class AdbDebuggingManager { if (mThread != null) { mThread.sendResponse("OK"); if (alwaysAllow) { - if (!mConnectedKeys.contains(key)) { - mConnectedKeys.add(key); + if (!mConnectedKeys.containsKey(key)) { + mConnectedKeys.put(key, 1); } mAdbKeyStore.setLastConnectionTime(key, System.currentTimeMillis()); sendPersistKeyStoreMessage(); @@ -407,7 +917,7 @@ public class AdbDebuggingManager { } logAdbConnectionChanged(key, AdbProtoEnums.AWAITING_USER_APPROVAL, false); mFingerprints = fingerprints; - startConfirmation(key, mFingerprints); + startConfirmationForKey(key, mFingerprints); break; } @@ -419,6 +929,7 @@ public class AdbDebuggingManager { if (mAdbKeyStore == null) { mAdbKeyStore = new AdbKeyStore(); } + mWifiConnectedKeys.clear(); mAdbKeyStore.deleteKeyStore(); cancelJobToUpdateAdbKeyStore(); break; @@ -428,12 +939,17 @@ public class AdbDebuggingManager { String key = (String) msg.obj; boolean alwaysAllow = false; if (key != null && key.length() > 0) { - if (mConnectedKeys.contains(key)) { + if (mConnectedKeys.containsKey(key)) { alwaysAllow = true; - mAdbKeyStore.setLastConnectionTime(key, System.currentTimeMillis()); - sendPersistKeyStoreMessage(); - scheduleJobToUpdateAdbKeyStore(); - mConnectedKeys.remove(key); + int refcount = mConnectedKeys.get(key) - 1; + if (refcount == 0) { + mAdbKeyStore.setLastConnectionTime(key, System.currentTimeMillis()); + sendPersistKeyStoreMessage(); + scheduleJobToUpdateAdbKeyStore(); + mConnectedKeys.remove(key); + } else { + mConnectedKeys.put(key, refcount); + } } } else { Slog.w(TAG, "Received a disconnected key message with an empty key"); @@ -451,8 +967,8 @@ public class AdbDebuggingManager { case MESSAGE_ADB_UPDATE_KEYSTORE: { if (!mConnectedKeys.isEmpty()) { - for (String connectedKey : mConnectedKeys) { - mAdbKeyStore.setLastConnectionTime(connectedKey, + for (Map.Entry entry : mConnectedKeys.entrySet()) { + mAdbKeyStore.setLastConnectionTime(entry.getKey(), System.currentTimeMillis()); } sendPersistKeyStoreMessage(); @@ -469,8 +985,10 @@ public class AdbDebuggingManager { if (key == null || key.length() == 0) { Slog.w(TAG, "Received a connected key message with an empty key"); } else { - if (!mConnectedKeys.contains(key)) { - mConnectedKeys.add(key); + if (!mConnectedKeys.containsKey(key)) { + mConnectedKeys.put(key, 1); + } else { + mConnectedKeys.put(key, mConnectedKeys.get(key) + 1); } mAdbKeyStore.setLastConnectionTime(key, System.currentTimeMillis()); sendPersistKeyStoreMessage(); @@ -479,6 +997,199 @@ public class AdbDebuggingManager { } break; } + case MSG_ADBDWIFI_ENABLE: { + if (mAdbWifiEnabled) { + break; + } + + AdbConnectionInfo currentInfo = getCurrentWifiApInfo(); + if (currentInfo == null) { + Settings.Global.putInt(mContentResolver, + Settings.Global.ADB_WIFI_ENABLED, 0); + break; + } + + if (!verifyWifiNetwork(currentInfo.getBSSID(), + currentInfo.getSSID())) { + // This means that the network is not in the list of trusted networks. + // We'll give user a prompt on whether to allow wireless debugging on + // the current wifi network. + Settings.Global.putInt(mContentResolver, + Settings.Global.ADB_WIFI_ENABLED, 0); + break; + } + + setAdbConnectionInfo(currentInfo); + IntentFilter intentFilter = + new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION); + intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); + mContext.registerReceiver(mBroadcastReceiver, intentFilter); + + SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "1"); + mConnectionPortPoller = + new AdbDebuggingManager.AdbConnectionPortPoller(mPortListener); + mConnectionPortPoller.start(); + + startAdbDebuggingThread(); + mAdbWifiEnabled = true; + + if (DEBUG) Slog.i(TAG, "adb start wireless adb"); + break; + } + case MSG_ADBDWIFI_DISABLE: + if (!mAdbWifiEnabled) { + break; + } + mAdbWifiEnabled = false; + setAdbConnectionInfo(null); + mContext.unregisterReceiver(mBroadcastReceiver); + + if (mThread != null) { + mThread.sendResponse(MSG_DISABLE_ADBDWIFI); + } + onAdbdWifiServerDisconnected(-1); + stopAdbDebuggingThread(); + break; + case MSG_ADBWIFI_ALLOW: + if (mAdbWifiEnabled) { + break; + } + String bssid = (String) msg.obj; + boolean alwaysAllow = msg.arg1 == 1; + if (alwaysAllow) { + mAdbKeyStore.addTrustedNetwork(bssid); + } + + // Let's check again to make sure we didn't switch networks while verifying + // the wifi bssid. + AdbConnectionInfo newInfo = getCurrentWifiApInfo(); + if (newInfo == null || !bssid.equals(newInfo.getBSSID())) { + break; + } + + setAdbConnectionInfo(newInfo); + Settings.Global.putInt(mContentResolver, + Settings.Global.ADB_WIFI_ENABLED, 1); + IntentFilter intentFilter = + new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION); + intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); + mContext.registerReceiver(mBroadcastReceiver, intentFilter); + + SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "1"); + mConnectionPortPoller = + new AdbDebuggingManager.AdbConnectionPortPoller(mPortListener); + mConnectionPortPoller.start(); + + startAdbDebuggingThread(); + mAdbWifiEnabled = true; + + if (DEBUG) Slog.i(TAG, "adb start wireless adb"); + break; + case MSG_ADBWIFI_DENY: + Settings.Global.putInt(mContentResolver, + Settings.Global.ADB_WIFI_ENABLED, 0); + sendServerConnectionState(false, -1); + break; + case MSG_REQ_UNPAIR: { + String fingerprint = (String) msg.obj; + // Tell adbd to disconnect the device if connected. + String publicKey = mAdbKeyStore.findKeyFromFingerprint(fingerprint); + if (publicKey == null || publicKey.isEmpty()) { + Slog.e(TAG, "Not a known fingerprint [" + fingerprint + "]"); + break; + } + String cmdStr = MSG_DISCONNECT_DEVICE + publicKey; + if (mThread != null) { + mThread.sendResponse(cmdStr); + } + mAdbKeyStore.removeKey(publicKey); + // Send the updated paired devices list to the UI. + sendPairedDevicesToUI(mAdbKeyStore.getPairedDevices()); + break; + } + case MSG_RESPONSE_PAIRING_RESULT: { + Bundle bundle = (Bundle) msg.obj; + String publicKey = bundle.getString("publicKey"); + onPairingResult(publicKey); + // Send the updated paired devices list to the UI. + sendPairedDevicesToUI(mAdbKeyStore.getPairedDevices()); + break; + } + case MSG_RESPONSE_PAIRING_PORT: { + int port = (int) msg.obj; + sendPairingPortToUI(port); + break; + } + case MSG_PAIR_PAIRING_CODE: { + String pairingCode = createPairingCode(PAIRING_CODE_LENGTH); + updateUIPairCode(pairingCode); + mPairingThread = new PairingThread(pairingCode, null); + mPairingThread.start(); + break; + } + case MSG_PAIR_QR_CODE: { + Bundle bundle = (Bundle) msg.obj; + String serviceName = bundle.getString("serviceName"); + String password = bundle.getString("password"); + mPairingThread = new PairingThread(password, serviceName); + mPairingThread.start(); + break; + } + case MSG_PAIRING_CANCEL: + if (mPairingThread != null) { + mPairingThread.cancelPairing(); + try { + mPairingThread.join(); + } catch (InterruptedException e) { + Slog.w(TAG, "Error while waiting for pairing thread to quit."); + e.printStackTrace(); + } + mPairingThread = null; + } + break; + case MSG_WIFI_DEVICE_CONNECTED: { + String key = (String) msg.obj; + if (mWifiConnectedKeys.add(key)) { + sendPairedDevicesToUI(mAdbKeyStore.getPairedDevices()); + showAdbConnectedNotification(true); + } + break; + } + case MSG_WIFI_DEVICE_DISCONNECTED: { + String key = (String) msg.obj; + if (mWifiConnectedKeys.remove(key)) { + sendPairedDevicesToUI(mAdbKeyStore.getPairedDevices()); + if (mWifiConnectedKeys.isEmpty()) { + showAdbConnectedNotification(false); + } + } + break; + } + case MSG_SERVER_CONNECTED: { + int port = (int) msg.obj; + onAdbdWifiServerConnected(port); + synchronized (mAdbConnectionInfo) { + mAdbConnectionInfo.setPort(port); + } + Settings.Global.putInt(mContentResolver, + Settings.Global.ADB_WIFI_ENABLED, 1); + break; + } + case MSG_SERVER_DISCONNECTED: { + if (!mAdbWifiEnabled) { + break; + } + int port = (int) msg.obj; + onAdbdWifiServerDisconnected(port); + Settings.Global.putInt(mContentResolver, + Settings.Global.ADB_WIFI_ENABLED, 0); + stopAdbDebuggingThread(); + if (mConnectionPortPoller != null) { + mConnectionPortPoller.cancelAndWait(); + mConnectionPortPoller = null; + } + break; + } } } @@ -540,6 +1251,142 @@ public class AdbDebuggingManager { private void cancelJobToUpdateAdbKeyStore() { removeMessages(AdbDebuggingHandler.MESSAGE_ADB_UPDATE_KEYSTORE); } + + // Generates a random string of digits with size |size|. + private String createPairingCode(int size) { + String res = ""; + SecureRandom rand = new SecureRandom(); + for (int i = 0; i < size; ++i) { + res += rand.nextInt(10); + } + + return res; + } + + private void sendServerConnectionState(boolean connected, int port) { + Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_STATE_CHANGED_ACTION); + intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA, connected + ? AdbManager.WIRELESS_STATUS_CONNECTED + : AdbManager.WIRELESS_STATUS_DISCONNECTED); + intent.putExtra(AdbManager.WIRELESS_DEBUG_PORT_EXTRA, port); + mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + } + + private void onAdbdWifiServerConnected(int port) { + // Send the paired devices list to the UI + sendPairedDevicesToUI(mAdbKeyStore.getPairedDevices()); + sendServerConnectionState(true, port); + } + + private void onAdbdWifiServerDisconnected(int port) { + // The TLS server disconnected while we had wireless debugging enabled. + // Let's disable it. + mWifiConnectedKeys.clear(); + showAdbConnectedNotification(false); + sendServerConnectionState(false, port); + } + + /** + * Returns the [bssid, ssid] of the current access point. + */ + private AdbConnectionInfo getCurrentWifiApInfo() { + WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + WifiInfo wifiInfo = wifiManager.getConnectionInfo(); + if (wifiInfo == null || wifiInfo.getNetworkId() == -1) { + Slog.i(TAG, "Not connected to any wireless network. Not enabling adbwifi."); + return null; + } + + String ssid = null; + if (wifiInfo.isPasspointAp() || wifiInfo.isOsuAp()) { + ssid = wifiInfo.getPasspointProviderFriendlyName(); + } else { + ssid = wifiInfo.getSSID(); + if (ssid == null || WifiManager.UNKNOWN_SSID.equals(ssid)) { + // OK, it's not in the connectionInfo; we have to go hunting for it + List networks = wifiManager.getConfiguredNetworks(); + int length = networks.size(); + for (int i = 0; i < length; i++) { + if (networks.get(i).networkId == wifiInfo.getNetworkId()) { + ssid = networks.get(i).SSID; + } + } + if (ssid == null) { + Slog.e(TAG, "Unable to get ssid of the wifi AP."); + return null; + } + } + } + + String bssid = wifiInfo.getBSSID(); + if (bssid == null || bssid.isEmpty()) { + Slog.e(TAG, "Unable to get the wifi ap's BSSID."); + return null; + } + return new AdbConnectionInfo(bssid, ssid); + } + + private boolean verifyWifiNetwork(String bssid, String ssid) { + // Check against a list of user-trusted networks. + if (mAdbKeyStore.isTrustedNetwork(bssid)) { + return true; + } + + // Ask user to confirm using wireless debugging on this network. + startConfirmationForNetwork(ssid, bssid); + return false; + } + + private void onPairingResult(String publicKey) { + if (publicKey == null) { + Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_PAIRING_RESULT_ACTION); + intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA, AdbManager.WIRELESS_STATUS_FAIL); + mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + } else { + Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_PAIRING_RESULT_ACTION); + intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA, + AdbManager.WIRELESS_STATUS_SUCCESS); + String fingerprints = getFingerprints(publicKey); + String hostname = "nouser@nohostname"; + String[] args = publicKey.split("\\s+"); + if (args.length > 1) { + hostname = args[1]; + } + PairDevice device = new PairDevice(fingerprints, hostname, false); + intent.putExtra(AdbManager.WIRELESS_PAIR_DEVICE_EXTRA, device); + mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + // Add the key into the keystore + mAdbKeyStore.setLastConnectionTime(publicKey, + System.currentTimeMillis()); + sendPersistKeyStoreMessage(); + scheduleJobToUpdateAdbKeyStore(); + } + } + + private void sendPairingPortToUI(int port) { + Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_PAIRING_RESULT_ACTION); + intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA, + AdbManager.WIRELESS_STATUS_CONNECTED); + intent.putExtra(AdbManager.WIRELESS_DEBUG_PORT_EXTRA, port); + mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + } + + private void sendPairedDevicesToUI(Map devices) { + Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_PAIRED_DEVICES_ACTION); + // Map is not serializable, so need to downcast + intent.putExtra(AdbManager.WIRELESS_DEVICES_EXTRA, (HashMap) devices); + mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + } + + private void updateUIPairCode(String code) { + if (DEBUG) Slog.i(TAG, "updateUIPairCode: " + code); + + Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_PAIRING_RESULT_ACTION); + intent.putExtra(AdbManager.WIRELESS_PAIRING_CODE_EXTRA, code); + intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA, + AdbManager.WIRELESS_STATUS_PAIRING_CODE); + mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + } } private String getFingerprints(String key) { @@ -576,7 +1423,34 @@ public class AdbDebuggingManager { return sb.toString(); } - private void startConfirmation(String key, String fingerprints) { + private void startConfirmationForNetwork(String ssid, String bssid) { + List> extras = new ArrayList>(); + extras.add(new AbstractMap.SimpleEntry("ssid", ssid)); + extras.add(new AbstractMap.SimpleEntry("bssid", bssid)); + int currentUserId = ActivityManager.getCurrentUser(); + UserInfo userInfo = UserManager.get(mContext).getUserInfo(currentUserId); + String componentString; + if (userInfo.isAdmin()) { + componentString = Resources.getSystem().getString( + com.android.internal.R.string.config_customAdbWifiNetworkConfirmationComponent); + } else { + componentString = Resources.getSystem().getString( + com.android.internal.R.string.config_customAdbWifiNetworkConfirmationComponent); + } + ComponentName componentName = ComponentName.unflattenFromString(componentString); + if (startConfirmationActivity(componentName, userInfo.getUserHandle(), extras) + || startConfirmationService(componentName, userInfo.getUserHandle(), + extras)) { + return; + } + Slog.e(TAG, "Unable to start customAdbWifiNetworkConfirmation[SecondaryUser]Component " + + componentString + " as an Activity or a Service"); + } + + private void startConfirmationForKey(String key, String fingerprints) { + List> extras = new ArrayList>(); + extras.add(new AbstractMap.SimpleEntry("key", key)); + extras.add(new AbstractMap.SimpleEntry("fingerprints", fingerprints)); int currentUserId = ActivityManager.getCurrentUser(); UserInfo userInfo = UserManager.get(mContext).getUserInfo(currentUserId); String componentString; @@ -591,9 +1465,9 @@ public class AdbDebuggingManager { R.string.config_customAdbPublicKeyConfirmationSecondaryUserComponent); } ComponentName componentName = ComponentName.unflattenFromString(componentString); - if (startConfirmationActivity(componentName, userInfo.getUserHandle(), key, fingerprints) + if (startConfirmationActivity(componentName, userInfo.getUserHandle(), extras) || startConfirmationService(componentName, userInfo.getUserHandle(), - key, fingerprints)) { + extras)) { return; } Slog.e(TAG, "unable to start customAdbPublicKeyConfirmation[SecondaryUser]Component " @@ -604,9 +1478,9 @@ public class AdbDebuggingManager { * @return true if the componentName led to an Activity that was started. */ private boolean startConfirmationActivity(ComponentName componentName, UserHandle userHandle, - String key, String fingerprints) { + List> extras) { PackageManager packageManager = mContext.getPackageManager(); - Intent intent = createConfirmationIntent(componentName, key, fingerprints); + Intent intent = createConfirmationIntent(componentName, extras); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) { try { @@ -623,8 +1497,8 @@ public class AdbDebuggingManager { * @return true if the componentName led to a Service that was started. */ private boolean startConfirmationService(ComponentName componentName, UserHandle userHandle, - String key, String fingerprints) { - Intent intent = createConfirmationIntent(componentName, key, fingerprints); + List> extras) { + Intent intent = createConfirmationIntent(componentName, extras); try { if (mContext.startServiceAsUser(intent, userHandle) != null) { return true; @@ -635,12 +1509,13 @@ public class AdbDebuggingManager { return false; } - private Intent createConfirmationIntent(ComponentName componentName, String key, - String fingerprints) { + private Intent createConfirmationIntent(ComponentName componentName, + List> extras) { Intent intent = new Intent(); intent.setClassName(componentName.getPackageName(), componentName.getClassName()); - intent.putExtra("key", key); - intent.putExtra("fingerprints", fingerprints); + for (Map.Entry entry : extras) { + intent.putExtra(entry.getKey(), entry.getValue()); + } return intent; } @@ -733,7 +1608,8 @@ public class AdbDebuggingManager { mHandler.sendEmptyMessage(enabled ? AdbDebuggingHandler.MESSAGE_ADB_ENABLED : AdbDebuggingHandler.MESSAGE_ADB_DISABLED); } else if (transportType == AdbTransportType.WIFI) { - // TODO(joshuaduong): Not implemented + mHandler.sendEmptyMessage(enabled ? AdbDebuggingHandler.MSG_ADBDWIFI_ENABLE + : AdbDebuggingHandler.MSG_ADBDWIFI_DISABLE); } else { throw new IllegalArgumentException( "setAdbEnabled called with unimplemented transport type=" + transportType); @@ -766,6 +1642,87 @@ public class AdbDebuggingManager { mHandler.sendEmptyMessage(AdbDebuggingHandler.MESSAGE_ADB_CLEAR); } + /** + * Allows wireless debugging on the network identified by {@code bssid} either once + * or always if {@code alwaysAllow} is {@code true}. + */ + public void allowWirelessDebugging(boolean alwaysAllow, String bssid) { + Message msg = mHandler.obtainMessage(AdbDebuggingHandler.MSG_ADBWIFI_ALLOW); + msg.arg1 = alwaysAllow ? 1 : 0; + msg.obj = bssid; + mHandler.sendMessage(msg); + } + + /** + * Denies wireless debugging connection on the last requested network. + */ + public void denyWirelessDebugging() { + mHandler.sendEmptyMessage(AdbDebuggingHandler.MSG_ADBWIFI_DENY); + } + + /** + * Returns the port adbwifi is currently opened on. + */ + public int getAdbWirelessPort() { + AdbConnectionInfo info = getAdbConnectionInfo(); + if (info == null) { + return 0; + } + return info.getPort(); + } + + /** + * Returns the list of paired devices. + */ + public Map getPairedDevices() { + AdbKeyStore keystore = new AdbKeyStore(); + return keystore.getPairedDevices(); + } + + /** + * Unpair with device + */ + public void unpairDevice(String fingerprint) { + Message message = Message.obtain(mHandler, + AdbDebuggingHandler.MSG_REQ_UNPAIR, + fingerprint); + mHandler.sendMessage(message); + } + + /** + * Enable pairing by pairing code + */ + public void enablePairingByPairingCode() { + mHandler.sendEmptyMessage(AdbDebuggingHandler.MSG_PAIR_PAIRING_CODE); + } + + /** + * Enable pairing by pairing code + */ + public void enablePairingByQrCode(String serviceName, String password) { + Bundle bundle = new Bundle(); + bundle.putString("serviceName", serviceName); + bundle.putString("password", password); + Message message = Message.obtain(mHandler, + AdbDebuggingHandler.MSG_PAIR_QR_CODE, + bundle); + mHandler.sendMessage(message); + } + + /** + * Disables pairing + */ + public void disablePairing() { + mHandler.sendEmptyMessage(AdbDebuggingHandler.MSG_PAIRING_CANCEL); + } + + /** + * Status enabled/disabled check + */ + public boolean isAdbWifiEnabled() { + return mAdbWifiEnabled; + } + /** * Sends a message to the handler to persist the keystore. */ @@ -819,9 +1776,19 @@ public class AdbDebuggingManager { private File mKeyFile; private AtomicFile mAtomicKeyFile; + private List mTrustedNetworks; + private static final int KEYSTORE_VERSION = 1; + private static final int MAX_SUPPORTED_KEYSTORE_VERSION = 1; + private static final String XML_KEYSTORE_START_TAG = "keyStore"; + private static final String XML_ATTRIBUTE_VERSION = "version"; private static final String XML_TAG_ADB_KEY = "adbKey"; private static final String XML_ATTRIBUTE_KEY = "key"; private static final String XML_ATTRIBUTE_LAST_CONNECTION = "lastConnection"; + // A list of trusted networks a device can always wirelessly debug on (always allow). + // TODO: Move trusted networks list into a different file? + private static final String XML_TAG_WIFI_ACCESS_POINT = "wifiAP"; + private static final String XML_ATTRIBUTE_WIFI_BSSID = "bssid"; + private static final String SYSTEM_KEY_FILE = "/adb_keys"; /** @@ -848,10 +1815,48 @@ public class AdbDebuggingManager { private void init() { initKeyFile(); mKeyMap = getKeyMap(); + mTrustedNetworks = getTrustedNetworks(); mSystemKeys = getSystemKeysFromFile(SYSTEM_KEY_FILE); addUserKeysToKeyStore(); } + public void addTrustedNetwork(String bssid) { + mTrustedNetworks.add(bssid); + sendPersistKeyStoreMessage(); + } + + public Map getPairedDevices() { + Map pairedDevices = new HashMap(); + for (Map.Entry keyEntry : mKeyMap.entrySet()) { + String fingerprints = getFingerprints(keyEntry.getKey()); + String hostname = "nouser@nohostname"; + String[] args = keyEntry.getKey().split("\\s+"); + if (args.length > 1) { + hostname = args[1]; + } + pairedDevices.put(keyEntry.getKey(), new PairDevice( + hostname, fingerprints, mWifiConnectedKeys.contains(keyEntry.getKey()))); + } + return pairedDevices; + } + + public String findKeyFromFingerprint(String fingerprint) { + for (Map.Entry entry : mKeyMap.entrySet()) { + String f = getFingerprints(entry.getKey()); + if (fingerprint.equals(f)) { + return entry.getKey(); + } + } + return null; + } + + public void removeKey(String key) { + if (mKeyMap.containsKey(key)) { + mKeyMap.remove(key); + sendPersistKeyStoreMessage(); + } + } + /** * Initializes the key file that will be used to persist the adb grants. */ @@ -905,6 +1910,78 @@ public class AdbDebuggingManager { * Returns the key map with the keys and last connection times from the key file. */ private Map getKeyMap() { + Map keyMap = new HashMap(); + // if the AtomicFile could not be instantiated before attempt again; if it still fails + // return an empty key map. + if (mAtomicKeyFile == null) { + initKeyFile(); + if (mAtomicKeyFile == null) { + Slog.e(TAG, "Unable to obtain the key file, " + mKeyFile + ", for reading"); + return keyMap; + } + } + if (!mAtomicKeyFile.exists()) { + return keyMap; + } + try (FileInputStream keyStream = mAtomicKeyFile.openRead()) { + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(keyStream, StandardCharsets.UTF_8.name()); + // Check for supported keystore version. + XmlUtils.beginDocument(parser, XML_KEYSTORE_START_TAG); + if (parser.next() != XmlPullParser.END_DOCUMENT) { + String tagName = parser.getName(); + if (tagName == null || !XML_KEYSTORE_START_TAG.equals(tagName)) { + Slog.e(TAG, "Expected " + XML_KEYSTORE_START_TAG + ", but got tag=" + + tagName); + return keyMap; + } + int keystoreVersion = Integer.parseInt( + parser.getAttributeValue(null, XML_ATTRIBUTE_VERSION)); + if (keystoreVersion > MAX_SUPPORTED_KEYSTORE_VERSION) { + Slog.e(TAG, "Keystore version=" + keystoreVersion + + " not supported (max_supported=" + + MAX_SUPPORTED_KEYSTORE_VERSION + ")"); + return keyMap; + } + } + while (parser.next() != XmlPullParser.END_DOCUMENT) { + String tagName = parser.getName(); + if (tagName == null) { + break; + } else if (!tagName.equals(XML_TAG_ADB_KEY)) { + XmlUtils.skipCurrentTag(parser); + continue; + } + String key = parser.getAttributeValue(null, XML_ATTRIBUTE_KEY); + long connectionTime; + try { + connectionTime = Long.valueOf( + parser.getAttributeValue(null, XML_ATTRIBUTE_LAST_CONNECTION)); + } catch (NumberFormatException e) { + Slog.e(TAG, + "Caught a NumberFormatException parsing the last connection time: " + + e); + XmlUtils.skipCurrentTag(parser); + continue; + } + keyMap.put(key, connectionTime); + } + } catch (IOException e) { + Slog.e(TAG, "Caught an IOException parsing the XML key file: ", e); + } catch (XmlPullParserException e) { + Slog.w(TAG, "Caught XmlPullParserException parsing the XML key file: ", e); + // The file could be written in a format prior to introducing keystore tag. + return getKeyMapBeforeKeystoreVersion(); + } + return keyMap; + } + + + /** + * Returns the key map with the keys and last connection times from the key file. + * This implementation was prior to adding the XML_KEYSTORE_START_TAG. + */ + private Map getKeyMapBeforeKeystoreVersion() { Map keyMap = new HashMap(); // if the AtomicFile could not be instantiated before attempt again; if it still fails // return an empty key map. @@ -950,6 +2027,63 @@ public class AdbDebuggingManager { return keyMap; } + /** + * Returns the map of trusted networks from the keystore file. + * + * This was implemented in keystore version 1. + */ + private List getTrustedNetworks() { + List trustedNetworks = new ArrayList(); + // if the AtomicFile could not be instantiated before attempt again; if it still fails + // return an empty key map. + if (mAtomicKeyFile == null) { + initKeyFile(); + if (mAtomicKeyFile == null) { + Slog.e(TAG, "Unable to obtain the key file, " + mKeyFile + ", for reading"); + return trustedNetworks; + } + } + if (!mAtomicKeyFile.exists()) { + return trustedNetworks; + } + try (FileInputStream keyStream = mAtomicKeyFile.openRead()) { + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(keyStream, StandardCharsets.UTF_8.name()); + // Check for supported keystore version. + XmlUtils.beginDocument(parser, XML_KEYSTORE_START_TAG); + if (parser.next() != XmlPullParser.END_DOCUMENT) { + String tagName = parser.getName(); + if (tagName == null || !XML_KEYSTORE_START_TAG.equals(tagName)) { + Slog.e(TAG, "Expected " + XML_KEYSTORE_START_TAG + ", but got tag=" + + tagName); + return trustedNetworks; + } + int keystoreVersion = Integer.parseInt( + parser.getAttributeValue(null, XML_ATTRIBUTE_VERSION)); + if (keystoreVersion > MAX_SUPPORTED_KEYSTORE_VERSION) { + Slog.e(TAG, "Keystore version=" + keystoreVersion + + " not supported (max_supported=" + + MAX_SUPPORTED_KEYSTORE_VERSION); + return trustedNetworks; + } + } + while (parser.next() != XmlPullParser.END_DOCUMENT) { + String tagName = parser.getName(); + if (tagName == null) { + break; + } else if (!tagName.equals(XML_TAG_WIFI_ACCESS_POINT)) { + XmlUtils.skipCurrentTag(parser); + continue; + } + String bssid = parser.getAttributeValue(null, XML_ATTRIBUTE_WIFI_BSSID); + trustedNetworks.add(bssid); + } + } catch (IOException | XmlPullParserException | NumberFormatException e) { + Slog.e(TAG, "Caught an exception parsing the XML key file: ", e); + } + return trustedNetworks; + } + /** * Updates the keystore with keys that were previously set to be always allowed before the * connection time of keys was tracked. @@ -986,7 +2120,7 @@ public class AdbDebuggingManager { // if there is nothing in the key map then ensure any keys left in the keystore files // are deleted as well. filterOutOldKeys(); - if (mKeyMap.isEmpty()) { + if (mKeyMap.isEmpty() && mTrustedNetworks.isEmpty()) { deleteKeyStore(); return; } @@ -1004,6 +2138,8 @@ public class AdbDebuggingManager { serializer.setOutput(keyStream, StandardCharsets.UTF_8.name()); serializer.startDocument(null, true); + serializer.startTag(null, XML_KEYSTORE_START_TAG); + serializer.attribute(null, XML_ATTRIBUTE_VERSION, String.valueOf(KEYSTORE_VERSION)); for (Map.Entry keyEntry : mKeyMap.entrySet()) { serializer.startTag(null, XML_TAG_ADB_KEY); serializer.attribute(null, XML_ATTRIBUTE_KEY, keyEntry.getKey()); @@ -1011,7 +2147,12 @@ public class AdbDebuggingManager { String.valueOf(keyEntry.getValue())); serializer.endTag(null, XML_TAG_ADB_KEY); } - + for (String bssid : mTrustedNetworks) { + serializer.startTag(null, XML_TAG_WIFI_ACCESS_POINT); + serializer.attribute(null, XML_ATTRIBUTE_WIFI_BSSID, bssid); + serializer.endTag(null, XML_TAG_WIFI_ACCESS_POINT); + } + serializer.endTag(null, XML_KEYSTORE_START_TAG); serializer.endDocument(); mAtomicKeyFile.finishWrite(keyStream); } catch (IOException e) { @@ -1072,6 +2213,7 @@ public class AdbDebuggingManager { */ public void deleteKeyStore() { mKeyMap.clear(); + mTrustedNetworks.clear(); deleteKeyFile(); if (mAtomicKeyFile == null) { return; @@ -1153,5 +2295,14 @@ public class AdbDebuggingManager { return false; } } + + /** + * Returns whether the specified bssid is in the list of trusted networks. This requires + * that the user previously allowed wireless debugging on this network and selected the + * option to 'Always allow'. + */ + public boolean isTrustedNetwork(String bssid) { + return mTrustedNetworks.contains(bssid); + } } } diff --git a/services/core/java/com/android/server/adb/AdbService.java b/services/core/java/com/android/server/adb/AdbService.java index 0d161b943d15..7ccb28474604 100644 --- a/services/core/java/com/android/server/adb/AdbService.java +++ b/services/core/java/com/android/server/adb/AdbService.java @@ -21,8 +21,10 @@ import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.ContentResolver; import android.content.Context; +import android.content.Intent; import android.content.pm.PackageManager; import android.database.ContentObserver; +import android.debug.AdbManager; import android.debug.AdbManagerInternal; import android.debug.AdbTransportType; import android.debug.IAdbManager; @@ -34,6 +36,7 @@ import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemProperties; +import android.os.UserHandle; import android.provider.Settings; import android.service.adb.AdbServiceDumpProto; import android.sysprop.AdbProperties; @@ -44,6 +47,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; +import com.android.internal.util.Preconditions; import com.android.internal.util.dump.DualDumpOutputStream; import com.android.server.FgThread; import com.android.server.LocalServices; @@ -54,12 +58,34 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Collections; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; /** * The Android Debug Bridge (ADB) service. This controls the availability of ADB and authorization * of devices allowed to connect to ADB. */ public class AdbService extends IAdbManager.Stub { + /** + * Adb native daemon. + */ + static final String ADBD = "adbd"; + + /** + * Command to start native service. + */ + static final String CTL_START = "ctl.start"; + + /** + * Command to start native service. + */ + static final String CTL_STOP = "ctl.stop"; + + // The tcp port adb is currently using + AtomicInteger mConnectionPort = new AtomicInteger(-1); + + private final AdbConnectionPortListener mPortListener = new AdbConnectionPortListener(); + private AdbDebuggingManager.AdbConnectionPortPoller mConnectionPortPoller; + /** * Manages the service lifecycle for {@code AdbService} in {@code SystemServer}. */ @@ -129,9 +155,8 @@ public class AdbService extends IAdbManager.Stub { mIsAdbUsbEnabled = containsFunction( SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, ""), UsbManager.USB_FUNCTION_ADB); - // TODO(joshuaduong): Read the adb wifi state from a persistent system - // property (persist.sys.adb.wifi). - mIsAdbWifiEnabled = false; + mIsAdbWifiEnabled = "1".equals( + SystemProperties.get(WIFI_PERSISTENT_CONFIG_PROPERTY, "0")); // register observer to listen for settings changes mObserver = new AdbSettingsObserver(); @@ -189,6 +214,7 @@ public class AdbService extends IAdbManager.Stub { * May also contain vendor-specific default functions for testing purposes. */ private static final String USB_PERSISTENT_CONFIG_PROPERTY = "persist.sys.usb.config"; + private static final String WIFI_PERSISTENT_CONFIG_PROPERTY = "persist.adb.tls_server.enable"; private final Context mContext; private final ContentResolver mContentResolver; @@ -245,8 +271,9 @@ public class AdbService extends IAdbManager.Stub { } @Override - public void allowDebugging(boolean alwaysAllow, String publicKey) { + public void allowDebugging(boolean alwaysAllow, @NonNull String publicKey) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); + Preconditions.checkStringNotEmpty(publicKey); if (mDebuggingManager != null) { mDebuggingManager.allowDebugging(alwaysAllow, publicKey); } @@ -296,53 +323,118 @@ public class AdbService extends IAdbManager.Stub { } @Override - public void allowWirelessDebugging(boolean alwaysAllow, String bssid) { + public void allowWirelessDebugging(boolean alwaysAllow, @NonNull String bssid) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); - // TODO(joshuaduong): NOT IMPLEMENTED + Preconditions.checkStringNotEmpty(bssid); + if (mDebuggingManager != null) { + mDebuggingManager.allowWirelessDebugging(alwaysAllow, bssid); + } } @Override public void denyWirelessDebugging() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); - // TODO(joshuaduong): NOT IMPLEMENTED + if (mDebuggingManager != null) { + mDebuggingManager.denyWirelessDebugging(); + } } @Override public Map getPairedDevices() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); - // TODO(joshuaduong): NOT IMPLEMENTED + if (mDebuggingManager != null) { + return mDebuggingManager.getPairedDevices(); + } return null; } @Override - public void unpairDevice(String fingerprint) { + public void unpairDevice(@NonNull String fingerprint) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); - // TODO(joshuaduong): NOT IMPLEMENTED + Preconditions.checkStringNotEmpty(fingerprint); + if (mDebuggingManager != null) { + mDebuggingManager.unpairDevice(fingerprint); + } } @Override public void enablePairingByPairingCode() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); - // TODO(joshuaduong): NOT IMPLEMENTED + if (mDebuggingManager != null) { + mDebuggingManager.enablePairingByPairingCode(); + } } @Override - public void enablePairingByQrCode(String serviceName, String password) { + public void enablePairingByQrCode(@NonNull String serviceName, @NonNull String password) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); - // TODO(joshuaduong): NOT IMPLEMENTED + Preconditions.checkStringNotEmpty(serviceName); + Preconditions.checkStringNotEmpty(password); + if (mDebuggingManager != null) { + mDebuggingManager.enablePairingByQrCode(serviceName, password); + } } @Override public void disablePairing() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); - // TODO(joshuaduong): NOT IMPLEMENTED + if (mDebuggingManager != null) { + mDebuggingManager.disablePairing(); + } } @Override public int getAdbWirelessPort() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); - // TODO(joshuaduong): NOT IMPLEMENTED - return 0; + if (mDebuggingManager != null) { + return mDebuggingManager.getAdbWirelessPort(); + } + // If ro.adb.secure=0 + return mConnectionPort.get(); + } + + /** + * This listener is only used when ro.adb.secure=0. Otherwise, AdbDebuggingManager will + * do this. + */ + class AdbConnectionPortListener implements AdbDebuggingManager.AdbConnectionPortListener { + public void onPortReceived(int port) { + if (port > 0 && port <= 65535) { + mConnectionPort.set(port); + } else { + mConnectionPort.set(-1); + // Turn off wifi debugging, since the server did not start. + try { + Settings.Global.putInt(mContentResolver, + Settings.Global.ADB_WIFI_ENABLED, 0); + } catch (SecurityException e) { + // If UserManager.DISALLOW_DEBUGGING_FEATURES is on, that this setting can't + // be changed. + Slog.d(TAG, "ADB_ENABLED is restricted."); + } + } + broadcastPortInfo(mConnectionPort.get()); + } + } + + private void broadcastPortInfo(int port) { + Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_STATE_CHANGED_ACTION); + intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA, (port >= 0) + ? AdbManager.WIRELESS_STATUS_CONNECTED + : AdbManager.WIRELESS_STATUS_DISCONNECTED); + intent.putExtra(AdbManager.WIRELESS_DEBUG_PORT_EXTRA, port); + mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + Slog.i(TAG, "sent port broadcast port=" + port); + } + + private void startAdbd() { + SystemProperties.set(CTL_START, ADBD); + } + + private void stopAdbd() { + if (!mIsAdbUsbEnabled && !mIsAdbWifiEnabled) { + SystemProperties.set(CTL_STOP, ADBD); + } } private void setAdbEnabled(boolean enable, byte transportType) { @@ -356,11 +448,33 @@ public class AdbService extends IAdbManager.Stub { mIsAdbUsbEnabled = enable; } else if (transportType == AdbTransportType.WIFI && enable != mIsAdbWifiEnabled) { mIsAdbWifiEnabled = enable; + if (mIsAdbWifiEnabled) { + if (!AdbProperties.secure().orElse(false) && mDebuggingManager == null) { + // Start adbd. If this is secure adb, then we defer enabling adb over WiFi. + SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "1"); + mConnectionPortPoller = + new AdbDebuggingManager.AdbConnectionPortPoller(mPortListener); + mConnectionPortPoller.start(); + } + } else { + // Stop adb over WiFi. + SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "0"); + if (mConnectionPortPoller != null) { + mConnectionPortPoller.cancelAndWait(); + mConnectionPortPoller = null; + } + } } else { // No change return; } + if (enable) { + startAdbd(); + } else { + stopAdbd(); + } + for (IAdbTransport transport : mTransports.values()) { try { transport.onAdbEnabled(enable, transportType); diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 81b42da7d953..153b006d8970 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -21,6 +21,7 @@ cc_library_static { "BroadcastRadio/convert.cpp", "BroadcastRadio/regions.cpp", "com_android_server_AlarmManagerService.cpp", + "com_android_server_adb_AdbDebuggingManager.cpp", "com_android_server_am_BatteryStatsService.cpp", "com_android_server_connectivity_Vpn.cpp", "com_android_server_ConsumerIrService.cpp", @@ -69,6 +70,8 @@ cc_library_static { cc_defaults { name: "libservices.core-libs", shared_libs: [ + "libadb_pairing_server", + "libadb_pairing_connection", "libandroid_runtime", "libandroidfw", "libaudioclient", diff --git a/services/core/jni/com_android_server_adb_AdbDebuggingManager.cpp b/services/core/jni/com_android_server_adb_AdbDebuggingManager.cpp new file mode 100644 index 000000000000..9c834aaece85 --- /dev/null +++ b/services/core/jni/com_android_server_adb_AdbDebuggingManager.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "AdbDebuggingManager-JNI" + +#define LOG_NDEBUG 0 + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include "jni.h" + +namespace android { + +// ---------------------------------------------------------------------------- +namespace { + +template +class JSmartWrapper { +public: + JSmartWrapper(JNIEnv* env, T* jData) : mEnv(env), mJData(jData) {} + + virtual ~JSmartWrapper() = default; + + const N* data() const { return mRawData; } + + jsize size() const { return mSize; } + +protected: + N* mRawData = nullptr; + JNIEnv* mEnv = nullptr; + T* mJData = nullptr; + jsize mSize = 0; +}; // JSmartWrapper + +class JStringUTFWrapper : public JSmartWrapper { +public: + explicit JStringUTFWrapper(JNIEnv* env, jstring* str) : JSmartWrapper(env, str) { + mRawData = env->GetStringUTFChars(*str, NULL); + mSize = env->GetStringUTFLength(*str); + } + + virtual ~JStringUTFWrapper() { + if (data()) { + mEnv->ReleaseStringUTFChars(*mJData, mRawData); + } + } +}; // JStringUTFWrapper + +struct ServerDeleter { + void operator()(PairingServerCtx* p) { pairing_server_destroy(p); } +}; +using PairingServerPtr = std::unique_ptr; +struct PairingResultWaiter { + std::mutex mutex_; + std::condition_variable cv_; + std::optional is_valid_; + PeerInfo peer_info_; + + static void ResultCallback(const PeerInfo* peer_info, void* opaque) { + auto* p = reinterpret_cast(opaque); + { + std::unique_lock lock(p->mutex_); + if (peer_info) { + memcpy(&(p->peer_info_), peer_info, sizeof(PeerInfo)); + } + p->is_valid_ = (peer_info != nullptr); + } + p->cv_.notify_one(); + } +}; + +PairingServerPtr sServer; +std::unique_ptr sWaiter; +} // namespace + +static jint native_pairing_start(JNIEnv* env, jobject thiz, jstring guid, jstring password) { + // Server-side only sends its GUID on success. + PeerInfo system_info = {}; + system_info.type = ADB_DEVICE_GUID; + JStringUTFWrapper guidWrapper(env, &guid); + memcpy(system_info.data, guidWrapper.data(), guidWrapper.size()); + + JStringUTFWrapper passwordWrapper(env, &password); + + // Create the pairing server + sServer = PairingServerPtr( + pairing_server_new_no_cert(reinterpret_cast(passwordWrapper.data()), + passwordWrapper.size(), &system_info, 0)); + + sWaiter.reset(new PairingResultWaiter); + uint16_t port = pairing_server_start(sServer.get(), sWaiter->ResultCallback, sWaiter.get()); + if (port == 0) { + ALOGE("Failed to start pairing server"); + return -1; + } + + return port; +} + +static void native_pairing_cancel(JNIEnv* /* env */, jclass /* clazz */) { + if (sServer != nullptr) { + sServer.reset(); + } +} + +static jboolean native_pairing_wait(JNIEnv* env, jobject thiz) { + ALOGI("Waiting for pairing server to complete"); + std::unique_lock lock(sWaiter->mutex_); + if (!sWaiter->is_valid_.has_value()) { + sWaiter->cv_.wait(lock, [&]() { return sWaiter->is_valid_.has_value(); }); + } + if (!*(sWaiter->is_valid_)) { + return JNI_FALSE; + } + + std::string peer_public_key = reinterpret_cast(sWaiter->peer_info_.data); + // Write to PairingThread's member variables + jclass clazz = env->GetObjectClass(thiz); + jfieldID mPublicKey = env->GetFieldID(clazz, "mPublicKey", "Ljava/lang/String;"); + jstring jpublickey = env->NewStringUTF(peer_public_key.c_str()); + env->SetObjectField(thiz, mPublicKey, jpublickey); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------------- + +static const JNINativeMethod gPairingThreadMethods[] = { + /* name, signature, funcPtr */ + {"native_pairing_start", "(Ljava/lang/String;Ljava/lang/String;)I", + (void*)native_pairing_start}, + {"native_pairing_cancel", "()V", (void*)native_pairing_cancel}, + {"native_pairing_wait", "()Z", (void*)native_pairing_wait}, +}; + +int register_android_server_AdbDebuggingManager(JNIEnv* env) { + int res = jniRegisterNativeMethods(env, + "com/android/server/adb/AdbDebuggingManager$PairingThread", + gPairingThreadMethods, NELEM(gPairingThreadMethods)); + (void)res; // Faked use when LOG_NDEBUG. + LOG_FATAL_IF(res < 0, "Unable to register native methods."); + return 0; +} + +} /* namespace android */ diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index 692c9d25baa9..657920e9a9c6 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -56,6 +56,7 @@ int register_android_server_net_NetworkStatsService(JNIEnv* env); int register_android_server_security_VerityUtils(JNIEnv* env); int register_android_server_am_AppCompactor(JNIEnv* env); int register_android_server_am_LowMemDetector(JNIEnv* env); +int register_android_server_AdbDebuggingManager(JNIEnv* env); }; using namespace android; @@ -105,5 +106,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_android_server_security_VerityUtils(env); register_android_server_am_AppCompactor(env); register_android_server_am_LowMemDetector(env); + register_android_server_AdbDebuggingManager(env); return JNI_VERSION_1_4; } diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 5bb75c92fd30..d2b30b2ff5ef 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -1717,21 +1717,6 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser */ private static final int ENUMERATION_TIME_OUT_MS = 2000; - /** - * Command to start native service. - */ - protected static final String CTL_START = "ctl.start"; - - /** - * Command to start native service. - */ - protected static final String CTL_STOP = "ctl.stop"; - - /** - * Adb native daemon. - */ - protected static final String ADBD = "adbd"; - /** * Gadget HAL fully qualified instance name for registering for ServiceNotification. */ @@ -1913,17 +1898,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser return; } try { - if ((config & UsbManager.FUNCTION_ADB) != 0) { - /** - * Start adbd if ADB function is included in the configuration. - */ - setSystemProperty(CTL_START, ADBD); - } else { - /** - * Stop adbd otherwise. - */ - setSystemProperty(CTL_STOP, ADBD); - } + // Adbd will be started by AdbService once Global.ADB_ENABLED is set. UsbGadgetCallback usbGadgetCallback = new UsbGadgetCallback(mCurrentRequest, config, chargingFunctions); mGadgetProxy.setCurrentUsbFunctions(config, usbGadgetCallback, -- GitLab From 2be3ba49733df585bcfbf63d3b299d15dbfb0f13 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Sat, 22 Feb 2020 23:20:41 +0800 Subject: [PATCH 098/219] RESTRICT AUTOMERGE Create separated tasks for different apps from startActivities Assume there are 2 applications A, B with different uids. There are 4 activities A1, A2, B1, B2 with default task affinity and launch mode. After A1 called startActivities(B1, A2, B2): Original : Task(A1, B1, A2, B2) This Change: Task(A1, B1), Task(A2, B2) In other words, the source caller cannot launch its activity above the activity of other application in the same task, and it can still launch activity of other application in its task. Bug: 145669109 Test: run cts --test android.server.cts.StartActivityTests \ -m CtsServicesHostTestCases Change-Id: I97bd875146a52f62b8fe82235487ccefb2955e8e --- .../com/android/server/am/ActivityStarter.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index 7ce80d33ed00..57a0756703d1 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -951,6 +951,8 @@ class ActivityStarter { } else { callingPid = callingUid = -1; } + boolean forceNewTask = false; + final int filterCallingUid = callingUid >= 0 ? callingUid : realCallingUid; final long origId = Binder.clearCallingIdentity(); try { synchronized (mService) { @@ -970,6 +972,9 @@ class ActivityStarter { // Don't modify the client's object! intent = new Intent(intent); + if (forceNewTask) { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + } // Collect information about the target of the Intent. ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 0, @@ -995,7 +1000,17 @@ class ActivityStarter { return res; } - resultTo = outActivity[0] != null ? outActivity[0].appToken : null; + final ActivityRecord started = outActivity[0]; + if (started != null && started.getUid() == filterCallingUid) { + // Only the started activity which has the same uid as the source caller can + // be the caller of next activity. + resultTo = started.appToken; + forceNewTask = false; + } else { + // Different apps not adjacent to the caller are forced to be new task. + resultTo = null; + forceNewTask = true; + } } } } finally { -- GitLab From 6075dd7f58766902e06941552f27ff5ceacd369f Mon Sep 17 00:00:00 2001 From: Evan Laird Date: Fri, 21 Feb 2020 14:33:42 -0500 Subject: [PATCH 099/219] DO NOT MERGE: Add SystemUI support for front-facing camera protection Devices with a DisplayCutout configured may want to add some extra area of turned-off pixels around the cutout in order to keep light from leaking into camera hardware. This CL adds two new config values to sysui to enable the configuration of this cutout protection, and listens for CameraManager events telling us that a relevant camera has turned on. Test: manual Bug: 145095085 Change-Id: Ifce67a593247e3a2151d41800ae46a50478e0b7d --- packages/SystemUI/res/values/config.xml | 17 +++ .../systemui/CameraAvailabilityListener.kt | 138 ++++++++++++++++++ .../android/systemui/ScreenDecorations.java | 83 ++++++++++- 3 files changed, 234 insertions(+), 4 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 8811ad57ab5a..6758efac7e2a 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -491,4 +491,21 @@ false + + + + + + + + false + diff --git a/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt b/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt new file mode 100644 index 000000000000..24fa91b9e838 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui + +import android.content.Context +import android.graphics.Path +import android.graphics.Rect +import android.graphics.RectF +import android.hardware.camera2.CameraManager +import android.util.PathParser +import java.util.concurrent.Executor + +import kotlin.math.roundToInt + +const val TAG = "CameraOpTransitionController" + +/** + * Listens for usage of the Camera and controls the ScreenDecorations transition to show extra + * protection around a display cutout based on config_frontBuiltInDisplayCutoutProtection and + * config_enableDisplayCutoutProtection + */ +class CameraAvailabilityListener( + private val cameraManager: CameraManager, + private val cutoutProtectionPath: Path, + private val targetCameraId: String, + private val executor: Executor +) { + private var cutoutBounds = Rect() + private val listeners = mutableListOf() + private val availabilityCallback: CameraManager.AvailabilityCallback = + object : CameraManager.AvailabilityCallback() { + override fun onCameraAvailable(cameraId: String) { + if (targetCameraId == cameraId) { + notifyCameraInactive() + } + } + + override fun onCameraUnavailable(cameraId: String) { + if (targetCameraId == cameraId) { + notifyCameraActive() + } + } + } + + init { + val computed = RectF() + cutoutProtectionPath.computeBounds(computed, false /* unused */) + cutoutBounds.set( + computed.left.roundToInt(), + computed.top.roundToInt(), + computed.right.roundToInt(), + computed.bottom.roundToInt()) + } + + /** + * Start listening for availability events, and maybe notify listeners + * + * @return true if we started listening + */ + fun startListening() { + registerCameraListener() + } + + fun stop() { + unregisterCameraListener() + } + + fun addTransitionCallback(callback: CameraTransitionCallback) { + listeners.add(callback) + } + + fun removeTransitionCallback(callback: CameraTransitionCallback) { + listeners.remove(callback) + } + + private fun registerCameraListener() { + cameraManager.registerAvailabilityCallback(executor, availabilityCallback) + } + + private fun unregisterCameraListener() { + cameraManager.unregisterAvailabilityCallback(availabilityCallback) + } + + private fun notifyCameraActive() { + listeners.forEach { it.onApplyCameraProtection(cutoutProtectionPath, cutoutBounds) } + } + + private fun notifyCameraInactive() { + listeners.forEach { it.onHideCameraProtection() } + } + + /** + * Callbacks to tell a listener that a relevant camera turned on and off. + */ + interface CameraTransitionCallback { + fun onApplyCameraProtection(protectionPath: Path, bounds: Rect) + fun onHideCameraProtection() + } + + companion object Factory { + fun build(context: Context, executor: Executor): CameraAvailabilityListener { + val manager = context + .getSystemService(Context.CAMERA_SERVICE) as CameraManager + val res = context.resources + val pathString = res.getString(R.string.config_frontBuiltInDisplayCutoutProtection) + val cameraId = res.getString(R.string.config_protectedCameraId) + + return CameraAvailabilityListener( + manager, pathFromString(pathString), cameraId, executor) + } + + private fun pathFromString(pathString: String): Path { + val spec = pathString.trim() + val p: Path + try { + p = PathParser.createPathFromPathData(spec) + } catch (e: Throwable) { + throw IllegalArgumentException("Invalid protection path", e) + } + + return p + } + } +} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index 84cfd9318932..3a8524a3ee7d 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -29,6 +29,7 @@ import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.annotation.Dimension; +import android.annotation.NonNull; import android.app.ActivityManager; import android.app.Fragment; import android.content.BroadcastReceiver; @@ -37,6 +38,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.ColorStateList; import android.content.res.Configuration; +import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; @@ -110,6 +112,7 @@ public class ScreenDecorations extends SystemUI implements Tunable, private DisplayManager mDisplayManager; private DisplayManager.DisplayListener mDisplayListener; + private CameraAvailabilityListener mCameraListener; @VisibleForTesting protected int mRoundedDefault; @@ -133,6 +136,25 @@ public class ScreenDecorations extends SystemUI implements Tunable, private boolean mInGesturalMode; private boolean mIsRoundedCornerMultipleRadius; + private CameraAvailabilityListener.CameraTransitionCallback mCameraTransitionCallback = + new CameraAvailabilityListener.CameraTransitionCallback() { + @Override + public void onApplyCameraProtection(@NonNull Path protectionPath, @NonNull Rect bounds) { + // Show the extra protection around the front facing camera if necessary + mCutoutTop.setProtection(protectionPath, bounds); + mCutoutTop.setShowProtection(true); + mCutoutBottom.setProtection(protectionPath, bounds); + mCutoutBottom.setShowProtection(true); + } + + @Override + public void onHideCameraProtection() { + // Go back to the regular anti-aliasing + mCutoutTop.setShowProtection(false); + mCutoutBottom.setShowProtection(false); + } + }; + /** * Converts a set of {@link Rect}s into a {@link Region} * @@ -331,6 +353,7 @@ public class ScreenDecorations extends SystemUI implements Tunable, updateRoundedCornerRadii(); if (hasRoundedCorners() || shouldDrawCutout() || shouldHostHandles()) { setupDecorations(); + setupCameraListener(); } mDisplayListener = new DisplayManager.DisplayListener() { @@ -446,6 +469,16 @@ public class ScreenDecorations extends SystemUI implements Tunable, new ValidatingPreDrawListener(mBottomOverlay)); } + private void setupCameraListener() { + Resources res = mContext.getResources(); + boolean enabled = res.getBoolean(R.bool.config_enableDisplayCutoutProtection); + if (enabled) { + mCameraListener = CameraAvailabilityListener.Factory.build(mContext, mHandler::post); + mCameraListener.addTransitionCallback(mCameraTransitionCallback); + mCameraListener.startListening(); + } + } + private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -841,6 +874,13 @@ public class ScreenDecorations extends SystemUI implements Tunable, private final List mBounds = new ArrayList(); private final Rect mBoundingRect = new Rect(); private final Path mBoundingPath = new Path(); + // Don't initialize these because they are cached elsewhere and may not exist + private Rect mProtectionRect; + private Path mProtectionPath; + private Rect mTotalBounds = new Rect(); + // Whether or not to show the cutout protection path + private boolean mShowProtection = false; + private final int[] mLocation = new int[2]; private final boolean mInitialStart; private final Runnable mVisibilityChangedListener; @@ -887,7 +927,13 @@ public class ScreenDecorations extends SystemUI implements Tunable, super.onDraw(canvas); getLocationOnScreen(mLocation); canvas.translate(-mLocation[0], -mLocation[1]); - if (!mBoundingPath.isEmpty()) { + + if (mShowProtection && !mProtectionRect.isEmpty()) { + mPaint.setColor(mColor); + mPaint.setStyle(Paint.Style.FILL); + mPaint.setAntiAlias(true); + canvas.drawPath(mProtectionPath, mPaint); + } else if (!mBoundingPath.isEmpty()) { mPaint.setColor(mColor); mPaint.setStyle(Paint.Style.FILL); mPaint.setAntiAlias(true); @@ -915,6 +961,22 @@ public class ScreenDecorations extends SystemUI implements Tunable, update(); } + void setProtection(Path protectionPath, Rect pathBounds) { + mProtectionPath = protectionPath; + mProtectionRect = pathBounds; + } + + void setShowProtection(boolean shouldShow) { + if (mShowProtection == shouldShow) { + return; + } + + mShowProtection = shouldShow; + updateBoundingPath(); + requestLayout(); + invalidate(); + } + private boolean isStart() { final boolean flipped = (mRotation == RotationUtils.ROTATION_SEASCAPE || mRotation == RotationUtils.ROTATION_UPSIDE_DOWN); @@ -961,6 +1023,9 @@ public class ScreenDecorations extends SystemUI implements Tunable, Matrix m = new Matrix(); transformPhysicalToLogicalCoordinates(mInfo.rotation, dw, dh, m); mBoundingPath.transform(m); + if (mProtectionPath != null) { + mProtectionPath.transform(m); + } } private static void transformPhysicalToLogicalCoordinates(@Surface.Rotation int rotation, @@ -1018,9 +1083,19 @@ public class ScreenDecorations extends SystemUI implements Tunable, super.onMeasure(widthMeasureSpec, heightMeasureSpec); return; } - setMeasuredDimension( - resolveSizeAndState(mBoundingRect.width(), widthMeasureSpec, 0), - resolveSizeAndState(mBoundingRect.height(), heightMeasureSpec, 0)); + + if (mShowProtection) { + // Make sure that our measured height encompases the protection + mTotalBounds.union(mBoundingRect); + mTotalBounds.union(mProtectionRect); + setMeasuredDimension( + resolveSizeAndState(mTotalBounds.width(), widthMeasureSpec, 0), + resolveSizeAndState(mTotalBounds.height(), heightMeasureSpec, 0)); + } else { + setMeasuredDimension( + resolveSizeAndState(mBoundingRect.width(), widthMeasureSpec, 0), + resolveSizeAndState(mBoundingRect.height(), heightMeasureSpec, 0)); + } } public static void boundsFromDirection(DisplayCutout displayCutout, int gravity, -- GitLab From 29c75abfe17c603cf075075beda32eb5d163d6c0 Mon Sep 17 00:00:00 2001 From: Ram Periathiruvadi Date: Tue, 25 Feb 2020 10:12:44 -0800 Subject: [PATCH 100/219] Resolve trust agents on USER_STARTED in addition to USER_ADDED. ACTION_USER_ADDED is a broadcast that is sent once when the user is created. TrustManagerService resolves the enabled trust agents for an user only when the user is created. However, if there is a reboot or power loss before the broadcast is received, the trust agents are never resolved for that user. This change also registers for ACTION_USER_STARTED, so the service checks for enabled trust agents on every boot. If the trust agents have been already resolved and initialized for that users, there is already a Secure Settings key (TRUST_AGENTS_INITIALIZED) that is turned on, so we wouldn't be doing this more than once per user. Bug: 150145767 Test: TrustManagerService resolves trust agents only once - either on USER_ADDED or USER_STARTED. Change-Id: I83c2dd02d4b476f8b85af1aa4d9d0c77095207ce --- .../java/com/android/server/trust/TrustManagerService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index 7408dd40b5ca..ef54d0477615 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -1389,7 +1389,8 @@ public class TrustManagerService extends SystemService { if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) { refreshAgentList(getSendingUserId()); updateDevicePolicyFeatures(); - } else if (Intent.ACTION_USER_ADDED.equals(action)) { + } else if (Intent.ACTION_USER_ADDED.equals(action) || Intent.ACTION_USER_STARTED.equals( + action)) { int userId = getUserId(intent); if (userId > 0) { maybeEnableFactoryTrustAgents(mLockPatternUtils, userId); @@ -1430,6 +1431,7 @@ public class TrustManagerService extends SystemService { filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); filter.addAction(Intent.ACTION_USER_ADDED); filter.addAction(Intent.ACTION_USER_REMOVED); + filter.addAction(Intent.ACTION_USER_STARTED); context.registerReceiverAsUser(this, UserHandle.ALL, filter, -- GitLab From e207aed32949a0d421029d1a1153469b06dc68d7 Mon Sep 17 00:00:00 2001 From: Evan Laird Date: Wed, 26 Feb 2020 11:18:57 -0500 Subject: [PATCH 101/219] Use status_bar_padding_top in QS system icons Test: manual Bug: 148651257 Change-Id: I771502c97623efb6513c0b12bac2ef7a95f09fc4 --- packages/SystemUI/res/layout/system_icons.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/SystemUI/res/layout/system_icons.xml b/packages/SystemUI/res/layout/system_icons.xml index f3b72bf23757..6fb5590df6ed 100644 --- a/packages/SystemUI/res/layout/system_icons.xml +++ b/packages/SystemUI/res/layout/system_icons.xml @@ -26,6 +26,7 @@ android:layout_weight="1" android:layout_height="match_parent" android:paddingEnd="@dimen/signal_cluster_battery_padding" + android:paddingTop="@dimen/status_bar_padding_top" android:gravity="center_vertical" android:orientation="horizontal"/> -- GitLab From 97e162d60551c7cac3316ee00a6c12d520ce91d3 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Wed, 26 Feb 2020 12:46:01 -0800 Subject: [PATCH 102/219] Allow settingIgnored for DBH request if inEmergency Bug: 150232136 Test: on device Change-Id: Ia987418a591d716b787d406d725338a8563a55dd --- .../android/server/location/GnssConfiguration.java | 9 ++++++--- .../server/location/GnssLocationProvider.java | 13 +++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/location/GnssConfiguration.java b/services/core/java/com/android/server/location/GnssConfiguration.java index 86a84e312899..18d9f69c9735 100644 --- a/services/core/java/com/android/server/location/GnssConfiguration.java +++ b/services/core/java/com/android/server/location/GnssConfiguration.java @@ -79,7 +79,7 @@ class GnssConfiguration { // Represents an HAL interface version. Instances of this class are created in the JNI layer // and returned through native methods. - private static class HalInterfaceVersion { + static class HalInterfaceVersion { final int mMajor; final int mMinor; @@ -205,6 +205,10 @@ class GnssConfiguration { native_set_satellite_blacklist(constellations, svids); } + HalInterfaceVersion getHalInterfaceVersion() { + return native_get_gnss_configuration_version(); + } + interface SetCarrierProperty { boolean set(int value); } @@ -231,8 +235,7 @@ class GnssConfiguration { logConfigurations(); - final HalInterfaceVersion gnssConfigurationIfaceVersion = - native_get_gnss_configuration_version(); + final HalInterfaceVersion gnssConfigurationIfaceVersion = getHalInterfaceVersion(); if (gnssConfigurationIfaceVersion != null) { // Set to a range checked value. if (isConfigEsExtensionSecSupported(gnssConfigurationIfaceVersion) diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index 4b79677b475b..342e9b8c3006 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -772,10 +772,15 @@ public class GnssLocationProvider extends AbstractLocationProvider implements locationRequest.setProvider(provider); - // Ignore location settings if in emergency mode. - if (isUserEmergency && mNIHandler.getInEmergency()) { - locationRequest.setLocationSettingsIgnored(true); - durationMillis *= EMERGENCY_LOCATION_UPDATE_DURATION_MULTIPLIER; + // Ignore location settings if in emergency mode. This is only allowed for + // isUserEmergency request (introduced in HAL v2.0), or DBH request in HAL v1.1. + if (mNIHandler.getInEmergency()) { + GnssConfiguration.HalInterfaceVersion halVersion = + mGnssConfiguration.getHalInterfaceVersion(); + if (isUserEmergency || (halVersion.mMajor < 2 && !independentFromGnss)) { + locationRequest.setLocationSettingsIgnored(true); + durationMillis *= EMERGENCY_LOCATION_UPDATE_DURATION_MULTIPLIER; + } } Log.i(TAG, -- GitLab From 348476e0944242bcf7c98b404293f4634f243ba2 Mon Sep 17 00:00:00 2001 From: Agatha Man Date: Thu, 14 Nov 2019 11:18:01 -0800 Subject: [PATCH 103/219] AudioService - remove sendBroadcastToAll() from setMasterMuteInternalNoCallerCheck() sendBroadcastToAll is a duplicate broadcast of MASTER_MUTE_CHANGED_ACTION. The same broadcast is called by sendMasterMuteUpdate. Test: make Bug: 144352459 Change-Id: I0f5283fe35521f04c04c159d42bd907fccfb226f (cherry picked from commit 1ae52c25c81bab7d0aa5c1994ea604a4836027eb) --- services/core/java/com/android/server/audio/AudioService.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index b5dbe9cb0895..3a5d4bc32d5c 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -2776,10 +2776,6 @@ public class AudioService extends IAudioService.Stub setSystemAudioMute(mute); AudioSystem.setMasterMute(mute); sendMasterMuteUpdate(mute, flags); - - Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION); - intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, mute); - sendBroadcastToAll(intent); } } } -- GitLab From d0555bba57fc8b2510a458cf07757e0db07e3aa6 Mon Sep 17 00:00:00 2001 From: Babak Bostan Date: Thu, 27 Feb 2020 11:17:55 -0800 Subject: [PATCH 104/219] DO NOT MERGE Add toast message when bluetooth connects to voice recognition. Bug: 143531081 Test: Manual Change-Id: I342a1e5eefc59d25a8bea1c0fe72b8669bfdbe84 --- packages/CarSystemUI/res/values/strings.xml | 2 + ...nnectedDeviceVoiceRecognitionNotifier.java | 90 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 packages/CarSystemUI/src/com/android/systemui/voicerecognition/car/ConnectedDeviceVoiceRecognitionNotifier.java diff --git a/packages/CarSystemUI/res/values/strings.xml b/packages/CarSystemUI/res/values/strings.xml index 0368e61978fd..9ea7ed027d34 100644 --- a/packages/CarSystemUI/res/values/strings.xml +++ b/packages/CarSystemUI/res/values/strings.xml @@ -20,4 +20,6 @@ Min Max + + Voice recognition now handled by connected Bluetooth device diff --git a/packages/CarSystemUI/src/com/android/systemui/voicerecognition/car/ConnectedDeviceVoiceRecognitionNotifier.java b/packages/CarSystemUI/src/com/android/systemui/voicerecognition/car/ConnectedDeviceVoiceRecognitionNotifier.java new file mode 100644 index 000000000000..5cd145b05a1b --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/voicerecognition/car/ConnectedDeviceVoiceRecognitionNotifier.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.voicerecognition.car; + +import android.bluetooth.BluetoothHeadsetClient; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Handler; +import android.os.UserHandle; +import android.util.Log; +import android.widget.Toast; + +import com.android.systemui.Dependency; +import com.android.systemui.R; +import com.android.systemui.SysUIToast; +import com.android.systemui.SystemUI; + +import javax.inject.Inject; + +/** + * Controller responsible for showing toast message when voice recognition over bluetooth device + * getting activated. + */ +public class ConnectedDeviceVoiceRecognitionNotifier extends SystemUI { + + private static final String TAG = "CarVoiceRecognition"; + private static final int INVALID_VALUE = -1; + private static final int VOICE_RECOGNITION_STARTED = 1; + + private Handler mHandler; + + private final BroadcastReceiver mVoiceRecognitionReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "Voice recognition received an intent!"); + } + if (intent == null + || intent.getAction() == null + || !BluetoothHeadsetClient.ACTION_AG_EVENT.equals(intent.getAction()) + || !intent.hasExtra(BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION)) { + return; + } + + int voiceRecognitionState = intent.getIntExtra( + BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION, INVALID_VALUE); + + if (voiceRecognitionState == VOICE_RECOGNITION_STARTED) { + mHandler.post(() -> { + SysUIToast.makeText(mContext, R.string.voice_recognition_toast, + Toast.LENGTH_LONG).show(); + }); + } + } + }; + + @Inject + public ConnectedDeviceVoiceRecognitionNotifier() { + super(); + mHandler = Dependency.get(Dependency.MAIN_HANDLER); + } + + @Override + public void start() { + } + + @Override + protected void onBootCompleted() { + IntentFilter filter = new IntentFilter(); + filter.addAction(BluetoothHeadsetClient.ACTION_AG_EVENT); + mContext.registerReceiverAsUser(mVoiceRecognitionReceiver, UserHandle.ALL, filter, + /* broadcastPermission= */ null, /* scheduler= */ null); + } +} -- GitLab From 9859e1724b9732aaba3e971bb3e34ef41fc2bac6 Mon Sep 17 00:00:00 2001 From: Malcolm Chen Date: Thu, 27 Feb 2020 17:11:43 -0800 Subject: [PATCH 105/219] Fix carrier config string typo. Bug: 148611362 Test: build Change-Id: Idf0c82a9920c62ecdc595973565656ed9ceedff6 --- telephony/java/android/telephony/CarrierConfigManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 81042f4a34bf..717adb9d2b93 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -3167,7 +3167,7 @@ public class CarrierConfigManager { * @hide */ public static final String KEY_DATA_SWITCH_VALIDATION_MIN_GAP_LONG = - "data_switch_validation_min_gap_LONG"; + "data_switch_validation_min_gap_long"; /** * A boolean property indicating whether this subscription should be managed as an opportunistic -- GitLab From 1180021cd841b0101339408fc5b593a67a44fca2 Mon Sep 17 00:00:00 2001 From: Jay Aliomer Date: Tue, 18 Feb 2020 11:48:29 -0500 Subject: [PATCH 106/219] Back porting Dark theme bug fixes from R Applying theme on start update system properties on startup to apply the updates Fixes: 149441632 Fixes: 149385662 Test: UiModeManager tests Change-Id: I7f71e27a43eb24be833b3003340653fefc75d0cc Merged-In: I0bee6517b39216146681097262cf55c7192b0131 --- .../android/server/UiModeManagerService.java | 107 +++++++++++------- .../server/UiModeManagerServiceTest.java | 5 +- 2 files changed, 71 insertions(+), 41 deletions(-) diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java index 7ad04728b512..479c9e4adb7a 100644 --- a/services/core/java/com/android/server/UiModeManagerService.java +++ b/services/core/java/com/android/server/UiModeManagerService.java @@ -74,6 +74,9 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import static android.app.UiModeManager.MODE_NIGHT_AUTO; +import static android.app.UiModeManager.MODE_NIGHT_YES; + final class UiModeManagerService extends SystemService { private static final String TAG = UiModeManager.class.getSimpleName(); private static final boolean LOG = false; @@ -131,6 +134,7 @@ final class UiModeManagerService extends SystemService { private NotificationManager mNotificationManager; private StatusBarManager mStatusBarManager; private WindowManagerInternal mWindowManager; + private PowerManager mPowerManager; private PowerManager.WakeLock mWakeLock; @@ -143,11 +147,12 @@ final class UiModeManagerService extends SystemService { @VisibleForTesting protected UiModeManagerService(Context context, WindowManagerInternal wm, PowerManager.WakeLock wl, TwilightManager tm, - boolean setupWizardComplete) { + PowerManager pm, boolean setupWizardComplete) { super(context); mWindowManager = wm; mWakeLock = wl; mTwilightManager = tm; + mPowerManager = pm; mSetupWizardComplete = setupWizardComplete; } @@ -268,14 +273,19 @@ final class UiModeManagerService extends SystemService { private final ContentObserver mDarkThemeObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange, Uri uri) { - int mode = Secure.getIntForUser(getContext().getContentResolver(), Secure.UI_NIGHT_MODE, - mNightMode, 0); - mode = mode == UiModeManager.MODE_NIGHT_AUTO - ? UiModeManager.MODE_NIGHT_YES : mode; - SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME, Integer.toString(mode)); + updateSystemProperties(); } }; + private void updateSystemProperties() { + int mode = Secure.getIntForUser(getContext().getContentResolver(), Secure.UI_NIGHT_MODE, + mNightMode, 0); + if (mode == MODE_NIGHT_AUTO) { + mode = MODE_NIGHT_YES; + } + SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME, Integer.toString(mode)); + } + @Override public void onSwitchUser(int userHandle) { super.onSwitchUser(userHandle); @@ -287,9 +297,9 @@ final class UiModeManagerService extends SystemService { public void onStart() { final Context context = getContext(); - final PowerManager powerManager = + mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - mWakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG); + mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG); mWindowManager = LocalServices.getService(WindowManagerInternal.class); // If setup isn't complete for this user listen for completion so we can unblock @@ -356,6 +366,7 @@ final class UiModeManagerService extends SystemService { context.getContentResolver().registerContentObserver(Secure.getUriFor(Secure.UI_NIGHT_MODE), false, mDarkThemeObserver, 0); + mHandler.post(() -> updateSystemProperties()); } @VisibleForTesting @@ -413,6 +424,7 @@ final class UiModeManagerService extends SystemService { } private void registerScreenOffEvent() { + if (mPowerSave) return; mWaitForScreenOff = true; final IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF); @@ -560,7 +572,9 @@ final class UiModeManagerService extends SystemService { persistNightMode(user); } // on screen off will update configuration instead - if (mNightMode != UiModeManager.MODE_NIGHT_AUTO || mCar) { + if ((mNightMode != MODE_NIGHT_AUTO) + || shouldApplyAutomaticChangesImmediately()) { + unregisterScreenOffEvent(); updateLocked(0, 0); } else { registerScreenOffEvent(); @@ -638,7 +652,6 @@ final class UiModeManagerService extends SystemService { pw.println("Current UI Mode Service state:"); pw.print(" mDockState="); pw.print(mDockState); pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState); - pw.print(" mNightMode="); pw.print(mNightMode); pw.print(" ("); pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") "); pw.print(" mNightModeLocked="); pw.println(mNightModeLocked); @@ -655,11 +668,9 @@ final class UiModeManagerService extends SystemService { pw.print(" mComputedNightMode="); pw.print(mComputedNightMode); pw.print(" mCarModeEnableFlags="); pw.print(mCarModeEnableFlags); pw.print(" mEnableCarDockLaunch="); pw.println(mEnableCarDockLaunch); - pw.print(" mCurUiMode=0x"); pw.print(Integer.toHexString(mCurUiMode)); pw.print(" mUiModeLocked="); pw.print(mUiModeLocked); pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode)); - pw.print(" mHoldingConfiguration="); pw.print(mHoldingConfiguration); pw.print(" mSystemReady="); pw.println(mSystemReady); @@ -678,7 +689,6 @@ final class UiModeManagerService extends SystemService { mTwilightManager = getLocalService(TwilightManager.class); mSystemReady = true; mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR; - updateComputedNightModeLocked(); registerVrStateListener(); updateLocked(0, 0); } @@ -857,40 +867,56 @@ final class UiModeManagerService extends SystemService { uiMode = Configuration.UI_MODE_TYPE_VR_HEADSET; } - if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) { + if (mNightMode == MODE_NIGHT_YES || mNightMode == UiModeManager.MODE_NIGHT_NO) { + mComputedNightMode = mNightMode == MODE_NIGHT_YES; + } + + if (mNightMode == MODE_NIGHT_AUTO) { + boolean activateNightMode = mComputedNightMode; if (mTwilightManager != null) { mTwilightManager.registerListener(mTwilightListener, mHandler); + final TwilightState lastState = mTwilightManager.getLastTwilightState(); + activateNightMode = lastState == null ? mComputedNightMode : lastState.isNight(); } - updateComputedNightModeLocked(); - uiMode |= mComputedNightMode ? Configuration.UI_MODE_NIGHT_YES - : Configuration.UI_MODE_NIGHT_NO; + + updateComputedNightModeLocked(activateNightMode); } else { if (mTwilightManager != null) { mTwilightManager.unregisterListener(mTwilightListener); } - uiMode |= mNightMode << 4; } // Override night mode in power save mode if not in car mode if (mPowerSave && !mCarModeEnabled) { uiMode &= ~Configuration.UI_MODE_NIGHT_NO; uiMode |= Configuration.UI_MODE_NIGHT_YES; + } else { + uiMode = getComputedUiModeConfiguration(uiMode); } if (LOG) { Slog.d(TAG, - "updateConfigurationLocked: mDockState=" + mDockState + "updateConfigurationLocked: mDockState=" + mDockState + "; mCarMode=" + mCarModeEnabled + "; mNightMode=" + mNightMode + "; uiMode=" + uiMode); } mCurUiMode = uiMode; - if (!mHoldingConfiguration || !mWaitForScreenOff) { + if (!mHoldingConfiguration && (!mWaitForScreenOff || mPowerSave)) { mConfiguration.uiMode = uiMode; } } + @UiModeManager.NightMode + private int getComputedUiModeConfiguration(@UiModeManager.NightMode int uiMode) { + uiMode |= mComputedNightMode ? Configuration.UI_MODE_NIGHT_YES + : Configuration.UI_MODE_NIGHT_NO; + uiMode &= mComputedNightMode ? ~Configuration.UI_MODE_NIGHT_NO + : ~Configuration.UI_MODE_NIGHT_YES; + return uiMode; + } + private void applyConfigurationExternallyLocked() { if (mSetUiMode != mConfiguration.uiMode) { mSetUiMode = mConfiguration.uiMode; @@ -898,10 +924,16 @@ final class UiModeManagerService extends SystemService { ActivityTaskManager.getService().updateConfiguration(mConfiguration); } catch (RemoteException e) { Slog.w(TAG, "Failure communicating with activity manager", e); + } catch (SecurityException e) { + Slog.e(TAG, "Activity does not have the ", e); } } } + private boolean shouldApplyAutomaticChangesImmediately() { + return mCar || !mPowerManager.isInteractive(); + } + void updateLocked(int enableFlags, int disableFlags) { String action = null; String oldAction = null; @@ -1132,26 +1164,21 @@ final class UiModeManagerService extends SystemService { } } - private void updateComputedNightModeLocked() { - if (mTwilightManager != null) { - TwilightState state = mTwilightManager.getLastTwilightState(); - if (state != null) { - mComputedNightMode = state.isNight(); - } - if (mNightModeOverride == UiModeManager.MODE_NIGHT_YES && !mComputedNightMode) { - mComputedNightMode = true; - return; - } - if (mNightModeOverride == UiModeManager.MODE_NIGHT_NO && mComputedNightMode) { - mComputedNightMode = false; - return; - } - - mNightModeOverride = mNightMode; - final int user = UserHandle.getCallingUserId(); - Secure.putIntForUser(getContext().getContentResolver(), - OVERRIDE_NIGHT_MODE, mNightModeOverride, user); + private void updateComputedNightModeLocked(boolean activate) { + mComputedNightMode = activate; + if (mNightModeOverride == UiModeManager.MODE_NIGHT_YES && !mComputedNightMode) { + mComputedNightMode = true; + return; + } + if (mNightModeOverride == UiModeManager.MODE_NIGHT_NO && mComputedNightMode) { + mComputedNightMode = false; + return; } + + mNightModeOverride = mNightMode; + final int user = UserHandle.getCallingUserId(); + Secure.putIntForUser(getContext().getContentResolver(), + OVERRIDE_NIGHT_MODE, mNightModeOverride, user); } private void registerVrStateListener() { @@ -1272,7 +1299,7 @@ final class UiModeManagerService extends SystemService { final boolean isIt = (mConfiguration.uiMode & Configuration.UI_MODE_NIGHT_YES) != 0; if (LOG) { Slog.d(TAG, - "LocalService.isNightMode(): mNightMode=" + mNightMode + "LocalService.isNightMode(): mNightMode=" + mNightMode + "; mComputedNightMode=" + mComputedNightMode + "; uiMode=" + mConfiguration.uiMode + "; isIt=" + isIt); diff --git a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java index 338f837b9b44..3fce5ebc8432 100644 --- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java @@ -24,6 +24,7 @@ import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; import android.os.PowerManager; +import android.os.PowerManagerInternal; import android.os.RemoteException; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -66,12 +67,14 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { TwilightManager mTwilightManager; @Mock PowerManager.WakeLock mWakeLock; + @Mock + PowerManager mPowerManager; private Set mScreenOffRecievers; @Before public void setUp() { mUiManagerService = new UiModeManagerService(mContext, mWindowManager, mWakeLock, - mTwilightManager, true); + mTwilightManager, mPowerManager, true); mScreenOffRecievers = new HashSet<>(); mService = mUiManagerService.getService(); when(mContext.checkCallingOrSelfPermission(anyString())) -- GitLab From eb2116bd30a5c8ce2f120f3ccd341ce42009b392 Mon Sep 17 00:00:00 2001 From: Matt Pape Date: Thu, 17 Oct 2019 15:20:34 -0700 Subject: [PATCH 107/219] CP ag/9571636 from master to qt-qpr1-dev Bug: 143299398 -------------------------------------------------------------- Enforce READ_DEVICE_CONFIG in DeviceConfig.getProperties path. Test: atest CtsDeviceConfigTestCases atest FrameworksCoreTests:DeviceConfigTest atest FrameworksCoreTests:SettingsProviderTest atest SettingsProviderTest:DeviceConfigServiceTest Bug: 142891501 Change-Id: Ic01632514862b640d9e3b280b1ac15b1391c3c17 --- .../src/com/android/providers/settings/SettingsProvider.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index fbfbe7fc1d9b..210aff717b7c 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -1136,6 +1136,9 @@ public class SettingsProvider extends ContentProvider { Slog.v(LOG_TAG, "getAllConfigFlags() for " + prefix); } + DeviceConfig.enforceReadPermission(getContext(), + prefix != null ? prefix.split("/")[0] : null); + synchronized (mLock) { // Get the settings. SettingsState settingsState = mSettingsRegistry.getSettingsLocked( -- GitLab From 3e27a339176670f563c845b3ee027d5d5e6b671b Mon Sep 17 00:00:00 2001 From: Tyler Trephan Date: Fri, 14 Feb 2020 14:13:53 -0800 Subject: [PATCH 108/219] Updated wakeLock permission descriptions. Test: None Change-Id: Idc5e4be36b1527722e0dd84e8f2bcd0c2a7b02a3 Fix: 146586093 (cherry picked from commit 4701da640cc255253f87576c636b9fcac879bd89) --- core/res/res/values/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index a0d2d842000b..5d5729b412be 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1211,6 +1211,8 @@ Allows the app to access the phone numbers of the device. + + keep car screen turned on prevent tablet from sleeping @@ -1218,6 +1220,8 @@ prevent phone from sleeping + Allows the app to keep the car screen turned on. + Allows the app to prevent the tablet from going to sleep. Allows the app to prevent the TV from going to sleep. -- GitLab From 9494c9dbb73b0ce237cb2f64fba90434b1b09c09 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Fri, 28 Feb 2020 23:04:58 +0000 Subject: [PATCH 109/219] DO NOT MERGE: Revert: Freeup lock when IME is set inactive and unbound Reason for revert: Caused an unexpected regression Bug 144174015 Bug: 139806621 Bug: 144103599 Fix: 144174015 Test: Manually verified Bug 144174015 disappeared as follows 1. Open Gmail then start composing an email 2. Swipe up the home button to recents then re-launch Gmail 3. Do the step 2 several times. 4. Make sure that you can still type something on Gmail. Change-Id: I04a77afea17f9d3eb05017fa00313fad4e48cd5c --- .../view/inputmethod/InputMethodManager.java | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index d3618adca6c4..d75810ad0e37 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -655,14 +655,14 @@ public final class InputMethodManager { } catch (RemoteException e) { } } - } - // Check focus again in case that "onWindowFocus" is called before - // handling this message. - if (mServedView != null && canStartInput(mServedView)) { - if (checkFocusNoStartInput(mRestartOnNextWindowFocus)) { - final int reason = active ? StartInputReason.ACTIVATED_BY_IMMS - : StartInputReason.DEACTIVATED_BY_IMMS; - startInputInner(reason, null, 0, 0, 0); + // Check focus again in case that "onWindowFocus" is called before + // handling this message. + if (mServedView != null && canStartInput(mServedView)) { + if (checkFocusNoStartInput(mRestartOnNextWindowFocus)) { + final int reason = active ? StartInputReason.ACTIVATED_BY_IMMS + : StartInputReason.DEACTIVATED_BY_IMMS; + startInputInner(reason, null, 0, 0, 0); + } } } return; @@ -1225,10 +1225,6 @@ public final class InputMethodManager { */ void clearBindingLocked() { if (DEBUG) Log.v(TAG, "Clearing binding!"); - if (mWindowFocusGainFuture != null) { - mWindowFocusGainFuture.cancel(false /* mayInterruptIfRunning */); - mWindowFocusGainFuture = null; - } clearConnectionLocked(); setInputChannelLocked(null); mBindSequence = -1; -- GitLab From 344858dd9c5616a0de16fa0ac72e0d384e2406c4 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Fri, 28 Feb 2020 23:04:58 +0000 Subject: [PATCH 110/219] DO NOT MERGE: Revert Move startInput for WINDOW_FOCUS_GAIN to background thread Reason for revert: Caused an unexpected regression Bug 144174015 Bug: 139806621 Bug: 144103599 Fix: 144174015 Test: Manually verified Bug 144174015 disappeared as follows 1. Open Gmail then start composing an email 2. Swipe up the home button to recents then re-launch Gmail 3. Do the step 2 several times. 4. Make sure that you can still type something on Gmail. Change-Id: I9265f01ed2f6e4aca7728d278f06ceea5633dac5 --- .../view/inputmethod/InputMethodManager.java | 77 ++++++------------- 1 file changed, 22 insertions(+), 55 deletions(-) diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index d75810ad0e37..032af1c5c7b5 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -92,10 +92,7 @@ import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.concurrent.CancellationException; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; /** @@ -424,13 +421,6 @@ public final class InputMethodManager { int mCursorCandStart; int mCursorCandEnd; - /** - * Initial startInput with {@link StartInputReason.WINDOW_FOCUS_GAIN} is executed - * in a background thread. Later, if there is an actual startInput it will wait on - * main thread till the background thread completes. - */ - private CompletableFuture mWindowFocusGainFuture; - /** * The instance that has previously been sent to the input method. */ @@ -1608,18 +1598,6 @@ public final class InputMethodManager { boolean startInputInner(@StartInputReason int startInputReason, @Nullable IBinder windowGainingFocus, @StartInputFlags int startInputFlags, @SoftInputModeFlags int softInputMode, int windowFlags) { - if (startInputReason != StartInputReason.WINDOW_FOCUS_GAIN - && mWindowFocusGainFuture != null) { - try { - mWindowFocusGainFuture.get(); - } catch (ExecutionException | InterruptedException e) { - // do nothing - } catch (CancellationException e) { - // window no longer has focus. - return true; - } - } - final View view; synchronized (mH) { view = mServedView; @@ -1973,38 +1951,31 @@ public final class InputMethodManager { startInputFlags |= StartInputFlags.FIRST_WINDOW_FOCUS_GAIN; } - final boolean forceNewFocus1 = forceNewFocus; - final int startInputFlags1 = startInputFlags; - if (mWindowFocusGainFuture != null) { - mWindowFocusGainFuture.cancel(false/* mayInterruptIfRunning */); - } - mWindowFocusGainFuture = CompletableFuture.runAsync(() -> { - if (checkFocusNoStartInput(forceNewFocus1)) { - // We need to restart input on the current focus view. This - // should be done in conjunction with telling the system service - // about the window gaining focus, to help make the transition - // smooth. - if (startInputInner(StartInputReason.WINDOW_FOCUS_GAIN, rootView.getWindowToken(), - startInputFlags1, softInputMode, windowFlags)) { - return; - } + if (checkFocusNoStartInput(forceNewFocus)) { + // We need to restart input on the current focus view. This + // should be done in conjunction with telling the system service + // about the window gaining focus, to help make the transition + // smooth. + if (startInputInner(StartInputReason.WINDOW_FOCUS_GAIN, rootView.getWindowToken(), + startInputFlags, softInputMode, windowFlags)) { + return; } + } - // For some reason we didn't do a startInput + windowFocusGain, so - // we'll just do a window focus gain and call it a day. - synchronized (mH) { - try { - if (DEBUG) Log.v(TAG, "Reporting focus gain, without startInput"); - mService.startInputOrWindowGainedFocus( - StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY, mClient, - rootView.getWindowToken(), startInputFlags1, softInputMode, windowFlags, - null, null, 0 /* missingMethodFlags */, - rootView.getContext().getApplicationInfo().targetSdkVersion); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + // For some reason we didn't do a startInput + windowFocusGain, so + // we'll just do a window focus gain and call it a day. + synchronized (mH) { + try { + if (DEBUG) Log.v(TAG, "Reporting focus gain, without startInput"); + mService.startInputOrWindowGainedFocus( + StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY, mClient, + rootView.getWindowToken(), startInputFlags, softInputMode, windowFlags, + null, null, 0 /* missingMethodFlags */, + rootView.getContext().getApplicationInfo().targetSdkVersion); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); } - }); + } } /** @hide */ @@ -2019,10 +1990,6 @@ public final class InputMethodManager { // If the mCurRootView is losing window focus, release the strong reference to it // so as not to prevent it from being garbage-collected. mCurRootView = null; - if (mWindowFocusGainFuture != null) { - mWindowFocusGainFuture.cancel(false /* mayInterruptIfRunning */); - mWindowFocusGainFuture = null; - } } else { if (DEBUG) { Log.v(TAG, "Ignoring onPreWindowFocus()." -- GitLab From 0d7e27af30e39fbb6dcafedc854daa639074e5cc Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Tue, 3 Mar 2020 14:36:21 +0800 Subject: [PATCH 111/219] RESTRICT AUTOMERGE Use consistent calling uid and package in navigateUpTo Originally, if the caller of navigateUpTo is alive, even the calling uid is set to the caller who launched the existing destination activity, the uid from caller process has higher priority to replace the given calling uid. So this change doesn't modify the existing behavior if the caller process is valid. Besides, the case of delivering new intent uses the source record as calling identity too, so the case of starting new activity should be consistent. Also forbid attaching null application thread to avoid unexpected state in process record. Bug: 144285917 Test: bit FrameworksServicesTests:com.android.server.am.ActivityStackTests Change-Id: I60732f430256d37cb926d08d093581f051c4afed --- .../android/server/am/ActivityManagerService.java | 5 ++++- .../java/com/android/server/am/ActivityStack.java | 13 +++++++++---- .../com/android/server/am/ActivityStackTests.java | 13 +++++++++++++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index b4c18b13947c..87bad5c049e0 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -6916,7 +6916,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } - private final boolean attachApplicationLocked(IApplicationThread thread, + private boolean attachApplicationLocked(@NonNull IApplicationThread thread, int pid) { // Find the application record that is being attached... either via @@ -7221,6 +7221,9 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public final void attachApplication(IApplicationThread thread) { + if (thread == null) { + throw new SecurityException("Invalid application interface"); + } synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 199860597f9a..c1ea022f1c11 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -3961,6 +3961,11 @@ class ActivityStack extends ConfigurationContai final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode, Intent resultData) { + if (srec.app == null || srec.app.thread == null) { + // Nothing to do if the caller is not attached, because this method should be called + // from an alive activity. + return false; + } final TaskRecord task = srec.getTask(); final ArrayList activities = task.mActivities; final int start = activities.indexOf(srec); @@ -4012,22 +4017,22 @@ class ActivityStack extends ConfigurationContai } if (parent != null && foundParentInTask) { + final int callingUid = srec.info.applicationInfo.uid; final int parentLaunchMode = parent.info.launchMode; final int destIntentFlags = destIntent.getFlags(); if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { - parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent, - srec.packageName); + parent.deliverNewIntentLocked(callingUid, destIntent, srec.packageName); } else { try { ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( destIntent.getComponent(), 0, srec.userId); int res = mService.mActivityStarter.startActivityLocked(srec.app.thread, destIntent, null /*ephemeralIntent*/, null, aInfo, null /*rInfo*/, null, - null, parent.appToken, null, 0, -1, parent.launchedFromUid, - parent.launchedFromPackage, -1, parent.launchedFromUid, 0, null, + null, parent.appToken, null, 0, -1, callingUid, + srec.packageName, -1, callingUid, 0, null, false, true, null, null, "navigateUpTo"); foundParentInTask = res == ActivityManager.START_SUCCESS; } catch (RemoteException e) { diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java index 02fba082ca98..33174b2bf074 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java @@ -122,4 +122,17 @@ public class ActivityStackTests extends ActivityTestsBase { assertEquals(task.getTopActivity(true /* includeOverlays */), taskOverlay); assertNotNull(result.r); } + + @Test + public void testNavigateUpTo() { + final ActivityManagerService service = createActivityManagerService(); + final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID); + final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task); + activityRecord.app = new ProcessRecord(null, activityRecord.appInfo, + activityRecord.processName, activityRecord.getUid()); + final ActivityStack testStack = service.mStackSupervisor.getStack(TEST_STACK_ID); + // No-op if the source activity record doesn't have attached process (app.thread == null). + assertFalse(testStack.navigateUpToLocked(activityRecord, activityRecord.intent, + 0 /* resultCode */, null /* resultData */)); + } } -- GitLab From 55e8fd2352e16f63f5ef5ab9d243712599e09091 Mon Sep 17 00:00:00 2001 From: jiabin Date: Mon, 23 Dec 2019 13:09:58 -0800 Subject: [PATCH 112/219] Set/get allowed capture policy via AudioService. Do not call AudioSystem.setAllowedCapturePolicy directly in AudioManager. Instead, send the request to AudioService and calling the function in AudioService. In that case, AudioService can cached the request so that it benefits returning correct playback configuration. When querying capture policy, AudioManager will query AudioService first to see if there is cached capture policy. If there is exception, return cached capture policy in AudioManager. Test: dumpsys audio, query active audio playback configuration Test: atest AudioManagerTest, AudioAttributesTest Test: atest AudioPlaybackCaptureTest, AudioPlaybackConfigurationTest Bug: 145115448 Change-Id: I170571d8a67839bc5a53991d6c89127b99b5c794 Merged-In: I170571d8a67839bc5a53991d6c89127b99b5c794 (cherry picked from commit b33f36971dd80e600be6a7ffc0c0df65849da016) --- media/java/android/media/AudioAttributes.java | 5 +- media/java/android/media/AudioManager.java | 29 ++++--- media/java/android/media/IAudioService.aidl | 4 + .../android/server/audio/AudioService.java | 58 +++++++++++++ .../server/audio/PlaybackActivityMonitor.java | 82 +++++++++++++++++++ 5 files changed, 165 insertions(+), 13 deletions(-) diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index 820d82dd3bd1..d2ae7c100c3f 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -1251,7 +1251,10 @@ public final class AudioAttributes implements Parcelable { } } - static int capturePolicyToFlags(@CapturePolicy int capturePolicy, int flags) { + /** + * @hide + */ + public static int capturePolicyToFlags(@CapturePolicy int capturePolicy, int flags) { switch (capturePolicy) { case ALLOW_CAPTURE_BY_NONE: flags |= FLAG_NO_MEDIA_PROJECTION | FLAG_NO_SYSTEM_CAPTURE; diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 6890270f1bb6..142bc12f25c4 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -1507,23 +1507,22 @@ public class AudioManager { * {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}, * {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM}, * {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}. - * @throws IllegalArgumentException if the argument is not a valid value. + * @throws RuntimeException if the argument is not a valid value. */ public void setAllowedCapturePolicy(@AudioAttributes.CapturePolicy int capturePolicy) { - int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0); - // TODO: got trough AudioService and save a cache to restore in case of AP crash // TODO: also pass the package in case multiple packages have the same UID - int result = AudioSystem.setAllowedCapturePolicy(Process.myUid(), flags); - if (result != AudioSystem.AUDIO_STATUS_OK) { - Log.e(TAG, "Could not setAllowedCapturePolicy: " + result); - return; + final IAudioService service = getService(); + try { + int result = service.setAllowedCapturePolicy(capturePolicy); + if (result != AudioSystem.AUDIO_STATUS_OK) { + Log.e(TAG, "Could not setAllowedCapturePolicy: " + result); + return; + } + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); } - mCapturePolicy = capturePolicy; } - @AudioAttributes.CapturePolicy - private int mCapturePolicy = AudioAttributes.ALLOW_CAPTURE_BY_ALL; - /** * Return the capture policy. * @return the capture policy set by {@link #setAllowedCapturePolicy(int)} or @@ -1531,7 +1530,13 @@ public class AudioManager { */ @AudioAttributes.CapturePolicy public int getAllowedCapturePolicy() { - return mCapturePolicy; + int result = AudioAttributes.ALLOW_CAPTURE_BY_ALL; + try { + result = getService().getAllowedCapturePolicy(); + } catch (RemoteException e) { + Log.e(TAG, "Failed to query allowed capture policy: " + e); + } + return result; } //==================================================================== diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 71f52a1b7d8e..7052e5afb565 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -259,6 +259,10 @@ interface IAudioService { boolean hasHapticChannels(in Uri uri); + int setAllowedCapturePolicy(in int capturePolicy); + + int getAllowedCapturePolicy(); + // WARNING: read warning at top of file, new methods that need to be used by native // code via IAudioManager.h need to be added to the top section. } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 3a5d4bc32d5c..d7bb4c074f48 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -1041,6 +1041,27 @@ public class AudioService extends IAudioService.Stub } } + // Restore capture policies + synchronized (mPlaybackMonitor) { + HashMap allowedCapturePolicies = + mPlaybackMonitor.getAllAllowedCapturePolicies(); + for (HashMap.Entry entry : allowedCapturePolicies.entrySet()) { + int result = AudioSystem.setAllowedCapturePolicy( + entry.getKey(), + AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0)); + if (result != AudioSystem.AUDIO_STATUS_OK) { + Log.e(TAG, "Failed to restore capture policy, uid: " + + entry.getKey() + ", capture policy: " + entry.getValue() + + ", result: " + result); + // When restoring capture policy failed, set the capture policy as + // ALLOW_CAPTURE_BY_ALL, which will result in removing the cached + // capture policy in PlaybackActivityMonitor. + mPlaybackMonitor.setAllowedCapturePolicy( + entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL); + } + } + } + onIndicateSystemReady(); // indicate the end of reconfiguration phase to audio HAL AudioSystem.setParameters("restarting=false"); @@ -7250,6 +7271,43 @@ public class AudioService extends IAudioService.Stub mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid()); } + /** + * Specifies whether the audio played by this app may or may not be captured by other apps or + * the system. + * + * @param capturePolicy one of + * {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}, + * {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM}, + * {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}. + * @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed. + * @throws IllegalArgumentException if the argument is not a valid value. + */ + public int setAllowedCapturePolicy(int capturePolicy) { + int callingUid = Binder.getCallingUid(); + int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0); + final long identity = Binder.clearCallingIdentity(); + synchronized (mPlaybackMonitor) { + int result = AudioSystem.setAllowedCapturePolicy(callingUid, flags); + if (result == AudioSystem.AUDIO_STATUS_OK) { + mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy); + } + Binder.restoreCallingIdentity(identity); + return result; + } + } + + /** + * Return the capture policy. + * @return the cached capture policy for the calling uid. + */ + public int getAllowedCapturePolicy() { + int callingUid = Binder.getCallingUid(); + final long identity = Binder.clearCallingIdentity(); + int capturePolicy = mPlaybackMonitor.getAllowedCapturePolicy(callingUid); + Binder.restoreCallingIdentity(identity); + return capturePolicy; + } + //====================== // Audio device management //====================== diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java index 3a25d980e97a..93ffe835338f 100644 --- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java +++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java @@ -160,6 +160,12 @@ public final class PlaybackActivityMonitor new AudioPlaybackConfiguration(pic, newPiid, Binder.getCallingUid(), Binder.getCallingPid()); apc.init(); + synchronized (mAllowedCapturePolicies) { + int uid = apc.getClientUid(); + if (mAllowedCapturePolicies.containsKey(uid)) { + updateAllowedCapturePolicy(apc, mAllowedCapturePolicies.get(uid)); + } + } sEventLogger.log(new NewPlayerEvent(apc)); synchronized(mPlayerLock) { mPlayers.put(newPiid, apc); @@ -169,6 +175,13 @@ public final class PlaybackActivityMonitor public void playerAttributes(int piid, @NonNull AudioAttributes attr, int binderUid) { final boolean change; + synchronized (mAllowedCapturePolicies) { + if (mAllowedCapturePolicies.containsKey(binderUid) + && attr.getAllowedCapturePolicy() < mAllowedCapturePolicies.get(binderUid)) { + attr = new AudioAttributes.Builder(attr) + .setAllowedCapturePolicy(mAllowedCapturePolicies.get(binderUid)).build(); + } + } synchronized(mPlayerLock) { final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid)); if (checkConfigurationCaller(piid, apc, binderUid)) { @@ -284,6 +297,69 @@ public final class PlaybackActivityMonitor } } + /** + * A map of uid to capture policy. + */ + private final HashMap mAllowedCapturePolicies = + new HashMap(); + + /** + * Cache allowed capture policy, which specifies whether the audio played by the app may or may + * not be captured by other apps or the system. + * + * @param uid the uid of requested app + * @param capturePolicy one of + * {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}, + * {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM}, + * {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}. + */ + public void setAllowedCapturePolicy(int uid, int capturePolicy) { + synchronized (mAllowedCapturePolicies) { + if (capturePolicy == AudioAttributes.ALLOW_CAPTURE_BY_ALL) { + // When the capture policy is ALLOW_CAPTURE_BY_ALL, it is okay to + // remove it from cached capture policy as it is the default value. + mAllowedCapturePolicies.remove(uid); + return; + } else { + mAllowedCapturePolicies.put(uid, capturePolicy); + } + } + synchronized (mPlayerLock) { + for (AudioPlaybackConfiguration apc : mPlayers.values()) { + if (apc.getClientUid() == uid) { + updateAllowedCapturePolicy(apc, capturePolicy); + } + } + } + } + + /** + * Return the capture policy for given uid. + * @param uid the uid to query its cached capture policy. + * @return cached capture policy for given uid or AudioAttributes.ALLOW_CAPTURE_BY_ALL + * if there is not cached capture policy. + */ + public int getAllowedCapturePolicy(int uid) { + return mAllowedCapturePolicies.getOrDefault(uid, AudioAttributes.ALLOW_CAPTURE_BY_ALL); + } + + /** + * Return all cached capture policies. + */ + public HashMap getAllAllowedCapturePolicies() { + return mAllowedCapturePolicies; + } + + private void updateAllowedCapturePolicy(AudioPlaybackConfiguration apc, int capturePolicy) { + AudioAttributes attr = apc.getAudioAttributes(); + if (attr.getAllowedCapturePolicy() >= capturePolicy) { + return; + } + apc.handleAudioAttributesEvent( + new AudioAttributes.Builder(apc.getAudioAttributes()) + .setAllowedCapturePolicy(capturePolicy).build()); + } + // Implementation of AudioPlaybackConfiguration.PlayerDeathMonitor @Override public void playerDeath(int piid) { @@ -331,6 +407,12 @@ public final class PlaybackActivityMonitor // log sEventLogger.dump(pw); } + synchronized (mAllowedCapturePolicies) { + pw.println("\n allowed capture policies:"); + for (HashMap.Entry entry : mAllowedCapturePolicies.entrySet()) { + pw.println(" uid: " + entry.getKey() + " policy: " + entry.getValue()); + } + } } /** -- GitLab From 8a2c62c2867d30dd2065096b63512d2861ebae51 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Tue, 3 Mar 2020 18:12:10 +0800 Subject: [PATCH 113/219] RESTRICT AUTOMERGE Use consistent calling uid and package in navigateUpTo Originally, if the caller of navigateUpTo is alive, even the calling uid is set to the caller who launched the existing destination activity, the uid from caller process has higher priority to replace the given calling uid. So this change doesn't modify the existing behavior if the caller process is valid. Besides, the case of delivering new intent uses the source record as calling identity too, so the case of starting new activity should be consistent. Also forbid attaching null application thread to avoid unexpected state in process record. Bug: 144285917 Test: atest ActivityStackTests#testNavigateUpTo Change-Id: I60732f430256d37cb926d08d093581f051c4afed --- .../server/am/ActivityManagerService.java | 5 ++- .../com/android/server/wm/ActivityStack.java | 15 ++++--- .../android/server/wm/ActivityStarter.java | 5 +++ .../android/server/wm/ActivityStackTests.java | 41 +++++++++++++++++-- .../android/server/wm/ActivityTestsBase.java | 1 + 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index cf00210c34d3..f9d13c286093 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -4759,7 +4759,7 @@ public class ActivityManagerService extends IActivityManager.Stub } @GuardedBy("this") - private final boolean attachApplicationLocked(IApplicationThread thread, + private boolean attachApplicationLocked(@NonNull IApplicationThread thread, int pid, int callingUid, long startSeq) { // Find the application record that is being attached... either via @@ -5173,6 +5173,9 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public final void attachApplication(IApplicationThread thread, long startSeq) { + if (thread == null) { + throw new SecurityException("Invalid application interface"); + } synchronized (this) { int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index 56be335c2624..1a9b11cd62d5 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -4257,6 +4257,11 @@ class ActivityStack extends ConfigurationContainer { final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode, Intent resultData) { + if (!srec.attachedToProcess()) { + // Nothing to do if the caller is not attached, because this method should be called + // from an alive activity. + return false; + } final TaskRecord task = srec.getTaskRecord(); final ArrayList activities = task.mActivities; final int start = activities.indexOf(srec); @@ -4310,14 +4315,14 @@ class ActivityStack extends ConfigurationContainer { } if (parent != null && foundParentInTask) { + final int callingUid = srec.info.applicationInfo.uid; final int parentLaunchMode = parent.info.launchMode; final int destIntentFlags = destIntent.getFlags(); if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { - parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent, - srec.packageName); + parent.deliverNewIntentLocked(callingUid, destIntent, srec.packageName); } else { try { ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( @@ -4330,10 +4335,10 @@ class ActivityStack extends ConfigurationContainer { .setActivityInfo(aInfo) .setResultTo(parent.appToken) .setCallingPid(-1) - .setCallingUid(parent.launchedFromUid) - .setCallingPackage(parent.launchedFromPackage) + .setCallingUid(callingUid) + .setCallingPackage(srec.packageName) .setRealCallingPid(-1) - .setRealCallingUid(parent.launchedFromUid) + .setRealCallingUid(callingUid) .setComponentSpecified(true) .execute(); foundParentInTask = res == ActivityManager.START_SUCCESS; diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 5b697ee89602..f37698de34d5 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -2763,6 +2763,11 @@ class ActivityStarter { return mRequest.intent; } + @VisibleForTesting + int getCallingUid() { + return mRequest.callingUid; + } + ActivityStarter setReason(String reason) { mRequest.reason = reason; return this; diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java index bde0ef6aa39e..ff27b9bb1c9e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -28,7 +28,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING; import static com.android.server.wm.ActivityStack.ActivityState.FINISHING; @@ -54,8 +54,11 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import android.app.ActivityManager; +import android.app.IApplicationThread; import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.os.UserHandle; @@ -82,8 +85,9 @@ public class ActivityStackTests extends ActivityTestsBase { @Before public void setUp() throws Exception { mDefaultDisplay = mRootActivityContainer.getDefaultDisplay(); - mStack = spy(mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, - true /* onTop */)); + mStack = mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, + true /* onTop */); + spyOn(mStack); mTask = new TaskBuilder(mSupervisor).setStack(mStack).build(); } @@ -1078,6 +1082,37 @@ public class ActivityStackTests extends ActivityTestsBase { assertTrue(listener.mChanged); } + @Test + public void testNavigateUpTo() { + final ActivityStartController controller = mock(ActivityStartController.class); + final ActivityStarter starter = new ActivityStarter(controller, + mService, mService.mStackSupervisor, mock(ActivityStartInterceptor.class)); + doReturn(controller).when(mService).getActivityStartController(); + spyOn(starter); + doReturn(ActivityManager.START_SUCCESS).when(starter).execute(); + + final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build(); + final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask) + .setUid(firstActivity.getUid() + 1).build(); + doReturn(starter).when(controller).obtainStarter(eq(firstActivity.intent), anyString()); + + final IApplicationThread thread = secondActivity.app.getThread(); + secondActivity.app.setThread(null); + // This should do nothing from a non-attached caller. + assertFalse(mStack.navigateUpToLocked(secondActivity /* source record */, + firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */)); + + secondActivity.app.setThread(thread); + assertTrue(mStack.navigateUpToLocked(secondActivity /* source record */, + firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */)); + // The firstActivity uses default launch mode, so the activities between it and itself will + // be finished. + assertTrue(secondActivity.finishing); + assertTrue(firstActivity.finishing); + // The calling uid of the new activity should be the current real caller. + assertEquals(secondActivity.getUid(), starter.getCallingUid()); + } + private void verifyShouldSleepActivities(boolean focusedStack, boolean keyguardGoingAway, boolean displaySleeping, boolean expected) { final ActivityDisplay display = mock(ActivityDisplay.class); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java index 84bdecb86826..f94f00203521 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java @@ -290,6 +290,7 @@ class ActivityTestsBase { aInfo.applicationInfo.packageName = mComponent.getPackageName(); aInfo.applicationInfo.uid = mUid; aInfo.packageName = mComponent.getPackageName(); + aInfo.name = mComponent.getClassName(); if (mTargetActivity != null) { aInfo.targetActivity = mTargetActivity; } -- GitLab From be885c832f23b32aa11d44d234adffeedc6a90a7 Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Wed, 20 Nov 2019 13:04:54 -0500 Subject: [PATCH 114/219] Remove Dependency.staticOnConfigurationChanged ConfigurationChangedReceiver is removed. Classes that want to be notified of configuration changes should implement ConfigurationController.ConfigurationListener instead and register themselves with the ConfigurationController. This CPs http://ag/9762349 Change-Id: I00c08a30b6d8dcac7e26230cb4354bc1fda74b10 Merged-In: Id2c3fe5ae2729b181769fb31b8050da264299d72 Bug: 150541820 Test: atest SystemUITests --- .../ConfigurationChangedReceiver.java | 21 ------- .../src/com/android/systemui/Dependency.java | 10 --- .../android/systemui/SystemUIApplication.java | 6 +- .../systemui/SystemUIRootComponent.java | 9 +++ .../systemui/assist/AssistManager.java | 61 +++++++++++-------- .../systemui/fragments/FragmentService.java | 25 +++++--- .../phone/ConfigurationControllerImpl.kt | 5 +- .../policy/ConfigurationController.java | 6 +- .../policy/NetworkControllerImpl.java | 22 +++---- .../com/android/systemui/DependencyTest.java | 11 ---- .../leaks/FakeConfigurationController.java | 6 ++ 11 files changed, 84 insertions(+), 98 deletions(-) delete mode 100644 packages/SystemUI/src/com/android/systemui/ConfigurationChangedReceiver.java diff --git a/packages/SystemUI/src/com/android/systemui/ConfigurationChangedReceiver.java b/packages/SystemUI/src/com/android/systemui/ConfigurationChangedReceiver.java deleted file mode 100644 index 4fba6404f370..000000000000 --- a/packages/SystemUI/src/com/android/systemui/ConfigurationChangedReceiver.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.android.systemui; - -import android.content.res.Configuration; - -public interface ConfigurationChangedReceiver { - void onConfigurationChanged(Configuration newConfiguration); -} diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index 15bea2484d7f..c09c7673d376 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -16,7 +16,6 @@ package com.android.systemui; import android.annotation.Nullable; import android.app.INotificationManager; -import android.content.res.Configuration; import android.hardware.SensorPrivacyManager; import android.hardware.display.NightDisplayListener; import android.os.Handler; @@ -521,15 +520,6 @@ public class Dependency { .forEach(o -> ((Dumpable) o).dump(fd, pw, args)); } - protected static void staticOnConfigurationChanged(Configuration newConfig) { - sDependency.onConfigurationChanged(newConfig); - } - - protected synchronized void onConfigurationChanged(Configuration newConfig) { - mDependencies.values().stream().filter(obj -> obj instanceof ConfigurationChangedReceiver) - .forEach(o -> ((ConfigurationChangedReceiver) o).onConfigurationChanged(newConfig)); - } - protected final T getDependency(Class cls) { return getDependencyInner(cls); } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index 9252e5767996..0d1bd6bae2b3 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -286,7 +286,11 @@ public class SystemUIApplication extends Application implements SysUiServiceProv @Override public void onConfigurationChanged(Configuration newConfig) { if (mServicesStarted) { - Dependency.staticOnConfigurationChanged(newConfig); + SystemUIFactory + .getInstance() + .getRootComponent() + .getConfigurationController() + .onConfigurationChanged(newConfig); int len = mServices.length; for (int i = 0; i < len; i++) { if (mServices[i] != null) { diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java index f18c8b2c3da6..a5b386eddd34 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java @@ -20,6 +20,7 @@ import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME import com.android.systemui.fragments.FragmentService; import com.android.systemui.statusbar.phone.StatusBar; +import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.util.InjectionInflationController; import com.android.systemui.util.leak.GarbageMonitor; @@ -40,12 +41,20 @@ import dagger.Component; SystemUIModule.class, SystemUIDefaultModule.class}) public interface SystemUIRootComponent { + /** * Main dependency providing module. */ @Singleton Dependency.DependencyInjector createDependency(); + + /** + * Creates a ConfigurationController. + */ + @Singleton + ConfigurationController getConfigurationController(); + /** * Injects the StatusBar. */ diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java index 1a2d062f1b80..74b4f9537b87 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java @@ -39,13 +39,13 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.settingslib.applications.InterestingConfigChanges; -import com.android.systemui.ConfigurationChangedReceiver; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; import com.android.systemui.assist.ui.DefaultUiController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import javax.inject.Inject; @@ -55,7 +55,7 @@ import javax.inject.Singleton; * Class to manage everything related to assist in SystemUI. */ @Singleton -public class AssistManager implements ConfigurationChangedReceiver { +public class AssistManager { /** * Controls the UI for showing Assistant invocation progress. @@ -153,12 +153,40 @@ public class AssistManager implements ConfigurationChangedReceiver { } }; + private ConfigurationController.ConfigurationListener mConfigurationListener = + new ConfigurationController.ConfigurationListener() { + @Override + public void onConfigChanged(Configuration newConfig) { + if (!mInterestingConfigChanges.applyNewConfig(mContext.getResources())) { + return; + } + boolean visible = false; + if (mView != null) { + visible = mView.isShowing(); + mWindowManager.removeView(mView); + } + + mView = (AssistOrbContainer) LayoutInflater.from(mContext).inflate( + R.layout.assist_orb, null); + mView.setVisibility(View.GONE); + mView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + WindowManager.LayoutParams lp = getLayoutParams(); + mWindowManager.addView(mView, lp); + if (visible) { + mView.show(true /* show */, false /* animate */); + } + } + }; + @Inject public AssistManager( DeviceProvisionedController controller, Context context, AssistUtils assistUtils, - AssistHandleBehaviorController handleController) { + AssistHandleBehaviorController handleController, + ConfigurationController configurationController) { mContext = context; mDeviceProvisionedController = controller; mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); @@ -167,11 +195,13 @@ public class AssistManager implements ConfigurationChangedReceiver { mPhoneStateMonitor = new PhoneStateMonitor(context); mHandleController = handleController; + configurationController.addCallback(mConfigurationListener); + registerVoiceInteractionSessionListener(); mInterestingConfigChanges = new InterestingConfigChanges(ActivityInfo.CONFIG_ORIENTATION | ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_UI_MODE | ActivityInfo.CONFIG_SCREEN_LAYOUT | ActivityInfo.CONFIG_ASSETS_PATHS); - onConfigurationChanged(context.getResources().getConfiguration()); + mConfigurationListener.onConfigChanged(context.getResources().getConfiguration()); mShouldEnableOrb = !ActivityManager.isLowRamDeviceStatic(); mUiController = new DefaultUiController(mContext); @@ -221,29 +251,6 @@ public class AssistManager implements ConfigurationChangedReceiver { }); } - public void onConfigurationChanged(Configuration newConfiguration) { - if (!mInterestingConfigChanges.applyNewConfig(mContext.getResources())) { - return; - } - boolean visible = false; - if (mView != null) { - visible = mView.isShowing(); - mWindowManager.removeView(mView); - } - - mView = (AssistOrbContainer) LayoutInflater.from(mContext).inflate( - R.layout.assist_orb, null); - mView.setVisibility(View.GONE); - mView.setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - WindowManager.LayoutParams lp = getLayoutParams(); - mWindowManager.addView(mView, lp); - if (visible) { - mView.show(true /* show */, false /* animate */); - } - } - protected boolean shouldShowOrb() { return false; } diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java index b4cc571be061..bbf49e3d13d2 100644 --- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java +++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java @@ -20,11 +20,11 @@ import android.os.Handler; import android.util.ArrayMap; import android.view.View; -import com.android.systemui.ConfigurationChangedReceiver; import com.android.systemui.Dumpable; import com.android.systemui.SystemUIRootComponent; import com.android.systemui.qs.QSFragment; import com.android.systemui.statusbar.phone.NavigationBarFragment; +import com.android.systemui.statusbar.policy.ConfigurationController; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -41,7 +41,7 @@ import dagger.Subcomponent; * Also dispatches the configuration changes to all current FragmentHostStates. */ @Singleton -public class FragmentService implements ConfigurationChangedReceiver, Dumpable { +public class FragmentService implements Dumpable { private static final String TAG = "FragmentService"; @@ -50,10 +50,22 @@ public class FragmentService implements ConfigurationChangedReceiver, Dumpable { private final Handler mHandler = new Handler(); private final FragmentCreator mFragmentCreator; + private ConfigurationController.ConfigurationListener mConfigurationListener = + new ConfigurationController.ConfigurationListener() { + @Override + public void onConfigChanged(Configuration newConfig) { + for (FragmentHostState state : mHosts.values()) { + state.sendConfigurationChange(newConfig); + } + } + }; + @Inject - public FragmentService(SystemUIRootComponent rootComponent) { + public FragmentService(SystemUIRootComponent rootComponent, + ConfigurationController configurationController) { mFragmentCreator = rootComponent.createFragmentCreator(); initInjectionMap(); + configurationController.addCallback(mConfigurationListener); } ArrayMap getInjectionMap() { @@ -96,13 +108,6 @@ public class FragmentService implements ConfigurationChangedReceiver, Dumpable { } } - @Override - public void onConfigurationChanged(Configuration newConfig) { - for (FragmentHostState state : mHosts.values()) { - state.sendConfigurationChange(newConfig); - } - } - @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("Dumping fragments:"); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt index 424acfd9916b..54ef623e95ab 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt @@ -18,14 +18,11 @@ import android.content.Context import android.content.pm.ActivityInfo import android.content.res.Configuration import android.os.LocaleList - -import com.android.systemui.ConfigurationChangedReceiver import com.android.systemui.statusbar.policy.ConfigurationController import java.util.ArrayList -class ConfigurationControllerImpl(context: Context) - : ConfigurationController, ConfigurationChangedReceiver { +class ConfigurationControllerImpl(context: Context) : ConfigurationController { private val listeners: MutableList = ArrayList() private val lastConfig = Configuration() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java index 0e5c8c105df8..0a6cf7be736f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java @@ -24,7 +24,11 @@ import com.android.systemui.statusbar.policy.ConfigurationController.Configurati */ public interface ConfigurationController extends CallbackController { - public void notifyThemeChanged(); + /** Alert controller of a change in the configuration. */ + void onConfigurationChanged(Configuration newConfiguration); + + /** Alert controller of a change in between light and dark themes. */ + void notifyThemeChanged(); interface ConfigurationListener { default void onConfigChanged(Configuration newConfig) {} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index 7a09455017dd..2ad5a8aa7fe5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -61,7 +61,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.TelephonyIntents; import com.android.settingslib.net.DataUsageController; -import com.android.systemui.ConfigurationChangedReceiver; import com.android.systemui.DemoMode; import com.android.systemui.Dumpable; import com.android.systemui.R; @@ -87,8 +86,7 @@ import javax.inject.Singleton; /** Platform implementation of the network controller. **/ @Singleton public class NetworkControllerImpl extends BroadcastReceiver - implements NetworkController, DemoMode, DataUsageController.NetworkNameProvider, - ConfigurationChangedReceiver, Dumpable { + implements NetworkController, DemoMode, DataUsageController.NetworkNameProvider, Dumpable { // debug static final String TAG = "NetworkController"; static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -166,6 +164,14 @@ public class NetworkControllerImpl extends BroadcastReceiver private boolean mUserSetup; private boolean mSimDetected; + private ConfigurationController.ConfigurationListener mConfigurationListener = + new ConfigurationController.ConfigurationListener() { + @Override + public void onConfigChanged(Configuration newConfig) { + mConfig = Config.readConfig(mContext); + mReceiverHandler.post(() -> handleConfigurationChanged()); + } + }; /** * Construct this controller object and register for updates. */ @@ -553,16 +559,6 @@ public class NetworkControllerImpl extends BroadcastReceiver } } - public void onConfigurationChanged(Configuration newConfig) { - mConfig = Config.readConfig(mContext); - mReceiverHandler.post(new Runnable() { - @Override - public void run() { - handleConfigurationChanged(); - } - }); - } - @VisibleForTesting void handleConfigurationChanged() { updateMobileControllers(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java index b9d09ce91c1a..420acc507f19 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java @@ -36,8 +36,6 @@ import java.io.PrintWriter; public class DependencyTest extends SysuiTestCase { public static final DependencyKey DUMPABLE = new DependencyKey<>("dumpable"); - public static final DependencyKey CONFIGURATION_CHANGED_RECEIVER - = new DependencyKey<>("config_changed_receiver"); @Test public void testClassDependency() { @@ -62,15 +60,6 @@ public class DependencyTest extends SysuiTestCase { verify(d).dump(eq(null), any(), eq(null)); } - @Test - public void testConfigurationChanged() { - ConfigurationChangedReceiver d = mock(ConfigurationChangedReceiver.class); - mDependency.injectTestDependency(CONFIGURATION_CHANGED_RECEIVER, d); - Dependency.get(CONFIGURATION_CHANGED_RECEIVER); - mDependency.onConfigurationChanged(null); - verify(d).onConfigurationChanged(eq(null)); - } - @Test public void testInitDependency() { Dependency.clearDependencies(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java index 5ddf7a208379..f5ccac39ed20 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java +++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java @@ -14,6 +14,8 @@ package com.android.systemui.utils.leaks; +import android.content.res.Configuration; + import com.android.systemui.statusbar.policy.ConfigurationController; public class FakeConfigurationController @@ -24,6 +26,10 @@ public class FakeConfigurationController super(sysuiLeakCheck, "config"); } + @Override + public void onConfigurationChanged(Configuration newConfiguration) { + } + @Override public void notifyThemeChanged() { } -- GitLab From 24ee8ef61e696248f6bdcc23842418808e3630ef Mon Sep 17 00:00:00 2001 From: Kai Shi Date: Wed, 26 Feb 2020 15:46:56 -0800 Subject: [PATCH 115/219] Add EAP methods in wifi.proto To help find the root cause of high authentication failure rate in enterprise network, add EAP method and authentication phase2 method in connection event metrics. Bug: 150237135 Test: manual Test: atest com.android.server.wifi Merged-In: I7f3268b2842783f99c0a43d8b4996d0a7dd46c6e Change-Id: Id4ac7947871785d16b81c0806986f54d64fdb0ce --- proto/src/wifi.proto | 66 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto index 353a18756ca2..03495d2e8c40 100644 --- a/proto/src/wifi.proto +++ b/proto/src/wifi.proto @@ -635,6 +635,66 @@ message RouterFingerPrint { ROUTER_TECH_OTHER = 6; } + enum EapMethod { + + // No EAP method used + TYPE_EAP_UNKNOWN = 0; + + // EAP with Transport Layer Security + TYPE_EAP_TLS = 1; + + // EAP with Tunneled Transport Layer Security + TYPE_EAP_TTLS = 2; + + // EAP with Subscriber Identity Module [RFC-4186] + TYPE_EAP_SIM = 3; + + // EAP with Authentication and Key Agreement [RFC-4187] + TYPE_EAP_AKA = 4; + + // EAP with Authentication and Key Agreement Prime [RFC-5448] + TYPE_EAP_AKA_PRIME = 5; + + // Protected EAP + TYPE_EAP_PEAP = 6; + + // EAP for Hotspot 2.0 r2 OSEN + TYPE_EAP_UNAUTH_TLS = 7; + + // EAP with Password + TYPE_EAP_PWD = 8; + + // EAP with WAPI certifcate + TYPE_EAP_WAPI_CERT = 9; + } + + enum AuthPhase2Method { + + // No phase2 method + TYPE_PHASE2_NONE = 0; + + // Password Authentication Protocol + TYPE_PHASE2_PAP = 1; + + // Microsoft Challenge Handshake Authentication Protocol + TYPE_PHASE2_MSCHAP = 2; + + // Microsoft Challenge Handshake Authentication Protocol v2 + TYPE_PHASE2_MSCHAPV2 = 3; + + // Generic Token Card + TYPE_PHASE2_GTC = 4; + + // EAP-Subscriber Identity Module [RFC-4186] + TYPE_PHASE2_SIM = 5; + + // EAP-Authentication and Key Agreement [RFC-4187] + TYPE_PHASE2_AKA = 6; + + // EAP-Authentication and Key Agreement Prime [RFC-5448] + TYPE_PHASE2_AKA_PRIME = 7; + } + optional RoamType roam_type = 1; // Channel on which the connection takes place. @@ -657,6 +717,12 @@ message RouterFingerPrint { // If the router is a passpoint / hotspot 2.0 network optional bool passpoint = 8; + + // EAP method used by the enterprise network + optional EapMethod eap_method = 9; + + // Phase 2 authentication method after setting up a secure channel + optional AuthPhase2Method auth_phase2_method = 10; } message ConnectionEvent { -- GitLab From 96a9e48520fc2359a3cdd6b3513bf158d6844365 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Mon, 2 Mar 2020 17:09:44 -0800 Subject: [PATCH 116/219] Create different KeyId for saved and suggestion network Bug: 150500247 Test: atest android.net.wifi Merged-In: I31ee6f3a3295aca0bd7fcb83ce74327922977797 Change-Id: Ia416b2e986c86fe0a29641f6a20236802d72a233 --- .../android/net/wifi/WifiConfiguration.java | 14 ++++- .../net/wifi/WifiConfigurationTest.java | 61 +++++++++++++++++++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index ed416429a279..88f2bb2ad6e8 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -2113,15 +2113,23 @@ public class WifiConfiguration implements Parcelable { throw new IllegalStateException("Not an EAP network"); } - return trimStringForKeyId(SSID) + "_" + keyMgmt + "_" + - trimStringForKeyId(enterpriseConfig.getKeyId(current != null ? - current.enterpriseConfig : null)); + String keyId = trimStringForKeyId(SSID) + "_" + keyMgmt + "_" + + trimStringForKeyId(enterpriseConfig.getKeyId(current != null + ? current.enterpriseConfig : null)); + + if (!fromWifiNetworkSuggestion) { + return keyId; + } + return keyId + "_" + trimStringForKeyId(BSSID) + "_" + trimStringForKeyId(creatorName); } catch (NullPointerException e) { throw new IllegalStateException("Invalid config details"); } } private String trimStringForKeyId(String string) { + if (string == null) { + return ""; + } // Remove quotes and spaces return string.replace("\"", "").replace(" ", ""); } diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index ba9fc786afe7..f56cdc30af36 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -349,6 +349,67 @@ public class WifiConfigurationTest { assertTrue(exceptionThrown); } + /** + * Verifies that getKeyIdForCredentials returns the expected string for Suggestion Enterprise + * networks + * @throws Exception + */ + @Test + public void testGetKeyIdForCredentialsForSuggestion() throws Exception { + WifiConfiguration config = new WifiConfiguration(); + final String mSsid = "TestAP"; + final String packageName = "TestApp"; + final String bSsid = MacAddress.createRandomUnicastAddress().toString(); + String suggestionSuffix = "_" + bSsid + "_" + packageName; + config.SSID = mSsid; + config.fromWifiNetworkSuggestion = true; + config.creatorName = packageName; + config.BSSID = bSsid; + + // Test various combinations + // EAP with TLS + config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); + config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); + config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE); + String keyId = config.getKeyIdForCredentials(config); + assertEquals(keyId, mSsid + "_WPA_EAP_TLS_NULL" + suggestionSuffix); + + // EAP with TTLS & MSCHAPv2 + config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); + config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS); + config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2); + keyId = config.getKeyIdForCredentials(config); + assertEquals(keyId, mSsid + "_WPA_EAP_TTLS_MSCHAPV2" + suggestionSuffix); + + // Suite-B 192 with PWD & GTC + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192); + config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PWD); + config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC); + keyId = config.getKeyIdForCredentials(config); + assertEquals(keyId, mSsid + "_SUITE_B_192_PWD_GTC" + suggestionSuffix); + + // IEEE8021X with SIM + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); + config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM); + config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE); + keyId = config.getKeyIdForCredentials(config); + assertEquals(keyId, mSsid + "_IEEE8021X_SIM_NULL" + suggestionSuffix); + + // Try calling this method with non-Enterprise network, expect an exception + boolean exceptionThrown = false; + try { + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK); + config.preSharedKey = "TestPsk"; + keyId = config.getKeyIdForCredentials(config); + } catch (IllegalStateException e) { + exceptionThrown = true; + } + assertTrue(exceptionThrown); + } + /** * Verifies that getSsidAndSecurityTypeString returns the correct String for networks of * various different security types -- GitLab From dfa720a5e97f1f68209c708c3a1fd1294d57b459 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Wed, 4 Mar 2020 00:04:48 -0800 Subject: [PATCH 117/219] fix break build Bug: 150747236 Test: build Change-Id: Ic63771975d3d951548b3454d5971dc8cd817218d --- wifi/tests/src/android/net/wifi/WifiConfigurationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index f9bd6bb4e230..fe30ddd3765a 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -361,7 +361,7 @@ public class WifiConfigurationTest { WifiConfiguration config = new WifiConfiguration(); final String mSsid = "TestAP"; final String packageName = "TestApp"; - final String bSsid = MacAddress.createRandomUnicastAddress().toString(); + final String bSsid = MacAddressUtils.createRandomUnicastAddress().toString(); String suggestionSuffix = "_" + bSsid + "_" + packageName; config.SSID = mSsid; config.fromWifiNetworkSuggestion = true; -- GitLab From 2fd00cd4032c67242f26da16e24ccb51dac8ca48 Mon Sep 17 00:00:00 2001 From: Orion Hodson Date: Thu, 14 Nov 2019 18:18:30 +0000 Subject: [PATCH 118/219] Frameworks/base: Support dex2oat cpu-set system property Check dalvik.vm.dex2oat-cpu-set in AndroidRuntime and pass to ART with "--cpu-set=" as a compiler option, if found. Check dalvik.vm.image-dex2oat-cpu-set in AndroidRuntime and pass to ART with "--cpu-set=" as an image compiler option, if found. Bug: 141446571 Bug: 149395059 Test: manual Change-Id: Ica6a39048292d3d43aeb58d25f79f1398a7d5a79 Merged-In: Ica6a39048292d3d43aeb58d25f79f1398a7d5a79 (cherry picked from commit 870ce3f6d790f9c692b6d5e8872b33f5b642ea0b) --- core/jni/AndroidRuntime.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index cd0b340d489d..c2a7c79f714b 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -665,6 +665,8 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote) char dex2oatImageCompilerFilterBuf[sizeof("--compiler-filter=")-1 + PROPERTY_VALUE_MAX]; char dex2oatThreadsBuf[sizeof("-j")-1 + PROPERTY_VALUE_MAX]; char dex2oatThreadsImageBuf[sizeof("-j")-1 + PROPERTY_VALUE_MAX]; + char dex2oatCpuSetBuf[sizeof("--cpu-set=")-1 + PROPERTY_VALUE_MAX]; + char dex2oatCpuSetImageBuf[sizeof("--cpu-set=")-1 + PROPERTY_VALUE_MAX]; char dex2oat_isa_variant_key[PROPERTY_KEY_MAX]; char dex2oat_isa_variant[sizeof("--instruction-set-variant=") -1 + PROPERTY_VALUE_MAX]; char dex2oat_isa_features_key[PROPERTY_KEY_MAX]; @@ -937,6 +939,10 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote) parseCompilerOption("dalvik.vm.dex2oat-threads", dex2oatThreadsBuf, "-j", "-Xcompiler-option"); parseCompilerOption("dalvik.vm.image-dex2oat-threads", dex2oatThreadsImageBuf, "-j", "-Ximage-compiler-option"); + parseCompilerOption("dalvik.vm.dex2oat-cpu-set", dex2oatCpuSetBuf, "--cpu-set=", + "-Xcompiler-option"); + parseCompilerOption("dalvik.vm.image-dex2oat-cpu-set", dex2oatCpuSetImageBuf, "--cpu-set=", + "-Ximage-compiler-option"); // The runtime will compile a boot image, when necessary, not using installd. Thus, we need to // pass the instruction-set-features/variant as an image-compiler-option. -- GitLab From da78af4d6696dda77c692a7c6f2f49d4277cf341 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Tue, 3 Mar 2020 16:29:31 +0800 Subject: [PATCH 119/219] RESTRICT AUTOMERGE Use consistent calling uid and package in navigateUpTo Originally, if the caller of navigateUpTo is alive, even the calling uid is set to the caller who launched the existing destination activity, the uid from caller process has higher priority to replace the given calling uid. So this change doesn't modify the existing behavior if the caller process is valid. Besides, the case of delivering new intent uses the source record as calling identity too, so the case of starting new activity should be consistent. Also forbid attaching null application thread to avoid unexpected state in process record. Bug: 144285917 Test: atest ActivityStackTests#testNavigateUpTo Test: atest CtsSecurityTestCases:ActivityManagerTest# \ testActivityManager_attachNullApplication Change-Id: I60732f430256d37cb926d08d093581f051c4afed --- .../android/server/am/ActivityManagerService.java | 5 ++++- .../java/com/android/server/am/ActivityStack.java | 15 ++++++++++----- .../com/android/server/am/ActivityStackTests.java | 13 +++++++++++++ .../com/android/server/am/ActivityTestsBase.java | 2 ++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 7c57c43533af..13ec0133938b 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -7593,7 +7593,7 @@ public class ActivityManagerService extends IActivityManager.Stub } @GuardedBy("this") - private final boolean attachApplicationLocked(IApplicationThread thread, + private boolean attachApplicationLocked(@NonNull IApplicationThread thread, int pid, int callingUid, long startSeq) { // Find the application record that is being attached... either via @@ -7974,6 +7974,9 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public final void attachApplication(IApplicationThread thread, long startSeq) { + if (thread == null) { + throw new SecurityException("Invalid application interface"); + } synchronized (this) { int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 19ee3572d619..0fd8bb8d697a 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -3943,6 +3943,11 @@ class ActivityStack extends ConfigurationContai final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode, Intent resultData) { + if (srec.app == null || srec.app.thread == null) { + // Nothing to do if the caller is not attached, because this method should be called + // from an alive activity. + return false; + } final TaskRecord task = srec.getTask(); final ArrayList activities = task.mActivities; final int start = activities.indexOf(srec); @@ -3994,14 +3999,14 @@ class ActivityStack extends ConfigurationContai } if (parent != null && foundParentInTask) { + final int callingUid = srec.info.applicationInfo.uid; final int parentLaunchMode = parent.info.launchMode; final int destIntentFlags = destIntent.getFlags(); if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { - parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent, - srec.packageName); + parent.deliverNewIntentLocked(callingUid, destIntent, srec.packageName); } else { try { ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( @@ -4014,10 +4019,10 @@ class ActivityStack extends ConfigurationContai .setActivityInfo(aInfo) .setResultTo(parent.appToken) .setCallingPid(-1) - .setCallingUid(parent.launchedFromUid) - .setCallingPackage(parent.launchedFromPackage) + .setCallingUid(callingUid) + .setCallingPackage(srec.packageName) .setRealCallingPid(-1) - .setRealCallingUid(parent.launchedFromUid) + .setRealCallingUid(callingUid) .setComponentSpecified(true) .execute(); foundParentInTask = res == ActivityManager.START_SUCCESS; diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java index 01425ed51b55..55ece4cf03da 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java @@ -606,6 +606,19 @@ public class ActivityStackTests extends ActivityTestsBase { assertTrue(listener.changed); } + @Test + public void testNavigateUpTo() { + final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build(); + final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask) + .setUid(firstActivity.getUid() + 1).build(); + secondActivity.app.thread = null; + // This should do nothing from a non-attached caller (app.thread == null). + assertFalse(mStack.navigateUpToLocked(secondActivity /* source record */, + firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */)); + assertFalse(secondActivity.finishing); + assertFalse(firstActivity.finishing); + } + private void verifyShouldSleepActivities(boolean focusedStack, boolean keyguardGoingAway, boolean displaySleeping, boolean expected) { mSupervisor.mFocusedStack = focusedStack ? mStack : null; diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java index 1cd111fce0ec..6467dbd85701 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java @@ -192,6 +192,8 @@ public class ActivityTestsBase { aInfo.applicationInfo = new ApplicationInfo(); aInfo.applicationInfo.packageName = mComponent.getPackageName(); aInfo.applicationInfo.uid = mUid; + aInfo.packageName = mComponent.getPackageName(); + aInfo.name = mComponent.getClassName(); aInfo.flags |= mActivityFlags; final ActivityRecord activity = new ActivityRecord(mService, null /* caller */, -- GitLab From 1ec2f403e9552d4d43413231e436bbdfd9eec1ec Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Tue, 3 Mar 2020 18:12:10 +0800 Subject: [PATCH 120/219] RESTRICT AUTOMERGE Use consistent calling uid and package in navigateUpTo Originally, if the caller of navigateUpTo is alive, even the calling uid is set to the caller who launched the existing destination activity, the uid from caller process has higher priority to replace the given calling uid. So this change doesn't modify the existing behavior if the caller process is valid. Besides, the case of delivering new intent uses the source record as calling identity too, so the case of starting new activity should be consistent. Also forbid attaching null application thread to avoid unexpected state in process record. Bug: 144285917 Test: atest ActivityStackTests#testNavigateUpTo Test: atest CtsSecurityTestCases:ActivityManagerTest# \ testActivityManager_attachNullApplication Change-Id: I60732f430256d37cb926d08d093581f051c4afed --- .../server/am/ActivityManagerService.java | 5 ++- .../com/android/server/wm/ActivityStack.java | 15 ++++--- .../android/server/wm/ActivityStarter.java | 5 +++ .../android/server/wm/ActivityStackTests.java | 41 +++++++++++++++++-- .../android/server/wm/ActivityTestsBase.java | 1 + 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index c6cae530e795..f045274e43f7 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -4759,7 +4759,7 @@ public class ActivityManagerService extends IActivityManager.Stub } @GuardedBy("this") - private final boolean attachApplicationLocked(IApplicationThread thread, + private boolean attachApplicationLocked(@NonNull IApplicationThread thread, int pid, int callingUid, long startSeq) { // Find the application record that is being attached... either via @@ -5173,6 +5173,9 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public final void attachApplication(IApplicationThread thread, long startSeq) { + if (thread == null) { + throw new SecurityException("Invalid application interface"); + } synchronized (this) { int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index 6bed46226b42..764b92929de0 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -4241,6 +4241,11 @@ class ActivityStack extends ConfigurationContainer { final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode, Intent resultData) { + if (!srec.attachedToProcess()) { + // Nothing to do if the caller is not attached, because this method should be called + // from an alive activity. + return false; + } final TaskRecord task = srec.getTaskRecord(); final ArrayList activities = task.mActivities; final int start = activities.indexOf(srec); @@ -4294,14 +4299,14 @@ class ActivityStack extends ConfigurationContainer { } if (parent != null && foundParentInTask) { + final int callingUid = srec.info.applicationInfo.uid; final int parentLaunchMode = parent.info.launchMode; final int destIntentFlags = destIntent.getFlags(); if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { - parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent, - srec.packageName); + parent.deliverNewIntentLocked(callingUid, destIntent, srec.packageName); } else { try { ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( @@ -4314,10 +4319,10 @@ class ActivityStack extends ConfigurationContainer { .setActivityInfo(aInfo) .setResultTo(parent.appToken) .setCallingPid(-1) - .setCallingUid(parent.launchedFromUid) - .setCallingPackage(parent.launchedFromPackage) + .setCallingUid(callingUid) + .setCallingPackage(srec.packageName) .setRealCallingPid(-1) - .setRealCallingUid(parent.launchedFromUid) + .setRealCallingUid(callingUid) .setComponentSpecified(true) .execute(); foundParentInTask = res == ActivityManager.START_SUCCESS; diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 0a88eef86ea8..1ebfa46f1955 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -2743,6 +2743,11 @@ class ActivityStarter { return mRequest.intent; } + @VisibleForTesting + int getCallingUid() { + return mRequest.callingUid; + } + ActivityStarter setReason(String reason) { mRequest.reason = reason; return this; diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java index bde0ef6aa39e..ff27b9bb1c9e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -28,7 +28,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING; import static com.android.server.wm.ActivityStack.ActivityState.FINISHING; @@ -54,8 +54,11 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import android.app.ActivityManager; +import android.app.IApplicationThread; import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.os.UserHandle; @@ -82,8 +85,9 @@ public class ActivityStackTests extends ActivityTestsBase { @Before public void setUp() throws Exception { mDefaultDisplay = mRootActivityContainer.getDefaultDisplay(); - mStack = spy(mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, - true /* onTop */)); + mStack = mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, + true /* onTop */); + spyOn(mStack); mTask = new TaskBuilder(mSupervisor).setStack(mStack).build(); } @@ -1078,6 +1082,37 @@ public class ActivityStackTests extends ActivityTestsBase { assertTrue(listener.mChanged); } + @Test + public void testNavigateUpTo() { + final ActivityStartController controller = mock(ActivityStartController.class); + final ActivityStarter starter = new ActivityStarter(controller, + mService, mService.mStackSupervisor, mock(ActivityStartInterceptor.class)); + doReturn(controller).when(mService).getActivityStartController(); + spyOn(starter); + doReturn(ActivityManager.START_SUCCESS).when(starter).execute(); + + final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build(); + final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask) + .setUid(firstActivity.getUid() + 1).build(); + doReturn(starter).when(controller).obtainStarter(eq(firstActivity.intent), anyString()); + + final IApplicationThread thread = secondActivity.app.getThread(); + secondActivity.app.setThread(null); + // This should do nothing from a non-attached caller. + assertFalse(mStack.navigateUpToLocked(secondActivity /* source record */, + firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */)); + + secondActivity.app.setThread(thread); + assertTrue(mStack.navigateUpToLocked(secondActivity /* source record */, + firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */)); + // The firstActivity uses default launch mode, so the activities between it and itself will + // be finished. + assertTrue(secondActivity.finishing); + assertTrue(firstActivity.finishing); + // The calling uid of the new activity should be the current real caller. + assertEquals(secondActivity.getUid(), starter.getCallingUid()); + } + private void verifyShouldSleepActivities(boolean focusedStack, boolean keyguardGoingAway, boolean displaySleeping, boolean expected) { final ActivityDisplay display = mock(ActivityDisplay.class); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java index 4986a6d5bd0d..1d366259b590 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java @@ -265,6 +265,7 @@ class ActivityTestsBase { aInfo.applicationInfo.packageName = mComponent.getPackageName(); aInfo.applicationInfo.uid = mUid; aInfo.packageName = mComponent.getPackageName(); + aInfo.name = mComponent.getClassName(); if (mTargetActivity != null) { aInfo.targetActivity = mTargetActivity; } -- GitLab From 60a6583adfdb50df1643e0df2dc37096f977a483 Mon Sep 17 00:00:00 2001 From: Linus Tufvesson Date: Tue, 4 Feb 2020 16:41:06 +0000 Subject: [PATCH 121/219] RESTRICT AUTOMERGE Block TYPE_PRESENTATION windows on default display ... and any other display that isn't considered a public presentation display, as per Display.isPublicPresentation() Bug: 141745510 Test: cts-tradefed run cts -m CtsWindowManagerDeviceTestCases -t android.server.wm.PresentationTest Change-Id: I2aaab1903dee54190338f7b6e49888aa51437108 --- core/java/android/app/Presentation.java | 16 +++++++++------- .../android/server/wm/WindowManagerService.java | 8 ++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java index cb72d4d5dc2c..b3a39f5025c7 100644 --- a/core/java/android/app/Presentation.java +++ b/core/java/android/app/Presentation.java @@ -26,18 +26,18 @@ import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.os.Binder; +import android.os.Handler; import android.os.IBinder; +import android.os.Message; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.Gravity; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; -import android.os.Handler; -import android.os.Message; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.TypedValue; /** * Base class for presentations. @@ -116,7 +116,9 @@ import android.util.TypedValue; * The display manager keeps track of all displays in the system. However, not all * displays are appropriate for showing presentations. For example, if an activity * attempted to show a presentation on the main display it might obscure its own content - * (it's like opening a dialog on top of your activity). + * (it's like opening a dialog on top of your activity). Creating a presentation on the main + * display will result in {@link android.view.WindowManager.InvalidDisplayException} being thrown + * when invoking {@link #show()}. *

* Here's how to identify suitable displays for showing presentations using * {@link DisplayManager#getDisplays(String)} and the @@ -243,7 +245,7 @@ public class Presentation extends Dialog { /** * Inherited from {@link Dialog#show}. Will throw * {@link android.view.WindowManager.InvalidDisplayException} if the specified secondary - * {@link Display} can't be found. + * {@link Display} can't be found or if it does not have {@link Display#FLAG_PRESENTATION} set. */ @Override public void show() { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 436a5c729b86..2de8ae155f81 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -60,6 +60,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_DREAM; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; +import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; @@ -1276,6 +1277,13 @@ public class WindowManagerService extends IWindowManager.Stub return WindowManagerGlobal.ADD_PERMISSION_DENIED; } + if (type == TYPE_PRESENTATION && !displayContent.getDisplay().isPublicPresentation()) { + Slog.w(TAG_WM, + "Attempted to add presentation window to a non-suitable display. " + + "Aborting."); + return WindowManagerGlobal.ADD_INVALID_DISPLAY; + } + AppWindowToken atoken = null; final boolean hasParent = parentWindow != null; // Use existing parent window token for child windows since they go in the same token -- GitLab From bf89805ea34cc6232a34538bad9e00d51b3672eb Mon Sep 17 00:00:00 2001 From: Linus Tufvesson Date: Tue, 4 Feb 2020 16:41:06 +0000 Subject: [PATCH 122/219] RESTRICT AUTOMERGE Block TYPE_PRESENTATION windows on default display ... and any other display that isn't considered a public presentation display, as per Display.isPublicPresentation() Bug: 141745510 Test: cts-tradefed run cts -m CtsActivityManagerDeviceTestCases -t android.server.am.PresentationTest Change-Id: I2aaab1903dee54190338f7b6e49888aa51437108 --- core/java/android/app/Presentation.java | 16 +++++++++------- .../android/server/wm/WindowManagerService.java | 8 ++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java index af55788e617f..bc2b250328a6 100644 --- a/core/java/android/app/Presentation.java +++ b/core/java/android/app/Presentation.java @@ -25,18 +25,18 @@ import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.os.Binder; +import android.os.Handler; import android.os.IBinder; +import android.os.Message; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.Gravity; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; -import android.os.Handler; -import android.os.Message; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.TypedValue; /** * Base class for presentations. @@ -115,7 +115,9 @@ import android.util.TypedValue; * The display manager keeps track of all displays in the system. However, not all * displays are appropriate for showing presentations. For example, if an activity * attempted to show a presentation on the main display it might obscure its own content - * (it's like opening a dialog on top of your activity). + * (it's like opening a dialog on top of your activity). Creating a presentation on the main + * display will result in {@link android.view.WindowManager.InvalidDisplayException} being thrown + * when invoking {@link #show()}. *

* Here's how to identify suitable displays for showing presentations using * {@link DisplayManager#getDisplays(String)} and the @@ -242,7 +244,7 @@ public class Presentation extends Dialog { /** * Inherited from {@link Dialog#show}. Will throw * {@link android.view.WindowManager.InvalidDisplayException} if the specified secondary - * {@link Display} can't be found. + * {@link Display} can't be found or if it does not have {@link Display#FLAG_PRESENTATION} set. */ @Override public void show() { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 8b4a2dd36e6c..b438d044d102 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -55,6 +55,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_DREAM; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; +import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; @@ -1182,6 +1183,13 @@ public class WindowManagerService extends IWindowManager.Stub return WindowManagerGlobal.ADD_PERMISSION_DENIED; } + if (type == TYPE_PRESENTATION && !displayContent.getDisplay().isPublicPresentation()) { + Slog.w(TAG_WM, + "Attempted to add presentation window to a non-suitable display. " + + "Aborting."); + return WindowManagerGlobal.ADD_INVALID_DISPLAY; + } + AppWindowToken atoken = null; final boolean hasParent = parentWindow != null; // Use existing parent window token for child windows since they go in the same token -- GitLab From 06a7bf9e9e1ae1b6b5a162fa664ad5ed5670ad74 Mon Sep 17 00:00:00 2001 From: Heemin Seog Date: Wed, 4 Mar 2020 12:19:37 -0800 Subject: [PATCH 123/219] DO NOT MERGE Set the sensor threshold only if sensor exists Bug: 150779130 Test: atest SystemUITests and manual test for automotive Change-Id: I18e3584c66f1286713a6fdadc678a9048869913b --- .../SystemUI/src/com/android/systemui/doze/DozeSensors.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java index b7c8f707b850..e6cbab26c655 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java @@ -305,7 +305,7 @@ public class DozeSensors { mContext.getResources()); } else { sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); - mSensorThreshold = sensor.getMaximumRange(); + mSensorThreshold = sensor == null ? 0 : sensor.getMaximumRange(); } mSensor = sensor; } -- GitLab From 04b394d07b4a54ba595e630344d4c33e47388a4f Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Tue, 17 Dec 2019 00:33:18 +0800 Subject: [PATCH 124/219] Remove framework code that has moved to frameworks/libs/net Add srcs to framework and change import path. Remove the codes which are moved to frameworks/libs/net. Bug: 139268426 Bug: 135998869 Bug: 138306002 Bug: 143925787 Test: atest FrameworksNetTests atest FrameworksTelephonyTests ./frameworks/opt/net/wifi/tests/wifitests/runtests.sh Change-Id: I44e0a8361637c2d43be2e5d033d405b22e1a149c Merged-In: I067cdc404e5a63947c19cb75069a39ae42faa3c8 Merged-In: Ieb8927f9af7f87a5ae038bd6c7daeb3d70117fef --- core/java/android/net/LinkProperties.java | 76 ++---------------- core/java/android/net/MacAddress.java | 79 ++----------------- core/java/android/net/NetworkUtils.java | 10 --- core/java/android/net/RouteInfo.java | 17 +--- .../android/server/ConnectivityService.java | 2 +- .../java/android/net/LinkPropertiesTest.java | 2 +- .../net/java/android/net/MacAddressTest.java | 12 +-- .../android/net/wifi/WifiConfiguration.java | 5 +- .../net/wifi/WifiConfigurationTest.java | 8 +- 9 files changed, 32 insertions(+), 179 deletions(-) diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index d25ee0e69e88..732ceb560cab 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -21,6 +21,8 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.net.util.LinkPropertiesUtils; +import android.net.util.LinkPropertiesUtils.CompareResult; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -90,36 +92,6 @@ public final class LinkProperties implements Parcelable { // Indexed by interface name to allow modification and to prevent duplicates being added. private Hashtable mStackedLinks = new Hashtable<>(); - /** - * @hide - */ - public static class CompareResult { - public final List removed = new ArrayList<>(); - public final List added = new ArrayList<>(); - - public CompareResult() {} - - public CompareResult(Collection oldItems, Collection newItems) { - if (oldItems != null) { - removed.addAll(oldItems); - } - if (newItems != null) { - for (T newItem : newItems) { - if (!removed.remove(newItem)) { - added.add(newItem); - } - } - } - } - - @Override - public String toString() { - return "removed=[" + TextUtils.join(",", removed) - + "] added=[" + TextUtils.join(",", added) - + "]"; - } - } - /** * @hide */ @@ -1326,7 +1298,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalInterfaceName(@NonNull LinkProperties target) { - return TextUtils.equals(getInterfaceName(), target.getInterfaceName()); + return LinkPropertiesUtils.isIdenticalInterfaceName(target, this); } /** @@ -1349,10 +1321,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalAddresses(@NonNull LinkProperties target) { - Collection targetAddresses = target.getAddresses(); - Collection sourceAddresses = getAddresses(); - return (sourceAddresses.size() == targetAddresses.size()) ? - sourceAddresses.containsAll(targetAddresses) : false; + return LinkPropertiesUtils.isIdenticalAddresses(target, this); } /** @@ -1364,15 +1333,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalDnses(@NonNull LinkProperties target) { - Collection targetDnses = target.getDnsServers(); - String targetDomains = target.getDomains(); - if (mDomains == null) { - if (targetDomains != null) return false; - } else { - if (!mDomains.equals(targetDomains)) return false; - } - return (mDnses.size() == targetDnses.size()) ? - mDnses.containsAll(targetDnses) : false; + return LinkPropertiesUtils.isIdenticalDnses(target, this); } /** @@ -1425,9 +1386,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalRoutes(@NonNull LinkProperties target) { - Collection targetRoutes = target.getRoutes(); - return (mRoutes.size() == targetRoutes.size()) ? - mRoutes.containsAll(targetRoutes) : false; + return LinkPropertiesUtils.isIdenticalRoutes(target, this); } /** @@ -1439,8 +1398,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public boolean isIdenticalHttpProxy(@NonNull LinkProperties target) { - return getHttpProxy() == null ? target.getHttpProxy() == null : - getHttpProxy().equals(target.getHttpProxy()); + return LinkPropertiesUtils.isIdenticalHttpProxy(target, this); } /** @@ -1662,26 +1620,6 @@ public final class LinkProperties implements Parcelable { && isIdenticalCaptivePortalData(target); } - /** - * Compares the addresses in this LinkProperties with another - * LinkProperties, examining only addresses on the base link. - * - * @param target a LinkProperties with the new list of addresses - * @return the differences between the addresses. - * @hide - */ - public @NonNull CompareResult compareAddresses(@Nullable LinkProperties target) { - /* - * Duplicate the LinkAddresses into removed, we will be removing - * address which are common between mLinkAddresses and target - * leaving the addresses that are different. And address which - * are in target but not in mLinkAddresses are placed in the - * addedAddresses. - */ - return new CompareResult<>(mLinkAddresses, - target != null ? target.getLinkAddresses() : null); - } - /** * Compares the DNS addresses in this LinkProperties with another * LinkProperties, examining only DNS addresses on the base link. diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java index 74c9aac05b41..0e10c42e61db 100644 --- a/core/java/android/net/MacAddress.java +++ b/core/java/android/net/MacAddress.java @@ -20,11 +20,11 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.net.util.MacAddressUtils; import android.net.wifi.WifiInfo; import android.os.Parcel; import android.os.Parcelable; -import com.android.internal.util.BitUtils; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; @@ -33,7 +33,6 @@ import java.net.Inet6Address; import java.net.UnknownHostException; import java.security.SecureRandom; import java.util.Arrays; -import java.util.Random; /** * Representation of a MAC address. @@ -109,20 +108,12 @@ public final class MacAddress implements Parcelable { if (equals(BROADCAST_ADDRESS)) { return TYPE_BROADCAST; } - if (isMulticastAddress()) { + if ((mAddr & MULTICAST_MASK) != 0) { return TYPE_MULTICAST; } return TYPE_UNICAST; } - /** - * @return true if this MacAddress is a multicast address. - * @hide - */ - public boolean isMulticastAddress() { - return (mAddr & MULTICAST_MASK) != 0; - } - /** * @return true if this MacAddress is a locally assigned address. */ @@ -192,7 +183,7 @@ public final class MacAddress implements Parcelable { * @hide */ public static boolean isMacAddress(byte[] addr) { - return addr != null && addr.length == ETHER_ADDR_LEN; + return MacAddressUtils.isMacAddress(addr); } /** @@ -261,26 +252,11 @@ public final class MacAddress implements Parcelable { } private static byte[] byteAddrFromLongAddr(long addr) { - byte[] bytes = new byte[ETHER_ADDR_LEN]; - int index = ETHER_ADDR_LEN; - while (index-- > 0) { - bytes[index] = (byte) addr; - addr = addr >> 8; - } - return bytes; + return MacAddressUtils.byteAddrFromLongAddr(addr); } private static long longAddrFromByteAddr(byte[] addr) { - Preconditions.checkNotNull(addr); - if (!isMacAddress(addr)) { - throw new IllegalArgumentException( - Arrays.toString(addr) + " was not a valid MAC address"); - } - long longAddr = 0; - for (byte b : addr) { - longAddr = (longAddr << 8) + BitUtils.uint8(b); - } - return longAddr; + return MacAddressUtils.longAddrFromByteAddr(addr); } // Internal conversion function equivalent to longAddrFromByteAddr(byteAddrFromStringAddr(addr)) @@ -350,50 +326,7 @@ public final class MacAddress implements Parcelable { * @hide */ public static @NonNull MacAddress createRandomUnicastAddressWithGoogleBase() { - return createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom()); - } - - /** - * Returns a generated MAC address whose 46 bits, excluding the locally assigned bit and the - * unicast bit, are randomly selected. - * - * The locally assigned bit is always set to 1. The multicast bit is always set to 0. - * - * @return a random locally assigned, unicast MacAddress. - * - * @hide - */ - public static @NonNull MacAddress createRandomUnicastAddress() { - return createRandomUnicastAddress(null, new SecureRandom()); - } - - /** - * Returns a randomly generated MAC address using the given Random object and the same - * OUI values as the given MacAddress. - * - * The locally assigned bit is always set to 1. The multicast bit is always set to 0. - * - * @param base a base MacAddress whose OUI is used for generating the random address. - * If base == null then the OUI will also be randomized. - * @param r a standard Java Random object used for generating the random address. - * @return a random locally assigned MacAddress. - * - * @hide - */ - public static @NonNull MacAddress createRandomUnicastAddress(MacAddress base, Random r) { - long addr; - if (base == null) { - addr = r.nextLong() & VALID_LONG_MASK; - } else { - addr = (base.mAddr & OUI_MASK) | (NIC_MASK & r.nextLong()); - } - addr |= LOCALLY_ASSIGNED_MASK; - addr &= ~MULTICAST_MASK; - MacAddress mac = new MacAddress(addr); - if (mac.equals(DEFAULT_MAC_ADDRESS)) { - return createRandomUnicastAddress(base, r); - } - return mac; + return MacAddressUtils.createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom()); } // Convenience function for working around the lack of byte literals. diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java index 08cc4e24b245..779f7bc91e8f 100644 --- a/core/java/android/net/NetworkUtils.java +++ b/core/java/android/net/NetworkUtils.java @@ -31,7 +31,6 @@ import android.util.Pair; import java.io.FileDescriptor; import java.math.BigInteger; import java.net.Inet4Address; -import java.net.Inet6Address; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; @@ -312,15 +311,6 @@ public class NetworkUtils { return new Pair(address, prefixLength); } - /** - * Check if IP address type is consistent between two InetAddress. - * @return true if both are the same type. False otherwise. - */ - public static boolean addressTypeMatches(InetAddress left, InetAddress right) { - return (((left instanceof Inet4Address) && (right instanceof Inet4Address)) || - ((left instanceof Inet6Address) && (right instanceof Inet6Address))); - } - /** * Convert a 32 char hex string into a Inet6Address. * throws a runtime exception if the string isn't 32 chars, isn't hex or can't be diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java index 67bad532cd0d..2b9e9fe81b1b 100644 --- a/core/java/android/net/RouteInfo.java +++ b/core/java/android/net/RouteInfo.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.net.util.NetUtils; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -483,21 +484,7 @@ public final class RouteInfo implements Parcelable { @UnsupportedAppUsage @Nullable public static RouteInfo selectBestRoute(Collection routes, InetAddress dest) { - if ((routes == null) || (dest == null)) return null; - - RouteInfo bestRoute = null; - // pick a longest prefix match under same address type - for (RouteInfo route : routes) { - if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) { - if ((bestRoute != null) && - (bestRoute.mDestination.getPrefixLength() >= - route.mDestination.getPrefixLength())) { - continue; - } - if (route.matches(dest)) bestRoute = route; - } - } - return bestRoute; + return NetUtils.selectBestRoute(routes, dest); } /** diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index a3fb55cec5e8..e0a1bd971b0c 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -89,7 +89,6 @@ import android.net.InetAddresses; import android.net.IpMemoryStore; import android.net.IpPrefix; import android.net.LinkProperties; -import android.net.LinkProperties.CompareResult; import android.net.MatchAllNetworkSpecifier; import android.net.NattSocketKeepalive; import android.net.Network; @@ -124,6 +123,7 @@ import android.net.metrics.IpConnectivityLog; import android.net.metrics.NetworkEvent; import android.net.netlink.InetDiagMessage; import android.net.shared.PrivateDnsConfig; +import android.net.util.LinkPropertiesUtils.CompareResult; import android.net.util.MultinetworkPolicyTracker; import android.net.util.NetdService; import android.os.Binder; diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java index 6ec2cd632872..48b65e592f39 100644 --- a/tests/net/common/java/android/net/LinkPropertiesTest.java +++ b/tests/net/common/java/android/net/LinkPropertiesTest.java @@ -27,8 +27,8 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import android.net.LinkProperties.CompareResult; import android.net.LinkProperties.ProvisioningChange; +import android.net.util.LinkPropertiesUtils.CompareResult; import android.system.OsConstants; import android.util.ArraySet; diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java index daf187d01533..91c9a2a38036 100644 --- a/tests/net/java/android/net/MacAddressTest.java +++ b/tests/net/java/android/net/MacAddressTest.java @@ -22,6 +22,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.net.util.MacAddressUtils; + import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -122,11 +124,11 @@ public class MacAddressTest { for (MacAddress mac : multicastAddresses) { String msg = mac.toString() + " expected to be a multicast address"; - assertTrue(msg, mac.isMulticastAddress()); + assertTrue(msg, MacAddressUtils.isMulticastAddress(mac)); } for (MacAddress mac : unicastAddresses) { String msg = mac.toString() + " expected not to be a multicast address"; - assertFalse(msg, mac.isMulticastAddress()); + assertFalse(msg, MacAddressUtils.isMulticastAddress(mac)); } } @@ -156,7 +158,7 @@ public class MacAddressTest { public void testMacAddressConversions() { final int iterations = 10000; for (int i = 0; i < iterations; i++) { - MacAddress mac = MacAddress.createRandomUnicastAddress(); + MacAddress mac = MacAddressUtils.createRandomUnicastAddress(); String stringRepr = mac.toString(); byte[] bytesRepr = mac.toByteArray(); @@ -188,7 +190,7 @@ public class MacAddressTest { final String expectedLocalOui = "26:5f:78"; final MacAddress base = MacAddress.fromString(anotherOui + ":0:0:0"); for (int i = 0; i < iterations; i++) { - MacAddress mac = MacAddress.createRandomUnicastAddress(base, r); + MacAddress mac = MacAddressUtils.createRandomUnicastAddress(base, r); String stringRepr = mac.toString(); assertTrue(stringRepr + " expected to be a locally assigned address", @@ -199,7 +201,7 @@ public class MacAddressTest { } for (int i = 0; i < iterations; i++) { - MacAddress mac = MacAddress.createRandomUnicastAddress(); + MacAddress mac = MacAddressUtils.createRandomUnicastAddress(); String stringRepr = mac.toString(); assertTrue(stringRepr + " expected to be a locally assigned address", diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 933dded815b9..ce49ab1208b0 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -28,6 +28,7 @@ import android.net.NetworkSpecifier; import android.net.ProxyInfo; import android.net.StaticIpConfiguration; import android.net.Uri; +import android.net.util.MacAddressUtils; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -1037,7 +1038,7 @@ public class WifiConfiguration implements Parcelable { * @return true if mac is good to use */ public static boolean isValidMacAddressForRandomization(MacAddress mac) { - return mac != null && !mac.isMulticastAddress() && mac.isLocallyAssigned() + return mac != null && !MacAddressUtils.isMulticastAddress(mac) && mac.isLocallyAssigned() && !MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS).equals(mac); } @@ -1051,7 +1052,7 @@ public class WifiConfiguration implements Parcelable { int randomMacGenerationCount = 0; while (!isValidMacAddressForRandomization(mRandomizedMacAddress) && randomMacGenerationCount < MAXIMUM_RANDOM_MAC_GENERATION_RETRY) { - mRandomizedMacAddress = MacAddress.createRandomUnicastAddress(); + mRandomizedMacAddress = MacAddressUtils.createRandomUnicastAddress(); randomMacGenerationCount++; } diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index ba9fc786afe7..15aa3cc4a355 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import android.net.MacAddress; +import android.net.util.MacAddressUtils; import android.net.wifi.WifiConfiguration.KeyMgmt; import android.net.wifi.WifiConfiguration.NetworkSelectionStatus; import android.os.Parcel; @@ -62,7 +63,8 @@ public class WifiConfigurationTest { config.updateIdentifier = "1234"; config.fromWifiNetworkSpecifier = true; config.fromWifiNetworkSuggestion = true; - MacAddress macBeforeParcel = config.getOrCreateRandomizedMacAddress(); + config.setRandomizedMacAddress(MacAddressUtils.createRandomUnicastAddress()); + MacAddress macBeforeParcel = config.getRandomizedMacAddress(); Parcel parcelW = Parcel.obtain(); config.writeToParcel(parcelW, 0); byte[] bytes = parcelW.marshall(); @@ -75,7 +77,7 @@ public class WifiConfigurationTest { // lacking a useful config.equals, check two fields near the end. assertEquals(cookie, reconfig.getMoTree()); - assertEquals(macBeforeParcel, reconfig.getOrCreateRandomizedMacAddress()); + assertEquals(macBeforeParcel, reconfig.getRandomizedMacAddress()); assertEquals(config.updateIdentifier, reconfig.updateIdentifier); assertFalse(reconfig.trusted); assertTrue(config.fromWifiNetworkSpecifier); @@ -211,7 +213,7 @@ public class WifiConfigurationTest { MacAddress defaultMac = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); assertEquals(defaultMac, config.getRandomizedMacAddress()); - MacAddress macToChangeInto = MacAddress.createRandomUnicastAddress(); + MacAddress macToChangeInto = MacAddressUtils.createRandomUnicastAddress(); config.setRandomizedMacAddress(macToChangeInto); MacAddress macAfterChange = config.getRandomizedMacAddress(); -- GitLab From 2b05cccddfe4a57f5e3ecb83be16e3f88c052849 Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Wed, 4 Mar 2020 14:15:52 -0800 Subject: [PATCH 125/219] Animate cuttout protection Bug: 145095085 Change-Id: Ida54d4369a2cb8c300cbeb90f0d7f3e4b562be42 Merged-In: Ida54d4369a2cb8c300cbeb90f0d7f3e4b562be42 --- .../android/systemui/ScreenDecorations.java | 46 +++++++++++++++---- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index 3a8524a3ee7d..022a254ca937 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -26,8 +26,10 @@ import static com.android.systemui.tuner.TunablePadding.FLAG_END; import static com.android.systemui.tuner.TunablePadding.FLAG_START; import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; import android.annotation.Dimension; import android.annotation.NonNull; import android.app.ActivityManager; @@ -869,6 +871,8 @@ public class ScreenDecorations extends SystemUI implements Tunable, public static class DisplayCutoutView extends View implements DisplayManager.DisplayListener, RegionInterceptableView { + private static final float HIDDEN_CAMERA_PROTECTION_SCALE = 0.5f; + private final DisplayInfo mInfo = new DisplayInfo(); private final Paint mPaint = new Paint(); private final List mBounds = new ArrayList(); @@ -888,6 +892,8 @@ public class ScreenDecorations extends SystemUI implements Tunable, private int mColor = Color.BLACK; private boolean mStart; private int mRotation; + private float mCameraProtectionProgress = HIDDEN_CAMERA_PROTECTION_SCALE; + private ValueAnimator mCameraProtectionAnimator; public DisplayCutoutView(Context context, boolean start, Runnable visibilityChangedListener, ScreenDecorations decorations) { @@ -928,17 +934,18 @@ public class ScreenDecorations extends SystemUI implements Tunable, getLocationOnScreen(mLocation); canvas.translate(-mLocation[0], -mLocation[1]); - if (mShowProtection && !mProtectionRect.isEmpty()) { - mPaint.setColor(mColor); - mPaint.setStyle(Paint.Style.FILL); - mPaint.setAntiAlias(true); - canvas.drawPath(mProtectionPath, mPaint); - } else if (!mBoundingPath.isEmpty()) { + if (!mBoundingPath.isEmpty()) { mPaint.setColor(mColor); mPaint.setStyle(Paint.Style.FILL); mPaint.setAntiAlias(true); canvas.drawPath(mBoundingPath, mPaint); } + if (mCameraProtectionProgress > HIDDEN_CAMERA_PROTECTION_SCALE + && !mProtectionRect.isEmpty()) { + canvas.scale(mCameraProtectionProgress, mCameraProtectionProgress, + mProtectionRect.centerX(), mProtectionRect.centerY()); + canvas.drawPath(mProtectionPath, mPaint); + } } @Override @@ -973,8 +980,31 @@ public class ScreenDecorations extends SystemUI implements Tunable, mShowProtection = shouldShow; updateBoundingPath(); - requestLayout(); - invalidate(); + // Delay the relayout until the end of the animation when hiding the cutout, + // otherwise we'd clip it. + if (mShowProtection) { + requestLayout(); + } + if (mCameraProtectionAnimator != null) { + mCameraProtectionAnimator.cancel(); + } + mCameraProtectionAnimator = ValueAnimator.ofFloat(mCameraProtectionProgress, + mShowProtection ? 1.0f : HIDDEN_CAMERA_PROTECTION_SCALE).setDuration(750); + mCameraProtectionAnimator.setInterpolator(Interpolators.DECELERATE_QUINT); + mCameraProtectionAnimator.addUpdateListener(animation -> { + mCameraProtectionProgress = (float) animation.getAnimatedValue(); + invalidate(); + }); + mCameraProtectionAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mCameraProtectionAnimator = null; + if (!mShowProtection) { + requestLayout(); + } + } + }); + mCameraProtectionAnimator.start(); } private boolean isStart() { -- GitLab From 16dfe7bfd80768bfd8228e5ea4a7119af2230edc Mon Sep 17 00:00:00 2001 From: Chris Tate Date: Fri, 6 Mar 2020 03:35:09 +0000 Subject: [PATCH 126/219] Revert "[automerger skipped] Merge "DO NOT MERGE - Kill apps out..." Revert "DO NOT MERGE - Track framework changes to crashApplicati..." Revert "[automerger skipped] Merge "DO NOT MERGE - Add test of f..." Revert submission 10557201-am-f98a6c51a74d42d6bc57f980bd694e3e Reason for revert: Should not have been automerged from qt-dev; the whole topic should have been skipped. Reverted Changes: I01c0b570b:[automerger skipped] Merge "DO NOT MERGE - Add tes... I7451c89d1:DO NOT MERGE - Track framework changes to crashApp... Iec866858c:DO NOT MERGE - Track framework changes to crashApp... I200606752:[automerger skipped] Merge "DO NOT MERGE - Kill ap... Change-Id: Ib0ecc5fc825a7c6f38679d1818178869d6cef23e -- GitLab From a9bb977a7158b010920228f287b07e5023634951 Mon Sep 17 00:00:00 2001 From: Chris Tate Date: Fri, 6 Mar 2020 03:54:52 +0000 Subject: [PATCH 127/219] Revert "[automerger skipped] Merge "DO NOT MERGE - Kill apps out..." Revert "[automerger skipped] Merge "DO NOT MERGE - Add test of f..." Revert "DO NOT MERGE - Track framework changes to crashApplicati..." Revert submission 10556828-am-2e2e7004e4cb4ef8b776d65e9ffe33f3 Reason for revert: Should never have automerged downstream from qt-dev; the entire topic should have been skipped. Reverted Changes: I241d8d8da:DO NOT MERGE - Track framework changes to crashApp... Ib1a5695f9:[automerger skipped] Merge "DO NOT MERGE - Add tes... I3e6eb3f5c:[automerger skipped] Merge "DO NOT MERGE - Kill ap... Ibe4652916:DO NOT MERGE - Track framework changes to crashApp... Change-Id: I4d73e88c87891af1540dfd95c9e9bc3c39b11531 -- GitLab From 377838b451d53ed2e8cd9fc751e989d6ab877e18 Mon Sep 17 00:00:00 2001 From: Evan Laird Date: Fri, 6 Mar 2020 16:55:46 -0500 Subject: [PATCH 128/219] Reset protection path on rotation Fixes the issue where camera cutout protection paths were accruing rotation by not caching the unmodified path. Fixes: 150531720 Test: manual Change-Id: I0cece9900e86dc553401200346dc964c562b0ce0 --- .../android/systemui/CameraAvailabilityListener.kt | 2 +- .../src/com/android/systemui/ScreenDecorations.java | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt b/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt index 24fa91b9e838..284074e76ae2 100644 --- a/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt +++ b/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt @@ -26,7 +26,7 @@ import java.util.concurrent.Executor import kotlin.math.roundToInt -const val TAG = "CameraOpTransitionController" +const val TAG = "CameraAvailabilityListener" /** * Listens for usage of the Camera and controls the ScreenDecorations transition to show extra diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index 022a254ca937..6ea6a748ae8d 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -878,9 +878,10 @@ public class ScreenDecorations extends SystemUI implements Tunable, private final List mBounds = new ArrayList(); private final Rect mBoundingRect = new Rect(); private final Path mBoundingPath = new Path(); - // Don't initialize these because they are cached elsewhere and may not exist + // Don't initialize these yet because they may never exist private Rect mProtectionRect; private Path mProtectionPath; + private Path mProtectionPathOrig; private Rect mTotalBounds = new Rect(); // Whether or not to show the cutout protection path private boolean mShowProtection = false; @@ -969,7 +970,11 @@ public class ScreenDecorations extends SystemUI implements Tunable, } void setProtection(Path protectionPath, Rect pathBounds) { - mProtectionPath = protectionPath; + if (mProtectionPathOrig == null) { + mProtectionPathOrig = new Path(); + mProtectionPath = new Path(); + } + mProtectionPathOrig.set(protectionPath); mProtectionRect = pathBounds; } @@ -1053,7 +1058,9 @@ public class ScreenDecorations extends SystemUI implements Tunable, Matrix m = new Matrix(); transformPhysicalToLogicalCoordinates(mInfo.rotation, dw, dh, m); mBoundingPath.transform(m); - if (mProtectionPath != null) { + if (mProtectionPathOrig != null) { + // Reset the protection path so we don't aggregate rotations + mProtectionPath.set(mProtectionPathOrig); mProtectionPath.transform(m); } } -- GitLab From 7a66c7b39c50376efa042ef849fcecf7e41b2a17 Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Fri, 6 Mar 2020 11:52:04 -0800 Subject: [PATCH 129/219] Do not accept NaN as scrim values Scrim values are becoming NaN and causing the status bar window to not collapse. These are inavlid values and should not be accepted. Bug: 150672579 Test: make Change-Id: I8217a0fa9a08f94b98121d6584fafab1bca88b4d Merged-In: I8217a0fa9a08f94b98121d6584fafab1bca88b4d --- .../android/systemui/statusbar/ScrimView.java | 5 ++++ .../statusbar/phone/ScrimController.java | 25 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java index 04f1c3248a6f..1524b0799084 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar; +import static java.lang.Float.isNaN; + import android.annotation.NonNull; import android.content.Context; import android.graphics.Canvas; @@ -179,6 +181,9 @@ public class ScrimView extends View { * @param alpha Gradient alpha from 0 to 1. */ public void setViewAlpha(float alpha) { + if (isNaN(alpha)) { + throw new IllegalArgumentException("alpha cannot be NaN"); + } if (alpha != mViewAlpha) { mViewAlpha = alpha; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 9019e9a3f44b..d9bb995c5da8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.phone; +import static java.lang.Float.isNaN; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; @@ -261,6 +263,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo mCurrentBehindTint = state.getBehindTint(); mCurrentInFrontAlpha = state.getFrontAlpha(); mCurrentBehindAlpha = state.getBehindAlpha(); + if (isNaN(mCurrentBehindAlpha) || isNaN(mCurrentInFrontAlpha)) { + throw new IllegalStateException("Scrim opacity is NaN for state: " + state + ", front: " + + mCurrentInFrontAlpha + ", back: " + mCurrentBehindAlpha); + } applyExpansionToAlpha(); // Scrim might acquire focus when user is navigating with a D-pad or a keyboard. @@ -390,6 +396,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo * @param fraction From 0 to 1 where 0 means collapsed and 1 expanded. */ public void setPanelExpansion(float fraction) { + if (isNaN(fraction)) { + throw new IllegalArgumentException("Fraction should not be NaN"); + } if (mExpansionFraction != fraction) { mExpansionFraction = fraction; @@ -464,6 +473,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo mCurrentBehindTint = ColorUtils.blendARGB(ScrimState.BOUNCER.getBehindTint(), mState.getBehindTint(), interpolatedFract); } + if (isNaN(mBehindAlpha) || isNaN(mInFrontAlpha)) { + throw new IllegalStateException("Scrim opacity is NaN for state: " + mState + + ", front: " + mInFrontAlpha + ", back: " + mBehindAlpha); + } } /** @@ -523,6 +536,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo float newBehindAlpha = mState.getBehindAlpha(); if (mCurrentBehindAlpha != newBehindAlpha) { mCurrentBehindAlpha = newBehindAlpha; + if (isNaN(mCurrentBehindAlpha)) { + throw new IllegalStateException("Scrim opacity is NaN for state: " + mState + + ", back: " + mCurrentBehindAlpha); + } updateScrims(); } } @@ -903,7 +920,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo pw.print(" alpha="); pw.print(mCurrentBehindAlpha); pw.print(" tint=0x"); pw.println(Integer.toHexString(mScrimBehind.getTint())); - pw.print(" mTracking="); pw.println(mTracking); + pw.print(" mTracking="); pw.println(mTracking); + + pw.print(" mExpansionFraction="); pw.println(mExpansionFraction); } public void setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode) { @@ -950,6 +969,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo // in this case, back-scrim needs to be re-evaluated if (mState == ScrimState.AOD || mState == ScrimState.PULSING) { float newBehindAlpha = mState.getBehindAlpha(); + if (isNaN(newBehindAlpha)) { + throw new IllegalStateException("Scrim opacity is NaN for state: " + mState + + ", back: " + mCurrentBehindAlpha); + } if (mCurrentBehindAlpha != newBehindAlpha) { mCurrentBehindAlpha = newBehindAlpha; updateScrims(); -- GitLab From 12c8c244a63113612c69d4970878e6722efdaab8 Mon Sep 17 00:00:00 2001 From: Aleks Rozman Date: Sun, 8 Mar 2020 15:03:06 -0700 Subject: [PATCH 130/219] DO NOT MERGE: Resolve mBehindAlpha with mCurrentBehindAlpha fixes a build breakage, mBehindAlpha is a master thing but mCurrentBehindAlpha is a QPR1 thing BUG: 151041066 Test: Compile Change-Id: I78d767319d2ba856a9f453f71b39ddd3c96e6b9f --- .../com/android/systemui/statusbar/phone/ScrimController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index d9bb995c5da8..08ba50857fa7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -473,9 +473,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo mCurrentBehindTint = ColorUtils.blendARGB(ScrimState.BOUNCER.getBehindTint(), mState.getBehindTint(), interpolatedFract); } - if (isNaN(mBehindAlpha) || isNaN(mInFrontAlpha)) { + if (isNaN(mCurrentBehindAlpha) || isNaN(mCurrentInFrontAlpha)) { throw new IllegalStateException("Scrim opacity is NaN for state: " + mState - + ", front: " + mInFrontAlpha + ", back: " + mBehindAlpha); + + ", front: " + mCurrentInFrontAlpha + ", back: " + mCurrentBehindAlpha); } } -- GitLab From d61f3f9ce1df28e7d5be040550dfe95c57a4f0a0 Mon Sep 17 00:00:00 2001 From: weichinweng Date: Thu, 5 Mar 2020 10:37:44 +0800 Subject: [PATCH 131/219] Fix bluetooth can't turn off during network reset (2/3) Remove disable Bluetooth action from AdapterService and move to BluetoothManagerService. Add factory reset reason into Bluetooth enable/disable reason list. Bug: 110181479 Test: manual Change-Id: I4bff3c3bb75fbb0d1e13c459c0d9d3fd3b8b3195 Merged-In: I4bff3c3bb75fbb0d1e13c459c0d9d3fd3b8b3195 --- .../android/bluetooth/BluetoothAdapter.java | 6 +- core/proto/android/bluetooth/enums.proto | 1 + .../server/BluetoothManagerService.java | 114 ++++++++++++------ 3 files changed, 85 insertions(+), 36 deletions(-) diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 31bbd16497cb..3b620b388eff 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -1195,9 +1195,11 @@ public final class BluetoothAdapter { public boolean factoryReset() { try { mServiceLock.readLock().lock(); - if (mService != null) { - return mService.factoryReset(); + if (mService != null && mService.factoryReset() + && mManagerService != null && mManagerService.onFactoryReset()) { + return true; } + Log.e(TAG, "factoryReset(): Setting persist.bluetooth.factoryreset to retry later"); SystemProperties.set("persist.bluetooth.factoryreset", "true"); } catch (RemoteException e) { Log.e(TAG, "", e); diff --git a/core/proto/android/bluetooth/enums.proto b/core/proto/android/bluetooth/enums.proto index b4f3d1ea5ae4..22f249820b11 100644 --- a/core/proto/android/bluetooth/enums.proto +++ b/core/proto/android/bluetooth/enums.proto @@ -40,6 +40,7 @@ enum EnableDisableReasonEnum { ENABLE_DISABLE_REASON_CRASH = 7; ENABLE_DISABLE_REASON_USER_SWITCH = 8; ENABLE_DISABLE_REASON_RESTORE_USER_SETTING = 9; + ENABLE_DISABLE_REASON_FACTORY_RESET = 10; } enum DirectionEnum { diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index 188d65494868..f88032a40f68 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -73,11 +73,14 @@ import com.android.server.pm.UserRestrictionsUtils; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -257,6 +260,47 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } }; + public boolean onFactoryReset() { + // Wait for stable state if bluetooth is temporary state. + int state = getState(); + if (state == BluetoothAdapter.STATE_BLE_TURNING_ON + || state == BluetoothAdapter.STATE_TURNING_ON + || state == BluetoothAdapter.STATE_TURNING_OFF) { + if (!waitForState(new HashSet(Arrays.asList(BluetoothAdapter.STATE_BLE_ON, + BluetoothAdapter.STATE_ON)))) { + return false; + } + } + + // Clear registered LE apps to force shut-off Bluetooth + clearBleApps(); + state = getState(); + try { + mBluetoothLock.readLock().lock(); + if (mBluetooth == null) { + return false; + } + if (state == BluetoothAdapter.STATE_BLE_ON) { + addActiveLog( + BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET, + mContext.getPackageName(), false); + mBluetooth.onBrEdrDown(); + return true; + } else if (state == BluetoothAdapter.STATE_ON) { + addActiveLog( + BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET, + mContext.getPackageName(), false); + mBluetooth.disable(); + return true; + } + } catch (RemoteException e) { + Slog.e(TAG, "Unable to shutdown Bluetooth", e); + } finally { + mBluetoothLock.readLock().unlock(); + } + return false; + } + private final ContentObserver mAirplaneModeObserver = new ContentObserver(null) { @Override public void onChange(boolean unused) { @@ -1627,7 +1671,9 @@ class BluetoothManagerService extends IBluetoothManager.Stub { // the previous Bluetooth process has exited. The // waiting period has three components: // (a) Wait until the local state is STATE_OFF. This - // is accomplished by "waitForOnOff(false, true)". + // is accomplished by + // "waitForState(new HashSet( + // Arrays.asList(BluetoothAdapter.STATE_OFF)))". // (b) Wait until the STATE_OFF state is updated to // all components. // (c) Wait until the Bluetooth process exits, and @@ -1637,7 +1683,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { // message. On slower devices, that delay needs to be // on the order of (2 * SERVICE_RESTART_TIME_MS). // - waitForOnOff(false, true); + waitForState(new HashSet(Arrays.asList( + BluetoothAdapter.STATE_OFF))); Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE); mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS); @@ -1650,10 +1697,16 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); if (mEnable && mBluetooth != null) { - waitForOnOff(true, false); + waitForState(new HashSet(Arrays.asList( + BluetoothAdapter.STATE_ON))); mEnable = false; handleDisable(); - waitForOnOff(false, false); + waitForState(new HashSet(Arrays.asList(BluetoothAdapter.STATE_OFF, + BluetoothAdapter.STATE_TURNING_ON, + BluetoothAdapter.STATE_TURNING_OFF, + BluetoothAdapter.STATE_BLE_TURNING_ON, + BluetoothAdapter.STATE_BLE_ON, + BluetoothAdapter.STATE_BLE_TURNING_OFF))); } else { mEnable = false; handleDisable(); @@ -1782,9 +1835,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } if (!mEnable) { - waitForOnOff(true, false); + waitForState(new HashSet(Arrays.asList( + BluetoothAdapter.STATE_ON))); handleDisable(); - waitForOnOff(false, false); + waitForState(new HashSet(Arrays.asList(BluetoothAdapter.STATE_OFF, + BluetoothAdapter.STATE_TURNING_ON, + BluetoothAdapter.STATE_TURNING_OFF, + BluetoothAdapter.STATE_BLE_TURNING_ON, + BluetoothAdapter.STATE_BLE_ON, + BluetoothAdapter.STATE_BLE_TURNING_OFF))); } break; } @@ -1816,7 +1875,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { == BluetoothAdapter.STATE_OFF)) { if (mEnable) { Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting."); - waitForOnOff(false, true); + waitForState(new HashSet(Arrays.asList( + BluetoothAdapter.STATE_OFF))); Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE); mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS); @@ -1939,7 +1999,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { mState = BluetoothAdapter.STATE_TURNING_ON; } - waitForOnOff(true, false); + waitForState(new HashSet(Arrays.asList( + BluetoothAdapter.STATE_ON))); if (mState == BluetoothAdapter.STATE_TURNING_ON) { bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON); @@ -1954,7 +2015,9 @@ class BluetoothManagerService extends IBluetoothManager.Stub { bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON, BluetoothAdapter.STATE_TURNING_OFF); - boolean didDisableTimeout = !waitForOnOff(false, true); + boolean didDisableTimeout = + !waitForState(new HashSet(Arrays.asList( + BluetoothAdapter.STATE_OFF))); bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF, BluetoothAdapter.STATE_OFF); @@ -2206,12 +2269,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } } - /** - * if on is true, wait for state become ON - * if off is true, wait for state become OFF - * if both on and off are false, wait for state not ON - */ - private boolean waitForOnOff(boolean on, boolean off) { + private boolean waitForState(Set states) { int i = 0; while (i < 10) { try { @@ -2219,18 +2277,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (mBluetooth == null) { break; } - if (on) { - if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) { - return true; - } - } else if (off) { - if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) { - return true; - } - } else { - if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) { - return true; - } + if (states.contains(mBluetooth.getState())) { + return true; } } catch (RemoteException e) { Slog.e(TAG, "getState()", e); @@ -2238,14 +2286,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } finally { mBluetoothLock.readLock().unlock(); } - if (on || off) { - SystemClock.sleep(300); - } else { - SystemClock.sleep(50); - } + SystemClock.sleep(300); i++; } - Slog.e(TAG, "waitForOnOff time out"); + Slog.e(TAG, "waitForState " + states + " time out"); return false; } @@ -2306,7 +2350,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { mContext.getPackageName(), false); handleDisable(); - waitForOnOff(false, true); + waitForState(new HashSet(Arrays.asList(BluetoothAdapter.STATE_OFF))); sendBluetoothServiceDownCallback(); @@ -2468,6 +2512,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { return "USER_SWITCH"; case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING: return "RESTORE_USER_SETTING"; + case BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET: + return "FACTORY_RESET"; case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED: default: return "UNKNOWN[" + reason + "]"; } -- GitLab From 7d4adf4d46caa7695c395e3e994e1d57a94ae92c Mon Sep 17 00:00:00 2001 From: Linus Tufvesson Date: Tue, 4 Feb 2020 16:41:06 +0000 Subject: [PATCH 132/219] RESTRICT AUTOMERGE Block TYPE_PRESENTATION windows on default display ... and any other display that isn't considered a public presentation display, as per Display.isPublicPresentation() Bug: 141745510 Test: manual test via test app Change-Id: I2aaab1903dee54190338f7b6e49888aa51437108 --- core/java/android/app/Presentation.java | 16 +++++++++------- .../android/server/wm/WindowManagerService.java | 8 ++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java index af55788e617f..bc2b250328a6 100644 --- a/core/java/android/app/Presentation.java +++ b/core/java/android/app/Presentation.java @@ -25,18 +25,18 @@ import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.os.Binder; +import android.os.Handler; import android.os.IBinder; +import android.os.Message; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.Gravity; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; -import android.os.Handler; -import android.os.Message; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.TypedValue; /** * Base class for presentations. @@ -115,7 +115,9 @@ import android.util.TypedValue; * The display manager keeps track of all displays in the system. However, not all * displays are appropriate for showing presentations. For example, if an activity * attempted to show a presentation on the main display it might obscure its own content - * (it's like opening a dialog on top of your activity). + * (it's like opening a dialog on top of your activity). Creating a presentation on the main + * display will result in {@link android.view.WindowManager.InvalidDisplayException} being thrown + * when invoking {@link #show()}. *

* Here's how to identify suitable displays for showing presentations using * {@link DisplayManager#getDisplays(String)} and the @@ -242,7 +244,7 @@ public class Presentation extends Dialog { /** * Inherited from {@link Dialog#show}. Will throw * {@link android.view.WindowManager.InvalidDisplayException} if the specified secondary - * {@link Display} can't be found. + * {@link Display} can't be found or if it does not have {@link Display#FLAG_PRESENTATION} set. */ @Override public void show() { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 5f4c99437af9..d35ad413ccef 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -58,6 +58,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_DREAM; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; +import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; @@ -1255,6 +1256,13 @@ public class WindowManagerService extends IWindowManager.Stub return WindowManagerGlobal.ADD_PERMISSION_DENIED; } + if (type == TYPE_PRESENTATION && !displayContent.getDisplay().isPublicPresentation()) { + Slog.w(TAG_WM, + "Attempted to add presentation window to a non-suitable display. " + + "Aborting."); + return WindowManagerGlobal.ADD_INVALID_DISPLAY; + } + AppWindowToken atoken = null; final boolean hasParent = parentWindow != null; // Use existing parent window token for child windows since they go in the same token -- GitLab From 0bb93d4b1c05d717ed4cbf5772a6a766b5281f1e Mon Sep 17 00:00:00 2001 From: Linus Tufvesson Date: Tue, 4 Feb 2020 16:41:06 +0000 Subject: [PATCH 133/219] RESTRICT AUTOMERGE Block TYPE_PRESENTATION windows on default display ... and any other display that isn't considered a public presentation display, as per Display.isPublicPresentation() Bug: 141745510 Test: manual test via test app Change-Id: I2aaab1903dee54190338f7b6e49888aa51437108 --- core/java/android/app/Presentation.java | 16 +++++++++------- .../android/server/wm/WindowManagerService.java | 8 ++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java index af55788e617f..bc2b250328a6 100644 --- a/core/java/android/app/Presentation.java +++ b/core/java/android/app/Presentation.java @@ -25,18 +25,18 @@ import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.os.Binder; +import android.os.Handler; import android.os.IBinder; +import android.os.Message; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.Gravity; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; -import android.os.Handler; -import android.os.Message; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.TypedValue; /** * Base class for presentations. @@ -115,7 +115,9 @@ import android.util.TypedValue; * The display manager keeps track of all displays in the system. However, not all * displays are appropriate for showing presentations. For example, if an activity * attempted to show a presentation on the main display it might obscure its own content - * (it's like opening a dialog on top of your activity). + * (it's like opening a dialog on top of your activity). Creating a presentation on the main + * display will result in {@link android.view.WindowManager.InvalidDisplayException} being thrown + * when invoking {@link #show()}. *

* Here's how to identify suitable displays for showing presentations using * {@link DisplayManager#getDisplays(String)} and the @@ -242,7 +244,7 @@ public class Presentation extends Dialog { /** * Inherited from {@link Dialog#show}. Will throw * {@link android.view.WindowManager.InvalidDisplayException} if the specified secondary - * {@link Display} can't be found. + * {@link Display} can't be found or if it does not have {@link Display#FLAG_PRESENTATION} set. */ @Override public void show() { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 8439669a2147..361c116b67f6 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -56,6 +56,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_DREAM; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; +import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; @@ -1227,6 +1228,13 @@ public class WindowManagerService extends IWindowManager.Stub return WindowManagerGlobal.ADD_PERMISSION_DENIED; } + if (type == TYPE_PRESENTATION && !displayContent.getDisplay().isPublicPresentation()) { + Slog.w(TAG_WM, + "Attempted to add presentation window to a non-suitable display. " + + "Aborting."); + return WindowManagerGlobal.ADD_INVALID_DISPLAY; + } + AppWindowToken atoken = null; final boolean hasParent = parentWindow != null; // Use existing parent window token for child windows since they go in the same token -- GitLab From ae242892e2ba416cfbf5fd707069faf2350ace9c Mon Sep 17 00:00:00 2001 From: Beverly Date: Mon, 9 Mar 2020 16:07:56 -0400 Subject: [PATCH 134/219] DO NOT MERGE Ignore insets on status_bar_container - Instead, PhoneStatusBarView will take care of display cutout insets based on the rotation of the device Test: atest SystemUITests Bug: 149197103 Change-Id: Ie4df9ce5c754408dcf2d50108576df42173fa17d --- .../SystemUI/res/layout/super_status_bar.xml | 3 +- .../statusbar/phone/PhoneStatusBarView.java | 50 +++++++++++++++---- .../statusbar/phone/StatusBarWindowView.java | 3 +- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml index 9d56e08bc555..d68bd5d442ed 100644 --- a/packages/SystemUI/res/layout/super_status_bar.xml +++ b/packages/SystemUI/res/layout/super_status_bar.xml @@ -55,7 +55,8 @@ android:id="@+id/status_bar_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@drawable/system_bar_background" /> + android:background="@drawable/system_bar_background" + sysui:ignoreRightInset="true" /> cornerCutoutMargins = cornerCutoutMargins(mDisplayCutout, - getDisplay()); + getDisplay(), mRotationOrientation, mStatusBarHeight); updateCutoutLocation(cornerCutoutMargins); updateSafeInsets(cornerCutoutMargins); } @@ -332,15 +336,13 @@ public class PhoneStatusBarView extends PanelBar { // or letterboxing from the right or left sides. FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); - if (mDisplayCutout == null || mDisplayCutout.isEmpty() - || mLastOrientation != ORIENTATION_PORTRAIT || cornerCutoutMargins == null) { + if (mDisplayCutout == null || mDisplayCutout.isEmpty() || cornerCutoutMargins == null) { lp.leftMargin = 0; lp.rightMargin = 0; return; } - - lp.leftMargin = Math.max(lp.leftMargin, cornerCutoutMargins.first); - lp.rightMargin = Math.max(lp.rightMargin, cornerCutoutMargins.second); + lp.leftMargin = cornerCutoutMargins.first; + lp.rightMargin = cornerCutoutMargins.second; // If we're already inset enough (e.g. on the status bar side), we can have 0 margin WindowInsets insets = getRootWindowInsets(); @@ -354,8 +356,19 @@ public class PhoneStatusBarView extends PanelBar { } } + /** + * Returns a Pair of integers where + * - Pair.first is the left margin inset + * - Pair.second is the right margin inset + * This method always assumes the cutout is on the top when the device is in portrait mode. + */ public static Pair cornerCutoutMargins(DisplayCutout cutout, Display display) { + return cornerCutoutMargins(cutout, display, RotationUtils.ROTATION_NONE, -1); + } + + private static Pair cornerCutoutMargins(DisplayCutout cutout, + Display display, int rotationOrientation, int statusBarHeight) { if (cutout == null) { return null; } @@ -363,14 +376,33 @@ public class PhoneStatusBarView extends PanelBar { display.getRealSize(size); Rect bounds = new Rect(); - boundsFromDirection(cutout, Gravity.TOP, bounds); + switch (rotationOrientation) { + case RotationUtils.ROTATION_LANDSCAPE: + boundsFromDirection(cutout, Gravity.LEFT, bounds); + break; + case RotationUtils.ROTATION_SEASCAPE: + boundsFromDirection(cutout, Gravity.RIGHT, bounds); + break; + case RotationUtils.ROTATION_NONE: + boundsFromDirection(cutout, Gravity.TOP, bounds); + break; + case RotationUtils.ROTATION_UPSIDE_DOWN: + // we assume the cutout is always on top in portrait mode + return null; + } + + if (statusBarHeight >= 0 && bounds.top > statusBarHeight) { + return null; + } if (bounds.left <= 0) { return new Pair<>(bounds.right, 0); } + if (bounds.right >= size.x) { return new Pair<>(0, size.x - bounds.left); } + return null; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index 0ab2af864383..459e0da0b067 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -180,7 +180,8 @@ public class StatusBarWindowView extends FrameLayout { int targetLeft = Math.max(insets.left, leftCutout); int targetRight = Math.max(insets.right, rightCutout); - // Super-special right inset handling, because scrims and backdrop need to ignore it. + // Super-special right inset handling, because scrims, backdrop and status bar + // container need to ignore it. if (targetRight != mRightInset || targetLeft != mLeftInset) { mRightInset = targetRight; mLeftInset = targetLeft; -- GitLab From 447394f90871f10f58ac423004bd01a5d44079d0 Mon Sep 17 00:00:00 2001 From: Beverly Date: Mon, 9 Mar 2020 12:24:06 -0400 Subject: [PATCH 135/219] DO NOT MERGE Add null check for status bar transitions Test: atest SystemUITests Bug: 150570478 Change-Id: I4c93a08ddcbe35a95b77012e2345bfa25167be1b --- .../src/com/android/systemui/statusbar/phone/StatusBar.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 7e6d11b77f64..cc691ae2d9be 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -2277,8 +2277,10 @@ public class StatusBar extends SystemUI implements DemoMode, void checkBarModes() { if (mDemoMode) return; - if (mStatusBarView != null) checkBarMode(mStatusBarMode, mStatusBarWindowState, - getStatusBarTransitions()); + if (mStatusBarView != null && getStatusBarTransitions() != null) { + checkBarMode(mStatusBarMode, mStatusBarWindowState, + getStatusBarTransitions()); + } mNavigationBarController.checkNavBarModes(mDisplayId); mNoAnimationOnNextBarModeChange = false; } -- GitLab From 973ecc619c0bb87a03481774ea9e86d2924601e4 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Sat, 22 Feb 2020 23:20:41 +0800 Subject: [PATCH 136/219] RESTRICT AUTOMERGE Create separated tasks for different apps from startActivities Assume there are 2 applications A, B with different uids. There are 4 activities A1, A2, B1, B2 with default task affinity and launch mode. After A1 called startActivities(B1, A2, B2): Original : Task(A1, B1, A2, B2) This Change: Task(A1, B1), Task(A2, B2) In other words, the source caller cannot launch its activity above the activity of other application in the same task, and it can still launch activity of other application in its task. Bug: 145669109 Test: run cts --test android.server.cts.StartActivityTests \ -m CtsServicesHostTestCases Change-Id: I97bd875146a52f62b8fe82235487ccefb2955e8e --- .../com/android/server/am/ActivityStarter.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index fa2e04f70a30..aec552d3e145 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -940,6 +940,8 @@ class ActivityStarter { } else { callingPid = callingUid = -1; } + boolean forceNewTask = false; + final int filterCallingUid = callingUid >= 0 ? callingUid : realCallingUid; final long origId = Binder.clearCallingIdentity(); try { synchronized (mService) { @@ -959,6 +961,9 @@ class ActivityStarter { // Don't modify the client's object! intent = new Intent(intent); + if (forceNewTask) { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + } // Collect information about the target of the Intent. ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 0, @@ -984,7 +989,17 @@ class ActivityStarter { return res; } - resultTo = outActivity[0] != null ? outActivity[0].appToken : null; + final ActivityRecord started = outActivity[0]; + if (started != null && started.getUid() == filterCallingUid) { + // Only the started activity which has the same uid as the source caller can + // be the caller of next activity. + resultTo = started.appToken; + forceNewTask = false; + } else { + // Different apps not adjacent to the caller are forced to be new task. + resultTo = null; + forceNewTask = true; + } } } } finally { -- GitLab From 70db873eeaf11f8e5f882bbbac7f605badb45a92 Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Tue, 15 Oct 2019 11:39:52 -0400 Subject: [PATCH 137/219] Allow two finger swipes down. Bug: 140715042 Test: atest SystemUITests Change-Id: Iebfec76045897818cec89f588ebd1d72a782c942 --- .../brightline/PointerCountClassifier.java | 8 ++++++++ .../classifier/brightline/ClassifierTest.java | 3 +++ .../PointerCountClassifierTest.java | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java index 40e141fbf988..6f9e12061974 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java @@ -16,6 +16,9 @@ package com.android.systemui.classifier.brightline; +import static com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN; +import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS; + import android.view.MotionEvent; /** @@ -27,6 +30,7 @@ import android.view.MotionEvent; class PointerCountClassifier extends FalsingClassifier { private static final int MAX_ALLOWED_POINTERS = 1; + private static final int MAX_ALLOWED_POINTERS_SWIPE_DOWN = 2; private int mMaxPointerCount; PointerCountClassifier(FalsingDataProvider dataProvider) { @@ -48,6 +52,10 @@ class PointerCountClassifier extends FalsingClassifier { @Override public boolean isFalseTouch() { + int interactionType = getInteractionType(); + if (interactionType == QUICK_SETTINGS || interactionType == NOTIFICATION_DRAG_DOWN) { + return mMaxPointerCount > MAX_ALLOWED_POINTERS_SWIPE_DOWN; + } return mMaxPointerCount > MAX_ALLOWED_POINTERS; } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ClassifierTest.java index d011e486d2e0..3ba5d1ac79ea 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ClassifierTest.java @@ -16,6 +16,8 @@ package com.android.systemui.classifier.brightline; +import static com.android.systemui.classifier.Classifier.UNLOCK; + import android.util.DisplayMetrics; import android.view.MotionEvent; @@ -42,6 +44,7 @@ public class ClassifierTest extends SysuiTestCase { displayMetrics.widthPixels = 1000; displayMetrics.heightPixels = 1000; mDataProvider = new FalsingDataProvider(displayMetrics); + mDataProvider.setInteractionType(UNLOCK); } @After diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/PointerCountClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/PointerCountClassifierTest.java index 341b74b33784..96b2028da326 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/PointerCountClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/PointerCountClassifierTest.java @@ -16,6 +16,8 @@ package com.android.systemui.classifier.brightline; +import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS; + import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -74,4 +76,21 @@ public class PointerCountClassifierTest extends ClassifierTest { motionEvent.recycle(); assertThat(mClassifier.isFalseTouch(), is(true)); } + + @Test + public void testPass_multiPointerDragDown() { + MotionEvent.PointerProperties[] pointerProperties = + MotionEvent.PointerProperties.createArray(2); + pointerProperties[0].id = 0; + pointerProperties[1].id = 1; + MotionEvent.PointerCoords[] pointerCoords = MotionEvent.PointerCoords.createArray(2); + MotionEvent motionEvent = MotionEvent.obtain( + 1, 1, MotionEvent.ACTION_DOWN, 2, pointerProperties, pointerCoords, 0, 0, 0, 0, 0, + 0, + 0, 0); + mClassifier.onTouchEvent(motionEvent); + motionEvent.recycle(); + getDataProvider().setInteractionType(QUICK_SETTINGS); + assertThat(mClassifier.isFalseTouch(), is(false)); + } } -- GitLab From e375ee8f8a4e767040cfbef1ead28623b3e986e0 Mon Sep 17 00:00:00 2001 From: Shuzhen Wang Date: Fri, 6 Mar 2020 11:38:21 -0800 Subject: [PATCH 138/219] Camera: Add new hidden API for camera open/close callback The hidden API is used by SystemUI process to adjust the system UI based on when a certain camera is opened or closed. Test: Manually observe callbacks in SystemUI when running camera CTS Bug: 150540299 Change-Id: I04cae782d96f0e32be8ef588dcd328f84b32887a Merged-In: I04cae782d96f0e32be8ef588dcd328f84b32887a --- .../hardware/camera2/CameraManager.java | 85 +++++++++++++++++++ core/res/AndroidManifest.xml | 8 ++ core/res/res/values/strings.xml | 5 ++ data/etc/com.android.systemui.xml | 1 + .../integration/CameraBinderTest.java | 9 ++ packages/SystemUI/AndroidManifest.xml | 1 + 6 files changed, 109 insertions(+) diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index c8276b25c52d..13f2a5ebc785 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -701,6 +701,33 @@ public final class CameraManager { public void onCameraAccessPrioritiesChanged() { // default empty implementation } + + /** + * A camera device has been opened by an application. + * + *

The default implementation of this method does nothing.

+ * + * @param cameraId The unique identifier of the new camera. + * @param packageId The package Id of the application opening the camera. + * + * @see #onCameraClosed + */ + /** @hide */ + public void onCameraOpened(@NonNull String cameraId, @NonNull String packageId) { + // default empty implementation + } + + /** + * A previously-opened camera has been closed. + * + *

The default implementation of this method does nothing.

+ * + * @param cameraId The unique identifier of the closed camera. + */ + /** @hide */ + public void onCameraClosed(@NonNull String cameraId) { + // default empty implementation + } } /** @@ -1139,6 +1166,38 @@ public final class CameraManager { } } + private void postSingleCameraOpenedUpdate(final AvailabilityCallback callback, + final Executor executor, final String id, final String packageId) { + final long ident = Binder.clearCallingIdentity(); + try { + executor.execute( + new Runnable() { + @Override + public void run() { + callback.onCameraOpened(id, packageId); + } + }); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + private void postSingleCameraClosedUpdate(final AvailabilityCallback callback, + final Executor executor, final String id) { + final long ident = Binder.clearCallingIdentity(); + try { + executor.execute( + new Runnable() { + @Override + public void run() { + callback.onCameraClosed(id); + } + }); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + private void postSingleUpdate(final AvailabilityCallback callback, final Executor executor, final String id, final int status) { if (isAvailable(status)) { @@ -1401,6 +1460,32 @@ public final class CameraManager { } } + @Override + public void onCameraOpened(String cameraId, String clientPackageId) { + synchronized (mLock) { + final int callbackCount = mCallbackMap.size(); + for (int i = 0; i < callbackCount; i++) { + Executor executor = mCallbackMap.valueAt(i); + final AvailabilityCallback callback = mCallbackMap.keyAt(i); + + postSingleCameraOpenedUpdate(callback, executor, cameraId, clientPackageId); + } + } + } + + @Override + public void onCameraClosed(String cameraId) { + synchronized (mLock) { + final int callbackCount = mCallbackMap.size(); + for (int i = 0; i < callbackCount; i++) { + Executor executor = mCallbackMap.valueAt(i); + final AvailabilityCallback callback = mCallbackMap.keyAt(i); + + postSingleCameraClosedUpdate(callback, executor, cameraId); + } + } + } + /** * Try to connect to camera service after some delay if any client registered camera * availability callback or torch status callback. diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 5778d02737b9..7b95d92ce1d6 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1267,6 +1267,14 @@ android:description="@string/permdesc_camera" android:protectionLevel="dangerous|instant" /> + + diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 5d5729b412be..044e07420c2d 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1151,6 +1151,11 @@ This app can take pictures and record videos using the camera at any time. + + Allow an application or service to receive callbacks about camera devices being opened or closed. + + This signature app can receive callbacks when any camera device is being opened (by what application package) or closed. + control vibration diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml index a305d48c4633..2f5b5f3bf7b4 100644 --- a/data/etc/com.android.systemui.xml +++ b/data/etc/com.android.systemui.xml @@ -60,5 +60,6 @@ + diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java index 87a59df19e8e..0889192099df 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java @@ -313,6 +313,15 @@ public class CameraBinderTest extends AndroidTestCase { public void onCameraAccessPrioritiesChanged() { Log.v(TAG, "Camera access permission change"); } + @Override + public void onCameraOpened(String cameraId, String clientPackageName) { + Log.v(TAG, String.format("Camera %s is opened by client package %s", + cameraId, clientPackageName)); + } + @Override + public void onCameraClosed(String cameraId) { + Log.v(TAG, String.format("Camera %s is closed", cameraId)); + } } /** diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 862abfda6a65..20b61f966d2d 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -151,6 +151,7 @@ + -- GitLab From ace57ca0dfdbb2d4af52370628a3a63575355ad2 Mon Sep 17 00:00:00 2001 From: Govinda Wasserman Date: Thu, 5 Mar 2020 17:01:21 -0500 Subject: [PATCH 139/219] [DO NOT MERGE] Allows the Assistant to request suppression of fling Test: Tested locally BUG: 150688842 Change-Id: I8e8b2ccb87d9ff48d5a287f12ca9a6a2240a2cdb --- .../shared/system/QuickStepContract.java | 5 ++++ .../systemui/assist/AssistManager.java | 25 +++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java index 08996c38baf6..cfefe0c3c0fd 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java @@ -85,6 +85,9 @@ public class QuickStepContract { // The notification panel is expanded and interactive (either locked or unlocked), and the // quick settings is not expanded public static final int SYSUI_STATE_QUICK_SETTINGS_EXPANDED = 1 << 11; + // The Assistant gesture should be constrained. It is up to the launcher implementation to + // decide how to constrain it + public static final int SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED = 1 << 12; @Retention(RetentionPolicy.SOURCE) @IntDef({SYSUI_STATE_SCREEN_PINNING, @@ -117,6 +120,8 @@ public class QuickStepContract { str.add((flags & SYSUI_STATE_BOUNCER_SHOWING) != 0 ? "bouncer_visible" : ""); str.add((flags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0 ? "a11y_click" : ""); str.add((flags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0 ? "a11y_long_click" : ""); + str.add((flags & SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED) != 0 + ? "asst_gesture_constrain" : ""); return str.toString(); } diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java index 74b4f9537b87..d2c5f1e91ea7 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java @@ -1,5 +1,9 @@ package com.android.systemui.assist; +import static android.view.Display.DEFAULT_DISPLAY; + +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED; + import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; @@ -39,7 +43,6 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.settingslib.applications.InterestingConfigChanges; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; import com.android.systemui.assist.ui.DefaultUiController; @@ -103,6 +106,9 @@ public class AssistManager { public static final String INVOCATION_TYPE_KEY = "invocation_type"; protected static final String ACTION_KEY = "action"; protected static final String SHOW_ASSIST_HANDLES_ACTION = "show_assist_handles"; + protected static final String SET_ASSIST_GESTURE_CONSTRAINED_ACTION = + "set_assist_gesture_constrained"; + protected static final String CONSTRAINED_KEY = "should_constrain"; public static final int INVOCATION_TYPE_GESTURE = 1; public static final int INVOCATION_TYPE_ACTIVE_EDGE = 2; @@ -125,6 +131,7 @@ public class AssistManager { private final PhoneStateMonitor mPhoneStateMonitor; private final AssistHandleBehaviorController mHandleController; private final UiController mUiController; + protected final OverviewProxyService mOverviewProxyService; private AssistOrbContainer mView; private final DeviceProvisionedController mDeviceProvisionedController; @@ -186,7 +193,8 @@ public class AssistManager { Context context, AssistUtils assistUtils, AssistHandleBehaviorController handleController, - ConfigurationController configurationController) { + ConfigurationController configurationController, + OverviewProxyService overviewProxyService) { mContext = context; mDeviceProvisionedController = controller; mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); @@ -206,8 +214,8 @@ public class AssistManager { mUiController = new DefaultUiController(mContext); - OverviewProxyService overviewProxy = Dependency.get(OverviewProxyService.class); - overviewProxy.addCallback(new OverviewProxyService.OverviewProxyListener() { + mOverviewProxyService = overviewProxyService; + mOverviewProxyService.addCallback(new OverviewProxyService.OverviewProxyListener() { @Override public void onAssistantProgress(float progress) { // Progress goes from 0 to 1 to indicate how close the assist gesture is to @@ -244,8 +252,15 @@ public class AssistManager { if (VERBOSE) { Log.v(TAG, "UI hints received"); } - if (SHOW_ASSIST_HANDLES_ACTION.equals(hints.getString(ACTION_KEY))) { + + String action = hints.getString(ACTION_KEY); + if (SHOW_ASSIST_HANDLES_ACTION.equals(action)) { requestAssistHandles(); + } else if (SET_ASSIST_GESTURE_CONSTRAINED_ACTION.equals(action)) { + mOverviewProxyService.setSystemUiStateFlag( + SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED, + hints.getBoolean(CONSTRAINED_KEY, false), + DEFAULT_DISPLAY); } } }); -- GitLab From 7890462180ec409a9c5e4845685304e8690378af Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Tue, 10 Mar 2020 14:13:02 -0700 Subject: [PATCH 140/219] Properly rotate cutout protection rect Test: visual Fixes: 151054867 Change-Id: I4840e7650b30d9ce6f73c0e2ea0d0b3b47222fb4 --- .../com/android/systemui/ScreenDecorations.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index 6ea6a748ae8d..e0a9bb166fb2 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -48,6 +48,7 @@ import android.graphics.Paint; import android.graphics.Path; import android.graphics.PixelFormat; import android.graphics.Rect; +import android.graphics.RectF; import android.graphics.Region; import android.graphics.drawable.VectorDrawable; import android.hardware.display.DisplayManager; @@ -879,7 +880,8 @@ public class ScreenDecorations extends SystemUI implements Tunable, private final Rect mBoundingRect = new Rect(); private final Path mBoundingPath = new Path(); // Don't initialize these yet because they may never exist - private Rect mProtectionRect; + private RectF mProtectionRect; + private RectF mProtectionRectOrig; private Path mProtectionPath; private Path mProtectionPathOrig; private Rect mTotalBounds = new Rect(); @@ -975,7 +977,11 @@ public class ScreenDecorations extends SystemUI implements Tunable, mProtectionPath = new Path(); } mProtectionPathOrig.set(protectionPath); - mProtectionRect = pathBounds; + if (mProtectionRectOrig == null) { + mProtectionRectOrig = new RectF(); + mProtectionRect = new RectF(); + } + mProtectionRectOrig.set(pathBounds); } void setShowProtection(boolean shouldShow) { @@ -1062,6 +1068,7 @@ public class ScreenDecorations extends SystemUI implements Tunable, // Reset the protection path so we don't aggregate rotations mProtectionPath.set(mProtectionPathOrig); mProtectionPath.transform(m); + m.mapRect(mProtectionRect, mProtectionRectOrig); } } @@ -1124,7 +1131,8 @@ public class ScreenDecorations extends SystemUI implements Tunable, if (mShowProtection) { // Make sure that our measured height encompases the protection mTotalBounds.union(mBoundingRect); - mTotalBounds.union(mProtectionRect); + mTotalBounds.union((int) mProtectionRect.left, (int) mProtectionRect.top, + (int) mProtectionRect.right, (int) mProtectionRect.bottom); setMeasuredDimension( resolveSizeAndState(mTotalBounds.width(), widthMeasureSpec, 0), resolveSizeAndState(mTotalBounds.height(), heightMeasureSpec, 0)); -- GitLab From 45a53e6cb8d3276126cfe0e717ad7ed486d39b24 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Mon, 19 Aug 2019 16:16:20 -0700 Subject: [PATCH 141/219] DO NOT MERGE - Kill apps outright for API contract violations ...rather than relying on in-app code to perform the shutdown. Bug: 128649910 Bug: 140108616 Test: manual Test: atest OsHostTests#testForegroundServiceBadNotification Change-Id: I94d9de50bb03c33666471e3dbd9c721e9278f7cb Merged-In: I94d9de50bb03c33666471e3dbd9c721e9278f7cb --- core/java/android/app/IActivityManager.aidl | 3 ++- .../com/android/server/am/ActiveServices.java | 11 +++++++- .../server/am/ActivityManagerService.java | 5 ++-- .../am/ActivityManagerShellCommand.java | 2 +- .../java/com/android/server/am/AppErrors.java | 26 ++++++++++++++----- .../com/android/server/am/ServiceRecord.java | 7 +++-- .../NotificationManagerService.java | 2 +- 7 files changed, 39 insertions(+), 17 deletions(-) diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 48ca71690a1b..c0c63555b10a 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -287,7 +287,8 @@ interface IActivityManager { void handleApplicationStrictModeViolation(in IBinder app, int penaltyMask, in StrictMode.ViolationInfo crashInfo); boolean isTopActivityImmersive(); - void crashApplication(int uid, int initialPid, in String packageName, int userId, in String message); + void crashApplication(int uid, int initialPid, in String packageName, int userId, + in String message, boolean force); @UnsupportedAppUsage String getProviderMimeType(in Uri uri, int userId); // Cause the specified process to dump the specified heap. diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 7bc2e6d647be..5d72828964c7 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -829,6 +829,15 @@ public final class ActiveServices { } } + void killMisbehavingService(ServiceRecord r, + int appUid, int appPid, String localPackageName) { + synchronized (mAm) { + stopServiceLocked(r); + mAm.crashApplication(appUid, appPid, localPackageName, -1, + "Bad notification for startForeground", true /*force*/); + } + } + IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) { ServiceLookupResult r = retrieveServiceLocked(service, null, resolvedType, callingPackage, Binder.getCallingPid(), Binder.getCallingUid(), @@ -3918,7 +3927,7 @@ public final class ActiveServices { void serviceForegroundCrash(ProcessRecord app, CharSequence serviceRecord) { mAm.crashApplication(app.uid, app.pid, app.info.packageName, app.userId, "Context.startForegroundService() did not then call Service.startForeground(): " - + serviceRecord); + + serviceRecord, false /*force*/); } void scheduleServiceTimeoutLocked(ProcessRecord proc) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index f9d13c286093..67bb1c0268d4 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -3568,7 +3568,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void crashApplication(int uid, int initialPid, String packageName, int userId, - String message) { + String message, boolean force) { if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: crashApplication() from pid=" @@ -3580,7 +3580,8 @@ public class ActivityManagerService extends IActivityManager.Stub } synchronized(this) { - mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message); + mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, + message, force); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 26b3f435dea1..9f3a7e93a433 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -1051,7 +1051,7 @@ final class ActivityManagerShellCommand extends ShellCommand { } catch (NumberFormatException e) { packageName = arg; } - mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash"); + mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash", false); return 0; } diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index a4c695067139..bbd2d34e92a6 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -314,20 +314,24 @@ class AppErrors { } void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) { - app.setCrashing(false); - app.crashingReport = null; - app.setNotResponding(false); - app.notRespondingReport = null; if (app.anrDialog == fromDialog) { app.anrDialog = null; } if (app.waitDialog == fromDialog) { app.waitDialog = null; } + killAppImmediateLocked(app, "user-terminated", "user request after error"); + } + + private void killAppImmediateLocked(ProcessRecord app, String reason, String killReason) { + app.setCrashing(false); + app.crashingReport = null; + app.setNotResponding(false); + app.notRespondingReport = null; if (app.pid > 0 && app.pid != MY_PID) { - handleAppCrashLocked(app, "user-terminated" /*reason*/, + handleAppCrashLocked(app, reason, null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/); - app.kill("user request after error", true); + app.kill(killReason, true); } } @@ -341,7 +345,7 @@ class AppErrors { * @param message */ void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId, - String message) { + String message, boolean force) { ProcessRecord proc = null; // Figure out which process to kill. We don't trust that initialPid @@ -374,6 +378,14 @@ class AppErrors { } proc.scheduleCrash(message); + if (force) { + // If the app is responsive, the scheduled crash will happen as expected + // and then the delayed summary kill will be a no-op. + final ProcessRecord p = proc; + mService.mHandler.postDelayed( + () -> killAppImmediateLocked(p, "forced", "killed for invalid state"), + 5000L); + } } /** diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index dee8e3b285a7..c408695bcb66 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -798,6 +798,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN final String localPackageName = packageName; final int localForegroundId = foregroundId; final Notification _foregroundNoti = foregroundNoti; + final ServiceRecord record = this; ams.mHandler.post(new Runnable() { public void run() { NotificationManagerInternal nm = LocalServices.getService( @@ -896,10 +897,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN Slog.w(TAG, "Error showing notification for service", e); // If it gave us a garbage notification, it doesn't // get to be foreground. - ams.setServiceForeground(instanceName, ServiceRecord.this, - 0, null, 0, 0); - ams.crashApplication(appUid, appPid, localPackageName, -1, - "Bad notification for startForeground: " + e); + ams.mServices.killMisbehavingService(record, + appUid, appPid, localPackageName); } } }); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 09a79433cb5c..47ed7f54e1b0 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -920,7 +920,7 @@ public class NotificationManagerService extends SystemService { () -> mAm.crashApplication(uid, initialPid, pkg, -1, "Bad notification(tag=" + tag + ", id=" + id + ") posted from package " + pkg + ", crashing app(uid=" + uid + ", pid=" + initialPid + "): " - + message)); + + message, true /* force */)); } } -- GitLab From 931583291316957774205d7d4403988d4818be35 Mon Sep 17 00:00:00 2001 From: Evan Laird Date: Tue, 10 Mar 2020 14:16:56 -0400 Subject: [PATCH 142/219] DO NOT MERGE: Allow corner UI to decouple from rounded_corner_radius frameworks/base/core/res/res/dimens value rounded_corner_radius can change not to reflect the actual device size due to tuning the rounding on window corners. This change allows us to decouple corner UI's idea of what the corner size is from the framework dimension Test: manual Change-Id: I6548d74921d6e71250486984869572bdd304b0d0 --- packages/SystemUI/res/values/dimens.xml | 5 +++++ .../src/com/android/systemui/CornerHandleView.java | 6 +++--- .../com/android/systemui/assist/ui/DisplayUtils.java | 12 ++++++------ .../assist/ui/PathSpecCornerPathRenderer.java | 4 ++-- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 2e1799168b5d..0263329dbe8e 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1156,4 +1156,9 @@ 10sp + + + @*android:dimen/rounded_corner_radius + @*android:dimen/rounded_corner_radius_top + @*android:dimen/rounded_corner_radius_top diff --git a/packages/SystemUI/src/com/android/systemui/CornerHandleView.java b/packages/SystemUI/src/com/android/systemui/CornerHandleView.java index a94952c5bc19..6606c8235def 100644 --- a/packages/SystemUI/src/com/android/systemui/CornerHandleView.java +++ b/packages/SystemUI/src/com/android/systemui/CornerHandleView.java @@ -152,14 +152,14 @@ public class CornerHandleView extends View { // Attempt to get the bottom corner radius, otherwise fall back on the generic or top // values. If none are available, use the FALLBACK_RADIUS_DP. int radius = getResources().getDimensionPixelSize( - com.android.internal.R.dimen.rounded_corner_radius_bottom); + com.android.systemui.R.dimen.config_rounded_mask_size_bottom); if (radius == 0) { radius = getResources().getDimensionPixelSize( - com.android.internal.R.dimen.rounded_corner_radius); + com.android.systemui.R.dimen.config_rounded_mask_size); } if (radius == 0) { radius = getResources().getDimensionPixelSize( - com.android.internal.R.dimen.rounded_corner_radius_top); + com.android.systemui.R.dimen.config_rounded_mask_size_top); } if (radius == 0) { radius = (int) convertDpToPixel(FALLBACK_RADIUS_DP, mContext); diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java index 251229f42da3..33e6ca49ddd5 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java @@ -84,8 +84,8 @@ public class DisplayUtils { public static int getCornerRadiusBottom(Context context) { int radius = 0; - int resourceId = context.getResources().getIdentifier("rounded_corner_radius_bottom", - "dimen", "android"); + int resourceId = context.getResources().getIdentifier("config_rounded_mask_size_bottom", + "dimen", "com.android.systemui"); if (resourceId > 0) { radius = context.getResources().getDimensionPixelSize(resourceId); } @@ -103,8 +103,8 @@ public class DisplayUtils { public static int getCornerRadiusTop(Context context) { int radius = 0; - int resourceId = context.getResources().getIdentifier("rounded_corner_radius_top", - "dimen", "android"); + int resourceId = context.getResources().getIdentifier("config_rounded_mask_size_top", + "dimen", "com.android.systemui"); if (resourceId > 0) { radius = context.getResources().getDimensionPixelSize(resourceId); } @@ -118,8 +118,8 @@ public class DisplayUtils { private static int getCornerRadiusDefault(Context context) { int radius = 0; - int resourceId = context.getResources().getIdentifier("rounded_corner_radius", "dimen", - "android"); + int resourceId = context.getResources().getIdentifier("config_rounded_mask_size", + "dimen", "com.android.systemui"); if (resourceId > 0) { radius = context.getResources().getDimensionPixelSize(resourceId); } diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java b/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java index 2bad7fc9583a..523378e97c94 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java @@ -45,8 +45,8 @@ public final class PathSpecCornerPathRenderer extends CornerPathRenderer { mWidth = DisplayUtils.getWidth(context); mHeight = DisplayUtils.getHeight(context); - mBottomCornerRadius = DisplayUtils.getCornerRadiusBottom(context); - mTopCornerRadius = DisplayUtils.getCornerRadiusTop(context); + mBottomCornerRadius = DisplayUtils.getCornerRadiusBottom(context); + mTopCornerRadius = DisplayUtils.getCornerRadiusTop(context); String pathData = context.getResources().getString(R.string.config_rounded_mask); Path path = PathParser.createPathFromPathData(pathData); -- GitLab From 1c9bf5cc54d0b32d8f3046c452e710b017c477c0 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Tue, 3 Mar 2020 14:36:21 +0800 Subject: [PATCH 143/219] RESTRICT AUTOMERGE Use consistent calling uid and package in navigateUpTo Originally, if the caller of navigateUpTo is alive, even the calling uid is set to the caller who launched the existing destination activity, the uid from caller process has higher priority to replace the given calling uid. So this change doesn't modify the existing behavior if the caller process is valid. Besides, the case of delivering new intent uses the source record as calling identity too, so the case of starting new activity should be consistent. Also forbid attaching null application thread to avoid unexpected state in process record. Bug: 144285917 Test: bit FrameworksServicesTests:ActivityStackTests Test: bit CtsSecurityTestCases:ActivityManagerTest# \ testActivityManager_attachNullApplication Merged-In: I60732f430256d37cb926d08d093581f051c4afed Change-Id: I60732f430256d37cb926d08d093581f051c4afed --- .../android/server/am/ActivityManagerService.java | 5 ++++- .../java/com/android/server/am/ActivityStack.java | 13 +++++++++---- .../com/android/server/am/ActivityStackTests.java | 14 ++++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 348a0376e08c..e0ac45adb3f4 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -6722,7 +6722,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } - private final boolean attachApplicationLocked(IApplicationThread thread, + private boolean attachApplicationLocked(@NonNull IApplicationThread thread, int pid) { // Find the application record that is being attached... either via @@ -7027,6 +7027,9 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public final void attachApplication(IApplicationThread thread) { + if (thread == null) { + throw new SecurityException("Invalid application interface"); + } synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index bde317a163db..a65a59465166 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -3853,6 +3853,11 @@ class ActivityStack extends ConfigurationContai final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode, Intent resultData) { + if (srec.app == null || srec.app.thread == null) { + // Nothing to do if the caller is not attached, because this method should be called + // from an alive activity. + return false; + } final TaskRecord task = srec.getTask(); final ArrayList activities = task.mActivities; final int start = activities.indexOf(srec); @@ -3904,22 +3909,22 @@ class ActivityStack extends ConfigurationContai } if (parent != null && foundParentInTask) { + final int callingUid = srec.info.applicationInfo.uid; final int parentLaunchMode = parent.info.launchMode; final int destIntentFlags = destIntent.getFlags(); if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { - parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent, - srec.packageName); + parent.deliverNewIntentLocked(callingUid, destIntent, srec.packageName); } else { try { ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( destIntent.getComponent(), 0, srec.userId); int res = mService.mActivityStarter.startActivityLocked(srec.app.thread, destIntent, null /*ephemeralIntent*/, null, aInfo, null /*rInfo*/, null, - null, parent.appToken, null, 0, -1, parent.launchedFromUid, - parent.launchedFromPackage, -1, parent.launchedFromUid, 0, null, + null, parent.appToken, null, 0, -1, callingUid, + srec.packageName, -1, callingUid, 0, null, false, true, null, null, null, "navigateUpTo"); foundParentInTask = res == ActivityManager.START_SUCCESS; } catch (RemoteException e) { diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java index 711c36b8b1d4..bdd89da1df88 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java @@ -17,6 +17,7 @@ package com.android.server.am; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -119,4 +120,17 @@ public class ActivityStackTests extends ActivityTestsBase { assertEquals(ActivityStack.STACK_VISIBLE_ACTIVITY_BEHIND, fullscreenWorkspaceStackId.shouldBeVisible(null /*starting*/)); } + + @Test + public void testNavigateUpTo() { + final ActivityManagerService service = createActivityManagerService(); + final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID); + final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task); + activityRecord.app = new ProcessRecord(null, activityRecord.appInfo, + activityRecord.processName, activityRecord.getUid()); + final ActivityStack testStack = service.mStackSupervisor.getStack(TEST_STACK_ID); + // No-op if the source activity record doesn't have attached process (app.thread == null). + assertFalse(testStack.navigateUpToLocked(activityRecord, activityRecord.intent, + 0 /* resultCode */, null /* resultData */)); + } } -- GitLab From 2263309459abe979774735bf3fe5ca53f65fa96a Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Wed, 11 Mar 2020 16:37:28 -0700 Subject: [PATCH 144/219] Either reuse sensor values or don't dim down at all ALS latency is unpredictable and sometimes debounced. This means that it might take at least 3 seconds for the display to wake-up, if it wakes-up at all. We might also get stuck and never show HUNs if the event doesn't arrive. This is a bug that we had in the past, but was not as noticeable because the padlock was below the scrims, now, users are reporting that the padlock shows up, but the hun is not. Test: manual Fixes: 150852696 Change-Id: Iade5ebd4c33e7c9d668b09144964f1408ef529ad Merged-In: Iade5ebd4c33e7c9d668b09144964f1408ef529ad --- .../systemui/doze/DozeScreenBrightness.java | 11 +---- .../doze/DozeScreenBrightnessTest.java | 42 ------------------- 2 files changed, 2 insertions(+), 51 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java index c27e633f2a96..1145501f4c51 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java @@ -155,15 +155,8 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi } int scrimOpacity = -1; - if (mPaused || mScreenOff) { - // If AOD is paused, force the screen black until the - // sensor reports a new brightness. This ensures that when the screen comes on - // again, it will only show after the brightness sensor has stabilized, - // avoiding a potential flicker. - scrimOpacity = 255; - } else if (!mScreenOff && mLightSensor == null) { - // No light sensor but previous state turned the screen black. Make the scrim - // transparent and below views visible. + if (mLightSensor == null) { + // No light sensor, scrims are always transparent. scrimOpacity = 0; } else if (brightnessReady) { // Only unblank scrim once brightness is ready. diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java index 3b760e31b4ac..0e8dffd57079 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java @@ -220,48 +220,6 @@ public class DozeScreenBrightnessTest extends SysuiTestCase { assertEquals(10/255f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); } - @Test - public void pausingAod_softBlanks() throws Exception { - mScreen.transitionTo(UNINITIALIZED, INITIALIZED); - mScreen.transitionTo(INITIALIZED, DOZE_AOD); - - mSensor.sendSensorEvent(2); - - mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING); - mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED); - - assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); - - mSensor.sendSensorEvent(0); - assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); - - mScreen.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD); - assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); - } - - @Test - public void pausingAod_softBlanks_withSpuriousSensorDuringPause() throws Exception { - mScreen.transitionTo(UNINITIALIZED, INITIALIZED); - mScreen.transitionTo(INITIALIZED, DOZE_AOD); - mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING); - mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED); - - mSensor.sendSensorEvent(1); - assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); - } - - @Test - public void screenOff_softBlanks() throws Exception { - mScreen.transitionTo(UNINITIALIZED, INITIALIZED); - mScreen.transitionTo(INITIALIZED, DOZE_AOD); - mScreen.transitionTo(DOZE_AOD, DOZE); - assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); - - mScreen.transitionTo(DOZE, DOZE_AOD); - mSensor.sendSensorEvent(2); - assertEquals(0f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); - } - @Test public void pausingAod_unblanksAfterSensor() throws Exception { mScreen.transitionTo(UNINITIALIZED, INITIALIZED); -- GitLab From b6cd9c2003d258e1f60a839d22720f442e150d52 Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Mon, 24 Feb 2020 11:51:43 +0800 Subject: [PATCH 145/219] Fix race condition while WallpaperMS rebinding service. Connection object could not receive onServiceConnected after new process of the service was active. How issue happen: 1. The process of wallpaper service died, AM schedule to restart, WallpaperMS schedule to rebind. 2. WallpaperMS bind service with new connection object. => ActiveService bring up new process. Add this ServiceRecord to mPendingServices. 3. WallpaperMS unbind previous connection object. => ActiveService remove previous connection, also remove this ServiceRecord object from mPendingServices list. 4. Process ready, attach application but cannot find the service from pendingServices. Solution: Do not remove the ServiceRecord object from mPendingServices if there is any connection left. Also use runnable object instead of method reference. Bug: 148834472 Test: atest WallpaperManagerTest WallpaperManagerServiceTests Change-Id: I3adec66de8ac0c7efc9ad3ffbf604b01eacb5720 Merged-In: I3adec66de8ac0c7efc9ad3ffbf604b01eacb5720 (cherry picked from commit d1551333823f4e86ec0e19b65c4faafeb617f87b) --- .../core/java/com/android/server/am/ActiveServices.java | 7 +++++-- .../android/server/wallpaper/WallpaperManagerService.java | 8 ++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 5d72828964c7..f03d9df6ed5f 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -3159,8 +3159,11 @@ public final class ActiveServices { } } - // If unbound while waiting to start, remove the pending service - mPendingServices.remove(s); + // If unbound while waiting to start and there is no connection left in this service, + // remove the pending service + if (s.getConnections().isEmpty()) { + mPendingServices.remove(s); + } if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { boolean hasAutoCreate = s.hasAutoCreateConnections(); diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index 4e136af0fdc3..0e2f0ce991c7 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -1180,6 +1180,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } }; + private Runnable mTryToRebindRunnable = () -> { + tryToRebind(); + }; + WallpaperConnection(WallpaperInfo info, WallpaperData wallpaper, int clientUid) { mInfo = info; mWallpaper = wallpaper; @@ -1286,7 +1290,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub saveSettingsLocked(mWallpaper.userId); } FgThread.getHandler().removeCallbacks(mResetRunnable); - mContext.getMainThreadHandler().removeCallbacks(this::tryToRebind); + mContext.getMainThreadHandler().removeCallbacks(mTryToRebindRunnable); } } } @@ -1344,7 +1348,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub < WALLPAPER_RECONNECT_TIMEOUT_MS) { // Bind fail without timeout, schedule rebind Slog.w(TAG, "Rebind fail! Try again later"); - mContext.getMainThreadHandler().postDelayed(this::tryToRebind, 1000); + mContext.getMainThreadHandler().postDelayed(mTryToRebindRunnable, 1000); } else { // Timeout Slog.w(TAG, "Reverting to built-in wallpaper!"); -- GitLab From 44f50d484de99b0801649ac052acd46c7be66192 Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Fri, 13 Mar 2020 16:55:42 +0800 Subject: [PATCH 146/219] [RESTRICT AUTOMERGE] Allow bar to be transparent during animating. When top window request fullscreen and device contain a real cutout and the layoutInDisplayCutout is default or never, a letterbox will be created for this activity, which cause BarController#isTransparentAllowed return false so the status bar cannot be transparent, the bar will shows a black background during hidding animation. A simple workaround is to allow the bar can be transparent during hidding, since the surface of letterbox is not really overlapped with bar because it's also animating. Bug: 150048810 Test: No black background shows on status bar when opening fullscreen app. Test: atest DisplayPolicyTests Change-Id: I2dd5b1fbad8e79ec80f799d63bba8824acc6a639 --- services/core/java/com/android/server/wm/BarController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/BarController.java b/services/core/java/com/android/server/wm/BarController.java index 90bb494232c7..338df39a1624 100644 --- a/services/core/java/com/android/server/wm/BarController.java +++ b/services/core/java/com/android/server/wm/BarController.java @@ -164,7 +164,8 @@ public class BarController { } boolean isTransparentAllowed(WindowState win) { - return win == null || !win.isLetterboxedOverlappingWith(mContentFrame); + return win == null || mState == StatusBarManager.WINDOW_STATE_HIDING + || !win.isLetterboxedOverlappingWith(mContentFrame); } boolean setBarShowingLw(final boolean show) { -- GitLab From a1c9c5433d8a3a5de757b90d59d63a8bede358b2 Mon Sep 17 00:00:00 2001 From: Bill Lin Date: Fri, 13 Mar 2020 16:09:43 +0800 Subject: [PATCH 147/219] DO NOT MERGE Optimizing ScreenDecorations performance Avoid calling onTuningChanged() when onConfigurationChanged() trigger Only calling onTuningChanged() when roundedCornersChanged is true. Test: atest SystemUITests Test: atest ScreenDecorationsTest Bug: 148912090 Change-Id: I2507d12b277d058cef390d7c55488d0d09dde206 Merged-In: Ie33526214072ad324ca00a10074ad212dfbf4258 --- .../SystemUI/src/com/android/systemui/ScreenDecorations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index e0a9bb166fb2..8e5d5a83750d 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -588,8 +588,8 @@ public class ScreenDecorations extends SystemUI implements Tunable, mRoundedDefaultTop = newRoundedDefaultTop; mRoundedDefaultBottom = newRoundedDefaultBottom; } + onTuningChanged(SIZE, null); } - onTuningChanged(SIZE, null); } private void updateViews() { -- GitLab From 07808d1477d03b50c6e5535cf54210dad8e4f133 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sun, 15 Mar 2020 15:03:31 -0700 Subject: [PATCH 148/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: Icdc4ac69264d3712e36961f588a783cc13122b4c --- core/res/res/values-af/strings.xml | 4 + core/res/res/values-am/strings.xml | 4 + core/res/res/values-ar/strings.xml | 90 ++++++++++++----------- core/res/res/values-as/strings.xml | 6 ++ core/res/res/values-az/strings.xml | 4 + core/res/res/values-b+sr+Latn/strings.xml | 6 +- core/res/res/values-be/strings.xml | 6 +- core/res/res/values-bg/strings.xml | 4 + core/res/res/values-bn/strings.xml | 8 +- core/res/res/values-bs/strings.xml | 4 + core/res/res/values-ca/strings.xml | 28 ++++--- core/res/res/values-cs/strings.xml | 4 + core/res/res/values-da/strings.xml | 4 + core/res/res/values-de/strings.xml | 4 + core/res/res/values-el/strings.xml | 4 + core/res/res/values-en-rAU/strings.xml | 4 + core/res/res/values-en-rCA/strings.xml | 4 + core/res/res/values-en-rGB/strings.xml | 4 + core/res/res/values-en-rIN/strings.xml | 4 + core/res/res/values-en-rXC/strings.xml | 4 + core/res/res/values-es-rUS/strings.xml | 8 +- core/res/res/values-es/strings.xml | 12 ++- core/res/res/values-et/strings.xml | 4 + core/res/res/values-eu/strings.xml | 18 +++-- core/res/res/values-fa/strings.xml | 4 + core/res/res/values-fi/strings.xml | 4 + core/res/res/values-fr-rCA/strings.xml | 6 +- core/res/res/values-fr/strings.xml | 4 + core/res/res/values-gl/strings.xml | 4 + core/res/res/values-gu/strings.xml | 8 +- core/res/res/values-hi/strings.xml | 6 ++ core/res/res/values-hr/strings.xml | 4 + core/res/res/values-hu/strings.xml | 4 + core/res/res/values-hy/strings.xml | 8 +- core/res/res/values-in/strings.xml | 6 +- core/res/res/values-is/strings.xml | 4 + core/res/res/values-it/strings.xml | 8 +- core/res/res/values-iw/strings.xml | 4 + core/res/res/values-ja/strings.xml | 8 +- core/res/res/values-ka/strings.xml | 4 + core/res/res/values-kk/strings.xml | 4 + core/res/res/values-km/strings.xml | 4 + core/res/res/values-kn/strings.xml | 8 +- core/res/res/values-ko/strings.xml | 4 + core/res/res/values-ky/strings.xml | 60 ++++++++------- core/res/res/values-lo/strings.xml | 4 + core/res/res/values-lt/strings.xml | 4 + core/res/res/values-lv/strings.xml | 4 + core/res/res/values-mk/strings.xml | 14 ++-- core/res/res/values-ml/strings.xml | 6 ++ core/res/res/values-mn/strings.xml | 4 + core/res/res/values-mr/strings.xml | 8 +- core/res/res/values-ms/strings.xml | 4 + core/res/res/values-my/strings.xml | 6 +- core/res/res/values-nb/strings.xml | 6 +- core/res/res/values-ne/strings.xml | 6 ++ core/res/res/values-nl/strings.xml | 4 + core/res/res/values-or/strings.xml | 6 ++ core/res/res/values-pa/strings.xml | 4 + core/res/res/values-pl/strings.xml | 12 ++- core/res/res/values-pt-rBR/strings.xml | 10 ++- core/res/res/values-pt-rPT/strings.xml | 4 + core/res/res/values-pt/strings.xml | 10 ++- core/res/res/values-ro/strings.xml | 4 + core/res/res/values-ru/strings.xml | 10 ++- core/res/res/values-si/strings.xml | 4 + core/res/res/values-sk/strings.xml | 6 +- core/res/res/values-sl/strings.xml | 4 + core/res/res/values-sq/strings.xml | 16 ++-- core/res/res/values-sr/strings.xml | 6 +- core/res/res/values-sv/strings.xml | 8 +- core/res/res/values-sw/strings.xml | 8 +- core/res/res/values-ta/strings.xml | 44 ++++++----- core/res/res/values-te/strings.xml | 4 + core/res/res/values-th/strings.xml | 4 + core/res/res/values-tl/strings.xml | 4 + core/res/res/values-tr/strings.xml | 4 + core/res/res/values-uk/strings.xml | 4 + core/res/res/values-ur/strings.xml | 6 ++ core/res/res/values-uz/strings.xml | 4 + core/res/res/values-vi/strings.xml | 4 + core/res/res/values-zh-rCN/strings.xml | 4 + core/res/res/values-zh-rHK/strings.xml | 6 +- core/res/res/values-zh-rTW/strings.xml | 4 + core/res/res/values-zu/strings.xml | 4 + 85 files changed, 524 insertions(+), 162 deletions(-) diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index c1723908441c..807fe648a2d5 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -434,6 +434,8 @@ "Hierdie program kan jou fisieke aktiwiteit herken." "neem foto\'s en video\'s" "Hierdie program kan enige tyd met die kamera foto\'s neem en video\'s opneem." + "Laat \'n program of diens toe om terugbeloproepe te ontvang oor kameratoestelle wat oopgemaak of toegemaak word." + "Hierdie handtekeningprogram kan terugbeloproepe ontvang wanneer enige kameratoestel oopgemaak (deur watter programpakket) of toegemaak word." "beheer vibrasie" "Laat die program toe om die vibrator te beheer." "skakel foonnommers direk" @@ -450,9 +452,11 @@ "Laat die program toe om \'n oproep voort te sit wat in \'n ander program begin is." "lees foonnommers" "Laat die program toe om toegang tot die toestel se foonnommers te kry." + "hou motorskerm aan" "verhoed dat tablet slaap" "keer TV om te sluimer" "verhoed foon om te slaap" + "Laat die program toe om die motorskerm aan te hou." "Laat die program toe om die tablet te keer om te slaap." "Laat die program toe om die TV te keer om te sluimer." "Laat die program toe om die foon te keer om te slaap." diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 5a6d63537048..a7102271e4f8 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -434,6 +434,8 @@ "ይህ መተግበሪያ አካላዊ እንቅስቃሴዎን ለይቶ ሊያውቅ ይችላል።" "ፎቶዎች እና ቪዲዮዎች ያንሱ" "ይህ መተግበሪያ በማናቸውም ጊዜ ካሜራውን በመጠቀም ፎቶ ሊያነሳ እና ቪዲዮዎችን ሊቀርጽ ይችላል።" + "አንድ መተግበሪያ ወይም አገልግሎት እየተከፈቱ ወይም እየተዘጉ ስላሉ የካሜራ መሣሪያዎች መልሶ ጥሪዎችን እንዲቀበል ይፍቀዱ።" + "ማንኛውም የካሜራ መሣሪያ እየተከፈተ (በምን የመተግበሪያ ጥቅል) ወይም እየተዘጋ ሲሆን ይህ የፊርማ መተግበሪያ መልሶ ጥሪዎችን መቀበል ይችላል።" "ነዛሪ ተቆጣጠር" "ነዛሪውን ለመቆጣጠር ለመተግበሪያው ይፈቅዳሉ።" "በቀጥታ ስልክ ቁጥሮች ደውል" @@ -450,9 +452,11 @@ "መተግበሪያው በሌላ መተግበሪያ ውስጥ የተጀመረ ጥሪ እንዲቀጥል ያስችለዋል።" "ስልክ ቁጥሮች ያንብቡ" "መተግበሪያው የመሣሪያውን የስልክ ቁጥሮች እንዲደርስባቸው ይፈቅድለታል።" + "የመኪና ማያ ገጽ እንደበራ አቆይ" "ጡባዊ ከማንቀላፋት ተከላከል" "ቴሌቪዥን እንዳይተኛ አግድ" "ስልክ ከማንቀላፋት ተከላከል" + "መተግበሪያው የመኪናው ማያ ገጽ እንደበራ እንዲያቆየው ያስችለዋል።" "ጡባዊውን ከመተኛት መከልከል ለመተግበሪያው ይፈቅዳሉ።" "መተግበሪያው ቴሌቪዥኑ እንዳይተኛ እንዲያግድ ያስችለዋል።" "ስልኩን ከመተኛት መከልከል ለመተግበሪያው ይፈቅዳሉ።" diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 954ffd3b50d5..3cbf14558666 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -49,7 +49,7 @@ "‏اكتب رمز PUK مكونًا من ٨ أرقام أو أكثر." "‏شريحة SIM مؤمّنة برمز PUK. اكتب رمز PUK لإلغاء تأمينها." "‏اكتب PUK2 لإلغاء تأمين شريحة SIM." - "‏محاولة غير ناجحة، مكّن قفل SIM/RUIM." + "‏محاولة غير ناجحة، فعّل قفل SIM/RUIM." ‏لم يتبق لديك أي محاولات (%d) يتم بعدها قفل شريحة SIM. ‏يتبقى لديك محاولتان (%d) يتم بعدهما قفل شريحة SIM. @@ -123,12 +123,12 @@ "التجوال - شريك متميز" "تجوال - وظائف الخدمة الكاملة" "تجوال - وظائف الخدمة الجزئية" - "إعلان بانر للتجوال قيد التشغيل" + "إعلان بانر للتجوال قيد التفعيل" "إعلان بانر للتجوال متوقف" "البحث عن خدمة" "‏تعذّر إعداد الاتصال عبر Wi‑Fi." - "‏لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذه الخدمة، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات. (رمز الخطأ: %1$s)" + "‏لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مفعِّل شبكة الجوّال أولاً إعداد هذه الخدمة، ثم فعِّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات. (رمز الخطأ: %1$s)" "‏حدثت مشكلة أثناء تسجيل الاتصال عبر Wi‑Fi باستخدام مشغِّل شبكة الجوّال: %1$s" @@ -206,8 +206,8 @@ "خيارات التلفزيون" "خيارات الهاتف" "وضع صامت" - "تشغيل اللاسلكي" - "إيقاف تشغيل الشبكة اللاسلكية" + "تفعيل اللاسلكي" + "إيقاف تفعيل الشبكة اللاسلكية" "قفل الشاشة" "إيقاف التشغيل" "إيقاف الرنين" @@ -217,13 +217,13 @@ "جارٍ الإعداد للتحديث…" "جارٍ معالجة حزمة التحديث…" "جارٍ إعادة التشغيل…" - "إعادة الضبط بحسب بيانات المصنع" + "إعادة الضبط على الإعدادات الأصلية" "جارٍ إعادة التشغيل…" "جارٍ إيقاف التشغيل..." - "سيتم إيقاف تشغيل الجهاز اللوحي." + "سيتم إيقاف تفعيل الجهاز اللوحي." "سيتم إيقاف التلفزيون." "سيتم إيقاف المشاهدة." - "سيتم إيقاف تشغيل هاتفك." + "سيتم إيقاف تفعيل هاتفك." "هل تريد إيقاف التشغيل؟" "إعادة تشغيل في الوضع الآمن" "هل تريد إعادة تشغيل الكمبيوتر في الوضع الآمن؟ سيؤدي ذلك إلى إيقاف جميع تطبيقات الجهات الخارجية التي تم تثبيتها. ستتم استعادتها عند إعادة التشغيل مرة أخرى." @@ -254,9 +254,9 @@ "وضع صامت" "الصوت متوقف" - "الصوت قيد التشغيل" + "الصوت قيد التفعيل" "وضع الطائرة" - "وضع الطائرة قيد التشغيل" + "وضع الطائرة قيد التفعيل" "وضع الطائرة متوقف" "الإعدادات" "مساعدة" @@ -327,8 +327,8 @@ "‏هل تريد السماح لتطبيق <b>%1$s</b> بالدخول إلى بيانات المستشعر حول علاماتك الحيوية؟" "استرداد محتوى النافذة" "فحص محتوى نافذة يتم التفاعل معها" - "تشغيل الاستكشاف باللمس" - "سيتم نطق العناصر التي تم النقر عليها بصوت عال ويمكن استكشاف الشاشة باستخدام الإيماءات." + "تفعيل الاستكشاف باللمس" + "سيتم قول العناصر التي تم النقر عليها بصوت عال ويمكن استكشاف الشاشة باستخدام الإيماءات." "ملاحظة النص الذي تكتبه" "يتضمن بيانات شخصية مثل أرقام بطاقات الائتمان وكلمات المرور." "التحكم في تكبير الشاشة" @@ -374,7 +374,7 @@ "إعادة ترتيب التطبيقات قيد التشغيل" "للسماح للتطبيق بنقل المهام إلى المقدمة والخلفية. وقد يجري التطبيق ذلك بدون إذنك." "تفعيل وضع السيارة" - "للسماح للتطبيق بتمكين وضع السيارة." + "للسماح للتطبيق بتفعيل وضع السيارة." "إغلاق التطبيقات الأخرى" "للسماح للتطبيق بإنهاء عمليات التطبيقات الأخرى في الخلفية. وقد يؤدي هذا إلى توقف تطبيقات أخرى عن العمل." "يمكن لهذا التطبيق الظهور في مقدمة التطبيقات الأخرى" @@ -426,7 +426,7 @@ "يمكن لهذا التطبيق إضافة أحداث تقويم أو إزالتها أو تغييرها على التلفزيون. كما يمكنه إرسال رسائل تبدو أنها من أصحاب التقويم، أو تغيير الأحداث بدون إشعار مالكيها." "يمكن لهذا التطبيق إضافة أحداث تقويم أو إزالتها أو تغييرها على الهاتف. كما يمكنه إرسال رسائل يبدو أنها واردة من مالكي التقويم، ويمكنه كذلك تغيير الأحداث بدون إشعار مالكيها." "الدخول إلى المزيد من أوامر موفر الموقع" - "‏للسماح للتطبيق بالدخول إلى أوامر إضافية لموفر الموقع. قد يتيح هذا للتطبيق التداخل مع تشغيل تقنية نظام تحديد المواقع العالمي (GPS) أو مصادر الموقع الأخرى." + "‏للسماح للتطبيق بالدخول إلى أوامر إضافية لموفر الموقع. قد يتيح هذا للتطبيق التداخل مع تفعيل تقنية نظام تحديد المواقع العالمي (GPS) أو مصادر الموقع الأخرى." "الوصول إلى الموقع الجغرافي الدقيق في الواجهة الأمامية فقط" "لا يمكن لهذا التطبيق معرفة موقعك الجغرافي بالضبط إلا عندما يعمل في الخلفية. ويجب تفعيل خدمات الموقع الجغرافي هذه وأن تكون متاحة على الهاتف حتى يتمكن التطبيق من استخدامها. وقد يؤدي هذا إلى زيادة استهلاك طاقة البطارية." "الوصول إلى الموقع الجغرافي التقريبي (بالاعتماد على الشبكة) في الخلفية فقط" @@ -446,6 +446,8 @@ "يمكن لهذا التطبيق التعرّف على نشاطك البدني." "التقاط صور وفيديوهات" "يمكن لهذا التطبيق التقاط صور وتسجيل فيديوهات باستخدام الكاميرا في أي وقت." + "يسمح الإذن لتطبيق أو خدمة بتلقّي استدعاءات عما إذا كانت أجهزة الكاميرات مفتوحة أو مغلقة." + "يمكن أن يتلقّى تطبيق التوقيع هذا استدعاءات عندما يكون جهاز أي كاميرا مفتوحًا (بحزمة تطبيق) أو مغلقًا." "التحكم في الاهتزاز" "للسماح للتطبيق بالتحكم في الهزّاز." "اتصال مباشر بأرقام الهواتف" @@ -462,9 +464,11 @@ "السماح للتطبيق بمواصلة مكالمة بدأت في تطبيق آخر." "قراءة أرقام الهواتف" "للسماح للتطبيق بالوصول إلى أرقام الهواتف على هذا الجهاز." + "الاحتفاظ بشاشة السيارة مفعَّلة" "منع الجهاز اللوحي من الدخول في وضع السكون" "منع التلفزيون من الدخول في وضع السكون" "منع الهاتف من الدخول في وضع السكون" + "يسمح هذا الإذن للتطبيق بالاحتفاظ بشاشة السيارة مفعَّلة." "للسماح للتطبيق بمنع الجهاز اللوحي من الانتقال إلى وضع السكون." "يتيح للتطبيق منع التلفزيون من الدخول في وضع السكون." "للسماح للتطبيق بمنع الهاتف من الانتقال إلى وضع السكون." @@ -609,8 +613,8 @@ "رمز الوجه" "قراءة إعدادات المزامنة" "للسماح للتطبيق بقراءة الإعدادات المتزامنة لحساب ما. على سبيل المثال، يمكن أن يؤدي هذا إلى تحديد ما إذا تمت مزامنة تطبيق \"الأشخاص\" مع حساب ما." - "التبديل بين تشغيل المزامنة وإيقافها" - "للسماح للتطبيق بتعديل إعدادات المزامنة لحساب ما. على سبيل المثال، يمكن استخدام ذلك لتمكين مزامنة تطبيق \"الأشخاص\" مع حساب ما." + "التبديل بين تفعيل المزامنة وإيقافها" + "للسماح للتطبيق بتعديل إعدادات المزامنة لحساب ما. على سبيل المثال، يمكن استخدام ذلك لتفعيل مزامنة تطبيق \"الأشخاص\" مع حساب ما." "قراءة إحصاءات المزامنة" "للسماح للتطبيق بقراءة إحصائيات المزامنة لحساب ما، بما في ذلك سجل الأحداث المتزامنة ومقدار البيانات التي تمت مزامنتها." "قراءة محتوى مساحة التخزين المشتركة" @@ -679,7 +683,7 @@ "قفل الشاشة" "التحكّم في طريقة ووقت قفل الشاشة" "محو جميع البيانات" - "يمكنك محو بيانات الجهاز اللوحي بدون تحذير، وذلك عبر إجراء إعادة الضبط بحسب بيانات المصنع." + "يمكنك محو بيانات الجهاز اللوحي بدون تحذير، وذلك عبر إجراء إعادة الضبط على الإعدادات الأصلية." "محو بيانات التلفزيون بدون تحذير من خلال إجراء إعادة ضبط البيانات على الإعدادات الأصلية." "محو بيانات الهاتف بدون تحذير، وذلك من خلال إعادة ضبط البيانات على الإعدادات الأصلية" "محو بيانات المستخدم" @@ -690,8 +694,8 @@ "لضبط الخادم الوكيل العام في الجهاز على الاستخدام أثناء تفعيل السياسة. ولن يمكن لأحد سوى مالك الجهاز ضبط الخادم الوكيل العام." "تعيين مدة انتهاء صلاحية كلمة مرور قفل الشاشة" "لتغيير عدد مرات تغيير كلمة المرور ورقم التعريف الشخصي والنمط في قفل الشاشة." - "تعيين تشفير التخزين" - "يمكنك طلب تشفير بيانات التطبيق المخزنة." + "تعيين ترميز التخزين" + "يمكنك طلب ترميز بيانات التطبيق المخزنة." "إيقاف الكاميرات" "يمكنك منع استخدام جميع كاميرات الجهاز." "إيقاف بعض ميزات قفل الشاشة" @@ -845,7 +849,7 @@ "إيقاف مؤقت" "تشغيل" "إيقاف" - "إرجاع" + "ترجيع" "تقديم سريع" "مكالمات الطوارئ فقط" "الشبكة مؤمّنة" @@ -859,12 +863,12 @@ "‏لقد رسمت نقش فتح القفل بشكل غير صحيح %1$d مرة. بعد %2$d من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات تسجيل الدخول إلى Google.\n\n أعد المحاولة خلال %3$d ثانية." "‏لديك %1$d من محاولات رسم نقش فتح القفل غير الصحيحة. بعد %2$d من المحاولات غير الناجحة الأخرى، سيُطلب منك فتح قفل التلفزيون من خلال تسجيل الدخول إلى Google.\n\n يمكنك إعادة التجربة خلال %3$d ثانية." "‏لقد رسمت نقش فتح القفل بشكل غير صحيح %1$d مرة. بعد %2$d من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام معلومات تسجيل الدخول إلى Google.\n\n أعد المحاولة خلال %3$d ثانية." - "لقد حاولت فتح قفل الجهاز اللوحي %1$d من المرات. بعد %2$d من المحاولات غير الناجحة، ستتم إعادة تعيين الجهاز اللوحي إلى الإعدادات الأساسية وسيتم فقد جميع بيانات المستخدم." + "لقد حاولت فتح قفل الجهاز اللوحي %1$d من المرات. بعد %2$d من المحاولات غير الناجحة، ستتم إعادة ضبط الجهاز اللوحي إلى الإعدادات الأساسية وسيتم فقد جميع بيانات المستخدم." "لديك %1$d من محاولات فتح قفل التلفزيون غير الصحيحة. بعد %2$d من المحاولات غير الناجحة الأخرى، ستتم إعادة ضبط التلفزيون على الإعدادات الأساسية وستفقد جميع بيانات المستخدم." - "لقد حاولت فتح قفل الهاتف %1$d من المرات. بعد %2$d من المحاولات غير الناجحة، ستتم إعادة تعيين الهاتف إلى الإعدادات الأساسية وسيتم فقد جميع بيانات المستخدم." - "لقد حاولت فتح قفل الجهاز اللوحي %d من المرات بشكل غير صحيح. سيتم الآن إعادة تعيين الجهاز اللوحي إلى الإعدادات الأساسية." + "لقد حاولت فتح قفل الهاتف %1$d من المرات. بعد %2$d من المحاولات غير الناجحة، ستتم إعادة ضبط الهاتف إلى الإعدادات الأساسية وسيتم فقد جميع بيانات المستخدم." + "لقد حاولت فتح قفل الجهاز اللوحي %d من المرات بشكل غير صحيح. سيتم الآن إعادة ضبط الجهاز اللوحي إلى الإعدادات الأساسية." "لديك %d من محاولات فتح قفل التلفزيون غير الصحيحة. ستتم الآن إعادة ضبط التلفزيون على الإعدادات الأساسية." - "لقد حاولت فتح قفل الهاتف %d من المرات بشكل غير صحيح. سيتم الآن إعادة تعيين الهاتف إلى الإعدادات الأساسية." + "لقد حاولت فتح قفل الهاتف %d من المرات بشكل غير صحيح. سيتم الآن إعادة ضبط الهاتف إلى الإعدادات الأساسية." "حاول مرة أخرى خلال %d ثانية." "هل نسيت النمط؟" "فتح قفل الحساب" @@ -920,7 +924,7 @@ "‏لم يتم العثور على أي حزمة توفر إجراء FACTORY_TEST." "إعادة تشغيل" "تعرض الصفحة في \"%s\":" - "جافا سكريبت" + "JavaScript" "تأكيد الانتقال" "مغادرة هذه الصفحة" "البقاء في هذه الصفحة" @@ -984,8 +988,8 @@ "إرسال طلب البحث" "البحث الصوتي" "‏هل تريد تفعيل ميزة Explore by Touch؟" - "‏يريد %1$s تفعيل ميزة Explore by Touch. عند تشغيل ميزة Explore by Touch، سيكون بإمكانك سماع أو مشاهدة أوصاف لما تحت إصبعك أو إجراء إيماءات للتفاعل مع الجهاز اللوحي." - "‏يريد %1$s تفعيل ميزة Explore by Touch. عند تشغيل ميزة Explore by Touch، سيكون بإمكانك سماع أو مشاهدة أوصاف لما تحت إصبعك أو إجراء إيماءات للتفاعل مع الهاتف." + "‏يريد %1$s تفعيل ميزة Explore by Touch. عند تفعيل ميزة Explore by Touch، سيكون بإمكانك سماع أو مشاهدة أوصاف لما تحت إصبعك أو إجراء إيماءات للتفاعل مع الجهاز اللوحي." + "‏يريد %1$s تفعيل ميزة Explore by Touch. عند تفعيل ميزة Explore by Touch، سيكون بإمكانك سماع أو مشاهدة أوصاف لما تحت إصبعك أو إجراء إيماءات للتفاعل مع الهاتف." "قبل شهر واحد" "قبل شهر واحد" @@ -1253,7 +1257,7 @@ "%1$s لا يستجيب" "%1$s لا يستجيب" "العملية %1$s لا تستجيب" - "موافق" + "حسنًا" "إرسال تقرير" "انتظار" "أصبحت الصفحة لا تستجيب.\n\nهل تريد إغلاقها؟" @@ -1356,7 +1360,7 @@ "شبكات %s المقترحة - قد يتم توصيل الجهاز تلقائيًا." "سماح" "لا، شكرًا" - "‏سيتم تشغيل شبكة Wi-Fi تلقائيًا." + "‏سيتم تفعيل شبكة Wi-Fi تلقائيًا." "عندما تكون بالقرب من شبكة محفوظة عالية الجودة" "عدم إعادة التشغيل" "‏تم تفعيل شبكة Wi-Fi تلقائيًا." @@ -1392,7 +1396,7 @@ "‏اتصال Wi-Fi مباشر" "‏ابدأ Wi-Fi Direct. يؤدي هذا إلى إيقاف عميل/نقطة اتصال Wi-Fi." "‏تعذر بدء Wi-Fi Direct." - "‏تم تشغيل اتصال Wi-Fi المباشر" + "‏تم تفعيل اتصال Wi-Fi المباشر" "انقر للحصول على الإعدادات." "قبول" "رفض" @@ -1456,7 +1460,7 @@ "‏اختيار إيقاف تصحيح أخطاء USB." "تم تفعيل وضع \"مفعّل الاختبار\"" "يمكنك إجراء إعادة ضبط على الإعدادات الأصلية لإيقاف وضع \"مفعِّل اختبار\"." - "‏السوائل والشوائب في منفذ USB" + "‏السوائل أو الشوائب في منفذ USB" "‏تمّ إيقاف منفذ USB تلقائيًا. انقُر لمعرفة المزيد من المعلومات." "‏مسموح باستخدام منفذ USB" "لم يَعُد الهاتف يكتشف سوائل أو شوائب." @@ -1562,8 +1566,8 @@ "‏تم تفعيل VPN بواسطة %s" "انقر لإدارة الشبكة." "تم الاتصال بـ %s. انقر لإدارة الشبكة." - "‏جارٍ الاتصال بشبكة افتراضية خاصة (VPN) دائمة التشغيل..." - "‏تم الاتصال بشبكة افتراضية خاصة (VPN) دائمة التشغيل" + "‏جارٍ الاتصال بشبكة افتراضية خاصة (VPN) دائمة التفعيل..." + "‏تم الاتصال بشبكة افتراضية خاصة (VPN) دائمة التفعيل" "‏تم قطع الاتصال بالشبكة الافتراضية الخاصة (VPN) التي يتم تشغيلها دائمًا" "‏تعذّر الاتصال بشبكة VPN التي يتم تشغيلها دائمًا." "‏تغيير إعدادات الشبكة أو الشبكة الافتراضية الخاصة (VPN)" @@ -1753,12 +1757,12 @@ "‏لقد كتبت رمز PIN بشكل غير صحيح %1$d مرة. \n\nأعد المحاولة خلال %2$d ثانية." "لقد كتبت كلمة المرور بشكل غير صحيح %1$d مرة. \n\nأعد المحاولة خلال %2$d ثانية." "لقد رسمت نقش فتح القفل بطريقة غير صحيحة %1$d مرة. \n\nأعد المحاولة خلال %2$d ثانية." - "لقد حاولت فتح قفل الجهاز اللوحي بشكل غير صحيح %1$d مرة. بعد إجراء %2$d من المحاولات غير الناجحة الأخرى، ستتم إعادة تعيين الجهاز اللوحي على الإعدادات الأساسية وسيتم فقد جميع بيانات المستخدم." + "لقد حاولت فتح قفل الجهاز اللوحي بشكل غير صحيح %1$d مرة. بعد إجراء %2$d من المحاولات غير الناجحة الأخرى، ستتم إعادة ضبط الجهاز اللوحي على الإعدادات الأساسية وسيتم فقد جميع بيانات المستخدم." "لديك %1$d من محاولات فتح قفل التلفزيون غير الصحيحة. بعد %2$d من المحاولات غير الناجحة الأخرى، ستتم إعادة ضبط التلفزيون على الإعدادات الأساسية وستفقد جميع بيانات المستخدم." - "لقد حاولت فتح قفل الهاتف بشكل غير صحيح %1$d مرة. بعد إجراء %2$d من المحاولات غير الناجحة الأخرى، ستتم إعادة تعيين الهاتف على الإعدادات الأساسية وسيتم فقد جميع بيانات المستخدم." - "لقد حاولت فتح قفل الجهاز اللوحي بشكل غير صحيح %d مرة. سيتم الآن إعادة تعيين الجهاز اللوحي على الإعدادات الأساسية." + "لقد حاولت فتح قفل الهاتف بشكل غير صحيح %1$d مرة. بعد إجراء %2$d من المحاولات غير الناجحة الأخرى، ستتم إعادة ضبط الهاتف على الإعدادات الأساسية وسيتم فقد جميع بيانات المستخدم." + "لقد حاولت فتح قفل الجهاز اللوحي بشكل غير صحيح %d مرة. سيتم الآن إعادة ضبط الجهاز اللوحي على الإعدادات الأساسية." "لديك %d من محاولات فتح قفل التلفزيون غير الصحيحة. ستتم الآن إعادة ضبط التلفزيون على الإعدادات الأساسية." - "لقد حاولت فتح قفل الهاتف بشكل غير صحيح %d مرة. سيتم الآن إعادة تعيين الهاتف على الإعدادات الأساسية." + "لقد حاولت فتح قفل الهاتف بشكل غير صحيح %d مرة. سيتم الآن إعادة ضبط الهاتف على الإعدادات الأساسية." "لقد رسمت نقش فتح القفل بشكل غير صحيح %1$d مرة. بعد إجراء %2$d من المحاولات غير الناجحة الأخرى، ستطالَب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات حساب بريد إلكتروني.\n\n أعد المحاولة خلال %3$d ثانية." "لقد رسمت نقش فتح القفل بشكل غير صحيح عدد %1$d من المرات. بعد %2$d من المحاولات غير الناجحة، سيُطلب منك فتح قفل التلفزيون باستخدام حساب بريد إلكتروني.\n\n يمكنك إعادة التجربة خلال %3$d ثانية." "لقد رسمت نقش فتح القفل بشكل غير صحيح %1$d مرة. بعد إجراء %2$d من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام حساب بريد إلكتروني لإلغاء تأمين الهاتف.\n\n أعد المحاولة خلال %3$d ثانية." @@ -1916,12 +1920,12 @@ "تم التثبيت بواسطة المشرف" "تم التحديث بواسطة المشرف" "تم الحذف بواسطة المشرف" - "موافق" + "حسنًا" "‏لإطالة عمر البطارية، \"توفير شحن البطارية\":\n·تفعيل \"التصميم الداكن\"\n إيقاف النشاط في الخلفية أو تقييده وأيضًا بعض التأثيرات المرئية والميزات الأخرى، مثلاً \"Ok Google\"\n\n""مزيد من المعلومات" "‏لإطالة عمر البطارية، \"توفير شحن البطارية\":\n·تفعيل \"التصميم الداكن\"\n إيقاف النشاط في الخلفية أو تقييده وأيضًا بعض التأثيرات المرئية والميزات الأخرى، مثلاً \"Ok Google\"." "للمساعدة في خفض استخدام البيانات، تمنع ميزة \"توفير البيانات\" بعض التطبيقات من إرسال البيانات وتلقّيها في الخلفية. يمكن للتطبيق الذي تستخدمه الآن الوصول إلى البيانات، ولكن لا يمكنه تنفيذ ذلك كثيرًا. وهذا يعني أن الصور مثلاً لا تظهر حتى تنقر عليها." - "هل تريد تشغيل توفير البيانات؟" - "تشغيل" + "هل تريد تفعيل توفير البيانات؟" + "تفعيل" ‏لمدة أقل من دقيقة (%1$d) (حتى %2$s) ‏لمدة دقيقتين (%1$d) (حتى %2$s) @@ -1999,7 +2003,7 @@ "حدث" "النوم" "يعمل %1$s على كتم بعض الأصوات." - "حدثت مشكلة داخلية في جهازك، وقد لا يستقر وضعه حتى إجراء إعادة الضبط بحسب بيانات المصنع." + "حدثت مشكلة داخلية في جهازك، وقد لا يستقر وضعه حتى إجراء إعادة الضبط على الإعدادات الأصلية." "حدثت مشكلة داخلية في جهازك. يمكنك الاتصال بالمصنِّع للحصول على تفاصيل." "‏تم تغيير طلب USSD إلى مكالمة عادية." "‏تم تغيير طلب USSD إلى طلب SS." @@ -2047,7 +2051,7 @@ "مزيد من المعلومات" "تفعيل الملف الشخصي للعمل؟" "سيتم تفعيل تطبيقات العمل التي تستخدمها والإشعارات والبيانات وغيرها من ميزات الملف الشخصي للعمل" - "تشغيل" + "تفعيل" "‏تمّ إنشاء هذا التطبيق لإصدار قديم من Android وقد لا يعمل بشكل صحيح. جرِّب البحث عن تحديثات أو الاتصال بمطوّر البرامج." "البحث عن تحديث" "لديك رسائل جديدة" @@ -2062,7 +2066,7 @@ "معلومات عن التطبيق" "−%1$s" "جارٍ بدء العرض التوضيحي…" - "جارٍ إعادة تعيين الجهاز…" + "جارٍ إعادة ضبط الجهاز…" "تم إيقاف %1$s" "مكالمة جماعية" "تلميح" diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 176b5f9922d0..0af9b14ab1b5 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -434,6 +434,10 @@ "এই এপটোৱে আপোনাৰ শাৰীৰিক কাৰ্যকলাপ চিনাক্ত কৰিব পাৰে।" "ফট\' তোলা আৰু ভিডিঅ\' ৰেকৰ্ড কৰা" "এই এপে যিকোনো সময়তে কেমেৰা ব্যৱহাৰ কৰি ফট\' তুলিব আৰু ভিডিঅ\' ৰেকর্ড কৰিব পাৰে।" + + + + "কম্পন নিয়ন্ত্ৰণ কৰক" "ভাইব্ৰেটৰ নিয়ন্ত্ৰণ কৰিবলৈ এপটোক অনুমতি দিয়ে।" "পোনপটীয়াকৈ ফ\'ন নম্বৰলৈ কল কৰক" @@ -450,9 +454,11 @@ "এপটোক এনে কল কৰিবলৈ দিয়ে যিটোৰ আৰম্ভণি অইন এটা এপত হৈছিল।" "ফ\'ন নম্বৰসমূহ পঢ়ে" "এপটোক ডিভাইচটোৰ ফ\'ন নম্বৰসমূহ চাবলৈ অনুমতি দিয়ে।" + "গাড়ীৰ স্ক্রীনখন অন কৰি ৰখা" "টে\'বলেট সুপ্ত অৱস্থালৈ যোৱাত বাধা দিয়ক" "টিভি সুপ্ত অৱস্থালৈ যোৱাত বাধা দিয়ে" "ফ\'ন সুপ্ত অৱস্থালৈ যোৱাত বাধা দিয়ক" + "এপ্‌টোক গাড়ীৰ স্ক্রীনখন অন কৰি ৰাখিবলৈ অনুমতি দিয়ে।" "টে\'বলেট সুপ্ত অৱস্থালৈ যোৱাৰ পৰা প্ৰতিৰোধ কৰিবলৈ এপটোক অনুমতি দিয়ে।" "টিভিটোক সুপ্ত অৱস্থালৈ যোৱাৰ পৰা প্ৰতিৰোধ কৰিবলৈ এপটোক অনুমতি দিয়ে।" "ফ\'ন সুপ্ত অৱস্থালৈ যোৱাৰ পৰা প্ৰতিৰোধ কৰিবলৈ এপটোক অনুমতি দিয়ে।" diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index d15fd8d1899a..14a8493c6ad7 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -434,6 +434,8 @@ "Bu tətbiq fiziki fəaliyyətinizi tanıya bilər." "şəkil və video çəkmək" "Bu tətbiq istədiyiniz zaman kameranı istifadə edərək şəkil çəkə və video qeydə ala bilər." + "Tətbiqə və ya xidmətə kamera cihazlarının açılması və ya bağlanması haqqında geri zənglər qəbul etməyə icazə verin." + "Hər hansı kamera cihazı açıldıqda (hansı tətbiq paketi tərəfindən) və ya bağlandıqda bu imza tətbiqi geri zənglər qəbul edə bilər." "vibrasiyaya nəzarət edir" "Tətbiqə vibratoru idarə etmə icazəsi verir." "telefon nömrələrinə birbaşa zəng edir" @@ -450,9 +452,11 @@ "Tətbiqə digər tətbiqdə başlayan zəngə davam etmək icazəsi verilir." "telefon nömrələrini oxuyun" "Tətbiqə cihazın telefon nömrələrinə daxil olmağa icazə verir." + "avtomobilin ekranını aktiv saxlamaq" "planşetin yuxu rejiminin qarşısını almaq" "TV-ni yuxu rejiminə keçməyə qoyma" "telefonun yuxu rejiminə keçməsini əngəllə" + "Tətbiqə avtomobilin ekranını aktiv saxlamaq icazəsi verir." "Tətbiqə planşetin yuxu rejimini qadağan etməyə imkan verir." "Proqrama TV-ni yuxulamağa qoymamaq imkanı verir." "Tətbiqə telefonun yuxu rejimini qadağan etmək imkanı verir." diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 837973d9f1fe..291f54099128 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -297,7 +297,7 @@ "Želite li da omogućite da <b>%1$s</b> šalje i pregleda SMS-ove?" "Memorijski prostor" "pristupa slikama, medijima i datotekama na uređaju" - "Želite li da omogućite da <b>%1$s</b> pristupa slikama, medijskim datotekama i datotekama na uređaju?" + "Želite li da omogućite da <b>%1$s</b> pristupa slikama, medijskim i drugim datotekama na uređaju?" "Mikrofon" "snima zvuk" "Želite li da omogućite da <b>%1$s</b> snima zvuk?" @@ -437,6 +437,8 @@ "Ova aplikacija može da prepozna fizičke aktivnosti." "snimanje fotografija i video snimaka" "Ova aplikacija može da snima fotografije i video snimke pomoću kamere u bilo kom trenutku." + "Dozvolite aplikaciji ili usluzi da dobija povratne pozive o otvaranju ili zatvaranju uređaja sa kamerom." + "Ova aplikacija za potpise može da dobija povratne pozive kada se bilo koji uređaj sa kamerom otvara ili zatvara (pomoću nekog paketa aplikacija)." "kontrola vibracije" "Dozvoljava aplikaciji da kontroliše vibraciju." "direktno pozivanje brojeva telefona" @@ -453,9 +455,11 @@ "Dozvoljava aplikaciji da nastavi poziv koji je započet u drugoj aplikaciji." "čitanje brojeva telefona" "Dozvoljava aplikaciji da pristupa brojevima telefona na uređaju." + "ne isključuj ekran u automobilu" "sprečavanje prelaska tableta u stanje spavanja" "sprečavanje TV-a da pređe u stanje spavanja" "sprečavanje prelaska telefona u stanje spavanja" + "Dozvoljava aplikaciji da ne isključuje ekran u automobilu." "Dozvoljava aplikaciji da spreči tablet da pređe u stanje spavanja." "Dozvoljava aplikaciji da spreči TV da pređe u stanje spavanja." "Dozvoljava aplikaciji da spreči telefon da pređe u stanje spavanja." diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 6fb269bbbe77..d0e50aae7de3 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -91,7 +91,7 @@ "Экстранныя выклікі ў сетцы Wi‑Fi недаступныя" "Абвесткі" "Пераадрасацыя выкліку" - "Рэжым экстраннага зваротнага выкліку" + "Рэжым экстранных зваротных выклікаў" "Стан мабільнай перадачы даных" "SMS-паведамленні" "Паведамленні галасавой пошты" @@ -440,6 +440,8 @@ "Гэта праграма можа распазнаваць фізічную актыўнасць." "рабіць фатаграфіі і відэа" "Гэта праграма можа рабіць фота і запісваць відэа з дапамогай камеры ў любы час." + "Дазволіць праграме ці сэрвісу атрымліваць зваротныя выклікі наконт адкрыцця ці закрыцця прылад камеры." + "Гэта праграма для подпісу можа атрымліваць зваротныя вылікі, калі адкрываецца (пакетам праграм) або закрываецца прылада камеры." "кіраванне вібрацыяй" "Дазваляе прыкладанням кіраваць вібрацыяй." "непасрэдна набіраць тэлефонныя нумары" @@ -456,9 +458,11 @@ "Дазваляе праграме працягваць выклік, які пачаўся ў іншай праграме." "счытваць нумары тэлефонаў" "Дазваляе праграме атрымліваць доступ да нумароў тэлефонаў на прыладзе." + "пакідаць экран аўтамабіля ўключаным" "прадухіліць планшэт ад пераходу ў рэжым сну" "прадухіленне пераходу тэлевізара ў рэжым сну" "забараняць тэлефону пераходзіць ў рэжым сну" + "Дазваляе праграме пакідаць экран аўтамабіля ўключаным." "Дазваляе прыкладанням прадухіляць пераход планшэта ў рэжым сну." "Дазваляе праграме прадухіляць пераход тэлевізара ў рэжым сну." "Дазваляе прыкладанням прадухіляць тэлефон ад пераходу ў рэжым сну." diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index dabc00be6a02..6a747f41107b 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -434,6 +434,8 @@ "Това приложение може да разпознава физическата ви активност." "правене на снимки и видеоклипове" "Това приложение може по всяко време да прави снимки и да записва видеоклипове посредством камерата." + "Разрешаване на приложение или услуга да получават обратни повиквания за отварянето или затварянето на снимачни устройства." + "Това приложение за подписване може да получава обратни повиквания, когато снимачно устройство бъде отворено (от кой пакет на приложение) или затворено." "контролиране на вибрирането" "Разрешава на приложението да контролира устройството за вибрация." "директно обаждане до телефонни номера" @@ -450,9 +452,11 @@ "Разрешава на приложението да продължи обаждане, стартирано в друго приложение." "четене на телефонните номера" "Разрешава на приложението да осъществява достъп до телефонните номера на устройството." + "постоянно включен екран на автомобила" "предотвратяване на спящия режим на таблета" "предотвратяване на преминаването на телевизора в спящ режим" "предотвратява спящ режим на телефона" + "Дава възможност на приложението да поддържа екрана на автомобила включен." "Разрешава на приложението да предотвратява преминаването на таблета в спящ режим." "Разрешава на приложението да предотвратява преминаването в спящ режим на телевизора." "Разрешава на приложението да предотвратява преминаването на телефона в спящ режим." diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 038e72664d4c..252308d6f21a 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -434,6 +434,10 @@ "এই অ্যাপ আপনার শারীরিক অ্যাক্টিভিটি শনাক্ত করতে পারবে।" "ছবি এবং ভিডিও তোলে" "এই অ্যাপটি যে কোনো সময় ক্যামেরা ব্যবহার করে ছবি তুলতে বা ভিডিও রেকর্ড করতে পারে৷" + + + + "ভাইব্রেশন নিয়ন্ত্রণ করুন" "অ্যাপ্লিকেশানকে কম্পক নিয়ন্ত্রণ করতে দেয়৷" "সরাসরি ফোন নম্বরগুলিতে কল করে" @@ -450,9 +454,11 @@ "অন্য কোনও অ্যাপ দিয়ে কল করলে এই অ্যাপটিকে সেটি চালিয়ে যেতে দেয়।" "ফোন নম্বরগুলি পড়া হোক" "অ্যাপটিকে এই ডিভাইসের ফোন নম্বরগুলি অ্যাক্সেস করতে দেয়।" + "গাড়ির স্ক্রিন চালু রাখা আছে" "ঘুমানো থেকে ট্যাবলেটকে প্রতিরোধ করে" "টিভিকে নিদ্রায় যাওয়া থেকে প্রতিরোধ করে" "ঘুমানো থেকে ফোনটিকে প্রতিরোধ করে" + "গাড়ির স্ক্রিন চালু রাখতে অ্যাপকে অনুমতি দেয়।" "অ্যাপ্লিকেশানকে ট্যাবলেট নিদ্রায় যাওয়া থেকে প্রতিরোধ করার মঞ্জুরি দেয়৷" "অ্যাপ্লিকেশানকে টিভিকে নিদ্রায় যাওয়া থেকে প্রতিরোধ করার মঞ্জুরি দেয়৷" "অ্যাপ্লিকেশানকে ফোনকে নিদ্রায় যাওয়া থেকে প্রতিরোধ করার মঞ্জুরি দেয়৷" @@ -1352,7 +1358,7 @@ "কোনো অনুমতির প্রয়োজন নেই" "এর জন্য অর্থপ্রদান করতে হতে পারে" "ঠিক আছে" - "এই ডিভাইসটি USB এর মাধ্যমে চার্জ করুন" + "এই ডিভাইসটি USB দিয়ে চার্জ করা হচ্ছে" "সংযুক্ত ডিভাইসটি USB এর মাধ্যমে চার্জ করা হচ্ছে" "USB ফাইল ট্রান্সফার চালু করা হয়েছে" "USB এর মাধ্যমে PTP চালু করা হয়েছে" diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 661910b939b0..6a284c94eecc 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -437,6 +437,8 @@ "Ova aplikacija može prepoznati vašu fizičku aktivnost." "snimanje slika i videozapisa" "Ova aplikacija može slikati fotografije i snimati videozapise koristeći kameru bilo kada." + "Dozvoliti aplikaciji ili usluzi da prima povratne pozive o otvaranju ili zatvaranju kamera." + "Ova aplikacija za potpisivanje može primati povratne pozive kada se otvara ili zatvara bilo koja kamera (kojim paketom aplikacija)." "kontrola vibracije" "Dozvoljava aplikaciji upravljanje vibracijom." "izravno zvanje telefonskih brojeva" @@ -453,9 +455,11 @@ "Dozvoljava aplikaciji nastavljanje poziva koji je započet u drugoj aplikaciji." "čitanje telefonskih brojeva" "Dozvoljava aplikaciji pristup telefonskim brojevima uređaja." + "ostavi ekran automobila uključenim" "sprečavanje tableta da uđe u režim mirovanja" "spriječi ulazak TV-a u režim mirovanja" "sprečavanje telefona da uđe u režim mirovanja" + "Dozvoljava aplikaciji da ostavi ekran automobila uključenim." "Dozvoljava aplikaciji da spriječi tablet da ode u stanje mirovanja." "Dozvoljava aplikaciji da spriječi ulazak TV-a u režim mirovanja." "Dozvoljava aplikaciji da spriječi telefon da ode u stanje mirovanja." diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index a79d847a11fa..e945690f2988 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -182,11 +182,11 @@ Autoritat de certificació instal·lada "Per un tercer desconegut" - "Per l\'administrador del teu perfil professional" + "Per l\'administrador del teu perfil de treball" "Per %s" - "S\'ha suprimit el perfil professional" - "Falta l\'aplicació d\'administració del perfil professional o està malmesa. Com a conseqüència, s\'han suprimit el teu perfil professional i les dades relacionades. Contacta amb l\'administrador per obtenir ajuda." - "El teu perfil professional ja no està disponible en aquest dispositiu" + "S\'ha suprimit el perfil de treball" + "Falta l\'aplicació d\'administració del perfil de treball o està malmesa. Com a conseqüència, s\'han suprimit el teu perfil de treball i les dades relacionades. Contacta amb l\'administrador per obtenir ajuda." + "El teu perfil de treball ja no està disponible en aquest dispositiu" "Has intentat introduir la contrasenya massa vegades" "El dispositiu està gestionat" "La teva organització gestiona aquest dispositiu i és possible que supervisi el trànsit de xarxa. Toca per obtenir més informació." @@ -276,7 +276,7 @@ "Mode segur" "Sistema Android" "Canvia al perfil personal" - "Canvia al perfil professional" + "Canvia al perfil de treball" "Contactes" "accedir als contactes" "Vols permetre que <b>%1$s</b> accedeixi als contactes?" @@ -434,6 +434,8 @@ "Aquesta aplicació pot reconèixer la teva activitat física." "fer fotos i vídeos" "Aquesta aplicació pot fer fotos i gravar vídeos amb la càmera en qualsevol moment." + "Permet que una aplicació o un servei pugui rebre crides de retorn sobre els dispositius de càmera que s\'obren o es tanquen." + "Aquesta aplicació de signatures pot rebre crides de retorn quan s’obre o es tanca un dispositiu de càmera (segons el paquet d’aplicació)." "controlar la vibració" "Permet que l\'aplicació controli el vibrador." "trucar directament a números de telèfon" @@ -450,9 +452,11 @@ "Permet que l\'aplicació continuï una trucada que s\'havia iniciat en una altra aplicació." "llegir els números de telèfon" "Permet que l\'aplicació accedeixi als números de telèfon del dispositiu." + "mantén la pantalla del cotxe encesa" "evita que la tauleta entri en mode de repòs" "impedir que el televisor entri en mode de repòs" "impedir que el telèfon entri en mode de repòs" + "Permet que l\'aplicació mantingui la pantalla del cotxe encesa." "Permet que l\'aplicació impedeixi que la tauleta entri en repòs." "Permet a l\'aplicació impedir que el televisor entri en repòs." "Permet que l\'aplicació impedeixi que el telèfon entri en repòs." @@ -1459,8 +1463,8 @@ "Denega" "Permís sol·licitat" "S\'ha sol·licitat permís\nper al compte %s." - "Estàs utilitzant aquesta aplicació fora del perfil professional." - "Estàs utilitzant l\'aplicació al perfil professional." + "Estàs utilitzant aquesta aplicació fora del perfil de treball." + "Estàs utilitzant l\'aplicació al perfil de treball." "Mètode d\'introducció de text" "Sincronització" "Accessibilitat" @@ -1549,7 +1553,7 @@ "Comparteix amb %s" "Llisca el dit. Mantén premut." "Llisca per desbloquejar." - "Torna a la pàgina d\'inici" + "Navega fins a la pàgina d\'inici" "Navega cap amunt" "Més opcions" "%1$s, %2$s" @@ -1877,7 +1881,7 @@ "La sol·licitud SS s\'ha canviat per una videotrucada" "La sol·licitud SS s\'ha canviat per una sol·licitud USSD" "S\'ha canviat a una nova sol·licitud SS" - "Perfil professional" + "Perfil de treball" "S\'ha enviat una alerta" "Desplega" "Replega" @@ -1909,15 +1913,15 @@ "L\'aplicació no està disponible" "%1$s no està disponible en aquests moments. Aquesta opció es gestiona a %2$s." "Més informació" - "Activar el perfil professional?" - "S\'activaran les teves aplicacions per a la feina, les notificacions, les dades i altres funcions del perfil professional" + "Activar el perfil de treball?" + "S\'activaran les teves aplicacions de treball, les notificacions, les dades i altres funcions del perfil de treball" "Activa" "Aquesta aplicació es va crear per a una versió antiga d\'Android i pot ser que no funcioni correctament. Prova de cercar actualitzacions o contacta amb el desenvolupador." "Cerca actualitzacions" "Tens missatges nous" "Obre l\'aplicació d\'SMS per veure\'ls" "Algunes funcions poden ser limitades" - "Perfil professional bloquejat" + "Perfil de treball bloquejat" "Toca per desbloquejar el perfil" "S\'ha connectat a %1$s" "Toca per veure els fitxers" diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index d5e736a76b86..5a1851b05431 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -440,6 +440,8 @@ "Tyto aplikace dokážou rozpoznat vaši fyzickou aktivitu." "pořizování fotografií a videí" "Tato aplikace může pomocí fotoaparátu kdykoli pořídit snímek nebo nahrát video." + "Povolte aplikaci nebo službě přijímat zpětná volání o otevření nebo zavření zařízení s fotoaparátem." + "Tato podpisová aplikace může přijímat zpětná volání při otevírání nebo zavírání jakéhokoli zařízení s fotoaparátem (balíčkem příslušné aplikace)." "ovládání vibrací" "Umožňuje aplikaci ovládat vibrace." "přímé volání na telefonní čísla" @@ -456,9 +458,11 @@ "Umožňuje aplikace pokračovat v hovoru, který byl zahájen v jiné aplikaci." "přístup k telefonním číslům" "Umožňuje aplikaci přístup k telefonním číslům v zařízení." + "ponechání zapnuté obrazovky auta" "bránění přechodu tabletu do režimu spánku" "zabránění přechodu televize do režimu spánku" "bránění přechodu telefonu do režimu spánku" + "Umožňuje aplikaci nechat obrazovku auta zapnutou." "Umožňuje aplikaci zabránit přechodu tabletu do režimu spánku." "Umožňuje aplikaci zabránit přechodu televize do režimu spánku." "Umožňuje aplikaci zabránit přechodu telefonu do režimu spánku." diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index f4e4f7377cbf..34c899115883 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -434,6 +434,8 @@ "Denne app kan genkende din fysiske aktivitet." "tage billeder og optage video" "Med denne app kan du tage billeder og optage video med kameraet når som helst." + "Tillad, at en app eller tjeneste modtager tilbagekald om kameraenheder, der åbnes eller lukkes." + "Denne signaturapp kan modtage tilbagekald, når en kameraenhed åbnes (efter app-pakke) eller lukkes." "administrere vibration" "Tillader, at appen kan administrere vibratoren." "ringe direkte op til telefonnumre" @@ -450,9 +452,11 @@ "Tillader, at appen fortsætter et opkald, der blev startet i en anden app." "læse telefonnumre" "Tillader, at appen får adgang til telefonnumrene på denne enhed." + "hold bilens skærm tændt" "afholde tabletcomputeren fra at gå i dvale" "forhindre tv i at gå i dvale" "afholde telefonen fra at gå i dvale" + "Tillader, at appen holder bilens skærm tændt." "Tillader, at appen kan forhindre tabletten i at gå i dvale." "Giver appen lov til at forhindre fjernsynet i at gå i dvale." "Tillader, at appen kan forhindre, at telefonen går i dvale." diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 9bd46b2b828f..34de9e22a44e 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -434,6 +434,8 @@ "Diese App kann deine körperliche Aktivität erkennen." "Bilder und Videos aufnehmen" "Diese App kann mit der Kamera jederzeit Bilder und Videos aufnehmen." + "Einer App oder einem Dienst den Empfang von Callbacks erlauben, wenn eine Kamera geöffnet oder geschlossen wird." + "Diese Premium-App kann Callbacks empfangen, wenn eine Kamera mit einem Anwendungspaket geöffnet oder geschlossen wird." "Vibrationsalarm steuern" "Ermöglicht der App, den Vibrationsalarm zu steuern" "Telefonnummern direkt anrufen" @@ -450,9 +452,11 @@ "Ermöglicht der App, einen Anruf weiterzuführen, der in einer anderen App begonnen wurde." "Telefonnummern vorlesen" "Ermöglicht der App, auf die Telefonnummern auf dem Gerät zuzugreifen." + "Autodisplay eingeschaltet lassen" "Ruhezustand des Tablets deaktivieren" "Ruhemodus des Fernsehers deaktivieren" "Ruhezustand deaktivieren" + "Ermöglicht der App, das Autodisplay eingeschaltet zu lassen." "Ermöglicht der App, den Ruhezustand des Tablets zu deaktivieren" "Ermöglicht der App, den Ruhemodus des Fernsehers zu deaktivieren" "Ermöglicht der App, den Ruhezustand des Telefons zu deaktivieren" diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 9b2259034ab9..bf6559c003c9 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -434,6 +434,8 @@ "Αυτή η εφαρμογή μπορεί να αναγνωρίσει τη σωματική σας δραστηριότητα." "κάνει λήψη φωτογραφιών και βίντεο" "Αυτή η εφαρμογή μπορεί να τραβήξει φωτογραφίες και βίντεο χρησιμοποιώντας την κάμερα, ανά πάσα στιγμή." + "Επιτρέψτε σε μια εφαρμογή ή μια υπηρεσία να λαμβάνει επανάκλησεις σχετικά με το άνοιγμα ή το κλείσιμο συσκευών κάμερας." + "Αυτή η εφαρμογή υπογραφής μπορεί να λαμβάνει επανακλήσεις κατά το άνοιγμα οποιασδήποτε συσκευής κάμερας (από οποιοδήποτε πακέτο εφαρμογής) ή κατά το κλείσιμο." "ελέγχει τη δόνηση" "Επιτρέπει στην εφαρμογή τον έλεγχο της δόνησης." "πραγματοποιεί απευθείας κλήση τηλεφωνικών αριθμών" @@ -450,9 +452,11 @@ "Επιτρέπει στην εφαρμογή να συνεχίσει μια κλήση η οποία ξεκίνησε σε άλλη εφαρμογή." "ανάγνωση αριθμών τηλεφώνου" "Επιτρέπει στην εφαρμογή να αποκτήσει πρόσβαση στους αριθμούς τηλεφώνου της συσκευής" + "διατήρηση ενεργοποίησης οθόνης αυτοκινήτου" "αποτρέπει την μετάβαση του tablet σε κατάσταση αδράνειας" "αποτρέπει την μετάβαση της τηλεόρασης σε κατάσταση αδράνειας" "αποτρέπει το τηλεφώνο να μεταβεί σε κατάσταση αδράνειας" + "Επιτρέπει στην εφαρμογή να διατηρεί την οθόνη του αυτοκινήτου ενεργοποιημένη." "Επιτρέπει στην εφαρμογή την παρεμπόδιση της μετάβασης του tablet σε κατάσταση αδράνειας." "Επιτρέπει στην εφαρμογή να εμποδίζει τη μετάβαση της τηλεόρασης στην κατάσταση αδράνειας." "Επιτρέπει στην εφαρμογή την παρεμπόδιση της μετάβασης του τηλεφώνου σε κατάσταση αδράνειας." diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 1ace09e87796..1cd734172de6 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -434,6 +434,8 @@ "This app can recognise your physical activity." "take pictures and videos" "This app can take pictures and record videos using the camera at any time." + "Allow an application or service to receive callbacks about camera devices being opened or closed." + "This signature app can receive callbacks when any camera device is being opened (by what application package) or closed." "control vibration" "Allows the app to control the vibrator." "directly call phone numbers" @@ -450,9 +452,11 @@ "Allows the app to continue a call which was started in another app." "read phone numbers" "Allows the app to access the phone numbers of the device." + "keep car screen turned on" "prevent tablet from sleeping" "prevent TV from sleeping" "prevent phone from sleeping" + "Allows the app to keep the car screen turned on." "Allows the app to prevent the tablet from going to sleep." "Allows the app to prevent the TV from going to sleep." "Allows the app to prevent the phone from going to sleep." diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 18c4fc7ff045..bd4a247340a5 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -434,6 +434,8 @@ "This app can recognise your physical activity." "take pictures and videos" "This app can take pictures and record videos using the camera at any time." + "Allow an application or service to receive callbacks about camera devices being opened or closed." + "This signature app can receive callbacks when any camera device is being opened (by what application package) or closed." "control vibration" "Allows the app to control the vibrator." "directly call phone numbers" @@ -450,9 +452,11 @@ "Allows the app to continue a call which was started in another app." "read phone numbers" "Allows the app to access the phone numbers of the device." + "keep car screen turned on" "prevent tablet from sleeping" "prevent TV from sleeping" "prevent phone from sleeping" + "Allows the app to keep the car screen turned on." "Allows the app to prevent the tablet from going to sleep." "Allows the app to prevent the TV from going to sleep." "Allows the app to prevent the phone from going to sleep." diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 1ace09e87796..1cd734172de6 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -434,6 +434,8 @@ "This app can recognise your physical activity." "take pictures and videos" "This app can take pictures and record videos using the camera at any time." + "Allow an application or service to receive callbacks about camera devices being opened or closed." + "This signature app can receive callbacks when any camera device is being opened (by what application package) or closed." "control vibration" "Allows the app to control the vibrator." "directly call phone numbers" @@ -450,9 +452,11 @@ "Allows the app to continue a call which was started in another app." "read phone numbers" "Allows the app to access the phone numbers of the device." + "keep car screen turned on" "prevent tablet from sleeping" "prevent TV from sleeping" "prevent phone from sleeping" + "Allows the app to keep the car screen turned on." "Allows the app to prevent the tablet from going to sleep." "Allows the app to prevent the TV from going to sleep." "Allows the app to prevent the phone from going to sleep." diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 1ace09e87796..1cd734172de6 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -434,6 +434,8 @@ "This app can recognise your physical activity." "take pictures and videos" "This app can take pictures and record videos using the camera at any time." + "Allow an application or service to receive callbacks about camera devices being opened or closed." + "This signature app can receive callbacks when any camera device is being opened (by what application package) or closed." "control vibration" "Allows the app to control the vibrator." "directly call phone numbers" @@ -450,9 +452,11 @@ "Allows the app to continue a call which was started in another app." "read phone numbers" "Allows the app to access the phone numbers of the device." + "keep car screen turned on" "prevent tablet from sleeping" "prevent TV from sleeping" "prevent phone from sleeping" + "Allows the app to keep the car screen turned on." "Allows the app to prevent the tablet from going to sleep." "Allows the app to prevent the TV from going to sleep." "Allows the app to prevent the phone from going to sleep." diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index f7d058f7fe79..dc3a35ed01bf 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -434,6 +434,8 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‏‎‎‏‏‏‏‎This app can recognize your physical activity.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‎take pictures and videos‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‏‏‎‎‏‎‎‎‎‎‎‏‏‎‏‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎This app can take pictures and record videos using the camera at any time.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‎‎‏‏‎Allow an application or service to receive callbacks about camera devices being opened or closed.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎This signature app can receive callbacks when any camera device is being opened (by what application package) or closed.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎control vibration‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‏‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‎Allows the app to control the vibrator.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‎‎directly call phone numbers‎‏‎‎‏‎" @@ -450,9 +452,11 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‏‎‎Allows the app to continue a call which was started in another app.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‎‏‏‎‏‎‎‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎read phone numbers‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‏‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‏‎Allows the app to access the phone numbers of the device.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‏‏‏‏‎‎‎keep car screen turned on‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‏‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‎‎‎prevent tablet from sleeping‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‎‎‎prevent TV from sleeping‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎‏‎‏‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎‏‎‏‏‎prevent phone from sleeping‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‎‎‎‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‎‏‎‏‎‏‏‎Allows the app to keep the car screen turned on.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‏‎Allows the app to prevent the tablet from going to sleep.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎Allows the app to prevent the TV from going to sleep.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎Allows the app to prevent the phone from going to sleep.‎‏‎‎‏‎" diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 588b63604f2e..373b01ce2543 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -434,6 +434,8 @@ "Esta app puede reconocer tu actividad física." "tomar fotografías y grabar videos" "Esta app puede tomar fotos y grabar videos con la cámara en cualquier momento." + "Permite que una aplicación o un servicio reciba devoluciones de llamada cuando se abren o cierran dispositivos de cámara." + "Esta app de firma puede recibir devoluciones de llamada cuando se cierra o se abre cualquier dispositivo de cámara (y qué paquete de aplicación lo hace)." "controlar la vibración" "Permite que la aplicación controle la vibración." "llamar directamente a números de teléfono" @@ -450,9 +452,11 @@ "Permite que la app continúe con una llamada que se inició en otra app." "leer números de teléfono" "Le permite a la app acceder a los números de teléfono del dispositivo." + "mantener la pantalla del vehículo encendida" "evitar que el tablet entre en estado de inactividad" "evitar que la TV entre en suspensión" "evitar que el dispositivo entre en estado de inactividad" + "Permite que la app mantenga la pantalla del vehículo encendida." "Permite que la aplicación evite que la tablet entre en estado de inactividad." "Permite que la aplicación evite que la TV se suspenda." "Permite que la aplicación evite que el dispositivo entre en estado de inactividad." @@ -1220,7 +1224,7 @@ "Tienes un volcado del montón del proceso de %1$s disponible para compartir. Ten cuidado: Es posible que este volcado contenga información personal sensible (incluido el contenido que hayas escrito) a la que puede acceder el proceso." "Seleccionar una acción para el texto" "Volumen del timbre" - "Volumen de los medios" + "Volumen multimedia" "Reproduciendo a través de Bluetooth" "Tono de silencio establecido" "Volumen de llamadas entrantes" @@ -1231,7 +1235,7 @@ "Volumen de Bluetooth" "Volumen del tono de llamada" "Volumen de la llamada" - "Volumen de los medios" + "Volumen multimedia" "Volumen de notificación" "Tono predeterminado" "Predeterminado (%1$s)" diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index f52aa9f6ad77..0581942dad9f 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -434,6 +434,8 @@ "Esta aplicación puede reconocer tu actividad física." "realizar fotografías y vídeos" "Esta aplicación puede hacer fotografías y grabar vídeos con la cámara en cualquier momento." + "Permitir que una aplicación o servicio reciba retrollamadas cada vez que se abra o cierre una cámara." + "Esta aplicación especial puede recibir retrollamadas cada vez que se abre o se cierra una cámara mediante cualquier paquete de aplicaciones." "controlar la vibración" "Permite que la aplicación controle la función de vibración." "llamar directamente a números de teléfono" @@ -450,9 +452,11 @@ "Permite que la aplicación continúe una llamada que se ha iniciado en otra aplicación." "leer números de teléfono" "Permite que la aplicación acceda a los números de teléfono del dispositivo." + "mantener la pantalla del coche encendida" "impedir que el tablet entre en modo de suspensión" "evitar que la TV entre en suspensión" "impedir que el teléfono entre en modo de suspensión" + "Permite que la aplicación deje la pantalla del coche encendida." "Permite que la aplicación impida que el tablet entre en modo de suspensión." "Permite que la aplicación evite que la TV entre en modo de suspensión." "Permite que la aplicación impida que el teléfono entre en modo de suspensión." @@ -807,7 +811,7 @@ "Introduce el código PIN para desbloquear." "Código PIN incorrecto" "Para desbloquear el teléfono, pulsa la tecla de menú y, a continuación, pulsa 0." - "Número de emergencia" + "Llamada de emergencia" "Sin servicio" "Pantalla bloqueada" "Pulsa la tecla de menú para desbloquear el teléfono o realizar una llamada de emergencia." @@ -1223,9 +1227,9 @@ "Volumen de multimedia" "Reproduciendo a través de Bluetooth" "Tono de silencio establecido" - "Volumen de la llamada" - "Volumen de la llamada de Bluetooth" - "Volumen de la alarma" + "Volumen de llamada" + "Volumen de llamada Bluetooth" + "Volumen de alarma" "Volumen de notificaciones" "Volumen" "Volumen de Bluetooth" diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index d420a7a90302..9e85c5e3b178 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -434,6 +434,8 @@ "See rakendus saab tuvastada teie füüsilised tegevused." "piltide ja videote tegemine" "See rakendus saab mis tahes ajal kaameraga pildistada ja videoid salvestada." + "Lubab rakendusel või teenusel kaameraseadmete avamise või sulgemise kohta tagasikutseid vastu võtta." + "See allkirjarakendus saab mis tahes kaameraseadme avamisel (vastava rakendusepaketiga) või sulgemisel tagasikutseid vastu võtta." "juhtige vibreerimist" "Võimaldab rakendusel juhtida vibreerimist." "helista otse telefoninumbritele" @@ -450,9 +452,11 @@ "Lubab rakendusel jätkata kõnet, mida alustati teises rakenduses." "lugeda telefoninumbreid" "Rakendusel lubatakse juurde pääseda seadme telefoninumbritele." + "hoida auto ekraani sisselülitatuna" "tahvelarvuti uinumise vältimine" "teleri unerežiimi lülitumise takistamine" "väldi telefoni uinumist" + "Lubab rakendusel auto ekraani sisselülitatuna hoida." "Võimaldab rakendusel vältida tahvelarvuti uinumist." "Lubab rakendusel takistada teleri unerežiimi lülitumist." "Võimaldab rakendusel vältida telefoni uinumist." diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index ddab35663835..9b08e767ae26 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -89,7 +89,7 @@ "Ezin duzu egin larrialdi-deirik Wi-Fi bidez" "Alertak" "Dei-desbideratzea" - "Larrialdi-deiak soilik jasotzeko modua" + "Larrialdi-zerbitzuen deiak jasotzeko modua" "Datu-konexioaren egoera" "SMS mezuak" "Erantzungailuko mezuak" @@ -434,6 +434,8 @@ "Aplikazioak ariketa fisikoa hauteman dezake." "atera argazkiak eta grabatu bideoak" "Aplikazioak edonoiz erabil dezake kamera argazkiak ateratzeko eta bideoak grabatzeko." + "Eman baimena aplikazio edo zerbitzuari jakinarazpenak jasotzeko kamerak ireki edo ixten direnean." + "Kamera ireki edo itxi dela (eta zer aplikazio-paketerekin) dioten jakinarazpenak jaso ditzake sinatzeko aplikazio honek." "kontrolatu dardara" "Bibragailua kontrolatzeko aukera ematen die aplikazioei." "deitu zuzenean telefono-zenbakietara" @@ -450,9 +452,11 @@ "Beste aplikazio batean hasitako dei bat jarraitzea baimentzen dio aplikazioari." "irakurri telefono-zenbakiak" "Gailuaren telefono-zenbakiak atzitzeko baimena ematen die aplikazioei." + "mantendu piztuta autoko pantaila" "eragotzi tableta inaktibo ezartzea" "eragotzi telebista inaktibo geratzea" "eragotzi telefonoa inaktibo ezartzea" + "Autoko pantaila piztuta mantentzeko baimena ematen dio aplikazioari." "Tableta inaktibo ezartzea galaraztea baimentzen die aplikazioei." "Telebista inaktibo ezar dadin eragoztea baimentzen die aplikazioei." "Telefonoa inaktibo ezartzea galaraztea baimentzen die aplikazioei." @@ -486,9 +490,9 @@ "Wi-Fi sarbide-puntuetara konektatzeko edo haietatik deskonektatzeko baimena ematen die aplikazioei, baita Wi-Fi sareen gailu-konfigurazioari aldaketak egitekoa ere." "onartu Wi-Fi Multicast harrera" "Wi-Fi sarearen bidez gailu guztiei bidalitako paketeak jasotzeko baimena ematen die aplikazioei multidifusio-helbideak erabilita, ez tableta soilik. Multidifusiokoa ez den moduak baino bateria gehiago erabiltzen du." - "Wi-Fi sareko gailu guztiei bidalitako paketeak jasotzeko baimena ematen die aplikazioei multidifusio-helbideak erabilita, ez telebista soilik. Multidifusiokoa ez den moduak baino bateria gehiago erabiltzen du." + "Wifi-sareko gailu guztiei bidalitako paketeak jasotzeko baimena ematen die aplikazioei multidifusio-helbideak erabilita, ez telebista soilik. Multidifusiokoa ez den moduak baino bateria gehiago erabiltzen du." "Wi-Fi sarearen bidez gailu guztiei bidalitako paketeak jasotzeko baimena ematen die aplikazioei multidifusio-helbideak erabilita, ez telefonoa soilik. Multidifusiokoa ez den moduak baino bateria gehiago erabiltzen du." - "atzitu Bluetooth ezarpenak" + "atzitu Bluetooth-aren ezarpenak" "Tokiko Bluetooth tableta konfiguratzea eta urruneko gailuak detektatzea eta haiekin parekatzea baimentzen die aplikazioei." "Tokiko Bluetooth telebista konfiguratzea eta urruneko gailuak hautematea eta haiekin parekatzea baimentzen die aplikazioei." "Tokiko Bluetooth telefonoa konfiguratzea eta urruneko gailuak detektatzea eta haiekin parekatzea baimentzen die aplikazioei." @@ -498,7 +502,7 @@ "Tableta WiMAX sareetara konektatzeko edo haietatik deskonektatzeko baimena ematen die aplikazioei." "Telebista WiMAX sareetara konektatzea edo haietatik deskonektatzea baimentzen die aplikazioei." "Telefonoa WiMAX sareetara konektatzeko edo haietatik deskonektatzeko baimena ematen die aplikazioei." - "partekatu Bluetooth gailuekin" + "partekatu Bluetooth bidezko gailuekin" "Tabletaren Bluetooth konfigurazioa ikusteko eta parekatutako gailuekin konexioak egiteko eta onartzeko baimena ematen die aplikazioei." "Telebistaren Bluetooth konexioaren konfigurazioa ikustea eta parekatutako gailuekin konexioak sortzea eta onartzea baimentzen die aplikazioei." "Telefonoaren Bluetooth konfigurazioa ikusteko eta parekatutako gailuekin konexioak egiteko eta onartzeko baimena ematen die aplikazioei." @@ -522,7 +526,7 @@ "Argazki-bilduma aldatzeko baimena ematen die aplikazioei." "multimedia-edukien bildumako kokapena irakurri" "Multimedia-edukien bildumako kokapena irakurtzeko baimena ematen die aplikazioei." - "Egiaztatu zu zarela" + "Egiaztatu zeu zarela" "Hardware biometrikoa ez dago erabilgarri" "Utzi da autentifikazioa" "Ez da ezagutu" @@ -1517,7 +1521,7 @@ "Ez egin ezer, oraingoz" "Aukeratu kontu bat" "Gehitu kontu bat" - "Gehitu kontua" + "Gehitu kontu bat" "Handitu" "Txikitu" "Eduki sakatuta %s." @@ -1604,7 +1608,7 @@ "Telefonoa" "Konektatu bozgorailuak oinarrira" "HDMI" - "Aurikularrak" + "Entzungailuak" "USB" "Sistema" "Bluetooth bidezko audioa" diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 6b0f738e3f10..94f9766253e7 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -434,6 +434,8 @@ "این برنامه نمی‌تواند فعالیت فیزیکی‌تان را تشخیص دهد." "عکسبرداری و فیلمبرداری" "این برنامه می‌تواند در هرزمانی با استفاده از دوربین عکس و فیلم بگیرد." + "مجاز کردن برنامه یا سرویس برای دریافت پاسخ تماس درباره دستگاه‌های دوربینی که باز یا بسته می‌شوند." + "این برنامهٔ امضا می‌تواند هروقت دستگاه دوربین باز (براساس بسته برنامه) یا بسته می‌شود، پاسخ تماس دریافت کند." "کنترل لرزش" "‏به برنامه اجازه می‎دهد تا لرزاننده را کنترل کند." "تماس مستقیم با شماره تلفن‌ها" @@ -450,9 +452,11 @@ "به برنامه اجازه می‌دهد تماسی را که در برنامه دیگری شروع شده ادامه دهد." "خواندن شماره تلفن‌ها" "به برنامه امکان می‌دهد به شماره تلفن‌های دستگاه دسترسی داشته باشد." + "روشن نگه داشتن صفحه‌نمایش خودرو" "ممانعت از به خواب رفتن رایانهٔ لوحی" "جلوگیری از به حالت خواب رفتن تلویزیون" "ممانعت از به خواب رفتن تلفن" + "به برنامه اجازه می‌دهد صفحه‌نمایش خودرو را روشن نگه دارد." "‏به برنامه اجازه می‎دهد تا از غیرفعال شدن رایانهٔ لوحی جلوگیری کند." "به برنامه اجازه می‌دهد تا از به حالت خواب رفتن تلویزیون جلوگیری کند." "‏به برنامه اجازه می‎دهد تا از غیرفعال شدن تلفن جلوگیری کند." diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 7e3d80ad990b..34ec6028f957 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -434,6 +434,8 @@ "Sovellus voi tunnistaa liikkumisesi." "ota kuvia ja videoita" "Tämä sovellus voi ottaa kameralla kuvia ja videoita koska tahansa." + "Salli sovelluksen tai palvelun vastaanottaa vastakutsuja kameralaitteiden avaamisesta tai sulkemisesta." + "Tämä allekirjoitussovellus voi vastaanottaa vastakutsuja, kun mikä tahansa kameralaite avataan tai suljetaan (jollakin sovelluspaketilla)" "hallita värinää" "Antaa sovelluksen hallita värinää." "soittaa puhelinnumeroihin suoraan" @@ -450,9 +452,11 @@ "Antaa sovelluksen jatkaa puhelua, joka aloitettiin toisessa sovelluksessa." "lukea puhelinnumeroita" "Anna sovelluksen käyttää laitteella olevia puhelinnumeroita." + "pitää auton näytön päällä" "estä tablet-laitetta menemästä virransäästötilaan" "Estä television siirtyminen virransäästötilaan" "estä puhelinta menemästä virransäästötilaan" + "Sallii sovelluksen pitää auton näytön päällä." "Antaa sovelluksen estää tablet-laitetta siirtymästä virransäästötilaan." "Antaa sovelluksen estää televisiota siirtymästä virransäästötilaan." "Antaa sovelluksen estää puhelinta siirtymästä virransäästötilaan." diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 23dfdb48a8ec..0ec2ef977723 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -294,7 +294,7 @@ "Autoriser <b>%1$s</b> à envoyer et à afficher des messages texte?" "Stockage" "accéder aux photos, aux contenus multimédias et aux fichiers sur votre appareil" - "Autoriser <b>%1$s</b> à accéder aux photos, aux médias et aux fichiers de votre appareil?" + "Autoriser <b>%1$s</b> à accéder aux photos, au contenu multimédia et aux fichiers de votre appareil?" "Microphone" "enregistrer des fichiers audio" "Autoriser <b>%1$s</b> à enregistrer l\'audio?" @@ -434,6 +434,8 @@ "Cette application peut reconnaître vos activités physiques." "prendre des photos et filmer des vidéos" "Cette application peut prendre des photos et enregistrer des vidéos à l\'aide de l\'appareil photo en tout temps." + "Autoriser une application ou un service de recevoir des rappels relatifs à l\'ouverture ou à la fermeture des appareils photos." + "Cette application signature peut recevoir des rappels lorsque l\'appareil photo est ouvert ou fermé (par le paquet d\'application) en question." "gérer le vibreur" "Permet à l\'application de gérer le vibreur de l\'appareil." "appeler directement des numéros de téléphone" @@ -450,9 +452,11 @@ "Permet à l\'application de continuer un appel commencé dans une autre application." "lire les numéros de téléphone" "Permet à l\'application d\'accéder aux numéros de téléphone de l\'appareil." + "garder l\'écran de la voiture allumé" "empêcher la tablette de passer en mode veille" "empêcher le téléviseur de passer en mode veille" "empêcher le téléphone de passer en mode veille" + "Permet à l\'application de garder l\'écran de la voiture allumé." "Permet à l\'application d\'empêcher la tablette de passer en mode veille." "Permet à l\'application d\'empêcher le téléviseur à passer en mode veille." "Permet à l\'application d\'empêcher le téléphone de passer en mode veille." diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index de8f8a475a19..ea065a98e965 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -434,6 +434,8 @@ "Cette application peut reconnaître votre activité physique." "prendre des photos et enregistrer des vidéos" "Cette application peut utiliser l\'appareil photo pour prendre des photos et enregistrer des vidéos à tout moment." + "Autoriser une application ou un service à recevoir des rappels liés à l\'ouverture ou à la fermeture de caméras" + "Cette application de signature peut recevoir des rappels lorsqu\'une caméra est ouverte (par un package d\'application) ou fermée." "contrôler le vibreur" "Permet à l\'application de contrôler le vibreur." "appeler directement les numéros de téléphone" @@ -450,9 +452,11 @@ "Autorise l\'application à continuer un appel qui a été démarré dans une autre application." "lire les numéros de téléphone" "Permet à l\'application d\'accéder aux numéros de téléphone de l\'appareil." + "laisser l\'écran de la voiture allumé" "empêcher la tablette de passer en mode veille" "empêcher l\'activation du mode veille sur le téléviseur" "empêcher le téléphone de passer en mode veille" + "Permet à l\'application de laisser l\'écran de la voiture allumé." "Permet à l\'application d\'empêcher la tablette de passer en mode veille." "Permet à l\'application d\'empêcher l\'activation du mode veille sur le téléviseur." "Permet à l\'application d\'empêcher le téléphone de passer en mode veille." diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 4917ca5acb0c..f4b9308d486c 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -434,6 +434,8 @@ "Esta aplicación pode recoñecer a túa actividade física." "facer fotos e vídeos" "Esta aplicación pode utilizar a cámara en calquera momento para sacar fotos e gravar vídeos." + "Permitir que unha aplicación ou servizo reciba retrochamadas cando se abran ou se pechen dispositivos con cámara." + "Esta aplicación de sinaturas pode recibir retrochamadas cando un paquete de aplicacións abra ou peche un dispositivo con cámara." "controlar a vibración" "Permite á aplicación controlar o vibrador." "chamar directamente aos números de teléfono" @@ -450,9 +452,11 @@ "Permite que a aplicación continúe unha chamada que se iniciou noutra aplicación." "ler números de teléfono" "Permite que a aplicación acceda aos números de teléfono do dispositivo." + "manter acendida a pantalla do coche" "evitar que a tableta entre en modo de inactividade" "evitar que a televisión entre en modo de suspensión" "evitar que o teléfono entre en modo de suspensión" + "Permite que a aplicación manteña acendida a pantalla do coche." "Permite á aplicación evitar que a tableta acceda ao modo de suspensión." "Permite que a aplicación impida que a televisión entre en modo de suspensión." "Permite á aplicación evitar que o teléfono acceda ao modo de suspensión." diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 853d27f2c84b..59fd056e8c38 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -303,7 +303,7 @@ "<b>%1$s</b>ને તમારી શારીરિક પ્રવૃત્તિને ઍક્સેસ કરવાની મંજૂરી આપવી છે?" "કૅમેરો" "ચિત્રો લેવાની અને વીડિઓ રેકોર્ડ કરવાની" - "<b>%1$s</b>ને ચિત્રો લેવાની અને વીડિઓ રેકૉર્ડ કરવાની મંજૂરી આપીએ?" + "<b>%1$s</b>ને ચિત્રો લેવાની અને વીડિયો રેકૉર્ડ કરવાની મંજૂરી આપીએ?" "કૉલ લૉગ" "ફોન કૉલ લૉગ વાંચો અને લખો" "<b>%1$s</b>ને તમારા ફોનના કૉલ લૉગ ઍક્સેસ કરવાની મંજૂરી આપીએ?" @@ -434,6 +434,10 @@ "આ ઍપ તમારી શારીરિક પ્રવૃત્તિને ઓળખી શકે છે." "ચિત્રો અને વિડિઓઝ લો" "આ ઍપ્લિકેશન, કૅમેરાનો ઉપયોગ કરીને કોઈપણ સમયે ચિત્રો લઈ અને વિડિઓઝ રેકોર્ડ કરી શકે છે." + + + + "વાઇબ્રેશન નિયંત્રિત કરો" "એપ્લિકેશનને વાઇબ્રેટરને નિયંત્રિત કરવાની મંજૂરી આપે છે." "સીધા જ ફોન નંબર્સ પર કૉલ કરો" @@ -450,9 +454,11 @@ "એક અન્ય તૃતીય પક્ષ ઍપમાં ચાલુ થયેલા કૉલને આ ઍપમાં ચાલુ રાખવાની મંજૂરી આપે છે." "ફોન નંબર વાંચો" "ઍપ્લિકેશનને ઉપકરણનાં ફોન નંબરને ઍક્સેસ કરવાની મંજૂરી આપે છે." + "કારની સ્ક્રીન ચાલુ રાખો." "ટેબ્લેટને નિષ્ક્રિય થતું અટકાવો" "ટીવીને નિષ્ક્રિય થતો અટકાવો" "ફોનને નિષ્ક્રિય થતો અટકાવો" + "ઍપને કારની સ્ક્રીન ચાલુ રાખવાની મંજૂરી આપો." "એપ્લિકેશનને ટેબ્લેટને નિષ્ક્રિય થઈ જતો અટકાવવાની મંજૂરી આપે છે." "એપ્લિકેશનને TV ને નિષ્ક્રિય થઈ જતો અટકાવવાની મંજૂરી આપે છે." "એપ્લિકેશનને ફોનને નિષ્ક્રિય થઈ જતો અટકાવવાની મંજૂરી આપે છે." diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index d63817b0be45..9e4e6d9e5b1c 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -434,6 +434,10 @@ "यह ऐप्लिकेशन आपके शरीर की गतिविधि को पहचान सकता है." "चित्र और वीडियो लें" "यह ऐप्लिकेशन किसी भी समय कैमरे का उपयोग करके चित्र ले सकता है और वीडियो रिकॉर्ड कर सकता है." + + + + "कंपन (वाइब्रेशन) को नियंत्रित करें" "ऐप्स को कंपनकर्ता नियंत्रित करने देता है." "फ़ोन नंबर पर सीधे कॉल करें" @@ -450,9 +454,11 @@ "इसके ज़रिए आप, किसी ऐप्लिकेशन में शुरू किया गया कॉल दूसरे ऐप्लिकेशन में जारी रख सकते हैं." "फ़ोन नंबर पढ़ना" "ऐप को डिवाइस के फ़ोन नंबर का इस्तेमाल करने देती है." + "कार की स्क्रीन चालू रखना" "टैबलेट को सोने (कम बैटरी मोड) से रोकें" "टीवी को सोने (कम बैटरी मोड) से रोकें" "फ़ोन को सोने (कम बैटरी मोड) से रोकें" + "यह अनुमति देने पर, ऐप्लिकेशन कार की स्क्रीन चालू रख पाएगा." "ऐप्स को टैबलेट को प्रयोग में नहीं हो जाने से रोकता है." "ऐप को टीवी को सोने (कम बैटरी मोड) से रोकने की अनुमति देता है." "ऐप्स को फ़ोन को प्रयोग में नहीं होने से रोकता है." diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index b89451aa610e..3c612f0ac50c 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -437,6 +437,8 @@ "Ova aplikacija može prepoznati vašu tjelesnu aktivnost." "snimi fotografije i videozapise" "Aplikacija u svakom trenutku može snimati fotografije i videozapise fotoaparatom." + "Dopustite aplikaciji ili usluzi da prima povratne pozive o otvaranju ili zatvaranju fotoaparata." + "Aplikacija za potpise može primati povratne pozive prilikom otvaranja (putem nekog paketa aplikacija) ili zatvaranja fotoaparata." "upravljanje vibracijom" "Aplikaciji omogućuje nadzor nad vibratorom." "izravno pozivanje telefonskog broja" @@ -453,9 +455,11 @@ "Omogućuje aplikaciji da nastavi poziv započet u nekoj drugoj aplikaciji." "čitati telefonske brojeve" "Aplikaciji omogućuje da pristupi telefonskim brojevima na uređaju." + "zadržati zaslon automobila uključenim" "spriječi mirovanje tabletnog uređaja" "sprječavanje mirovanja televizora" "sprečava telefon da prijeđe u stanje mirovanja" + "Aplikaciji omogućuje da zaslon automobila zadrži uključenim." "Aplikaciji omogućuje sprječavanje prelaska tabletnog računala u mirovanje." "Aplikaciji omogućuje sprječavanje prelaska televizora u stanje mirovanja." "Aplikaciji omogućuje da spriječi prelazak telefona u mirovanje." diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 2dbb70ebc483..315f0f8c6e1f 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -434,6 +434,8 @@ "Az alkalmazás képes felismerni a testmozgást." "fotók és videók készítése" "Az alkalmazás a kamera használatával bármikor készíthet fényképeket és rögzíthet videókat." + "Visszahívás fogadásának engedélyezése alkalmazás vagy szolgáltatás számára, ha a kamerákat megnyitják vagy bezárják." + "Az aláíró alkalmazás fogadhat visszahívásokat bármelyik kamera (adott alkalmazáscsomag általi) megnyitásakor vagy bezárásakor." "rezgés szabályozása" "Lehetővé teszi az alkalmazás számára a rezgés vezérlését." "telefonszámok közvetlen hívása" @@ -450,9 +452,11 @@ "Engedélyezi az alkalmazásnak, hogy folytassa a hívást, amelyet valamelyik másik alkalmazásban kezdtek meg." "telefonszámok olvasása" "Engedélyezi az alkalmazás számára az eszköz telefonszámaihoz való hozzáférést." + "az autó képernyőjének bekapcsolva tartása" "táblagép alvás üzemmódjának megakadályozása" "a tévé alvó üzemmódba való lépésének megakadályozása" "telefon alvó üzemmódjának megakadályozása" + "Lehetővé teszi az alkalmazás számára az autó képernyőjének bekapcsolva tartását." "Lehetővé teszi az alkalmazás számára, hogy megakadályozza, hogy a táblagép alvó üzemmódra váltson." "Lehetővé teszi az alkalmazás számára azt, hogy megakadályozza a tévé alvó üzemmódba való lépését." "Lehetővé teszi az alkalmazás számára, hogy megakadályozza, hogy a telefon alvó üzemmódra váltson." diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 401e27428224..67ac61a6dd50 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -434,6 +434,8 @@ "Հավելվածը կարող է ճանաչել ձեր ֆիզիկական ակտիվությունը:" "լուսանկարել և տեսանկարել" "Այս հավելվածը կարող է ցանկացած պահի լուսանկարել և տեսագրել՝ օգտագործելով տեսախցիկը:" + "Թույլատրել հավելվածին կամ ծառայությանը հետզանգեր ստանալ՝ տեսախցիկների բացվելու և փակվելու դեպքում։" + "Ստորագրությունների այս հավելվածը կարող է հետզանգեր ստանալ՝ ցանկացած տեսախցիկի բացվելու (կնշվի բացող հավելվածը) և փակվելու դեպքում։" "կառավարել թրթռումը" "Թույլ է տալիս հավելվածին կառավարել թրթռոցը:" "ուղղակիորեն զանգել հեռախոսահամարներին" @@ -450,9 +452,11 @@ "Թույլ է տալիս հավելվածին շարունակել մեկ այլ հավելվածի միջոցով սկսած զանգը:" "օգտագործել հեռախոսահամարները" "Հավելվածին թույլ է տալիս օգտագործել սարքի հեռախոսահամարները:" + "միացրած թողնել մեքենայի էկրանը" "զերծ պահել պլանշետը քնելուց" "թույլ չտալ հեռուստացույցին մտնել քնի ռեժիմ" "կանխել հեռախոսի քնի ռեժիմին անցնելը" + "Հավելվածին թույլ է տալիս միացրած թողնել մեքենայի էկրանը։" "Թույլ է տալիս հավելվածին կանխել պլանշետի` քնի ռեժիմին անցնելը:" "Թույլ է տալիս հավելվածին կանխել, որ հեռուստացույցը մտնի քնի ռեժիմ:" "Թույլ է տալիս հավելվածին կանխել հեռախոսի` քնի ռեժիմին անցնելը:" @@ -645,7 +649,7 @@ "Ծրագրին թույլ է տալիս ստանալ Android Beam-ով ընթացիկ փոխանցումների մասին տեղեկատվություն:" "հեռացնել DRM վկայագրեր" "Ծրագրին թույլ է տալիս հեռացնել DRM վկայագրեր: Սովորական ծրագրերի համար երբեք պետք չի գալիս:" - "Կապակցում օպերատորի հաղորդագրությունների ծառայության հետ" + "Միացում օպերատորի հաղորդագրությունների ծառայության հետ" "Թույլ է տալիս տիրոջը կապվել օպերատորի հաղորդագրությունների ծառայության վերին մակարդակի միջերեսի հետ: Սա երբեք չի պահանջվում սովորական հավելվածների համար:" "կապվել օպերատորի ծառայություններին" "Թույլ է տալիս սեփականատիրոջը կապվել օպերատորի ծառայություններին: Սովորական հավելվածների դեպքում չի պահանջվում:" @@ -1592,7 +1596,7 @@ "Ընտրել գործունեությունը" "Կիսվել" "Ուղարկվում է..." - "Գործարկե՞լ զննարկիչը:" + "Գործարկե՞լ դիտարկիչը:" "Ընդունե՞լ զանգը:" "Միշտ" "Միշտ բացել" diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index dc2ca1f8c39c..4f32666363b5 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -89,7 +89,7 @@ "Tidak dapat melakukan panggilan darurat melalui Wi-Fi" "Notifikasi" "Penerusan panggilan" - "Mode panggilan balik darurat" + "Mode telepon balik darurat" "Status data seluler" "Pesan SMS" "Notifikasi pesan suara" @@ -434,6 +434,8 @@ "Aplikasi ini dapat mengenali aktivitas fisik Anda." "ambil gambar dan video" "Aplikasi ini dapat mengambil foto dan merekam video menggunakan kamera kapan saja." + "Izinkan aplikasi atau layanan untuk menerima callback tentang perangkat kamera yang sedang dibuka atau ditutup." + "Aplikasi tanda tangan ini dapat menerima callback saat perangkat kamera sedang dibuka (oleh paket aplikasi) atau ditutup." "kontrol getaran" "Mengizinkan aplikasi untuk mengendalikan vibrator." "panggil nomor telepon secara langsung" @@ -450,9 +452,11 @@ "Mengizinkan aplikasi melanjutkan panggilan yang dimulai di aplikasi lain." "membaca nomor telepon" "Mengizinkan aplikasi mengakses nomor telepon perangkat." + "tetap aktifkan layar mobil" "cegah tablet dari tidur" "cegah agar TV tidak tidur" "mencegah ponsel menjadi tidak aktif" + "Mengizinkan aplikasi untuk menjaga agar layar mobil tetap aktif." "Mengizinkan apl mencegah tablet tidur." "Mengizinkan aplikasi untuk mencegah agar TV tidak tidur." "Mengizinkan apl mencegah ponsel tidur." diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 4bcbaedd1796..340d8a5067de 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -434,6 +434,8 @@ "Þetta forrit getur greint hreyfingu þína." "taka myndir og myndskeið" "Þetta forrit getur tekið myndir og tekið upp myndskeið með myndavélinni hvenær sem er." + "Leyfa forriti eða þjónustu að taka við svörum um myndavélar sem verið er að opna eða loka." + "Þetta undirritunarforrit getur tekið við svörum þegar verið er að opna (með forritapakka) eða loka hvaða myndavél sem er." "stjórna titringi" "Leyfir forriti að stjórna titraranum." "hringja beint í símanúmer" @@ -450,9 +452,11 @@ "Leyfir forritinu að halda áfram með símtal sem hófst í öðru forriti." "lesa símanúmer" "Veitir forritinu aðgang að símanúmerum tækisins." + "hafa kveikt á skjá bílsins" "koma í veg fyrir að spjaldtölvan fari í biðstöðu" "koma í veg fyrir að sjónvarpið fari í biðstöðu" "koma í veg fyrir að síminn fari í biðstöðu" + "Gerir forritinu kleift að hafa kveikt á skjá bílsins." "Leyfir forriti að koma í veg fyrir að spjaldtölvan fari í biðstöðu." "Leyfir forriti að koma í veg fyrir að sjónvarpið fari í biðstöðu." "Leyfir forriti að koma í veg fyrir að síminn fari í biðstöðu." diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index a750669ab8fc..4f3f735fd7f4 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -434,6 +434,8 @@ "Questa app può riconoscere la tua attività fisica." "acquisizione di foto e video" "Questa app può scattare foto e registrare video tramite la fotocamera in qualsiasi momento." + "Consenti a un\'applicazione o a un servizio di ricevere callback relativi all\'apertura o alla chiusura di videocamere." + "Questa app di firma può ricevere callback quando viene aperta (dal pacchetto dell\'applicazione) o chiusa qualsiasi videocamera." "controllo vibrazione" "Consente all\'applicazione di controllare la vibrazione." "chiamata diretta n. telefono" @@ -450,9 +452,11 @@ "Consente all\'app di continuare una chiamata che è stata iniziata in un\'altra app." "lettura dei numeri di telefono" "Consente all\'app di accedere ai numeri di telefono del dispositivo." + "Mantenere attivo lo schermo dell\'auto" "disattivazione stand-by del tablet" "disattivazione della modalità di sospensione della TV" "disattivazione stand-by del telefono" + "Consente all\'app di mantenere attivo lo schermo dell\'auto." "Consente all\'applicazione di impedire lo stand-by del tablet." "Consente all\'app di impedire l\'attivazione della modalità di sospensione della TV." "Consente all\'applicazione di impedire lo stand-by del telefono." @@ -1187,7 +1191,7 @@ "Mostra sempre" "L\'app %1$s è stata realizzata per una versione non compatibile del sistema operativo Android e potrebbe avere un comportamento imprevisto. Potrebbe essere disponibile una versione aggiornata dell\'app." "Mostra sempre" - "Verifica la presenza di aggiornamenti" + "Cerca aggiornamenti" "L\'applicazione %1$s (processo %2$s) ha violato la norma StrictMode autoimposta." "Il processo %1$s ha violato la norma StrictMode autoimposta." "Aggiornamento del telefono…" @@ -1913,7 +1917,7 @@ "Le tue app di lavoro, le notifiche, i dati e altri elementi del profilo di lavoro saranno attivati." "Attiva" "Questa app è stata realizzata per una versione precedente di Android e potrebbe non funzionare correttamente. Prova a verificare la disponibilità di aggiornamenti o contatta lo sviluppatore." - "Verifica la presenza di aggiornamenti" + "Cerca aggiornamenti" "Hai nuovi messaggi" "Apri l\'app SMS per la visualizzazione" "Alcune funzionalità sono limitate" diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 35039f2ebc4d..196cf46b2356 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -440,6 +440,8 @@ "האפליקציה מזהה את הפעילות הגופנית שלך." "צלם תמונות וסרטונים" "אפליקציה זו יכולה להשתמש במצלמה כדי לצלם תמונות ולהקליט סרטונים בכל עת." + "‏אפליקציה או שירות יוכלו לקבל קריאות חוזרות (callback) כשמכשירי מצלמה ייפתחו או ייסגרו." + "‏אפליקציית הפרימיום הזו יכולה לקבל קריאות חוזרות (callback) כשמכשיר מצלמה כלשהו נפתח (באמצעות חבילת אפליקציה) או נסגר." "שליטה ברטט" "מאפשר לאפליקציה לשלוט ברטט." "התקשר ישירות למספרי טלפון" @@ -456,9 +458,11 @@ "הרשאה זו מתירה לאפליקציה להמשיך שיחה שהחלה באפליקציה אחרת." "גישה למספרי הטלפון" "מתירה לאפליקציה גישה למספרי הטלפון במכשיר." + "מסך המכונית יישאר דלוק" "מנע מהטאבלט לעבור למצב שינה" "מניעת מעבר למצב שינה בטלוויזיה" "מניעת מעבר הטלפון למצב שינה" + "מסך המכונית יישאר דלוק כשהאפליקציה פועלת." "מאפשר לאפליקציה למנוע מהטאבלט לעבור למצב שינה." "מאפשרת לאפליקציה למנוע מהטלוויזיה לעבור למצב שינה." "מאפשר לאפליקציה למנוע מהטלפון לעבור למצב שינה." diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 6441fecccb05..ef64d4403f4e 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -434,6 +434,8 @@ "このアプリで身体活動が認識されるようにします。" "写真と動画の撮影" "このアプリは、いつでもカメラを使用して写真や動画を撮影できます。" + "カメラデバイスが起動または終了したときにコールバックを受け取ることを、アプリまたはサービスに許可してください。" + "この署名アプリを使用すると、カメラデバイスが(なんらかのアプリ パッケージによって)起動するとき、または終了するときにコールバックを受け取ることができます。" "バイブレーションの制御" "バイブレーションの制御をアプリに許可します。" "電話番号発信" @@ -450,9 +452,11 @@ "別のアプリで通話を続行することをこのアプリに許可します。" "電話番号の読み取り" "デバイスの電話番号へのアクセスをアプリに許可します。" + "車の画面を常にオンにする" "タブレットのスリープを無効化" "テレビのスリープを無効化" "デバイスのスリープを無効にする" + "車の画面を常にオンにすることをアプリに許可します。" "タブレットのスリープを無効にすることをアプリに許可します。" "テレビのスリープを無効にすることをアプリに許可します。" "モバイル デバイスのスリープを無効にすることをアプリに許可します。" @@ -1817,8 +1821,8 @@ "管理者により更新されています" "管理者により削除されています" "OK" - "電池を長持ちさせるためにバッテリー セーバーが行う操作:\n·ダークテーマをオンにする\n·バックグラウンド アクティビティ、一部の視覚効果や、「OK Google」などの機能をオフにする、または制限する\n\n""詳細" - "電池を長持ちさせるためにバッテリー セーバーが行う操作:\n·ダークテーマをオンにする\n·バックグラウンド アクティビティ、一部の視覚効果や、「OK Google」などの機能をオフにする、または制限する" + "電池を長持ちさせるためにバッテリー セーバーが行う操作:\n·ダークテーマを ON にする\n·バックグラウンド アクティビティ、一部の視覚効果や、「OK Google」などの機能を OFF にする、または制限する\n\n""詳細" + "電池を長持ちさせるためにバッテリー セーバーが行う操作:\n·ダークテーマを ON にする\n·バックグラウンド アクティビティ、一部の視覚効果や、「OK Google」などの機能を OFF にする、または制限する" "データセーバーは、一部のアプリによるバックグラウンドでのデータ送受信を停止することでデータ使用量を抑制します。使用中のアプリからデータにアクセスすることはできますが、その頻度は低くなる場合があります。この影響として、たとえば画像はタップしないと表示されないようになります。" "データセーバーを ON にしますか?" "ON にする" diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 40e9a1e52827..2d6c9f65e855 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -434,6 +434,8 @@ "ამ აპს შეუძლია თქვენი ფიზიკური აქტივობის ამოცნობა." "სურათებისა და ვიდეოების გადაღება" "ამ აპს ნებისმიერ დროს შეუძლია კამერით სურათების გადაღება და ვიდეოების ჩაწერა." + "ნება დაერთოს აპლიკაციას ან სერვისს, მიიღოს გადმორეკვები კამერის მოწყობილობის გახსნის ან დახურვისას." + "ამ მინაწერის აპს შეუძლია მიიღოს გადმორეკვები, როდესაც რომელიმე კამერის მოწყობილობა იხსნება (რომელიმე აპლიკაციის პაკეტით) ან იხურება." "ვიბრაციის კონტროლი" "აპს შეეძლება, მართოს ვიბრირება." "პირდაპირი დარეკვა ტელეფონის ნომრებზე" @@ -450,9 +452,11 @@ "ნებას რთავს აპს, გააგრძელოს ზარი, რომელიც სხვა აპშია წამოწყებული." "ტელეფონის ნომრების წაკითხვა" "აპს მოწყობილობის ტელეფონის ნომრებზე წვდომის საშუალებას მისცემს." + "ჩართული ჰქონდეს მანქანის ეკრანი" "დაიცავით ტაბლეტი დაძინებისგან" "ტელევიზორის დაცვა დაძინებისაგან" "ტელეფონის ძილის რეჟიმში გადასვლის აღკვეთა" + "ნებას რთავს აპს, ჩართული ჰქონდეს მანქანის ეკრანი." "აპს შეეძლება ხელი შეუშალოს ტაბლეტის დაძინებას." "ნებას რთავს აპლიკაციას დაიცვას ტელევიზორი დაძინებისაგან." "აპს შეეძლება ხელი შეუშალოს ტელეფონის დაძინებას." diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 4c4f36d5cd40..e56670b4aefc 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -434,6 +434,8 @@ "Бұл қолданба физикалық әрекетті тани алады." "фотосурет жасау және бейне жазу" "Бұл қолданба кез келген уақытта камерамен суретке түсіруі және бейнелерді жазуы мүмкін." + "Қолданбаға не қызметке ашылып не жабылып жатқан камера құрылғылары туралы кері шақыру алуға рұқсат ету" + "Кез келген камера ашылып (көрсетілген қолданба пакеті арқылы) не жабылып жатқанда, бұл қолтаңба қолданбасы кері шақыру алады." "тербелісті басқару" "Қолданбаға вибраторды басқаруға рұқсат береді." "нөмірлерге тікелей телефон шалу" @@ -450,9 +452,11 @@ "Қолданбаға басқа қолданбадағы қоңырауды жалғастыруға рұқсат береді." "телефон нөмірлерін оқу" "Қолданбаға құрылғының телефон нөмірлерін алуға мүмкіндік береді." + "көлік экранын қосулы күйде ұстау" "планшетті ұйқыдан бөгеу" "ТД ұйықтауын болдырмау" "телефонды ұйқыдан бөгеу" + "Қолданбаға көлік экранын қосулы күйде ұстауға мүмкіндік береді." "Қолданбаға планшеттің ұйқыға кетуін болдырмауға рұқсат береді." "Қолданбаға ТД ұйқыға кетуін болдырауға рұқсат етеді." "Қолданбаға телефонның ұйқыға кетуін болдырмауға рұқсат береді." diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 152379ae493d..946c99144444 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -434,6 +434,8 @@ "កម្មវិធីនេះ​អាចស្គាល់សកម្មភាព​រាងកាយ​របស់អ្នក។" "ថត​រូប និងវីដេអូ" "កម្មវិធី​នេះ​អាច​ថត​រូប​ និង​ថត​វីដេអូ​ ដោយ​ប្រើ​កាមេរ៉ា​បាន​គ្រប់​ពេល​។" + "អនុញ្ញាតឱ្យកម្មវិធី ឬសេវាកម្ម​ទទួលការហៅត្រឡប់វិញអំពី​កាមេរ៉ាដែលកំពុងបិទ ឬបើក។" + "កម្មវិធីពិសេសនេះ​អាចទទួលការហៅត្រឡប់វិញបាន នៅពេលកំពុងបិទ ឬបើកកាមេរ៉ា (ដោយកញ្ចប់កម្មវិធី)។" "ពិនិត្យ​ការ​ញ័រ" "ឲ្យ​កម្មវិធី​គ្រប់គ្រង​កម្មវិធី​ញ័រ។" "ហៅ​លេខ​ទូរស័ព្ទ​ដោយ​ផ្ទាល់" @@ -450,9 +452,11 @@ "អនុញ្ញាត​ឱ្យ​កម្មវិធី​បន្ត​ការ​ហៅ​ទូរសព្ទ​ ដែល​បាន​ចាប់ផ្តើម​នៅក្នុង​កម្មវិធី​ផ្សេង​។" "អាន​លេខ​ទូរសព្ទ" "អនុញ្ញាត​ឲ្យ​កម្មវិធីនេះ​ចូលប្រើប្រាស់​លេខទូរសព្ទ​របស់​ឧបករណ៍​នេះ។" + "បន្តបើក​អេក្រង់​រថយន្ត" "ការពារ​​កុំព្យូទ័រ​បន្ទះ​មិន​ឲ្យ​ដេក" "បង្ការទូរទស្សន៍ពីការបិទពន្លឺ" "ការ​ពារ​ទូរស័ព្ទ​មិន​ឲ្យ​ដេក" + "អនុញ្ញាតឱ្យ​កម្មវិធី​បន្តបើក​អេក្រង់​រថយន្ត។" "ឲ្យ​​កម្មវិធី​ការពារ​កុំព្យូទ័រ​បន្ទះ​មិន​ឲ្យ​ដេក។" "អនុញ្ញាតឲ្យកម្មវិធីបង្ការទូរទស្សន៍ពីការបិទពន្លឺ។" "ឲ្យ​កម្មវិធី​ការពារ​ទូរស័ព្ទ​មិន​ឲ្យ​ដេក។" diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 71185c1e46b0..cf5572d6865f 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -434,6 +434,10 @@ "ಈ ಆ್ಯಪ್‌ ನಿಮ್ಮ ದೈಹಿಕ ಚಟುವಟಿಕೆಯನ್ನು ಗುರುತಿಸಬಹುದು." "ಚಿತ್ರಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳನ್ನು ಸೆರೆಹಿಡಿಯಿರಿ" "ಈ ಅಪ್ಲಿಕೇಶನ್ ಯಾವ ಸಮಯದಲ್ಲಾದರೂ ಕ್ಯಾಮರಾ ಬಳಸಿಕೊಂಡು ಚಿತ್ರಗಳು ಮತ್ತು ವಿಡಿಯೋಗಳನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಬಹುದು." + + + + "ವೈಬ್ರೇಷನ್‌‌ ನಿಯಂತ್ರಿಸಿ" "ವೈಬ್ರೇಟರ್‌ ನಿಯಂತ್ರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ." "ಫೋನ್ ಸಂಖ್ಯೆಗಳಿಗೆ ನೇರವಾಗಿ ಕರೆ ಮಾಡಿ" @@ -450,9 +454,11 @@ "ಮತ್ತೊಂದು ಅಪ್ಲಿಕೇಶನ್‌ನಲ್ಲಿ ಪ್ರಾರಂಭವಾದ ಕರೆಯನ್ನು ಮುಂದುವರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡಿ." "ಫೋನ್‌ ಸಂಖ್ಯೆಗಳನ್ನು ಓದಿ" "ಸಾಧನದ ಫೋನ್ ಸಂಖ್ಯೆಗಳಿಗೆ ಪ್ರವೇಶ ಪಡೆಯಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ." + "ಕಾರ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಆನ್‌ನಲ್ಲೇ ಇರಿಸಿ" "ಟ್ಯಾಬ್ಲೆಟ್ ನಿದ್ರಾವಸ್ಥೆಯನ್ನು ತಡೆಯಿರಿ" "ಟಿವಿಗೆ ನಿದ್ರಿಸುವುದನ್ನು ತಪ್ಪಿಸಿ" "ಫೋನ್ ಆಫ್ ಆಗುವುದರಿಂದ ತಡೆಯಿರಿ" + "ಕಾರ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಆನ್‌ನಲ್ಲೇ ಇರಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ." "ಟ್ಯಾಬ್ಲೆಟ್‌ ನಿದ್ರೆಗೆ ಹೋಗುವುದನ್ನು ತಡೆಯಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ." "ಟಿವಿ ನಿದ್ರೆಗೆ ಹೋಗುವುದನ್ನು ತಡೆಗಟ್ಟಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ." "ಫೋನ್‌ ನಿದ್ರೆಗೆ ಹೋಗುವುದನ್ನು ತಡೆಯಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ." @@ -874,7 +880,7 @@ "ಪ್ಯಾಟರ್ನ್ ಪೂರ್ಣಗೊಂಡಿದೆ" "ಪ್ಯಾಟರ್ನ್ ಪ್ರದೇಶ." "%1$s.%3$d ರಲ್ಲಿ %2$d ವಿಜೆಟ್." - "ವಿಜೆಟ್ ಸೇರಿಸು." + "ವಿಜೆಟ್ ಸೇರಿಸಿ." "ಖಾಲಿ" "ಅನ್‌ಲಾಕ್ ಪ್ರದೇಶವನ್ನು ವಿಸ್ತರಿಸಲಾಗಿದೆ." "ಅನ್‌ಲಾಕ್ ಪ್ರದೇಶವನ್ನು ಸಂಕುಚಿಸಲಾಗಿದೆ." diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 278fac58c932..712226c4d5b8 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -434,6 +434,8 @@ "이 앱에서 내 신체 활동을 확인할 수 있습니다." "사진과 동영상 찍기" "이 앱은 언제든지 카메라를 사용하여 사진을 촬영하고 동영상을 녹화할 수 있습니다." + "애플리케이션 또는 서비스에서 카메라 기기 열림 또는 닫힘에 대한 콜백을 수신하도록 허용" + "이 서명 앱은 사용되는 애플리케이션 패키지와 관련 없이 카메라 기기가 열릴 때나 닫힐 때 콜백을 수신할 수 있습니다." "진동 제어" "앱이 진동을 제어할 수 있도록 허용합니다." "전화번호 자동 연결" @@ -450,9 +452,11 @@ "다른 앱에서 수신한 전화를 계속하려면 앱을 허용합니다." "전화번호 읽기" "앱에서 기기의 전화번호에 액세스하도록 허용합니다." + "차량 화면 켜진 상태로 유지" "태블릿이 절전 모드로 전환되지 않도록 설정" "TV의 절전 모드 전환 방지" "휴대전화가 절전 모드로 전환되지 않도록 설정" + "앱에서 차량 화면을 켜진 상태로 유지하도록 허용합니다." "앱이 태블릿의 절전 모드 전환을 막도록 허용합니다." "앱이 TV가 절전 모드로 전환되는 것을 방지할 수 있도록 허용합니다." "앱이 휴대전화의 절전 모드 전환을 막도록 허용합니다." diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 161e4e6cb8f0..41569d58215a 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -184,12 +184,12 @@ "Аныкталбаган үчүнчү тараптардан" "Жумуш профилиңиздин администратору тарабынан" "%s тарабынан" - "Жумуш профили жок кылынды" - "Жумуш профилинин башкаруучу колдонмосу жок же бузулгандыктан, жумуш профилиңиз жана ага байланыштуу дайындар жок кылынды. Жардам алуу үчүн администраторуңузга кайрылыңыз." - "Жумуш профилиңиз бул түзмөктөн жок кылынды" + "Жумуш профили өчүрүлдү" + "Жумуш профилинин башкаруучу колдонмосу жок же бузулгандыктан, жумуш профилиңиз жана ага байланыштуу дайындар өчүрүлдү. Жардам алуу үчүн администраторуңузга кайрылыңыз." + "Жумуш профилиңиз бул түзмөктөн өчүрүлдү" "Өтө көп жолу сырсөздү киргизүү аракети жасалды" "Түзмөктү ишкана башкарат" - "Ишканаңыз бул түзмөктү башкарат жана тармак трафигин көзөмөлдөшү мүмкүн. Чоо-жайын көрүү үчүн таптап коюңуз." + "Ишканаңыз бул түзмөктү башкарат жана тармак трафигин көзөмөлдөшү мүмкүн. Чоо-жайын билгиңиз келсе, таптап коюңуз." "Түзмөгүңүз тазаланат" "Түзмөктү башкаруучу колдонмо жараксыз. Түзмөгүңүз азыр тазаланат.\n\nСуроолоруңуз болсо, ишканаңыздын администраторуна кайрылыңыз." "Басып чыгаруу %s тарабынан өчүрүлдү." @@ -434,12 +434,14 @@ "Бул колдонмо кыймыл-аракетиңизди аныктап турат." "сүрөт жана видео тартуу" "Бул колдонмо каалаган убакта камера менен сүрөт же видеолорду тарта алат." + "Колдонмого же кызматка камера ачылып же жабылып жатканда чалууларды кабыл алууга уруксат берүү." + "Бул колдонмо камера ачылып же жабылып жатканда (колдонмонун таңгагы) чалууларды кабыл алат." "титирөөнү башкаруу" "Колдонмого дирилдегичти көзөмөлдөө мүмкүнчүлүгүн берет." "телефон номерлерине түз чалуу" "Колдонмого сиздин катышууңузсуз телефон номурларга чалуу уруксатын берет. Бул сиз күтпөгөн чыгымдарга же чалууларга алып келиши мүмкүн. Бул куткаруучулардын номурларына чалууга уруксат бербей тургандыгын эске алыңыз. Зыяндуу колдонмолор, сиздин ырастооңузсуз чалууларды аткарып, көп чыгымдарга себепкер болушу мүмкүн." "IMS чалуу кызматына мүмкүнчүлүк алуу" - "Колдонмого сизди катыштырбай туруп, IMS кызматынын жардамы менен чалууларды жасоо мүмкүнчүлүгүн берет." + "Колдонмого сизди катыштырбай туруп, IMS кызматынын жардамы менен, чалууларды жасоо мүмкүнчүлүгүн берет." "телефондун абалын жана аныктыгын окуу" "Колдонмого түзмөктүн чалуу мүмкүнчүлүктөрүнө жетки алуу уруксатын берет. Бул уруксат колдонмого, телефондун номурун, түзмөктүн ID-син, чалуунун абалын жана байланышта чыккан номурду аныктоого жол берет." "чалууларды тутум аркылуу өткөрүү" @@ -450,9 +452,11 @@ "Башка колдонмодон аткарылган чалууну бул колдонмодо улантууга уруксат берүү." "телефон номерлерин окуу" "Колдонмого түзмөктүн телефон номерлерин окуу мүмкүнчүлүгү берилет." + "унаанын экранын күйгүзүлгөн бойдон калтыруу" "планшетти уктатпай сактоо" "сыналгыны көшүтпөө" "телефонду уктатпай сактоо" + "Колдонмого унаанын экранын күйгүзүлгөн бойдон калтырууга уруксат берет." "Колдонмо планшетти көшүү режимине өткөрбөйт." "Колдонмо сыналгыны көшүү режимине өткөрбөйт." "Колдонмо телефонду көшүү режимине өткөрбөйт." @@ -528,11 +532,11 @@ "Таанылган жок" "Аныктыгын текшерүү жокко чыгарылды" "PIN код, графикалык ачкыч же сырсөз коюлган жок" - "Манжа изи жарым-жартылай аныкталды. Кайра аракет кылыңыз." - "Манжа изи иштелбей койду. Кайра аракет кылыңыз." - "Манжа изинин сенсору кирдеп калган. Тазалап, кайра аракет кылыңыз." - "Манжа өтө тез жылдырылды. Кайра аракет кылыңыз." - "Манжа өтө жай жылды. Кайра аракет кылыңыз." + "Манжа изи жарым-жартылай аныкталды. Кайталап көрүңүз." + "Манжа изи иштелбей койду. Кайталап көрүңүз." + "Манжа изинин сенсору кирдеп калган. Тазалап, кайталап көрүңүз." + "Манжа өтө тез жылдырылды. Кайталап көрүңүз." + "Манжа өтө жай жылды. Кайталап көрүңүз." "Манжа изи текшерилди" @@ -540,10 +544,10 @@ "Жүздүн аныктыгы текшерилди, эми \"Ырастоону\" басыңыз" "Манжа изинин аппараттык камсыздоосу жеткиликтүү эмес." "Манжа изин сактоо мүмкүн эмес. Учурдагы манжа изин алып салыңыз." - "Манжа изин күтүү мөөнөтү бүттү. Кайра аракет кылыңыз." + "Манжа изин күтүү мөөнөтү бүттү. Кайталап көрүңүз." "Манжа изи иш-аракети жокко чыгарылды." "Манжа изи операциясын колдонуучу жокко чыгарды." - "Аракеттер өтө көп болду. Кийинчерээк кайра аракет кылыңыз." + "Аракеттер өтө көп болду. Бир аздан кийин кайталап көрүңүз." "Өтө көп жолу аракет жасадыңыз. Манжа изинин сенсору өчүрүлдү." "Кайра бир аракеттениңиз." "Бир да манжа изи катталган эмес." @@ -559,7 +563,7 @@ "Жүзүнөн таануу" "Жүзүңүздү кайра таанытыңыз." "Мыкты таануу үчүн, жүзүңүздү кайра таанытыңыз" - "Жүзүңүз жакшы тартылган жок. Кайра аракет кылыңыз." + "Жүзүңүз жакшы тартылган жок. Кайталап көрүңүз." "Өтө жарык. Жарыктыкты азайтып көрүңүз." "Өтө караңгы. Жарыгыраак жерден тартып көрүңүз." "Телефонду алысыраак жылдырыңыз." @@ -572,7 +576,7 @@ "Телефонду жүзүңүздүн маңдайында кармаңыз." "Кыймылдап жибердиңиз. Телефонду түз кармаңыз." "Жүзүңүздү кайра таанытыңыз." - "Жүз таанылган жок. Кайра аракет кылыңыз." + "Жүз таанылган жок. Кайталап көрүңүз." "Мурункуга окшош болуп калды, башкача туруңуз." "Башыңызды бир аз гана эңкейтиңиз." "Башыңызды бир аз гана эңкейтиңиз." @@ -586,9 +590,9 @@ "Жаңы жүздү сактоо мүмкүн эмес. Адегенде эскисин өчүрүңүз." "Жүздүн аныктыгын текшерүү жокко чыгарылды." "Жүзүнөн таануу функциясын колдонуучу өчүрүп салды." - "Өтө көп жолу аракет жасадыңыз. Кийинчерээк кайра аракет кылыңыз." + "Өтө көп жолу аракет жасадыңыз. Бир аздан кийин кайталап көрүңүз." "Өтө көп жолу аракет кылдыңыз. Жүзүнөн таануу функциясы өчүрүлдү." - "Жүз ырасталбай жатат. Кайра аракет кылыңыз." + "Жүз ырасталбай жатат. Кайталап көрүңүз." "Жүзүнөн таануу функциясын жөндөй элексиз." "Жүзүнөн таануу функциясы бул түзмөктө иштебейт." "Жүз %d" @@ -847,9 +851,9 @@ "Кулпуну ачуу үлгүсүн %1$d жолу туура эмес тарттыңыз. Дагы %2$d жолу туура эмес тартсаңыз, планшетиңиздин кулпусун Google\'га кирип ачууга туура келет.\n\n %3$d секундадан кийин дагы аракет кылып көрүңүз." "Кулпуну ачуу үлгүсүн %1$d жолу туура эмес тарттыңыз. Дагы %2$d жолу туура эмес тартсаңыз, сыналгыңыздын кулпусун Google\'га кирип ачууга туура келет.\n\n %3$d секундадан кийин дагы аракет кылып көрүңүз." "Кулпуну ачуу үлгүсүн %1$d жолу туура эмес тарттыңыз. Дагы %2$d жолу туура эмес тартсаңыз, телефонуңуздун кулпусун Google\'га кирип ачууга туура келет.\n\n %3$d секундадан кийин дагы аракет кылып көрүңүз." - "Сиз планшетиңизди бөгөттөн чыгарууга %1$d жолу туура эмес аракет кылдыңыз. Дагы %2$d аракеттен кийин, планшет баштапкы абалына келтирилет жана бардык маалыматтар жок кылынат." + "Сиз планшетиңизди бөгөттөн чыгарууга %1$d жолу туура эмес аракет кылдыңыз. Дагы %2$d аракеттен кийин, планшет баштапкы абалына келтирилет жана бардык маалыматтар өчүрүлөт." "Кулпуну ачуу үлгүсүн %1$d жолу туура эмес тарттыңыз. Дагы %2$d жолу туура эмес тартсаңыз, сыналгыңыз баштапкы абалга келтирилип, колдонуучунун бардык дайындары жок болот." - "Сиз телефонуңузду бөгөттөн чыгарууга %1$d жолу туура эмес аракет кылдыңыз. Дагы %2$d аракеттен кийин, телефон баштапкы абалына келтирилет жана бардык маалыматтар жок кылынат." + "Сиз телефонуңузду бөгөттөн чыгарууга %1$d жолу туура эмес аракет кылдыңыз. Дагы %2$d аракеттен кийин, телефон баштапкы абалына келтирилет жана бардык маалыматтар өчүрүлөт." "Сиз планшетти бөгөттөн чыгарууга %d жолу туура эмес аракет кылдыңыз. Планшет баштапкы абалына келтирилет." "Сыналгыңыздын кулпусун ачууда %d_0 жолу туура эмес аракет кылдыңыз. Сыналгыңыз баштапкы абалга келтирилет." "Сиз телефонду бөгөттөн чыгарууга %d жолу туура эмес аракет кылдыңыз. Телефон баштапкы абалына келтирилет." @@ -885,7 +889,7 @@ "Медиа башкаруу" "Виджет иреттөө башталды." "Виджет иреттөө аяктады." - "%1$s виждети жок кылынды." + "%1$s виждети өчүрүлдү." "Бөгөттөн чыгаруу аймагын кеңейтүү." "Жылмыштырып ачуу." "Үлгү менен ачуу." @@ -1241,11 +1245,11 @@ "Эскертменин добуштары" "Белгисиз" "\"%1$s\" тармагына туташпай койду" - "Купуялык жөндөөлөрүн өзгөртүү үчүн таптап, кайра аракет кылыңыз" + "Купуялык жөндөөлөрүн өзгөртүү үчүн таптап, кайталап көрүңүз" "Купуялык жөндөөлөрүн өзгөртөсүзбү?" "%1$s түзмөгүңүздүн MAC дарегин, уникалдуу идентификаторуңузду колдонуп туташканы жатат. Ушуну менен түзмөгүңүздүн жайгашкан жерине жакын жердеги түзмөктөр көз сала алышат. \n\nЭгер улантсаңыз, %1$s купуялык жөндөөлөрүңүздү өзгөртүп, кайра туташууга аракет кылат." "Жөндөөнү өзгөртүү" - "Жөндөө жаңыртылды. Кайра туташып көрүңүз." + "Жөндөө жаңырды. Кайра туташып көрүңүз." "Купуялык жөндөөлөрүн өзгөртүүгө болбойт" "Тармак табылган жок" @@ -1331,7 +1335,7 @@ "Муну кийин Тууралоолор > Колдонмолордон өзгөртө аласыз" "Дайыма уруксат берүү" "Эч качан уруксат берилбесин" - "SIM-карта алынып салынды" + "SIM-карта өчүрүлдү" "Сиз жарактуу SIM салып, кайра иштетмейинче, мобилдик тармак жеткиликсиз болот." "Даяр" "SIM-карта кошулду" @@ -1401,7 +1405,7 @@ "%s колдоого алынбайт" "Бул түзмөктө %s колдоого алынбайт. Колдоого алынуучу форматта орнотуу үчүн таптап коюңуз." "Бул түзмөктө %s колдоого алынбайт. Колдоого алынуучу форматта орнотуу үчүн тандаңыз." - "%s күтүүсүздөн алынып салынды" + "%s күтүүсүздөн өчүрүлдү" "Мазмунду жоготуп албаш үчүн алып салуудан мурда медианы өчүрүңүз" "%s чыгарылды" "Айрым функциялар талаптагыдай иштебей калышы мүмкүн. Жаңы сактагычты салыңыз." @@ -1657,9 +1661,9 @@ "Сиз PIN-кодуңузду %1$d жолу туура эмес тердиңиз. \n\n %2$d секундадан кийин кайталаңыз." "Сиз сырсөзүңүздү %1$d жолу туура эмес тердиңиз. \n\n %2$d секундадан кийин кайталаңыз." "Сиз бөгөттөн чыгаруу үлгүсүн %1$d жолу туура эмес көрсөттүңүз. \n\n %2$d секундадан кийин кайталаңыз." - "Сиз планшетиңизди %1$d жолу ийгиликсиз бөгөттөн чыгаруу аракетин кылдыңыз. Дагы %2$d ийгиликсиз аракеттен кийин, планшет баштапкы абалына кайтарылат жана бардык берилиштериңиз жок кылынат." + "Сиз планшетиңизди %1$d жолу ийгиликсиз бөгөттөн чыгаруу аракетин кылдыңыз. Дагы %2$d ийгиликсиз аракеттен кийин, планшет баштапкы абалына кайтарылат жана бардык берилиштериңиз өчүрүлөт." "Кулпуну ачуу үлгүсүн %1$d жолу туура эмес тарттыңыз. Дагы %2$d жолу туура эмес тартсаңыз, сыналгыңыз баштапкы абалга келтирилип, колдонуучунун бардык дайындары жок болот." - "Сиз телефонуңузду %1$d жолу ийгиликсиз бөгөттөн чыгаруу аракетин кылдыңыз. Дагы %2$d ийгиликсиз аракеттен кийин, телефон баштапкы абалына кайтарылат жана бардык берилиштериңиз жок кылынат." + "Сиз телефонуңузду %1$d жолу ийгиликсиз бөгөттөн чыгаруу аракетин кылдыңыз. Дагы %2$d ийгиликсиз аракеттен кийин, телефон баштапкы абалына кайтарылат жана бардык берилиштериңиз өчүрүлөт." "Сиз планшетиңизди %d жолу ийгиликсиз бөгөттөн чыгаруу аракетин кылдыңыз. Планшет баштапкы абалына кайтарылат." "Сыналгыңыздын кулпусун ачууда %d_0 жолу туура эмес аракет кылдыңыз. Сыналгыңыз баштапкы абалга келтирилет." "Сиз телефонуңузду %d жолу ийгиликсиз бөгөттөн чыгаруу аракетин кылдыңыз. Телефон баштапкы абалына кайтарылат." @@ -1795,7 +1799,7 @@ %d секунддан кийин кайталаңыз 1 секунддан кийин кайталаңыз - "Кийинчерээк кайталаңыз" + "Бир аздан кийин кайталап көрүңүз" "Толук экран режими" "Чыгуу үчүн экранды ылдый сүрүп коюңуз." "Түшүндүм" @@ -1997,11 +2001,11 @@ "Зыянкеч колдонмо аныкталды" "%1$s колдонмосу %2$s үлгүлөрүн көрсөткөнү жатат" "Түзөтүү" - "Чалуулар менен эскертмелер дирилдөө режиминде иштейт" + "Чалуулар менен билдирмелер дирилдөө режиминде иштейт" "Чалуулар менен эскертмелердин үнү өчүрүлөт" "Тутум өзгөрүүлөрү" "Тынчымды алба" - "Жаңы: \"Тынчымды алба\" режими эскертмелерди жашырууда" + "Жаңы: \"Тынчымды алба\" режими билдирмелерди жашырууда" "Көбүрөөк маалымат алып, өзгөртүү үчүн таптаңыз." "\"Тынчымды алба\" режими өзгөрдү" "Бөгөттөлгөн нерселерди көрүү үчүн таптаңыз." diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 9f9fe2c7433c..3367722c867d 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -434,6 +434,8 @@ "ແອັບນີ້ສາມາດຈັດລະບຽບການເຄື່ອນໄຫວທາງກາຍຂອງທ່ານໄດ້." "ຖ່າຍຮູບ ແລະວິດີໂອ" "This app can take pictures and record videos using the camera at any time." + "ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ຫຼື ບໍລິການຮັບການເອີ້ນກັບກ່ຽວກັບອຸປະກອນກ້ອງຖືກເປີດ ຫຼື ປິດໄດ້." + "ແອັບລາຍເຊັນນີ້ສາມາດຮັບການເອີ້ນກັບໄດ້ເມື່ອມີອຸປະກອນກ້ອງໃດຖືກເປີດ (ໂດຍແພັກເກດແອັບພລິເຄຊັນຫຍັງ) ຫຼື ຖືກປິດ." "ຄວບຄຸມການສັ່ນ" "ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມໂຕສັ່ນ." "ໂທຫາເບີໂທລະສັບໂດຍກົງ" @@ -450,9 +452,11 @@ "ອະນຸຍາດໃຫ້ແອັບສືບຕໍ່ການໂທເຊິ່ງອາດຖືກເລີ່ມຕົ້ນໃນແອັບອື່ນ." "ອ່ານເບີໂທລະສັບ" "ອະນຸຍາດໃຫ້ແອັບເຂົ້າເຖິງເບີໂທລະສັບຂອງອຸປະກອນໄດ້." + "ເປີດໜ້າຈໍລົດໄວ້ຕະຫຼອດ" "ຂັດຂວາງບໍ່ໃຫ້ປິດໜ້າຈໍແທັບເລັດ" "ປ້ອງ​ກັນ​ບໍ່​ໃຫ້ໂທລະພາບຫຼັບ​ພັກ" "ຂັດຂວາງບໍ່ໃຫ້ໂທລະສັບປິດໜ້າຈໍ" + "ອະນຸຍາດໃຫ້ແອັບເຮັດໃຫ້ໜ້າຈໍລົດເປີດໄວ້ຕະຫຼອດ." "ອະນຸຍາດໃຫ້ແອັບຯ ປ້ອງກັນບໍ່ໃຫ້ປິດໜ້າຈໍແທັບເລັດ." "ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບ​ປ້ອງ​ກັນ​ບໍ່​ໃຫ້ໂທລະພາບຫຼັບ​ພັກ." "ອະນຸຍາດໃຫ້ແອັບຯປ້ອງກັນບໍ່ໃຫ້ປິດໜ້າຈໍໂທລະສັບ." diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index d41670f8f8b2..282fa238ab56 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -440,6 +440,8 @@ "Ši programa gali atpažinti jūsų fizinę veiklą." "fotografuoti ir filmuoti" "Ši programa gali bet kada fotografuoti ir įrašyti vaizdo įrašų naudodama fotoaparatą." + "Leisti programai ar paslaugai sulaukti atgalinio skambinimo, kai atidaromas ar uždaromas fotoaparatas." + "Ši pasirašymo programa gali sulaukti atgalinio skambinimo, kai atidaromas ar uždaromas (kurio nors programos paketo) koks nors fotoaparatas." "valdyti vibraciją" "Leidžiama programai valdyti vibravimą." "skambinti tiesiogiai telefono numeriais" @@ -456,9 +458,11 @@ "Programai leidžiama tęsti skambutį, kuris buvo pradėtas naudojant kitą programą." "skaityti telefonų numerius" "Programai leidžiama pasiekti įrenginio telefonų numerius." + "palikti automobilio ekraną įjungtą" "neleisti planšetiniam kompiuteriui užmigti" "neleisti įjungti TV miego būsenos" "neleisti telefonui snausti" + "Programai leidžiama palikti automobilio ekraną įjungtą." "Leidžiama programai neleisti planšetiniam kompiuteriui užmigti." "Programai leidžiama nustatyti, kad TV nebūtų perjungtas į miego būseną." "Leidžiama programai neleisti telefonui užmigti." diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index c5e269fa0c43..17dfeaa04772 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -437,6 +437,8 @@ "Šī lietotne var noteikt jūsu fiziskās aktivitātes." "uzņemt attēlus un videoklipus" "Šī lietotne jebkurā brīdī var uzņemt attēlus un ierakstīt videoklipus, izmantojot kameru." + "Atļaut lietojumprogrammai vai pakalpojumam saņemt atzvanus par kameras ierīču atvēršanu vai aizvēršanu" + "Šajā parakstu lietotnē var saņemt atzvanus, ja tiek atvērta vai aizvērta jebkāda kameras ierīce (atkarībā no lietojumprogrammas pakotnes)." "kontrolēt vibrosignālu" "Ļauj lietotnei kontrolēt vibrosignālu." "tieši zvanīt uz tālruņa numuriem" @@ -453,9 +455,11 @@ "Ļauj lietotnei turpināt zvanu, kas tika sākts citā lietotnē." "lasīt tālruņa numurus" "Ļauj lietotnei piekļūt ierīcē esošajiem tālruņa numuriem." + "paturēt ieslēgtu automašīnas ekrānu" "novērst planšetdatora pāriešanu miega režīmā" "novērst televizora pāreju miega režīmā" "novērst tālruņa pāriešanu miega režīmā" + "Ļauj lietotnei paturēt ieslēgtu automašīnas ekrānu." "Ļauj lietotnei novērst planšetdatora pāriešanu miega režīmā." "Ļauj lietotnei novērst televizora pāreju miega režīmā." "Ļauj lietotnei novērst tālruņa pāriešanu miega režīmā." diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index af73a792ddfd..fcfa19500706 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -21,9 +21,9 @@ "Б" - "КБ" - "МБ" - "ГБ" + "KB" + "MB" + "GB" "ТБ" "ПБ" "%1$s %2$s" @@ -434,6 +434,8 @@ "Апликацијава може да ја препознава вашата физичка активност." "снимај слики и видеа" "Апликацијава може да фотографира и да снима видеа со камерата во секое време." + "Дозволете апликацијатa или услугата да прима повратни повици за отворањето или затворањето на уредите со камера." + "Оваа апликација за потпис може да прима повратни повици кога кој било уред со камера (од некој пакет за апликации) е отворен или затворен." "контролирај вибрации" "Дозволува апликацијата да ги контролира вибрациите." "директно избирај телефонски броеви" @@ -450,9 +452,11 @@ "Овозможува апликацијата да продолжи повик започнат на друга апликација." "да чита телефонски броеви" "Ѝ дозволува на апликацијата да пристапи до телефонските броеви на уредот." + "оставете го екранот на автомобилот вклучен" "спречи режим на штедење кај таблет" "спречи го телевизорот да премине во режим на мирување" "спречи телефон од режим на штедење" + "Дозволува апликацијата да го држи екранот на автомобилот вклучен." "Дозволува апликацијата да го спречи таблетот да не заспие." "Дозволува апликацијата да го спречи телевизорот да оди во режим на мирување." "Дозволува апликацијата да го спречи телефонот да не заспие." @@ -1115,7 +1119,7 @@ "Дефинирајте го избраниот текст" "Капацитетот е речиси полн" "Некои системски функции може да не работат" - "Нема доволно меморија во системот. Проверете дали има слободен простор од 250 МБ и рестартирајте." + "Нема доволно меморија во системот. Проверете дали има слободен простор од 250 MB и рестартирајте." "%1$s работи" "Допрете за повеќе информации или за сопирање на апликацијата." "Во ред" @@ -1163,7 +1167,7 @@ "%1$s постојано запира" "%1$s постојано запира" "Отвори ја апликацијата повторно" - "Испрати повратни информации" + "Испратете повратни информации" "Затвори" "Исклучи го звукот додека уредот не се рестартира" "Почекај" diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 7602575ba90a..d474ff59d511 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -434,6 +434,10 @@ "നിങ്ങളുടെ ശാരീരിക പ്രവർത്തനം ഈ ആപ്പിന് തിരിച്ചറിയാനാവും." "ചിത്രങ്ങളും വീഡിയോകളും എടുക്കുക" "ഏതുസമയത്തും ക്യാമറ ഉപയോഗിച്ചുകൊണ്ട് ചിത്രങ്ങൾ എടുക്കാനും വീഡിയോകൾ റെക്കോർഡുചെയ്യാനും ഈ ആപ്പിന് കഴിയും." + + + + "വൈബ്രേറ്റുചെയ്യൽ നിയന്ത്രിക്കുക" "വൈബ്രേറ്റർ നിയന്ത്രിക്കുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു." "ഫോൺ നമ്പറുകളിലേക്ക് നേരിട്ട് വിളിക്കുക" @@ -450,9 +454,11 @@ "മറ്റൊരു ആപ്പിൽ ആരംഭിച്ച കോൾ തുടരാൻ ആപ്പിനെ അനുവദിക്കുന്നു." "ഫോൺ നമ്പറുകൾ റീഡുചെയ്യൽ" "ഉപകരണത്തിന്റെ ഫോൺ നമ്പറുകൾ ആക്‌സസ് ചെയ്യാൻ ആപ്പിനെ അനുവദിക്കുന്നു." + "കാറിലെ സ്ക്രീൻ ഓണാക്കി വയ്ക്കുക" "ഉറങ്ങുന്നതിൽ നിന്ന് ടാബ്‌ലെറ്റിനെ തടയുക" "ടിവിയെ നിർജ്ജീവമാകുന്നതിൽ നിന്ന് തടയുക" "ഉറങ്ങുന്നതിൽ നിന്ന് ഫോണിനെ തടയുക" + "കാറിലെ സ്ക്രീൻ ഓണാക്കി വയ്ക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു." "ടാബ്‌ലെറ്റ് സുഷുപ്തിയിലാകുന്നതിൽ നിന്നും തടയുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു." "ടിവി നിർജ്ജീവമാകുന്നത് തടയുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു." "ഫോൺ സുഷുപ്തിയിലാകുന്നതിൽ നിന്നും തടയുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു." diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 241ec82461eb..0234996f8587 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -434,6 +434,8 @@ "Энэ апп таны биеийн дасгал хөдөлгөөнийг таних боломжтой." "зураг авах болон видео бичих" "Энэ апп ямар ч үед камер ашиглан зураг авж, видео хийх боломжтой." + "Аппликэйшн эсвэл үйлчилгээнд камерын төхөөрөмжүүдийг нээж эсвэл хааж байгаа тухай залгасан дуудлага хүлээн авахыг зөвшөөрөх." + "Гарын үсгийн энэ апп нь дурын камерын төхөөрөмжийг нээх (ямар аппликэйшний багцаар болох) эсвэл хаах үед буцааж залгасан дуудлага хүлээн авах боломжтой." "чичиргээг удирдах" "Апп нь чичиргээг удирдах боломжтой." "утасны дугаарт шууд дуудлага хийх" @@ -450,9 +452,11 @@ "Аппад өөр аппад эхлүүлсэн дуудлагыг үргэлжлүүлэхийг зөвшөөрдөг." "утасны дугаарыг унших" "Төхөөрөмжийн утасны дугаарт хандах зөвшөөрлийг апп-д олгоно." + "машины дэлгэцийг асаалттай байлгах" "таблетыг унтуулахгүй байлгах" "Телевиз-ийн гэрэл унтрахаас сэргийл" "утсыг унтуулахгүй байлгах" + "Аппад машины дэлгэцийг асаалттай байлгахыг зөвшөөрдөг." "Апп нь таблетыг унтахаас сэргийлэх боломжтой" "Апп-д телевизийг унтраахгүй байлгахыг зөвшөөрдөг." "Апп нь утсыг унтахаас сэргийлэх боломжтой" diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 6f5e199c8b19..1cb979e95107 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -294,7 +294,7 @@ "<b>%1$s</b> ला एसएमएस पाठवू आणि पाहू द्यायचे?" "स्टोरेज" "तुमच्या डिव्हाइस वरील फोटो, मीडिया आणि फायलींमध्‍ये अ‍ॅक्सेस" - "<b>%1$s</b> ला तुमच्या डिव्हाइसवरील फोटो, मीडिया आणि फायली अ‍ॅक्सेस करू द्यायचे?" + "<b>%1$s</b> ला तुमच्या डिव्हाइसवरील फोटो, मीडिया आणि फाइल अ‍ॅक्सेस करू द्यायच्या?" "मायक्रोफोन" "ऑडिओ रेकॉर्ड" "<b>%1$s</b> ला ऑडिओ रेकॉर्ड करू द्यायचा?" @@ -434,6 +434,10 @@ "हे अ‍ॅप तुमच्या शारीरिक ॲक्टिव्हिटी ओळखू शकते." "चित्रे आणि व्हिडिओ घ्या" "हा अ‍ॅप कोणत्याही वेळी कॅमेरा वापरून चित्रेे घेऊ आणि व्ह‍िडिओ रेकॉर्ड करू शकतो." + + + + "व्हायब्रेट नियंत्रित करा" "अ‍ॅप ला व्हायब्रेटर नियंत्रित करण्यासाठी अनुमती देते." "फोन नंबरवर प्रत्यक्ष कॉल करा" @@ -450,9 +454,11 @@ "दुसऱ्या ॲपमध्ये सुरू झालेल्या कॉलला पुढे सुरू ठेवण्याची ॲपला अनुमती देते." "फोन नंबर वाचा" "ॲपला डिव्हाइसच्या फोन नंबरमध्ये प्रवेश करण्याची अनुमती देते." + "कारची स्क्रीन सुरू ठेवा" "टॅबलेट निष्क्रिय होण्यापासून प्रतिबंधित करा" "निष्क्रिय होण्यापासून प्रतिबंध करा" "फोन निष्‍क्रिय होण्‍यापासून प्रतिबंधित करा" + "ॲपला कारची स्क्रीन सुरू ठेवण्याची अनुमती देते." "टॅब्लेटला निष्क्रिय होण्यापासून प्रतिबंधित करण्यासाठी अ‍ॅप ला अनुमती देते." "निष्क्रिय होण्यापासून टीव्हीला प्रतिबंध करण्यासाठी ॲपला अनुमती देते." "फोनला निष्क्रिय होण्यापासून प्रतिबंधित करण्यासाठी अ‍ॅप ला अनुमती देते." diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 1698bb7cedac..2c7be25fadbd 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -434,6 +434,8 @@ "Apl ini dapat mengecam aktiviti fizikal anda." "ambil gambar dan video" "Apl ini boleh mengambil gambar dan merakam video menggunakan kamera pada bila-bila masa." + "Benarkan aplikasi atau perkhidmatan menerima panggilan balik tentang peranti kamera yang dibuka atau ditutup." + "Apl tandatangan ini boleh menerima panggilan balik apabila mana-mana peranti kamera dibuka (oleh pakej aplikasi tertentu) atau ditutup." "kawal getaran" "Membenarkan apl mengawal penggetar." "panggil terus nombor telefon" @@ -450,9 +452,11 @@ "Membenarkan apl meneruskan panggilan yang dimulakan dalam apl lain." "baca nombor telefon" "Membenarkan apl mengakses nombor telefon peranti." + "pastikan skrin kereta sentiasa hidup" "menghalang tablet daripada tidur" "halang TV daripada tidur" "halang telefon daripada tidur" + "Membenarkan apl memastikan skrin kereta sentiasa hidup." "Membenarkan apl menghalang tablet daripada tidur." "Membenarkan apl menghalang TV daripada tidur." "Membenarkan apl menghalang telefon daripada tidur." diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 99e5d4258cef..b43add50b95b 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -434,6 +434,8 @@ "ဤအက်ပ်က သင်၏ကိုယ်လက်လှုပ်ရှားမှုကို မှတ်သားနိုင်ပါသည်။" "ဓါတ်ပုံနှင့်ဗွီဒီယိုရိုက်ခြင်း" "ဤအက်ပ်သည် ကင်မရာကို အသုံးပြု၍ ဓာတ်ပုံနှင့် ဗီဒီယိုများကို အချိန်မရွေး ရိုက်ကူးနိုင်ပါသည်။" + "ကင်မရာစက်များ ပွင့်နေခြင်း သို့မဟုတ် ပိတ်နေခြင်းနှင့် ပတ်သက်ပြီး ပြန်လည်ခေါ်ဆိုမှုများ ရယူရန် အပလီကေးရှင်း သို့မဟုတ် ဝန်ဆောင်မှုကို ခွင့်ပြုခြင်း။" + "(မည်သည့် အပလီကေးရှင်းပက်ကေ့ဂျ်ကြောင့်) ကင်မရာစက်တစ်ခုခု ပွင့်နေသည့်အခါ သို့မဟုတ် ပိတ်နေသည့်အခါ ဤအထူးသီးသန့်အက်ပ်က ပြန်လည်ခေါ်ဆိုမှုများ ရယူနိုင်သည်။" "တုန်ခုန်မှုအား ထိန်းချုပ်ခြင်း" "အက်ပ်အား တုန်ခါစက်ကို ထိန်းချုပ်ခွင့် ပြုသည်။" "ဖုန်းနံပါတ်များကိုတိုက်ရိုက်ခေါ်ဆိုခြင်း" @@ -450,9 +452,11 @@ "အခြားအက်ပ်တွင် စတင်ထားသည့် ဖုန်းခေါ်ဆိုမှုကို ဆက်လက်ပြုလုပ်ရန် ဤအက်ပ်ကို ခွင့်ပြုသည်။" "ဖုန်းနံပါတ်များကို ဖတ်ရန်" "အက်ပ်ကို စက်ပစ္စည်း၏ ဖုန်းနံပါတ်များအား အသုံးပြုခွင့်ပေးပါ။" + "ကားဖန်သားပြင်ကို ဖွင့်ထားပါ" "တက်ပလက်အား ပိတ်ခြင်းမှ ကာကွယ်ခြင်း" "တီဗွီအား နားနေခြင်းမှ ကာကွယ်ရန်" "ဖုန်းအနားယူခြင်းမပြုလုပ်စေရန်" + "ကားဖန်သားပြင် ဖွင့်ထားနိုင်စေရန် အက်ပ်ကို ခွင့်ပြုပေးပါ။" "အက်ပ်အား တက်ဘလက်ကို အနားမယူနိုင်အောင် ဟန့်တားခွင့် ပြုသည်။" "တီဗွီ ရပ်နားသွားခြင်းအား ကာကွယ်ရန် အက်ပ်အား ခွင့်ပြုပါ။" "အက်ပ်အား ဖုန်းကို အနားမယူနိုင်အောင် ဟန့်တားခွင့် ပြုသည်။" @@ -1235,7 +1239,7 @@ "အကြောင်းကြားသံအတိုးအကျယ်" "မူရင်းမြည်သံ" "မူရင်း (%1$s)" - "တစ်ခုမှမဟုတ်" + "တစ်ခုမျှမဟုတ်" "မြည်သံများ" "နှိုးစက်သံ" "အကြောင်းကြားချက်အသံ" diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index e2d45e7d86aa..74bf9d73aa1f 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -298,7 +298,7 @@ "Mikrofon" "ta opp lyd" "Vil du la <b>%1$s</b> ta opp lyd?" - "Fysisk aktivitet-" + "Fysisk aktivitet" "tilgang til den fysiske aktiviteten din" "Vil du gi <b>%1$s</b> tilgang til den fysiske aktiviteten din?" "Kamera" @@ -434,6 +434,8 @@ "Denne appen kan gjenkjenne den fysiske aktiviteten din." "ta bilder og videoer" "Denne appen kan når som helst ta bilder og spille inn videoer ved hjelp av kameraet." + "Tillat at en app eller tjeneste mottar tilbakekallinger om kameraenheter som åpnes eller lukkes." + "Denne signaturappen kan motta tilbakekallinger når en kameraenhet blir åpnet (av hvilken app-pakke) eller lukket." "kontrollere vibreringen" "Lar appen kontrollere vibreringsfunksjonen." "ringe telefonnummer direkte" @@ -450,9 +452,11 @@ "Lar appen fortsette et anrop som ble startet i en annen app." "les telefonnumre" "Gir appen tilgang til telefonnumrene til enheten." + "hold bilskjermen på" "hindre nettbrettet fra å gå over til sovemodus" "hindre TV-en i å gå i hvilemodus" "forhindre telefonen fra å sove" + "Tillater at appen holder bilskjermen på." "Lar appen hindre nettbrettet fra å gå over i sovemodus." "Gjør at appen hindrer TV-en i å gå i dvale." "Lar appen hindre telefonen fra å gå over i sovemodus." diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index fa594d8694cb..e1dc55f98f40 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -434,6 +434,10 @@ "यो अनुप्रयोगले तपाईंको शारीरिक गतिविधिको पहिचान गर्न सक्छ।" "तस्बिरहरू र भिडियोहरू लिनुहोस्।" "यस अनुप्रयोगले जुनसुकै समय क्यामेराको प्रयोग गरी तस्बिर खिच्न र भिडियो रेकर्ड गर्न सक्छ।" + + + + "कम्पन नियन्त्रण गर्नुहोस्" "अनुप्रयोगलाई भाइब्रेटर नियन्त्रण गर्न अनुमति दिन्छ।" "फोन नम्बरहरूमा सीधै कल गर्नुहोस्" @@ -450,9 +454,11 @@ "यस अनुप्रयोगलाई अर्को अनुप्रयोगमा सुरु गरिएको कल जारी राख्ने अनुमति दिन्छ।" "फोन नम्बरहरू पढ्ने" "उक्त अनुप्रयोगलाई यस यन्त्रको फोन नम्बरहरूमाथि पहुँच राख्न दिनुहोस्।" + "कारको स्क्रिन सक्रिय राख्नुहोस्" "ट्याब्लेटलाई निन्द्रामा जानबाट रोक्नुहोस्" "TV निभ्नबाट जोगाउनुहोस्" "फोनलाई निदाउनबाट रोक्नुहोस्" + "यो अनुमतिले यस अनुप्रयोगलाई कारको स्क्रिन सक्रिय राख्न दिन्छ।" "ट्याब्लेटलाई निस्क्रिय हुनबाट रोक्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।" "अनुप्रयोगलाई अनुमति दिन्छ TV लाई निभ्नबाट जोगाउन।" "फोनलाई निस्क्रिय हुनबाट रोक्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।" diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index f1eb7a9ab891..cc35c8ee44ce 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -434,6 +434,8 @@ "Deze app kan je fysieke activiteit herkennen." "foto\'s en video\'s maken" "Deze app kan op elk moment foto\'s maken en video\'s opnemen met de camera." + "Een app of service toestaan callbacks te ontvangen over camera-apparaten die worden geopend of gesloten." + "Deze ondertekeningsapp kan callback ontvangen als een camera-apparaat wordt geopend (en door welk app-pakket) of gesloten." "trilling beheren" "Hiermee kan de app de trilstand beheren." "telefoonnummers rechtstreeks bellen" @@ -450,9 +452,11 @@ "Hiermee kan de app een gesprek voortzetten dat is gestart in een andere app." "telefoonnummers lezen" "Hiermee kan de app toegang krijgen tot de telefoonnummers van het apparaat." + "autoscherm ingeschakeld houden" "voorkomen dat tablet overschakelt naar slaapmodus" "voorkomen dat tv overschakelt naar slaapmodus" "voorkomen dat telefoon overschakelt naar slaapmodus" + "Hiermee kan de app het autoscherm ingeschakeld houden." "Hiermee kan de app voorkomen dat de tablet overschakelt naar de slaapmodus." "Hiermee kan de app voorkomen dat de tv overschakelt naar de slaapmodus." "Hiermee kan de app voorkomen dat de telefoon overschakelt naar de slaapmodus." diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index f3333c0479e6..9ef8e0ae71fe 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -434,6 +434,10 @@ "ଏହି ଆପ୍‍ଣ ଆପଣଙ୍କ ଶାରୀରିକ ଗତିବିଧିକୁ ଚିହ୍ନଟ କରିପାରେ" "ଫଟୋ ଓ ଭିଡିଓଗୁଡ଼ିକୁ ନିଅନ୍ତୁ" "ଏହି ଆପ୍‍ ଯେକୌଣସି ସମୟରେ କ୍ୟାମେରା ବ୍ୟବହାର କରି ଫଟୋ ଉଠାଇପାରେ ଏବଂ ଭିଡିଓ ରେକର୍ଡ କରିପାରେ।" + + + + "କମ୍ପନ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ" "ଆପ୍‍କୁ, ଭାଇବ୍ରେଟର୍‍ ନିୟନ୍ତ୍ରଣ କରିବାକୁ ଦେଇଥାଏ।" "ସିଧାସଳଖ ଫୋନ୍ ନମ୍ବରଗୁଡ଼ିକୁ କଲ୍ କରନ୍ତୁ" @@ -450,9 +454,11 @@ "ଅନ୍ୟ ଆପ୍‌ରେ ଆରମ୍ଭ ହୋଇଥିବା ଗୋଟିଏ କଲ୍‌କୁ ଜାରି ରଖିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦିଅନ୍ତୁ।" "ଫୋନ୍‍ ନମ୍ବର ପଢ଼େ" "ଏହି ଡିଭାଇସର ଫୋନ୍‍ ନମ୍ବର ଆକ୍ସେସ୍‍ କରିବାକୁ ଆପକୁ ଅନୁମତି ଦିଏ।" + "କାର ସ୍କ୍ରିନକୁ ଚାଲୁ ରଖନ୍ତୁ" "ଟାବଲେଟ୍‌କୁ ସ୍ଲୀପିଙ୍ଗ ମୋଡ୍‌କୁ ଯିବାକୁ ରୋକନ୍ତୁ" "ଟିଭିକୁ ସ୍ଲୀପିଙ୍ଗ ମୋଡ୍‌ରୁ ଯିବାକୁ ରୋକନ୍ତୁ।" "ଫୋନକୁ ସ୍ଲୀପିଙ୍ଗ ମୋଡ୍‌କୁ ଯିବାକୁ ରୋକନ୍ତୁ" + "କାର ସ୍କ୍ରିନକୁ ଚାଲୁ ରଖିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦେଇଥାଏ।" "ଆପ୍‍କୁ, ଟାବଲେଟ୍‍ଟିକୁ ସ୍ଲୀପ୍‍ ମୋଡ୍‍କୁ ଯିବାରେ ପ୍ରତିରୋଧ କରିବାକୁ ଦେଇଥାଏ।" "TVକୁ ଶୁଆଇବାକୁ ଯିବାରୁ ରୋକିବାକୁ ଆପ୍‌ ଅନୁମତି ଦେଇଥାଏ।" "ଆପ୍‍କୁ, ଫୋନ୍‌ଟିକୁ ସ୍ଲୀପ୍‍ ମୋଡ୍‍କୁ ଯିବାରେ ପ୍ରତିରୋଧ କରିବାକୁ ଦେଇଥାଏ।" diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 8471660d2684..3b264d3147a4 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -434,6 +434,8 @@ "ਇਹ ਐਪ ਤੁਹਾਡੀ ਸਰੀਰਕ ਸਰਗਰਮੀ ਨੂੰ ਪਛਾਣ ਸਕਦੀ ਹੈ।" "ਤਸਵੀਰਾਂ ਅਤੇ ਵੀਡੀਓ ਬਣਾਓ" "ਇਹ ਐਪ ਕਿਸੇ ਵੀ ਸਮੇਂ ਕੈਮਰੇ ਨੂੰ ਵਰਤ ਕੇ ਤਸਵੀਰਾਂ ਖਿੱਚ ਸਕਦੀ ਹੈ ਅਤੇ ਵੀਡੀਓ ਫ਼ਾਈਲਾਂ ਰਿਕਾਰਡ ਕਰ ਸਕਦੀ ਹੈ।" + "ਐਪਲੀਕੇਸ਼ਨ ਜਾਂ ਸੇਵਾ ਨੂੰ ਕੈਮਰਾ ਡੀਵਾਈਸਾਂ ਦੇ ਚਾਲੂ ਜਾਂ ਬੰਦ ਕੀਤੇ ਜਾਣ ਬਾਰੇ ਕਾਲਬੈਕ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ।" + "ਇਹ ਸਿਗਨੇਚਰ ਐਪ ਕੋਈ ਵੀ ਕੈਮਰਾ ਡੀਵਾਈਸ ਚਾਲੂ ਹੋਣ (ਕਿਸ ਐਪਲੀਕੇਸ਼ਨ ਪੈਕੇਜ ਰਾਹੀਂ) ਜਾਂ ਬੰਦ ਹੋਣ \'ਤੇ ਕਾਲਬੈਕ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੀ ਹੈ।" "ਵਾਈਬ੍ਰੇਸ਼ਨ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ" "ਐਪ ਨੂੰ ਵਾਈਬ੍ਰੇਟਰ ਤੇ ਨਿਯੰਤਰਣ ਪਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।" "ਫ਼ੋਨ ਨੰਬਰਾਂ ਤੇ ਸਿੱਧੇ ਕਾਲ ਕਰੋ" @@ -450,9 +452,11 @@ "ਐਪ ਨੂੰ ਉਹ ਕਾਲ ਜਾਰੀ ਰੱਖਣ ਦਿਓ ਜਿਸਨੂੰ ਹੋਰ ਐਪ ਤੋਂ ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਸੀ।" "ਫ਼ੋਨ ਨੰਬਰ ਪੜ੍ਹੋ" "ਐਪ ਨੂੰ ਡੀਵਾਈਸ ਦੇ ਫ਼ੋਨ ਨੰਬਰਾਂ \'ਤੇ ਪਹੁੰਚ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦੀ ਹੈ।" + "ਕਾਰ ਦੀ ਸਕ੍ਰੀਨ ਚਾਲੂ ਰੱਖੋ" "ਟੈਬਲੈੱਟ ਨੂੰ ਸਲੀਪ ਤੇ ਜਾਣ ਤੋਂ ਰੋਕੋ" "TV ਨੂੰ ਸਲੀਪਿੰਗ ਤੋਂ ਰੋਕੋ" "ਫ਼ੋਨ ਨੂੰ ਸਲੀਪਿੰਗ ਤੋਂ ਰੋਕੋ" + "ਐਪ ਨੂੰ ਕਾਰ ਦੀ ਸਕ੍ਰੀਨ ਹਰ ਵੇਲੇ ਚਾਲੂ ਰੱਖਣ ਦਿੰਦਾ ਹੈ।" "ਐਪ ਨੂੰ ਟੈਬਲੈੱਟ ਨੂੰ ਸਲੀਪ ਤੇ ਜਾਣ ਤੋਂ ਰੋਕਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।" "ਐਪ ਨੂੰ TV ਨੂੰ ਸਲੀਪ ਤੇ ਜਾਣ ਤੋਂ ਰੋਕਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।" "ਐਪ ਨੂੰ ਫ਼ੋਨ ਨੂੰ ਸਲੀਪ ਤੇ ਜਾਣ ਤੋਂ ਰੋਕਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।" diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index dbc3282bc38b..3273578d597a 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -95,7 +95,7 @@ "Stan mobilnej transmisji danych" "SMS-y" "Wiadomości poczty głosowej" - "Połączenia przez Wi-Fi" + "Połączenie przez Wi-Fi" "Stan karty SIM" "Stan karty SIM – wysoki priorytet" "Drugie urządzenie zażądało trybu „TTY pełny”" @@ -133,14 +133,14 @@ - "%s, połączenia przez Wi-Fi" + "%s, połączenie przez Wi-Fi" "%s, połączenia przez Wi-Fi" "Połączenie przez WLAN" "%s, połączenie przez WLAN" "%s, Wi-Fi" "Połączenia przez Wi-Fi | %s" "%s, VoWifi" - "Połączenia przez Wi-Fi" + "Połączenie przez Wi-Fi" "Wi-Fi" "Połączenia przez Wi-Fi" "VoWifi" @@ -298,7 +298,7 @@ "SMS" "wysyłanie i wyświetlanie SMS‑ów" "Zezwolić aplikacji <b>%1$s</b> na wysyłanie i wyświetlanie SMS-ów?" - "Pamięć" + "Pamięć wewnętrzna" "dostęp do zdjęć, multimediów i plików na Twoim urządzeniu" "Zezwolić aplikacji <b>%1$s</b> na dostęp do zdjęć, multimediów i plików na urządzeniu?" "Mikrofon" @@ -440,6 +440,8 @@ "Ta aplikacja może rozpoznawać Twoją aktywność fizyczną." "wykonywanie zdjęć i filmów wideo" "Ta aplikacja może w dowolnym momencie robić zdjęcia i nagrywać filmy przy użyciu aparatu." + "Zezwól na dostęp aplikacji lub usługi na otrzymywanie wywoływania zwrotnego o urządzeniach z aparatem, kiedy są one uruchamiane lub zamykane." + "Aplikacja z podpisami może korzystać z wywoływania zwrotnego, kiedy urządzenie z aparatem jest uruchamiane (przez jaki pakiet aplikacji) albo zamykane." "sterowanie wibracjami" "Pozwala aplikacji na sterowanie wibracjami." "bezpośrednie wybieranie numerów telefonów" @@ -456,9 +458,11 @@ "Zezwala na kontynuowanie przez aplikację połączenia rozpoczętego w innej aplikacji." "odczytywanie numerów telefonów" "Zezwala aplikacji na dostęp do numerów telefonów na urządzeniu." + "utrzymuj włączony ekran samochodu" "zapobieganie przechodzeniu tabletu do trybu uśpienia" "powstrzymywanie usypiania telewizora" "zapobieganie przejściu telefonu w stan uśpienia" + "Zezwala aplikacji na utrzymywanie włączonego ekranu samochodu" "Pozwala aplikacji na zapobieganie przechodzeniu tabletu do trybu uśpienia." "Pozwala aplikacji powstrzymać uśpienie telewizora." "Pozwala aplikacji na zapobieganie przechodzeniu telefonu w tryb uśpienia." diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 43721005895d..e050d50c0626 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -434,6 +434,8 @@ "Este app pode reconhecer sua atividade física." "tirar fotos e gravar vídeos" "Este app pode tirar fotos e gravar vídeos usando a câmera a qualquer momento." + "Permitir que um aplicativo ou serviço receba callbacks sobre dispositivos de câmera sendo abertos ou fechados." + "Esse app de assinatura pode receber callbacks quando um dispositivo de câmera é aberto (por qualquer pacote de apps) ou fechado." "controlar vibração" "Permite que o app controle a vibração." "ligar diretamente para números de telefone" @@ -450,9 +452,11 @@ "Permite que o app continue uma chamada que foi iniciada em outro app." "ler números de telefone" "Permite que o app acesse os número de telefone do dispositivo." + "manter a tela do carro ativada" "impedir modo de inatividade do tablet" "impedir a suspensão da TV" "impedir modo de inatividade do telefone" + "Permite que o app mantenha a tela do carro ativada." "Permite que o app impeça a suspensão do tablet." "Permite que o app impeça a suspensão da TV." "Permite que o app impeça a suspensão do telefone." @@ -514,8 +518,8 @@ "Permite que o app execute métodos para adicionar e excluir modelos de impressão digital para uso." "usar hardware de impressão digital" "Permite que o app use hardware de impressão digital para autenticação." - "modificar sua coleção de músicas" - "Permite que o app modifique sua coleção de músicas." + "modificar sua biblioteca de música" + "Permite que o app modifique sua biblioteca de música." "modificar sua coleção de vídeos" "Permite que o app modifique sua coleção de vídeos." "modificar sua coleção de fotos" @@ -912,7 +916,7 @@ "Confirmar navegação" "Sair desta página" "Permanecer nesta página" - "%s\n\nTem certeza que quer sair desta página?" + "%s\n\nVocê quer mesmo sair desta página?" "Confirmar" "Dica: toque duas vezes para aumentar e diminuir o zoom." "Preench. aut." diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 3ee2ea50b81d..a9e8f1490e1b 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -434,6 +434,8 @@ "Esta aplicação consegue reconhecer a sua atividade física." "tirar fotos e vídeos" "Esta aplicação pode tirar fotos e gravar vídeos através da câmara em qualquer altura." + "Permitir que uma app ou um serviço receba chamadas de retorno sobre dispositivos de câmara que estão a ser abertos ou fechados" + "Esta app de assinatura pode receber chamadas de retorno quando qualquer dispositivo de câmara está a ser aberto (e por que pacote de apps) ou fechado." "controlar vibração" "Permite à aplicação controlar o vibrador." "marcar números de telefone diretamente" @@ -450,9 +452,11 @@ "Permite à aplicação continuar uma chamada iniciada noutra aplicação." "ler os números de telefone" "Permite à aplicação aceder aos números de telefone do dispositivo." + "manter o ecrã do automóvel ligado" "impedir que o tablet entre em inactividade" "impedir a TV de entrar no modo de suspensão" "impedir modo de inactividade do telefone" + "Permite que a app mantenha o ecrã do automóvel ligado." "Permite que a aplicação impeça o tablet de entrar no modo de suspensão." "Permite à aplicação impedir a TV de entrar em modo de suspensão." "Permite que a aplicação impeça o telemóvel de entrar em inatividade." diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 43721005895d..e050d50c0626 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -434,6 +434,8 @@ "Este app pode reconhecer sua atividade física." "tirar fotos e gravar vídeos" "Este app pode tirar fotos e gravar vídeos usando a câmera a qualquer momento." + "Permitir que um aplicativo ou serviço receba callbacks sobre dispositivos de câmera sendo abertos ou fechados." + "Esse app de assinatura pode receber callbacks quando um dispositivo de câmera é aberto (por qualquer pacote de apps) ou fechado." "controlar vibração" "Permite que o app controle a vibração." "ligar diretamente para números de telefone" @@ -450,9 +452,11 @@ "Permite que o app continue uma chamada que foi iniciada em outro app." "ler números de telefone" "Permite que o app acesse os número de telefone do dispositivo." + "manter a tela do carro ativada" "impedir modo de inatividade do tablet" "impedir a suspensão da TV" "impedir modo de inatividade do telefone" + "Permite que o app mantenha a tela do carro ativada." "Permite que o app impeça a suspensão do tablet." "Permite que o app impeça a suspensão da TV." "Permite que o app impeça a suspensão do telefone." @@ -514,8 +518,8 @@ "Permite que o app execute métodos para adicionar e excluir modelos de impressão digital para uso." "usar hardware de impressão digital" "Permite que o app use hardware de impressão digital para autenticação." - "modificar sua coleção de músicas" - "Permite que o app modifique sua coleção de músicas." + "modificar sua biblioteca de música" + "Permite que o app modifique sua biblioteca de música." "modificar sua coleção de vídeos" "Permite que o app modifique sua coleção de vídeos." "modificar sua coleção de fotos" @@ -912,7 +916,7 @@ "Confirmar navegação" "Sair desta página" "Permanecer nesta página" - "%s\n\nTem certeza que quer sair desta página?" + "%s\n\nVocê quer mesmo sair desta página?" "Confirmar" "Dica: toque duas vezes para aumentar e diminuir o zoom." "Preench. aut." diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 1427b0c4f729..c31fd4676721 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -437,6 +437,8 @@ "Această aplicație vă poate recunoaște activitatea fizică." "realizarea de fotografii și videoclipuri" "Această aplicație poate să facă fotografii și să înregistreze videoclipuri folosind camera foto în orice moment." + "Permiteți unei aplicații sau unui serviciu să primească apeluri inverse atunci când sunt deschise sau închise dispozitive cu cameră." + "Această aplicație cu semnătură poate primi apeluri inverse atunci când este deschis (de un pachet al aplicației) sau închis orice dispozitiv cu cameră." "controlează vibrarea" "Permite aplicației să controleze mecanismul de vibrare." "apelare directă numere de telefon" @@ -453,9 +455,11 @@ "Permite aplicației să continue un apel care a fost inițiat dintr-o altă aplicație." "să citească numerele de telefon" "Permite aplicației să acceseze numerele de telefon ale dispozitivului." + "menține ecranul mașinii activat" "împiedicarea computerului tablet PC să intre în repaus" "împiedică intrarea televizorului în stare de inactivitate" "împiedicare intrare telefon în repaus" + "Permite aplicației să mențină ecranul mașinii activat." "Permite aplicației să împiedice intrarea tabletei în stare de repaus." "Permite aplicației să împiedice intrarea televizorului în stare de inactivitate." "Permite aplicației să împiedice intrarea telefonului în stare de repaus." diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 01bd4709b066..1d4d9b2c9eed 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -306,7 +306,7 @@ "Разрешить приложению <b>%1$s</b> записывать аудио?" "Физическая активность" "доступ к данным о физической активности" - "Открыть приложению <b>%1$s</b> доступ к данным о физической активности?" + "Разрешить приложению <b>%1$s</b> доступ к данным о физической активности?" "Камера" "снимать фото и видео" "Разрешить приложению <b>%1$s</b> снимать фото и видео?" @@ -440,6 +440,8 @@ "Приложение может распознавать физическую активность." "Фото- и видеосъемка" "Приложение может в любое время делать фотографии и снимать видео с помощью камеры." + "Разрешить приложению или сервису получать обратные вызовы при открытии и закрытии камер" + "Это приложение для создания подписей сможет получать обратные вызовы при открытии (с указанием открывающего приложения) и закрытии любых камер." "Управление функцией вибросигнала" "Приложение сможет контролировать вибросигналы." "Осуществление телефонных вызовов" @@ -456,9 +458,11 @@ "Разрешает приложению продолжить вызов, начатый в другом приложении." "чтение номеров телефонов" "Разрешает приложению доступ к телефонным номерам устройства." + "Не выключать экран автомобиля" "Отключение спящего режима" "запрещать переход в спящий режим" "Отключение спящего режима" + "Приложение сможет держать экран автомобиля включенным." "Приложение сможет запрещать перевод планшетного ПК в спящий режим." "Отключение перехода телевизора в спящий режим." "Приложение сможет запрещать перевод телефона в спящий режим." @@ -756,7 +760,7 @@ "MMS" "Особый" "День рождения" - "Юбилей" + "Годовщина" "Другой" "Новый тип" "Личный" @@ -1180,7 +1184,7 @@ "Редактировать с помощью приложения:" "Редактировать с помощью приложения \"%1$s\"" "Изменить" - "Отправка данных" + "Поделиться" "Поделиться через %1$s" "Поделиться" "Выберите приложение" diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 77055f439c43..973571a8844f 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -434,6 +434,8 @@ "මෙම යෙදුමට ඔබේ ශාරීරික ක්‍රියාකාරකම හඳුනා ගැනීමට නොහැකිය" "පින්තූර සහ වීඩියෝ ගන්න" "මෙම යෙදුමට ඕනෑම වේලාවක කැමරාව භාවිත කර පින්තූර ගැනීමට සහ වීඩියෝ පටිගත කිරීමට හැකිය." + "විවෘත වෙමින් හෝ වැසෙමින් පවතින කැමරා උපාංග පිළිබඳ පසු ඇමතුම් ලබා ගැනීමට යෙදුමකට හෝ සේවාවකට ඉඩ දෙන්න." + "මෙම අත්සන් යෙදුමට ඕනෑම කැමරා යෙදුමක් විවෘත වෙමින් හෝ වැසෙමින් (කුමන යෙදුම් පැකේජයෙන්ද) පවතින විට පසු ඇමතුම් ලබා ගැනීමට හැකිය." "කම්පනය පාලනය කිරීම" "කම්පකය පාලනයට යෙදුමට අවසර දෙන්න." "දුරකථන අංක වෙත ඍජුවම අමතන්න" @@ -450,9 +452,11 @@ "වෙනත් යෙදුමක ආරම්භ කරන ලද ඇමතුමක් දිගටම කරගෙන යාමට යෙදුමට ඉඩ දෙයි." "දුරකථන අංක කියවන්න" "උපාංගයේ දුරකථන අංක වෙත ප්‍රවේශයට යෙදුමට ඉඩ දෙයි." + "මෝටර් රථ තිරය ක්‍රියාත්මකව තබා ගන්න" "ටැබ්ලටය නින්දෙන් වැළක්වීම" "රූපවාහිනිය නින්දට යාමෙන් නවත්වන්න" "දුරකථනය නින්දට යාමෙන් වළකන්න" + "යෙදුමට මෝටර් රථ තිරය ක්‍රියාත්මකව තබා ගැනීමට ඉඩ දෙයි." "ටැබ්ලටය නින්දට යාමෙන් වැලැක්වීමට යෙදුමට අවසර දෙන්න." "යෙදුමට රූපවාහිනිය නින්දට යාමට නැවැත්වීම අවසර දෙයි." "දුරකථනය නින්දට යාමෙන් වැලැක්වීමට යෙදුමට අවසර දෙන්න." diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 31e8915cda4a..4b14c49a0c08 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -440,6 +440,8 @@ "Táto aplikácia dokáže rozpoznať vašu fyzickú aktivitu." "fotiť a nakrúcať videá" "Táto aplikácia môže kedykoľvek fotografovať a zaznamenávať videá pomocou fotoaparátu." + "Povoliť aplikácii alebo službe prijímať spätné volanie, keď sú zariadenia s kamerou otvorené alebo zatvorené." + "Táto podpisová aplikácia môže prijímať spätné volanie, keď je ľubovoľné zariadenie s kamerou otvorené (balíkom aplikácie, ktorý určíte) alebo zatvorené." "ovládať vibrovanie" "Umožňuje aplikácii ovládať vibrácie." "priamo volať na telefónne čísla" @@ -456,9 +458,11 @@ "Umožňuje aplikácii pokračovať v hovore začatom v inej aplikácii." "čítanie telefónnych čísel" "Umožňuje aplikácii pristupovať k telefónnym číslam zariadenia." + "zabránenie vypnutiu obrazovky auta" "zabránenie prechodu tabletu do režimu spánku" "zabránenie televízoru v prechode do režimu spánku" "deaktivovať režim spánku" + "Umožňuje aplikácii zabrániť vypnutiu obrazovky auta." "Umožňuje aplikácii zabrániť prechodu tabletu do režimu spánku." "Umožňuje aplikácii zabrániť televízoru v prechode do režimu spánku." "Umožňuje aplikácii zabrániť prechodu telefónu do režimu spánku." @@ -2005,7 +2009,7 @@ "Sociálne siete a komunikácia" "Noviny a časopisy" "Mapy a navigácia" - "Produktivita" + "Kancelárske" "Úložisko zariadenia" "Ladenie cez USB" "hodina" diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 8d3827f489a4..8a1579e77462 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -440,6 +440,8 @@ "Ta aplikacija lahko prepoznava vašo telesno dejavnost." "fotografiranje in snemanje videoposnetkov" "Ta aplikacija lahko poljubno uporablja fotoaparat za snemanje fotografij ali videoposnetkov." + "Aplikaciji ali storitvi dovoli prejemanje povratnih klicev o odpiranju ali zapiranju naprav s fotoaparati." + "Ta aplikacija za podpise lahko prejema povratne klice, ko se odpira (s katerim paketom aplikacij) ali zapira katera koli naprava s fotoaparatom." "nadzor vibriranja" "Aplikaciji omogoča nadzor vibriranja." "neposredno klicanje telefonskih številk" @@ -456,9 +458,11 @@ "Aplikaciji dovoljuje nadaljevanje klica, ki se je začel v drugi aplikaciji." "branje telefonskih številk" "Aplikaciji dovoljuje dostop do telefonskih številk v napravi." + "Ohranjanje vklopljenega zaslona avtomobila" "preprečitev prehoda tabličnega računalnika v stanje pripravljenosti" "preprečevanje preklopa televizorja v stanje pripravljenosti" "preprečevanje prehoda v stanje pripravljenosti telefona" + "Aplikaciji omogoča, da zaslon avtomobila ohranja vklopljen." "Omogoča, da aplikacija prepreči prehod tabličnega računalnika v stanje pripravljenosti." "Aplikaciji dovoljuje, da prepreči preklop televizorja v stanje pripravljenosti." "Aplikaciji omogoča, da v telefonu prepreči prehod v stanje pripravljenosti." diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 7d3368d695c1..decc3387a4d6 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -434,6 +434,8 @@ "Ky aplikacion mund të njohë aktivitetin tënd fizik." "bëj fotografi dhe video" "Ky aplikacion mund të nxjerrë fotografi dhe të regjistrojë video me kamerën tënde në çdo kohë." + "Lejo që një aplikacion ose shërbim të marrë telefonata mbrapsht për pajisjet e kamerës që hapen ose mbyllen." + "Ky aplikacion i nënshkrimit mund të marrë telefonata mbrapsht kur hapet ose mbyllet një pajisje e kamerës (nga një paketë e aplikacionit)." "kontrollo dridhjen" "Lejon aplikacionin të kontrollojë dridhësin." "telefono drejtpërdrejt numrat e telefonit" @@ -450,9 +452,11 @@ "Lejon që aplikacioni të vazhdojë një telefonatë që është nisur në një aplikacion tjetër." "lexo numrat e telefonit" "Lejon që aplikacioni të ketë qasje te numrat e telefonit të pajisjes." + "të mbajë ekranin e makinës të aktivizuar" "parandalo kalimin e tabletit në fjetje" "parandalo kalimin e televizorit në fjetje" "parandalo kalimin e telefonit në fjetje" + "Lejon që aplikacioni të mbajë ekranin e makinës të aktivizuar." "Lejon aplikacionin të parandalojë tabletin nga fjetja." "Lejon aplikacionin të parandalojë televizorin nga fjetja." "Lejon aplikacionin të parandalojë telefonin nga fjetja." @@ -1333,7 +1337,7 @@ "Mos lejo asnjëherë" "Karta SIM u hoq" "Rrjeti celular nuk do të mundësohet derisa ta rinisësh pajisjen me një kartë të vlefshme SIM në të." - "U krye!" + "U krye" "Karta SIM u shtua" "Rinise pajisjen për të pasur qasje në rrjetin celular." "Rifillo" @@ -1346,7 +1350,7 @@ "Cakto kohën" "Vendos datën" "Cakto" - "U krye!" + "U krye" "E RE: " "Ofruar nga %1$s." "Nuk kërkohen leje" @@ -1447,7 +1451,7 @@ "Kërko" "Dërgo" "Përpara" - "U krye!" + "U krye" "I mëparshëm" "Ekzekuto" "Telefono numrin\nduke përdorur %s" @@ -1498,7 +1502,7 @@ %d nga gjithsej %d 1 përputhje - "U krye!" + "U krye" "Po fshin hapësirën ruajtëse të brendshme…" "Shpërndaj" "Gjej" @@ -1539,7 +1543,7 @@ "Alt" "Anulo" "Fshi" - "U krye!" + "U krye" "Ndryshim modaliteti" "Shift" "Enter" @@ -1799,7 +1803,7 @@ "Po shikon ekranin e plotë" "Për të dalë, rrëshqit nga lart poshtë." "E kuptova" - "U krye!" + "U krye" "Rrëshqitësi rrethor i orëve" "Rrëshqitësi rrethor i minutave" "Përzgjidh orët" diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index afea01a24265..e7110fe6ed02 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -297,7 +297,7 @@ "Желите ли да омогућите да <b>%1$s</b> шаље и прегледа SMS-ове?" "Меморијски простор" "приступа сликама, медијима и датотекама на уређају" - "Желите ли да омогућите да <b>%1$s</b> приступа сликама, медијским датотекама и датотекама на уређају?" + "Желите ли да омогућите да <b>%1$s</b> приступа сликама, медијским и другим датотекама на уређају?" "Микрофон" "снима звук" "Желите ли да омогућите да <b>%1$s</b> снима звук?" @@ -437,6 +437,8 @@ "Ова апликација може да препозна физичке активности." "снимање фотографија и видео снимака" "Ова апликација може да снима фотографије и видео снимке помоћу камере у било ком тренутку." + "Дозволите апликацији или услузи да добија повратне позиве о отварању или затварању уређаја са камером." + "Ова апликација за потписе може да добија повратне позиве када се било који уређај са камером отвара или затвара (помоћу неког пакета апликација)." "контрола вибрације" "Дозвољава апликацији да контролише вибрацију." "директно позивање бројева телефона" @@ -453,9 +455,11 @@ "Дозвољава апликацији да настави позив који је започет у другој апликацији." "читање бројева телефона" "Дозвољава апликацији да приступа бројевима телефона на уређају." + "не искључуј екран у аутомобилу" "спречавање преласка таблета у стање спавања" "спречавање ТВ-а да пређе у стање спавања" "спречавање преласка телефона у стање спавања" + "Дозвољава апликацији да не искључује екран у аутомобилу." "Дозвољава апликацији да спречи таблет да пређе у стање спавања." "Дозвољава апликацији да спречи ТВ да пређе у стање спавања." "Дозвољава апликацији да спречи телефон да пређе у стање спавања." diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index d4d980d8a560..82c1336e6d67 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -209,7 +209,7 @@ "Förbereder uppdatering …" "Uppdateringspaketet behandlas ..." "Startar om …" - "Återställ standardinställning" + "Återställer standardinställning" "Startar om …" "Avslutar…" "Din surfplatta stängs av." @@ -298,7 +298,7 @@ "Mikrofon" "spela in ljud" "Vill du ge <b>%1$s</b> behörighet att spela in ljud?" - "Fysiska aktivitet" + "Fysisk aktivitet" "åtkomst till data om fysisk aktivitet" "Vill du ge <b>%1$s</b> åtkomst till data om fysisk aktivitet?" "Kamera" @@ -434,6 +434,8 @@ "Den här appen kan känna igen fysisk aktivitet." "ta bilder och spela in videoklipp" "Appen kan ta kort och spela in video med kameran när som helst." + "Tillåt att en app eller tjänst får återanrop när en kameraenhet öppnas eller stängs." + "Den här signerade appen kan få återanrop när en kameraenhet öppnas (efter applikationspaket) eller stängs." "styra vibration" "Tillåter att appen styr vibrationen." "ringa telefonnummer direkt" @@ -450,9 +452,11 @@ "Tillåter att appen fortsätter ett samtal som har startats i en annan app." "läsa telefonnummer" "Appen beviljas åtkomst till enhetens telefonnummer." + "låta bilens skärm vara på" "förhindra att surfplattan går in i viloläge" "förhindra att TV:n försätts i viloläge" "förhindra att telefonen sätts i viloläge" + "Tillåter appen att låta bilens skärm vara på." "Tillåter att appen förhindrar att surfplattan går in i viloläge." "Tillåter att appen förhindrar att TV:n försätts i viloläge." "Tillåter att appen förhindrar att mobilen går in i viloläge." diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 1bca94a195e6..90ef9489adb9 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -434,6 +434,8 @@ "Programu hii inaweza kutambua shughuli unazofanya." "Kupiga picha na kurekodi video" "Programu hii inaweza kupiga picha na kurekodi video kwa kutumia kamera wakati wowote." + "Ruhusu programu au huduma ipokee simu zinazopigwa tena kuhusu vifaa vya kamera kufunguliwa au kufungwa." + "Programu ya sahihi inaweza kupokea simu zinazopigwa tena wakati kifaa chochote cha kamera kinafunguliwa (kulingana na kifurushi cha programu) au kufungwa." "Kudhibiti mtetemo" "Inaruhusu programu kudhibiti kitingishi." "piga simu moja kwa moja kwa nambari za simu" @@ -450,9 +452,11 @@ "Huruhusu programu kuendelea na simu ambayo ilianzishwa katika programu nyingine." "kusoma nambari za simu" "Inaruhusu programu kufikia nambari za simu zilizo kwenye kifaa." + "kuweka skrini ya gari isijizime" "zuia kompyuta ndogo dhidi ya kulala" "zuia runinga isiingie katika hali tuli" "kuzuia simu isilale" + "Huruhusu programu kuweka skrini ya gari isijizime." "Inaruhusu programu kuzuia kompyuta kibao kwenda kulala." "Huruhusu programu kuzuia runinga kuingia katika hali tuli" "Inaruhusu programu kuzuia simu isiende kulala." @@ -1267,7 +1271,7 @@ "Ungependa kuruhusu mitandao inayopendekezwa ya Wi-Fi?" "Mitandao inayopendekezwa kwa ajili ya %s. Huenda kifaa kikaunganisha kiotomatiki." "Ruhusu" - "Hapana, asante" + "Hapana" "Wi‑Fi itawashwa kiotomatiki" "Unapokuwa karibu na mtandao uliohifadhiwa wenye ubora wa juu" "Usiwashe tena" @@ -1964,7 +1968,7 @@ "Ungependa kusasisha %1$s na %2$s katika ""%3$s""?" "Ungependa kusasisha vipengee hivi katika ""%4$s"": %1$s, %2$s na %3$s?" "Hifadhi" - "Hapana, asante" + "Hapana" "Sasisha" "nenosiri" "anwani" diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 134a5f449046..c21f9ce6643e 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -377,7 +377,7 @@ "நினைவகத்தில் நிலையாக இருக்கும் தன்னுடைய பகுதிகளை உருவாக்கப் ஆப்ஸை அனுமதிக்கிறது. இதனால பிற பயன்பாடுகளுக்குக் கிடைக்கும் நினைவகம் வரையறுக்கப்பட்டு, மொபைலின் வேகத்தைக் குறைக்கலாம்" "முன்புலத்தில் இயங்கும் சேவையை இயக்குதல்" "முன்புலத்தில் இயங்கும் சேவைகளை உபயோகிக்க, ஆப்ஸை அனுமதிக்கிறது." - "பயன்பாட்டுச் சேமிப்பு இடத்தை அளவிடல்" + "ஆப்ஸ் சேமிப்பு இடத்தை அளவிடல்" "ஆப்ஸ், அதன் குறியீடு, தரவு, மற்றும் தற்காலிகச் சேமிப்பு அளவுகளை மீட்டெடுக்க அனுமதிக்கிறது" "சாதன அமைப்புகளை மாற்றுதல்" "முறைமையின் அமைப்பு தரவைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. தீங்குவிளைவிக்கும் ஆப்ஸ், முறைமையின் உள்ளமைவைச் சிதைக்கலாம்." @@ -434,6 +434,10 @@ "உங்கள் உடல் செயல்பாட்டை இந்த ஆப்ஸால் கண்டறிய முடியும்." "படங்கள் மற்றும் வீடியோக்களை எடுத்தல்" "இந்த ஆப்ஸ் எப்போது வேண்டுமானாலும் கேமராவைப் பயன்படுத்தி படங்களை எடுக்கலாம், வீடியோக்களை ரெக்கார்டு செய்யலாம்." + + + + "அதிர்வைக் கட்டுப்படுத்துதல்" "அதிர்வைக் கட்டுப்படுத்தப் ஆப்ஸை அனுமதிக்கிறது." "தொலைபேசி எண்களை நேரடியாக அழைத்தல்" @@ -450,9 +454,11 @@ "மற்றொரு பயன்பாட்டில் தொடங்கப்பட்ட அழைப்பைத் தொடருவதற்கு, ஆப்ஸை அனுமதிக்கிறது." "ஃபோன் எண்களைப் படித்தல்" "சாதனத்தின் ஃபோன் எண்களை அணுக, ஆப்ஸை அனுமதிக்கும்." + "கார் திரையை ஆன் செய்து வைத்திருத்தல்" "டேப்லெட் உறக்க நிலைக்குச் செல்வதைத் தடுத்தல்" "டிவி உறக்கநிலைக்குச் செல்வதைத் தடுத்தல்" "தொலைபேசி உறக்கநிலைக்குச் செல்வதைத் தடுத்தல்" + "கார் திரையை ஆன் செய்து வைத்திருப்பதற்கு இந்த ஆப்ஸை அனுமதிக்கும்." "உறக்கநிலைக்குச் செல்லாமல் டேப்லெட்டைத் தடுக்க ஆப்ஸை அனுமதிக்கிறது." "டிவி உறக்க நிலைக்குச் செல்வதைத் தடுக்க, ஆப்ஸை அனுமதிக்கிறது." "உறக்கநிலைக்குச் செல்லாமல் மொபைலைத் தடுக்க ஆப்ஸை அனுமதிக்கிறது." @@ -475,7 +481,7 @@ "நெட்வொர்க் இணைப்புகளைக் காட்டு" "தற்போது இருக்கும் நெட்வொர்க்குகள் எவை மற்றும் இணைக்கப்பட்டுள்ளவை எவை போன்ற நெட்வொர்க் இணைப்புகள் குறித்த தகவலைப் பார்க்கப் ஆப்ஸை அனுமதிக்கிறது." "முழுமையான நெட்வொர்க் அணுகலைக் கொண்டிருக்கும்" - "நெட்வொர்க் சாக்கெட்டுகளை உருவாக்கவும் மற்றும் தனிப்பயன் நெட்வொர்க் நெறிமுறைகளைப் பயன்படுத்தவும் ஆப்ஸை அனுமதிக்கிறது. இணையத்தில் தரவை அனுப்ப உலாவியும், பிற பயன்பாடுகளும் இருப்பதால், இணையத்திற்குத் தரவை அனுப்ப இந்த அனுமதி தேவையில்லை." + "நெட்வொர்க் சாக்கெட்டுகளை உருவாக்கவும் மற்றும் பிரத்தியேக நெட்வொர்க் நெறிமுறைகளைப் பயன்படுத்தவும் ஆப்ஸை அனுமதிக்கிறது. இணையத்தில் தரவை அனுப்ப உலாவியும், பிற பயன்பாடுகளும் இருப்பதால், இணையத்திற்குத் தரவை அனுப்ப இந்த அனுமதி தேவையில்லை." "பிணைய இணைப்புத்தன்மையை மாற்றுதல்" "நெட்வொர்க் இணைப்பின் நிலையை மாற்ற, ஆப்ஸை அனுமதிக்கிறது." "இணைக்கப்பட்ட இணைப்புநிலையை மாற்றுதல்" @@ -692,30 +698,30 @@ "வீட்டு தொலைநகல்" "பேஜர்" "மற்றவை" - "தனிப்பயன்" + "பிரத்தியேகம்" "வீடு" "அலுவலகம்" "மற்றவை" - "தனிப்பயன்" + "பிரத்தியேகம்" "வீடு" "அலுவலகம்" "மற்றவை" - "தனிப்பயன்" + "பிரத்தியேகம்" "வீடு" "அலுவலகம்" "மற்றவை" - "தனிப்பயன்" + "பிரத்தியேகம்" "அலுவலகம்" "மற்றவை" - "தனிப்பயன்" + "பிரத்தியேகம்" "AIM" @@ -727,7 +733,7 @@ "ICQ" "Jabber" - "தனிப்பயன்" + "பிரத்தியேகம்" "வீடு" "மொபைல்" "அலுவலகம்" @@ -748,24 +754,24 @@ "பணியிட பேஜர்" "உதவியாளர்" "MMS" - "தனிப்பயன்" + "பிரத்தியேகம்" "பிறந்தநாள்" "ஆண்டுவிழா" "மற்றவை" - "தனிப்பயன்" + "பிரத்தியேகம்" "வீடு" "அலுவலகம்" "மற்றவை" "மொபைல்" - "தனிப்பயன்" + "பிரத்தியேகம்" "வீடு" "அலுவலகம்" "மற்றவை" - "தனிப்பயன்" + "பிரத்தியேகம்" "வீடு" "அலுவலகம்" "மற்றவை" - "தனிப்பயன்" + "பிரத்தியேகம்" "AIM" "Windows Live" "Yahoo" @@ -777,8 +783,8 @@ "NetMeeting" "அலுவலகம்" "மற்றவை" - "தனிப்பயன்" - "தனிப்பயன்" + "பிரத்தியேகம்" + "பிரத்தியேகம்" "உதவியாளர்" "சகோதரர்" "குழந்தை" @@ -793,7 +799,7 @@ "உறவினர்" "சகோதரி" "துணைவர்" - "தனிப்பயன்" + "பிரத்தியேகம்" "வீடு" "அலுவலகம்" "மற்றவை" @@ -828,8 +834,8 @@ "சிம் கார்டு இல்லை அல்லது படிக்கக்கூடியதாக இல்லை. சிம் கார்டைச் செருகவும்." "பயன்படுத்த முடியாத சிம் கார்டு." "உங்கள் சிம் கார்டு நிரந்தரமாக முடக்கப்பட்டது.\n மற்றொரு சிம் கார்டிற்காக உங்கள் வயர்லெஸ் சேவை வழங்குநரைத் தொடர்புகொள்ளவும்." - "முந்தைய ட்ராக்" - "அடுத்த ட்ராக்" + "முந்தைய டிராக்" + "அடுத்த டிராக்" "இடைநிறுத்து" "இயக்கு" "நிறுத்து" @@ -1989,7 +1995,7 @@ "+ %1$d" "ஆப்ஸ் முந்தையப் பதிப்பிற்கு மாற்றப்பட்டது, அல்லது இந்த ஷார்ட்கட் வேலை செய்யவில்லை" "காப்புப் பிரதி மற்றும் மீட்டமைவைப் ஆப்ஸ் ஆதரிக்காத காரணத்தால், ஷார்ட்கட்டை மீட்டமைக்க முடியவில்லை" - "பயன்பாட்டுச் சான்றுகள் பொருந்தாத காரணத்தினால், ஷார்ட்கட்டை மீட்டமைக்க முடியவில்லை" + "ஆப்ஸ் சான்றுகள் பொருந்தாத காரணத்தினால், ஷார்ட்கட்டை மீட்டமைக்க முடியவில்லை" "ஷார்ட்கட்டை மீட்டமைக்க முடியவில்லை" "ஷார்ட்கட் முடக்கப்பட்டுள்ளது" "நிறுவல் நீக்கு" diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 6b7296278ede..9064c06f2b05 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -434,6 +434,8 @@ "ఈ యాప్ మీ భౌతిక కార్యాకలాపాన్ని గుర్తించగలదు." "చిత్రాలు మరియు వీడియోలు తీయడం" "ఈ యాప్‌ కెమెరాను ఉపయోగించి ఎప్పుడైనా చిత్రాలను తీయగలదు మరియు వీడియోలను రికార్డ్ చేయగలదు." + "కెమెరా పరికరాలు తెరుచుకుంటున్నప్పుడు లేదా మూసుకుంటున్నప్పుడు కాల్‌బ్యాక్‌లను స్వీకరించడానికి యాప్‌ను లేదా సర్వీస్‌ను అనుమతించండి." + "ఏదైనా కెమెరా పరికరం తెరుచుకుంటున్నప్పుడు (ఏదైనా యాప్ ప్యాకేజీ ద్వారా) లేదా మూసుకుంటున్నప్పుడు ఈ సిగ్నేచర్ యాప్ కాల్‌బ్యాక్‌లను అందుకోగలదు." "వైబ్రేషన్‌ను నియంత్రించడం" "వైబ్రేటర్‌ను నియంత్రించడానికి యాప్‌ను అనుమతిస్తుంది." "నేరుగా కాల్ చేసే ఫోన్ నంబర్‌లు" @@ -450,9 +452,11 @@ "మరో యాప్‌లో ప్రారంభించిన కాల్‌ని కొనసాగించడానికి యాప్‌ని అనుమతిస్తుంది." "ఫోన్ నంబర్‌లను చదువు" "పరికరం యొక్క ఫోన్ నంబర్‌లను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది." + "కార్ స్క్రీన్‌ను ఆన్ చేసి ఉంచండి" "టాబ్లెట్‌ను నిద్రావస్థకు వెళ్లనీయకుండా నిరోధించడం" "టీవీ నిద్రావస్థకు వెళ్లకుండా నిరోధించడం" "ఫోన్‌ను స్లీప్ మోడ్‌లోకి వెళ్లనీయకుండా నిరోధించగలగడం" + "కార్ స్క్రీన్ ఆన్ చేసి ఉంచడానికి ఈ యాప్‌ను అనుమతిస్తుంది." "నిద్రావస్థకి వెళ్లకుండా టాబ్లెట్‌ను నిరోధించడానికి యాప్‌ను అనుమతిస్తుంది." "టీవీ నిద్రావస్థకు వెళ్లకుండా నిరోధించడానికి అనువర్తనాన్ని అనుమతిస్తుంది." "నిద్రావస్థకి వెళ్లకుండా ఫోన్‌ను నిరోధించడానికి యాప్‌ను అనుమతిస్తుంది." diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 020196e0af6e..b1d6e10495ea 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -434,6 +434,8 @@ "แอปนี้จดจำกิจกรรมการเคลื่อนไหวร่างกายของคุณได้" "ถ่ายภาพและวิดีโอ" "แอปนี้สามารถถ่ายภาพและวิดีโอด้วยกล้องได้ทุกเมื่อ" + "อนุญาตให้แอปพลิเคชันหรือบริการได้รับโค้ดเรียกกลับเมื่อมีการเปิดหรือปิดอุปกรณ์กล้อง" + "แอปลายเซ็นนี้จะได้รับโค้ดเรียกกลับเมื่อมีการปิดหรือเปิดอุปกรณ์กล้อง (แพ็กเกจแอปพลิเคชันที่เปิด)" "ควบคุมการสั่นเตือน" "อนุญาตให้แอปพลิเคชันควบคุมการสั่นเตือน" "โทรติดต่อหมายเลขโทรศัพท์โดยตรง" @@ -450,9 +452,11 @@ "อนุญาตให้แอปต่อสายที่เริ่มจากแอปอื่น" "อ่านหมายเลขโทรศัพท์" "อนุญาตให้แอปเข้าถึงหมายเลขโทรศัพท์ของอุปกรณ์นี้" + "เปิดหน้าจอในรถไว้" "ป้องกันไม่ให้แท็บเล็ตเข้าสู่โหมดสลีป" "ป้องกันไม่ให้ทีวีเข้าสู่โหมดสลีป" "ป้องกันไม่ให้โทรศัพท์เข้าโหมดสลีป" + "อนุญาตให้แอปเปิดหน้าจอในรถไว้" "อนุญาตให้แอปพลิเคชันป้องกันไม่ให้แท็บเล็ตเข้าสู่โหมดสลีป" "อนุญาตให้แอปป้องกันไม่ให้ทีวีเข้าสู่โหมดสลีป" "อนุญาตให้แอปพลิเคชันป้องกันไม่ให้โทรศัพท์เข้าสู่โหมดสลีป" diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index b500b235dd5d..97209a71d781 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -434,6 +434,8 @@ "Matutukoy ng app na ito ang iyong pisikal na aktibidad." "kumuha ng mga larawan at video" "Makakakuha ng mga larawan at makakapag-record ng mga video ang app na ito gamit ang camera anumang oras." + "Payagan ang isang application o serbisyo na makatanggap ng mga callback tungkol sa pagbubukas o pagsasara ng mga camera device." + "Ang signature app na ito ay makakatanggap ng mga callback kapag binubuksan (ng anumang application package) o isinasara ng anumang camera device." "kontrolin ang pag-vibrate" "Pinapayagan ang app na kontrolin ang vibrator." "direktang tawagan ang mga numero ng telepono" @@ -450,9 +452,11 @@ "Pinapayagan ang app na ipagpatuloy ang isang tawag na sinimulan sa ibang app." "basahin ang mga numero ng telepono" "Pinapayagan ang app na i-access ang mga numero ng telepono ng device." + "panatilihing naka-on ang screen ng sasakyan" "pigilan ang tablet mula sa pag-sleep" "pigilan ang TV sa pag-sleep" "pigilan ang telepono mula sa paghinto" + "Pinapayagan ang app na panatilihing naka-on ang screen ng sasakyan." "Pinapayagan ang app na pigilan ang tablet mula sa pag-sleep." "Nagbibigay-daan sa app na pigilan ang TV na mapunta sa sleep." "Pinapayagan ang app na pigilan ang telepono mula sa pag-sleep." diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index c93cb552ae2e..84cbacdf01cb 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -434,6 +434,8 @@ "Bu uygulama fiziksel aktivitenizi algılayabilir." "resim çekme ve görüntü kaydetme" "Bu uygulama, herhangi bir zamanda kamerayı kullanarak fotoğraf ve video çekebilir." + "Bir uygulama veya hizmetin açılıp kapatılan kamera cihazları hakkında geri çağırmalar almasına izin verin." + "Bu imza uygulaması, herhangi bir kamera cihazı açıldığında (herhangi bir uygulama paketi tarafından) veya kapatıldığında geri çağırmalar alabilir." "titreşimi denetleme" "Uygulamaya, titreşimi denetleme izni verir." "telefon numaralarına doğrudan çağrı yap" @@ -450,9 +452,11 @@ "Uygulamanın, başka bir uygulamada başlatılan çağrıya devam etmesine izin verir." "telefon numaralarını oku" "Uygulamaya, cihazınızın telefon numaralarına erişme izni verir." + "arabanın ekranını açık tutma" "tabletin uykuya geçmesini önle" "TV\'nin uyku moduna geçmesini önleme" "telefonun uykuya geçmesini önleme" + "Uygulamaya, arabanın ekranını açık tutmaya izin verir." "Uygulamaya, tabletin uykuya geçmesini önleme izni verir." "Uygulamaya, TV\'nin uyku moduna geçmesini önleme izni verir." "Uygulamaya, telefonun uykuya geçmesini önleme izni verir." diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 5d8481195652..158696503519 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -440,6 +440,8 @@ "Цей додаток може розпізнавати фізичну активність." "фотограф. та знімати відео" "Цей додаток може будь-коли робити фотографії та записувати відео за допомогою камери." + "Дозволити додатку або сервісу отримувати зворотні виклики щодо відкриття чи закриття камер." + "Цей додаток для підпису може отримувати зворотні виклики, коли будь-яка камера відкривається (з указанням пакета додатка) чи закривається." "контролювати вібросигнал" "Дозволяє програмі контролювати вібросигнал." "прямо набирати номери тел." @@ -456,9 +458,11 @@ "Додаток може продовжувати виклик, початий в іншому додатку." "переглядати номери телефону" "Надає додаткам доступ до номерів телефону на пристрої." + "залишати екран автомобіля ввімкненим" "не доп.перехід пристр.в реж.сну" "не допускати перехід телевізора в режим сну" "Вимкнення режиму сну" + "Дозволяє додатку залишати екран автомобіля ввімкненим." "Дозволяє програмі не допускати перехід планшетного ПК у режим сну." "Додаток може не допускати перехід телевізора в режим сну." "Дозволяє програмі не допускати перехід телефону в режим сну." diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 1c1dda8d1472..777da6c64175 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -434,6 +434,10 @@ "یہ ایپ آپ کی جسمانی سرگرمی کی شناخت کر سکتی ہے۔" "تصاویر لیں اور ویڈیوز بنائیں" "یہ ایپ کسی بھی وقت کیمرا استعمال کرتے ہوئے تصاویر لے سکتی ہے اور ویڈیوز ریکارڈ کر سکتی ہے۔" + + + + "ارتعاش کو کنٹرول کریں" "ایپ کو وائبریٹر کنٹرول کرنے کی اجازت دیتا ہے۔" "براہ راست فون نمبرز پر کال کریں" @@ -450,9 +454,11 @@ "ایپ کو دوسری ایپ میں شروع کردہ کال کو جاری رکھنے کی اجازت ملتی ہے۔" "فون نمبرز پڑھیں" "ایپ کو آلہ کے فون نمبرز تک رسائی کرنے دیتا ہے۔" + "کار کی اسکرین آن رکھیں" "ٹیبلیٹ کو سلیپ وضع میں جانے سے روکیں" "‏TV کو سلیپ وضع میں جانے سے روکیں" "فون کو سلیپ وضع میں جانے سے روکیں" + "ایپ کو کار کی اسکرین آن رکھنے کی اجازت دیتا ہے۔" "ایپ کو ٹیبلیٹ کو سلیپ وضع میں جانے سے روکنے کی اجازت دیتا ہے" "‏ایپ کو TV کو سلیپ وضع میں جانے سے روکنے کی اجازت دیتا ہے۔" "ایپ کو فون کو سلیپ وضع میں جانے سے روکنے کی اجازت دیتا ہے" diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index cf4c874eb83f..4d0e33042bb4 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -434,6 +434,8 @@ "Bu ilova jismoniy harakatlaringizni aniqlay oladi." "rasm va videoga olish" "Bu ilova xohlagan vaqtda kamera orqali suratga olishi va video yozib olishi mumkin." + "Ilova yoki xizmatga kamera qurilmalari ochilayotgani yoki yopilayotgani haqida qayta chaqiruvlar qabul qilishi uchun ruxsat berish." + "Bu imzo ilovasi har qanday kamera qurilmasi ochilayotganda (istalgan ilova paketi tarafidan) yoki yopilayotganda qayta chaqiruvlar qabul qilishi mumkin." "tebranishni boshqarish" "Ilova tebranishli signallarni boshqarishi mumkin." "telefon raqamlariga tog‘ridan to‘g‘ri qo‘ng‘iroq qilish" @@ -450,9 +452,11 @@ "Ilovaga boshqa ilovada boshlangan chaqiruvni davom ettirish imkon beradi" "telefon raqamlarini o‘qish" "Ilovaga qurilmaning telefon raqamlaridan foydalanishiga ruxsat beradi." + "avtomobil ekranini yoniq holatda saqlab turish" "planshetni uyquga ketishiga yo‘l qo‘ymaslik" "televizorning uyqu rejimiga o‘tishining oldini olish" "telefonni uxlashiga yo‘l qo‘ymaslik" + "Ilova avtomobil ekranini yoniq holatda saqlaydi." "Ilova planshetning uyqu rejimiga o‘tib qolishining oldini olishi mumkin." "Ilovaga televizorning uyqu rejimiga o‘tishining oldini olish huquqini beradi." "Ilova telefonning uyqu rejimiga o‘tib qolishining oldini olishi mumkin." diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index a155d63a2a1f..f05cd214a351 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -434,6 +434,8 @@ "Ứng dụng này có thể nhận dạng hoạt động thể chất của bạn." "chụp ảnh và quay video" "Ứng dụng này có thể chụp ảnh và quay video bằng máy ảnh bất cứ lúc nào." + "Cho phép một ứng dụng hoặc dịch vụ nhận lệnh gọi lại khi các thiết bị máy ảnh đang được mở/đóng." + "Ứng dụng chữ ký này có thể nhận các lệnh gọi lại khi có bất kỳ thiết bị máy ảnh nào đang được mở (bằng gói ứng dụng) hoặc đóng." "kiểm soát rung" "Cho phép ứng dụng kiểm soát bộ rung." "gọi trực tiếp số điện thoại" @@ -450,9 +452,11 @@ "Cho phép ứng dụng tiếp tục cuộc gọi được bắt đầu trong một ứng dụng khác." "đọc số điện thoại" "Cho phép ứng dụng truy cập số điện thoại của thiết bị." + "duy trì trạng thái bật của màn hình ô tô" "ngăn máy tính bảng chuyển sang chế độ ngủ" "ngăn TV chuyển sang chế độ ngủ" "ngăn điện thoại chuyển sang chế độ ngủ" + "Cho phép ứng dụng này duy trì trạng thái bật của màn hình ô tô." "Cho phép ứng dụng ngăn máy tính bảng chuyển sang chế độ ngủ." "Cho phép ứng dụng ngăn TV chuyển sang chế độ ngủ." "Cho phép ứng dụng ngăn điện thoại chuyển sang chế độ ngủ." diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 833fd533fe73..fee0eab260e5 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -434,6 +434,8 @@ "此应用可以识别您的身体活动。" "拍摄照片和视频" "此应用可随时使用相机拍摄照片和录制视频。" + "允许应用或服务接收与打开或关闭摄像头设备有关的回调。" + "此签名应用可在任何摄像头设备(被某些应用软件包)打开或关闭时接收相应回调。" "控制振动" "允许应用控制振动器。" "拨打电话" @@ -450,9 +452,11 @@ "允许该应用继续进行在其他应用中发起的通话。" "读取电话号码" "允许该应用访问设备上的电话号码。" + "使车载显示屏保持开启状态" "阻止平板电脑进入休眠状态" "阻止电视进入休眠状态" "防止手机休眠" + "允许该应用使车载显示屏保持开启状态。" "允许应用阻止平板电脑进入休眠状态。" "允许应用阻止电视进入休眠状态。" "允许应用阻止手机进入休眠状态。" diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 2309b5005d35..413be2c28315 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -280,7 +280,7 @@ "通訊錄" "存取您的通訊錄" "允許「%1$s」<b></b>存取您的聯絡人嗎?" - "位置資訊" + "位置" "存取此裝置的位置" "允許「%1$s」<b></b>存取此裝置的位置資訊嗎?" "此應用程式目前只有您在使用時才能存取位置資訊" @@ -434,6 +434,8 @@ "此應用程式可識別您的體能活動。" "拍照和拍攝影片" "此應用程式可以隨時使用相機拍照和攝錄。" + "允許應用程式或服務接收相機裝置開啟或關閉的相關回電。" + "當任何相機裝置在開啟 (由應用程式套件) 或關閉時,此簽名應用程式就能接收回電。" "控制震動" "允許應用程式控制震動。" "直接撥打電話號碼" @@ -450,9 +452,11 @@ "允許應用程式繼續進行在其他應用程式中開始的通話。" "讀取電話號碼" "允許應用程式存取裝置上的電話號碼。" + "保持汽車螢幕開啟" "防止平板電腦進入休眠狀態" "阻止電視進入休眠狀態" "防止手機進入休眠狀態" + "允許應用程式保持汽車螢幕開啟。" "允許應用程式防止平板電腦進入休眠狀態。" "允許應用程式阻止電視進入休眠狀態。" "允許應用程式防止手機進入休眠狀態。" diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index cea8c1cd4253..ebbfdf1abbc5 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -434,6 +434,8 @@ "這個應用程式可以辨識你從事的體能活動。" "拍攝相片和影片" "這個應用程式隨時可使用相機拍照及錄影。" + "允許應用程式或服務接收相機裝置開啟或關閉的相關回呼。" + "當任何相機裝置在開啟 (由應用程式套件) 或關閉時,這個簽名應用程式就能接收回呼。" "控制震動" "允許應用程式控制震動。" "直接撥打電話號碼" @@ -450,9 +452,11 @@ "允許應用程式繼續進行在其他應用程式中發起的通話。" "讀取電話號碼" "允許應用程式存取裝置上的電話號碼資料。" + "讓車輛螢幕保持開啟" "防止平板電腦進入休眠狀態" "防止電視進入休眠狀態" "防止手機進入待命狀態" + "允許應用程式讓車輛螢幕保持開啟。" "允許應用程式防止平板電腦進入休眠狀態。" "允許應用程式防止電視進入休眠狀態。" "允許應用程式防止手機進入休眠狀態。" diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 087d0a9fda70..dc51f2ee0e41 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -434,6 +434,8 @@ "Lolu hlelo lokusebenza lingabona umsebenzi wakho." "thatha izithombe namavidiyo" "Lolu hlelo lokusebenza lungathatha izithombe futhi lirekhode amavidiyo lusebenzisa ikhamera noma kunini." + "Vumela uhlelo lokusebenza noma isevisi ukwamukela ukuphinda ufonelwe mayelana namadivayisi wekhamera avuliwe noma avaliwe." + "Lolu hlelo lokusebenza lesiginesha lungakwazi ukuthola ukuphinda ufonelwe uma noma iyiphi idivayisi yekhamera ivuliwe (ngephakheji yohlelo lokusebenza) noma ivaliwe." "lawula ukudlidliza" "Ivumela uhlelo lokusebenza ukulawula isidlidlizi." "ngokuqondile shayela izinombolo zocingo" @@ -450,9 +452,11 @@ "Ivumela uhlelo lokusebenza ukuze luqhube ikholi eqalwe kolunye uhlelo lokusebenza." "funda izinombolo zefoni" "Ivumela uhlelo lokusebenza ukufinyelela izinombolo zefoni zedivayisi." + "gcina isikrini semoto sivuliwe" "gwema ithebhulethi ukuba ingalali" "vimbela i-TV kusukela ekulaleni" "gwema ifoni ukuba ingalali" + "Ivumela uhlelo lokusebenza ukuthi lugcine isikrini semoto sivuliwe." "Ivumela uhlelo lokusebenza ukuthi linqande ithebulethi yakho ukuthi ilale." "Ivumela uhlelo lokusebenza ukuvimbela i-TV ukuthi ilale." "Ivumela uhlelo lokusebenza ukuthi inqande ucingo ukuthi lulale." -- GitLab From 52b5e54980c9045c9b1185ef8ec5ebedd0f2b028 Mon Sep 17 00:00:00 2001 From: Shuzhen Wang Date: Mon, 16 Mar 2020 12:20:36 -0700 Subject: [PATCH 149/219] Camera: Clarify CAMERA_OPEN_CLOSE_LISTENER description Test: Build Bug: 151326743 Change-Id: Ia067f3b4021b184504147569374678f81f66daf3 --- core/res/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 044e07420c2d..d33cf42cd051 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1154,7 +1154,7 @@ Allow an application or service to receive callbacks about camera devices being opened or closed. - This signature app can receive callbacks when any camera device is being opened (by what application package) or closed. + This app can receive callbacks when any camera device is being opened (by what application) or closed. control vibration -- GitLab From b4aaa9d8adae5971f7f6589afc22008afa2f8d2b Mon Sep 17 00:00:00 2001 From: Eugene Susla Date: Thu, 28 Mar 2019 13:50:17 -0700 Subject: [PATCH 150/219] RESTRICT AUTOMERGE Prevent accessing companion records from arbitrary uids Test: manual Fixes: 129476618 Change-Id: I7b18cfcdf58e62a445cbb508116c6ce7c1cea8d7 --- core/res/AndroidManifest.xml | 5 +++++ packages/Shell/AndroidManifest.xml | 1 + .../server/companion/CompanionDeviceManagerService.java | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index e7e20fc41eee..4528985bc852 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -3518,6 +3518,11 @@ + + + + diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index 54a3ecb22687..067becbf0c52 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -660,6 +660,11 @@ public class CompanionDeviceManagerService extends SystemService implements Bind + "associate USER_ID PACKAGE MAC_ADDRESS\n" + "disassociate USER_ID PACKAGE MAC_ADDRESS"; + ShellCmd() { + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.MANAGE_COMPANION_DEVICES, "ShellCmd"); + } + @Override public int onCommand(String cmd) { switch (cmd) { -- GitLab From 2ade5356f8fff3dc04c90a4cf459e0ae5f0e87a8 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 16 Mar 2020 22:13:38 -0700 Subject: [PATCH 151/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: I1bf088868f58abbb8943fdac2c978dcd478810fe --- packages/SettingsLib/res/values-ar/arrays.xml | 2 +- .../SettingsLib/res/values-ar/strings.xml | 28 +++++++++---------- .../SettingsLib/res/values-es-rUS/strings.xml | 4 +-- .../SettingsLib/res/values-es/strings.xml | 4 +-- .../SettingsLib/res/values-eu/strings.xml | 8 +++--- .../SettingsLib/res/values-fr/strings.xml | 2 +- .../SettingsLib/res/values-gl/strings.xml | 2 +- .../SettingsLib/res/values-ja/strings.xml | 2 +- .../SettingsLib/res/values-ko/strings.xml | 2 +- .../SettingsLib/res/values-ky/strings.xml | 10 +++---- .../SettingsLib/res/values-pt-rPT/strings.xml | 2 +- .../SettingsLib/res/values-ru/strings.xml | 2 +- .../SettingsLib/res/values-ta/strings.xml | 8 +++--- .../SettingsLib/res/values-vi/strings.xml | 2 +- 14 files changed, 39 insertions(+), 39 deletions(-) diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml index 39ba506f2b3a..6e06c59c25a1 100644 --- a/packages/SettingsLib/res/values-ar/arrays.xml +++ b/packages/SettingsLib/res/values-ar/arrays.xml @@ -246,7 +246,7 @@ "عرض مناطق العجز في رؤية اللونين الأخضر والأحمر" - "الحد القياسي" + "الحدّ العادي" "ليست هناك عمليات بالخلفية" "عملية واحدة بحد أقصى" "عمليتان بحد أقصى" diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index 2308f06b026a..edc8226c4f47 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -56,7 +56,7 @@ "اكتمل الاشتراك. جارٍ الاتصال…" "بطيئة جدًا" "بطيئة" - "موافق" + "حسنًا" "متوسطة" "سريعة" "سريعة جدًا" @@ -122,7 +122,7 @@ "سماعة رأس" "هاتف" "تصوير" - "سماعة أذن" + "السمّاعة" "جهاز إدخال طرفي" "بلوتوث" "جارٍ إقران سماعة الأذن الطبية اليسرى…" @@ -155,7 +155,7 @@ "إعدادات تحويل النص إلى كلام" "تحويل النص إلى كلام" "معدل سرعة الكلام" - "سرعة نطق الكلام" + "سرعة قول الكلام" "درجة الصوت" "للتأثير في نبرة الكلام المُرَكَّب" "اللغة" @@ -179,7 +179,7 @@ "المحرّك المفضّل" "عامة" "إعادة ضبط طبقة صوت الكلام" - "إعادة ضبط طبقة الصوت التي يتم نطق النص بها على الإعداد التلقائي." + "إعادة ضبط طبقة الصوت التي يتم قول النص بها على الإعداد التلقائي." "بطيء جدًا" "بطيء" @@ -213,7 +213,7 @@ "فتح قفل المصنّع الأصلي للجهاز" "‏السماح بإلغاء قفل برنامج bootloader" "هل تريد السماح بإلغاء قفل المصنّع الأصلي للجهاز؟" - "تحذير: لن تعمل ميزات الحماية على هذا الجهاز أثناء تشغيل هذا الإعداد." + "تحذير: لن تعمل ميزات الحماية على هذا الجهاز أثناء تفعيل هذا الإعداد." "اختيار تطبيق الموقع الزائف" "لم يتم تعيين تطبيق موقع زائف" "تطبيق الموقع الزائف: %1$s" @@ -346,7 +346,7 @@ "نابض بالحياة (تلقائي)" "طبيعي" - "قياسي" + "عادي" "ألوان محسَّنة" @@ -362,11 +362,11 @@ "‏تطبيق WebView" "‏تعيين تطبيق WebView" "لم يعد هذا الاختيار صالحًا. أعد المحاولة." - "التحويل إلى تشفير ملفات" + "التحويل إلى ترميز ملفات" "تحويل…" - "تم استخدام تشفير ملفات من قبل" - "التحويل إلى تشفير على الملف" - "تحويل قسم البيانات إلى تشفير على الملف.\n !!تحذير!! سيؤدي هذا إلى محو جميع بياناتك.\n لا تزال هذه الميزة في مرحلة ألفا، وقد لا تعمل على نحو سليم.\n للمتابعة، اضغط على \"مسح وتحويل…\"." + "تم استخدام ترميز ملفات من قبل" + "التحويل إلى ترميز على الملف" + "تحويل قسم البيانات إلى ترميز على الملف.\n !!تحذير!! سيؤدي هذا إلى محو جميع بياناتك.\n لا تزال هذه الميزة في مرحلة ألفا، وقد لا تعمل على نحو سليم.\n للمتابعة، اضغط على \"مسح وتحويل…\"." "مسح وتحويل…" "نمط لون الصورة" "‏استخدام sRGB" @@ -430,7 +430,7 @@ "أكبر مستوى" "مخصص (%d)" "القائمة" - "إدخال كلمة المرور لإعادة الضبط بحسب بيانات المصنع في الوضع التجريبي" + "إدخال كلمة المرور لإعادة الضبط على الإعدادات الأصلية في الوضع التجريبي" "التالي" "يلزم توفر كلمة مرور" "طرق الإدخال النشطة" @@ -454,9 +454,9 @@ "وقت أكثر." "وقت أقل." "إلغاء" - "موافق" - "تشغيل" - "تشغيل وضع \"الرجاء عدم الإزعاج\"" + "حسنًا" + "تفعيل" + "تفعيل وضع \"الرجاء عدم الإزعاج\"" "مطلقًا" "الأولوية فقط" "%1$s. %2$s" diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 39f44174375c..795980d516b2 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -64,7 +64,7 @@ "Desconectado" "Desconectando…" "Conectando…" - "Conectado a %1$s" + "Conectado%1$s" "Vinculando..." "Conectado (sin teléfono) a %1$s" "Conectado (sin archivos multimedia) a %1$s" @@ -170,7 +170,7 @@ "Este idioma necesita una conexión de red en funcionamiento para la salida de texto a voz." "Ejemplo de síntesis de voz" "Estado del idioma predeterminado" - "El idioma %1$s es totalmente compatible." + "El idioma %1$s es totalmente compatible" "El idioma %1$s requiere una conexión de red." "El idioma %1$s no es compatible." "Comprobando…" diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index 76c983105b72..4712d6709736 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -188,7 +188,7 @@ "Más rápida" "Muy rápida" "Superrápida" - "Hiperrrápida" + "Hiperrápida" "La más rápida" "Seleccionar perfil" @@ -200,7 +200,7 @@ "Las opciones de desarrollador no están disponibles para este usuario" "Los ajustes de VPN no están disponibles para este usuario" "Los ajustes para compartir conexión no están disponibles para este usuario" - "Los ajustes del nombre de punto de acceso no están disponibles para este usuario" + "Los ajustes del nombre del punto de acceso no están disponibles para este usuario" "Depuración por USB" "Activar el modo de depuración cuando el dispositivo esté conectado por USB" "Revocar autorizaciones de depuración USB" diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 0722b8dac255..f1bb45fdfea6 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -27,7 +27,7 @@ "Desgaituta" "Ezin izan da konfiguratu IP helbidea" "Ez dago konektatuta sarearen kalitate eskasagatik" - "Ezin izan da konektatu Wi-Fi sarera" + "Ezin izan da konektatu wifi-sarera" "Autentifikazio-arazoa" "Ezin da konektatu" "Ezin da konektatu \"%1$s\" sarera" @@ -122,7 +122,7 @@ "Mikrofonodun entzungailua" "Telefonoa" "Irudietarako gailua" - "Aurikularra" + "Entzungailua" "Idazteko gailua" "Bluetooth gailua" "Ezkerreko audifonoa parekatzen…" @@ -223,7 +223,7 @@ "Wifi-sareen bilaketaren muga" "Datu-konexioa beti aktibo" "Konexioa partekatzeko hardwarearen azelerazioa" - "Erakutsi Bluetooth gailuak izenik gabe" + "Erakutsi Bluetooth bidezko gailuak izenik gabe" "Desgaitu bolumen absolutua" "Bluetooth AVRCP bertsioa" "Hautatu Bluetooth AVRCP bertsioa" @@ -270,7 +270,7 @@ "Ezarpen hauek garapen-xedeetarako pentsatu dira soilik. Baliteke ezarpenen eraginez gailua matxuratzea edo funtzionamendu okerra izatea." "Egiaztatu USBko aplikazioak" "Egiaztatu ADB/ADT bidez instalatutako aplikazioak portaera kaltegarriak atzemateko" - "Bluetooth gailuak izenik gabe (MAC helbideak soilik) erakutsiko dira" + "Bluetooth bidezko gailuak izenik gabe (MAC helbideak soilik) erakutsiko dira" "Bluetooth bidezko bolumen absolutuaren eginbidea desgaitu egiten du urruneko gailuetan arazoak hautematen badira; esaterako, bolumena ozenegia bada edo ezin bada kontrolatu" "Tokiko terminala" "Gaitu tokiko shell-sarbidea duen terminal-aplikazioa" diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index 78dedcfc512b..100088a82ca7 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -56,7 +56,7 @@ "Inscription terminée. Connexion…" "Très lente" "Lente" - "Correct" + "Correcte" "Moyenne" "Élevée" "Très rapide" diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index 59b927b424ec..92f0ab07875a 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -309,7 +309,7 @@ "Desactivar encamiñamento audio USB" "Desactiva o encamiñamento automático a periféricos de audio USB" "Mostrar límites de deseño" - "Mostra os límites dos clips, as marxes, etc." + "Mostra os límites dos clips, as marxes etc." "Forzar dirección do deseño RTL" "Forza a dirección de pantalla a RTL (dereita a esquerda) para todas as configuración rexionais" "Forzar MSAA 4x" diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index f2e20fa5e19d..20e200068df9 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -201,7 +201,7 @@ "このユーザーはVPN設定を利用できません。" "このユーザーはテザリング設定を利用できません" "このユーザーはアクセスポイント名設定を利用できません" - "USBデバッグ" + "USB デバッグ" "USB接続時はデバッグモードにする" "USBデバッグの許可の取り消し" "バグレポートのショートカット" diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index a259bb10c2aa..3c2acd16ea1d 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -188,7 +188,7 @@ "더 빠르게" "매우 빠르게" "상당히 빠르게" - "매우 빠르게" + "굉장히 빠르게" "가장 빠르게" "프로필 선택" diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index 84ca16705a66..565062c0124e 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -26,12 +26,12 @@ "Ажыратылды" "Өчүрүлгөн" "IP конфигурациясы бузулду" - "Тармактын сапаты начар болгондуктан туташкан жок" + "Тармактын сапаты начар болгондуктан, туташкан жок" "WiFi туташуусу бузулду" "Аутентификация маселеси бар" "Туташпай жатат" "\"%1$s\" тармагына туташпай койду" - "Сырсөздү текшерип, кайра аракет кылыңыз." + "Сырсөздү текшерип, кайталап көрүңүз." "Тейлөө аймагында эмес" "Автоматтык түрдө туташпайт" "Интернетке туташпай турат" @@ -115,7 +115,7 @@ "Жок" "Жупташканда байланыштарыңыз менен чалуу таржымалыңызды пайдалана аласыз." "%1$s менен жупташуу мүмкүн эмес." - "PIN же код туура эмес болгондуктан %1$s туташуу мүмкүн эмес." + "PIN же код туура эмес болгондуктан, %1$s туташуу мүмкүн эмес." "%1$s менен байланышуу мүмкүн эмес." "Жупташтырууну %1$s четке какты." "Компьютер" @@ -123,7 +123,7 @@ "Телефон" "Сүрөт тартуучу түзмөк" "Кулакчын" - "Дайындарды киргизүүчү сырткы түзмөк" + "Дайындарды киргизүүчү тышкы түзмөк" "Bluetooth" "Угуу аппаратынын сол кулагы жупташтырылууда…" "Угуу аппаратынын оң кулагы жупташтырылууда…" @@ -361,7 +361,7 @@ "Учурда иштеп жаткан кызматтарды көрүп, көзөмөлдөп турасыз" "WebView кызматы" "WebView аткарылышын коюу" - "Тандалган нерсе жараксыз болуп калган. Кайра аракет кылыңыз." + "Тандалган нерсе жараксыз болуп калган. Кайталап көрүңүз." "Файлдарды шифрлөөгө өтүү" "Айландыруу…" "Файл мурунтан эле шифрленген" diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index 0f9a4398cad6..345aa644db3a 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -237,7 +237,7 @@ "Acionar o codec de áudio Bluetooth\nSeleção: modo de canal" "Codec LDAC de áudio Bluetooth: qualidade de reprodução" "Acionar a seleção do codec LDAC de áudio\nBluetooth: Qualidade de reprodução" - "Transmissão em fluxo contínuo: %1$s" + "Stream: %1$s" "DNS privado" "Selecionar modo DNS privado" "Desativado" diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index 1c277ccacb4b..70fc3fa48e34 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -110,7 +110,7 @@ "Используется для передачи файлов" "Использовать для ввода" "Использовать для слухового аппарата" - "Добавить" + "Подключить" "ДОБАВИТЬ" "Отмена" "Установление соединения обеспечивает доступ к вашим контактам и журналу звонков при подключении." diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index b09e6dceecbc..f04fab20c53a 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -147,7 +147,7 @@ "டெதெரிங்" "டெதெரிங் & போர்டபிள் ஹாட்ஸ்பாட்" "எல்லா பணிப் பயன்பாடுகளும்" - "வேறொருவர்" + "கெஸ்ட்" "அறியப்படாத" "பயனர்: %1$s" "சில இயல்புநிலைகள் அமைக்கப்பட்டன" @@ -246,7 +246,7 @@ "DNS வழங்குநரின் ஹோஸ்ட் பெயரை உள்ளிடவும்" "இணைக்க முடியவில்லை" "வயர்லெஸ் காட்சி சான்றுக்கான விருப்பங்களைக் காட்டு" - "வைஃபை நுழைவு அளவை அதிகரித்து, வைஃபை தேர்வியில் ஒவ்வொன்றிற்கும் SSID RSSI ஐ காட்டுக" + "வைஃபை நுழைவு அளவை அதிகரித்து, வைஃபை தேர்வுக் கருவியில் ஒவ்வொன்றிற்கும் SSID RSSI ஐ காட்டுக" "பேட்டரி தீர்ந்துபோவதைக் குறைத்து நெட்வொர்க்கின் செயல்திறனை மேம்படுத்தும்" "கட்டண நெட்வொர்க்" "கட்டணமில்லா நெட்வொர்க்" @@ -376,7 +376,7 @@ "நிறம் அடையாளங்காண முடியாமை (சிவப்பு-பச்சை)" "நிறம் அடையாளங்காண முடியாமை (நீலம்-மஞ்சள்)" "வண்ணத்திருத்தம்" - "இது சோதனை முறையிலான அம்சம், இது செயல்திறனைப் பாதிக்கலாம்." + "இது பரிசோதனை முறையிலான அம்சம், இது செயல்திறனைப் பாதிக்கலாம்." "%1$s மூலம் மேலெழுதப்பட்டது" "%1$s - %2$s" "கிட்டத்தட்ட %1$s மீதமுள்ளது" @@ -428,7 +428,7 @@ "பெரியது" "கொஞ்சம் பெரியது" "மிகப் பெரியது" - "தனிப்பயன் (%d)" + "பிரத்தியேக (%d)" "மெனு" "டெமோ பயன்முறையில் ஆரம்பநிலை மீட்டமைவைச் செயல்படுத்த, கடவுச்சொல்லை உள்ளிடவும்" "அடுத்து" diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index fcd2d3614265..981602aeee81 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -199,7 +199,7 @@ "Đặt tùy chọn cho phát triển ứng dụng" "Tùy chọn dành cho nhà phát triển không khả dụng cho người dùng này" "Cài đặt VPN không khả dụng cho người dùng này" - "Cài đặt chia sẻ kết nối không khả dụng cho người dùng này" + "Cài đặt cách chia sẻ kết nối không khả dụng cho người dùng này" "Cài đặt tên điểm truy cập không khả dụng cho người dùng này" "Gỡ lỗi qua USB" "Bật chế độ gỡ lỗi khi kết nối USB" -- GitLab From 84cccfe6cdbc57ee372ee1a0fea64c7a11c53766 Mon Sep 17 00:00:00 2001 From: Eugene Susla Date: Thu, 28 Mar 2019 13:50:17 -0700 Subject: [PATCH 152/219] RESTRICT AUTOMERGE Prevent accessing companion records from arbitrary uids Test: manual Fixes: 129476618 Change-Id: I7b18cfcdf58e62a445cbb508116c6ce7c1cea8d7 --- core/res/AndroidManifest.xml | 5 +++++ .../server/companion/CompanionDeviceManagerService.java | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index d0ae9dbc55ae..778d3189db21 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -3128,6 +3128,11 @@ + + + + + Change privacy setting? - %1$s may want to connect using your device MAC address, a unique identifier. This may allow your device\u2019s location to be tracked by nearby devices. - \n\nIf you continue, %1$s will change your privacy setting and try to connect again. + To connect, %1$s needs to use your device MAC address, a unique identifier. Currently, your privacy setting for this network uses a randomized identifier. + \n\nThis change may allow your device\u2019s location to be tracked by nearby devices. Change setting -- GitLab From f5d301c277e64169ba173b0204dea1b2382876d8 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Mon, 2 Mar 2020 17:09:44 -0800 Subject: [PATCH 158/219] Create different KeyId for saved and suggestion network Bug: 150500247 Test: atest android.net.wifi Merged-In: Ia416b2e986c86fe0a29641f6a20236802d72a233 Change-Id: Ia416b2e986c86fe0a29641f6a20236802d72a233 (cherry picked from commit 96a9e48520fc2359a3cdd6b3513bf158d6844365) --- .../android/net/wifi/WifiConfiguration.java | 14 ++++- .../net/wifi/WifiConfigurationTest.java | 61 +++++++++++++++++++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index ed416429a279..88f2bb2ad6e8 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -2113,15 +2113,23 @@ public class WifiConfiguration implements Parcelable { throw new IllegalStateException("Not an EAP network"); } - return trimStringForKeyId(SSID) + "_" + keyMgmt + "_" + - trimStringForKeyId(enterpriseConfig.getKeyId(current != null ? - current.enterpriseConfig : null)); + String keyId = trimStringForKeyId(SSID) + "_" + keyMgmt + "_" + + trimStringForKeyId(enterpriseConfig.getKeyId(current != null + ? current.enterpriseConfig : null)); + + if (!fromWifiNetworkSuggestion) { + return keyId; + } + return keyId + "_" + trimStringForKeyId(BSSID) + "_" + trimStringForKeyId(creatorName); } catch (NullPointerException e) { throw new IllegalStateException("Invalid config details"); } } private String trimStringForKeyId(String string) { + if (string == null) { + return ""; + } // Remove quotes and spaces return string.replace("\"", "").replace(" ", ""); } diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index ba9fc786afe7..f56cdc30af36 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -349,6 +349,67 @@ public class WifiConfigurationTest { assertTrue(exceptionThrown); } + /** + * Verifies that getKeyIdForCredentials returns the expected string for Suggestion Enterprise + * networks + * @throws Exception + */ + @Test + public void testGetKeyIdForCredentialsForSuggestion() throws Exception { + WifiConfiguration config = new WifiConfiguration(); + final String mSsid = "TestAP"; + final String packageName = "TestApp"; + final String bSsid = MacAddress.createRandomUnicastAddress().toString(); + String suggestionSuffix = "_" + bSsid + "_" + packageName; + config.SSID = mSsid; + config.fromWifiNetworkSuggestion = true; + config.creatorName = packageName; + config.BSSID = bSsid; + + // Test various combinations + // EAP with TLS + config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); + config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); + config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE); + String keyId = config.getKeyIdForCredentials(config); + assertEquals(keyId, mSsid + "_WPA_EAP_TLS_NULL" + suggestionSuffix); + + // EAP with TTLS & MSCHAPv2 + config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); + config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS); + config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2); + keyId = config.getKeyIdForCredentials(config); + assertEquals(keyId, mSsid + "_WPA_EAP_TTLS_MSCHAPV2" + suggestionSuffix); + + // Suite-B 192 with PWD & GTC + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192); + config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PWD); + config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC); + keyId = config.getKeyIdForCredentials(config); + assertEquals(keyId, mSsid + "_SUITE_B_192_PWD_GTC" + suggestionSuffix); + + // IEEE8021X with SIM + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); + config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM); + config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE); + keyId = config.getKeyIdForCredentials(config); + assertEquals(keyId, mSsid + "_IEEE8021X_SIM_NULL" + suggestionSuffix); + + // Try calling this method with non-Enterprise network, expect an exception + boolean exceptionThrown = false; + try { + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK); + config.preSharedKey = "TestPsk"; + keyId = config.getKeyIdForCredentials(config); + } catch (IllegalStateException e) { + exceptionThrown = true; + } + assertTrue(exceptionThrown); + } + /** * Verifies that getSsidAndSecurityTypeString returns the correct String for networks of * various different security types -- GitLab From f9ab7ef51e758425f466872fd5c3bdc33dbde9a7 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 17 Mar 2020 22:54:08 -0700 Subject: [PATCH 159/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: I374deac620c12227ea7cf6a2838444329ba32faa --- core/res/res/values-ar/strings.xml | 2 +- core/res/res/values-as/strings.xml | 6 ++---- core/res/res/values-bg/strings.xml | 2 +- core/res/res/values-bn/strings.xml | 6 ++---- core/res/res/values-de/strings.xml | 2 +- core/res/res/values-eu/strings.xml | 26 +++++++++++++------------- core/res/res/values-fr/strings.xml | 2 +- core/res/res/values-gu/strings.xml | 6 ++---- core/res/res/values-it/strings.xml | 2 +- core/res/res/values-kn/strings.xml | 6 ++---- core/res/res/values-ky/strings.xml | 2 +- core/res/res/values-ml/strings.xml | 6 ++---- core/res/res/values-mr/strings.xml | 6 ++---- core/res/res/values-ne/strings.xml | 6 ++---- core/res/res/values-or/strings.xml | 6 ++---- core/res/res/values-pt-rPT/strings.xml | 2 +- core/res/res/values-ur/strings.xml | 6 ++---- 17 files changed, 38 insertions(+), 56 deletions(-) diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 3cbf14558666..e78b9f46f304 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1455,7 +1455,7 @@ "جارٍ شحن الجهاز المتصل. انقر لعرض خيارات أكثر." "تم اكتشاف ملحق صوتي تناظري" "الجهاز الذي تم توصيله بالهاتف غير متوافق معه. انقر للحصول على المزيد من المعلومات." - "‏تم توصيل تصحيح أخطاء الجهاز عبر USB" + "‏تم توصيل أداة تصحيح أخطاء الجهاز عبر USB" "‏انقر لإيقاف تصحيح أخطاء الجهاز عبر USB." "‏اختيار إيقاف تصحيح أخطاء USB." "تم تفعيل وضع \"مفعّل الاختبار\"" diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 0af9b14ab1b5..81bdd46d7447 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -434,10 +434,8 @@ "এই এপটোৱে আপোনাৰ শাৰীৰিক কাৰ্যকলাপ চিনাক্ত কৰিব পাৰে।" "ফট\' তোলা আৰু ভিডিঅ\' ৰেকৰ্ড কৰা" "এই এপে যিকোনো সময়তে কেমেৰা ব্যৱহাৰ কৰি ফট\' তুলিব আৰু ভিডিঅ\' ৰেকর্ড কৰিব পাৰে।" - - - - + "কোনো এপ্লিকেশ্বন অথবা সেৱাক কেমেৰা ডিভাইচসমূহ খোলা অথবা বন্ধ কৰাৰ বিষয়ে কলবেকসমূহ গ্ৰহণ কৰিবলৈ অনুমতি দিয়ক।" + "যেতিয়া কোনো কেমেৰা ডিভাইচ খোলা (কোনো এপ্লিকেশ্বন পেকেজৰ দ্বাৰা) অথবা বন্ধ কৰা হয়, তেতিয়া এই স্বাক্ষৰ এপ্‌টোৱে কলবেকসমূহ গ্ৰহণ কৰিব পাৰে।" "কম্পন নিয়ন্ত্ৰণ কৰক" "ভাইব্ৰেটৰ নিয়ন্ত্ৰণ কৰিবলৈ এপটোক অনুমতি দিয়ে।" "পোনপটীয়াকৈ ফ\'ন নম্বৰলৈ কল কৰক" diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 6a747f41107b..9077629f26d4 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -294,7 +294,7 @@ "Да се разреши ли на <b>%1$s</b> да изпраща и преглежда SMS съобщения?" "Хранилище" "да има достъп до снимките, мултимедията и файловете на устройството ви" - "Да се разреши ли на <b>%1$s</b> да осъществява достъп до снимките, мултимедията и файловете на устройството ви?" + "Да се разреши ли на <b>%1$s</b> да има достъп до снимките, мултимедията и файловете на устройството ви?" "Микрофон" "записва звук" "Да се разреши ли на <b>%1$s</b> да записва аудио?" diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 252308d6f21a..f83e537e6d11 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -434,10 +434,8 @@ "এই অ্যাপ আপনার শারীরিক অ্যাক্টিভিটি শনাক্ত করতে পারবে।" "ছবি এবং ভিডিও তোলে" "এই অ্যাপটি যে কোনো সময় ক্যামেরা ব্যবহার করে ছবি তুলতে বা ভিডিও রেকর্ড করতে পারে৷" - - - - + "কোনও অ্যাপ্লিকেশন বা পরিষেবাকে ক্যামেরা ডিভাইসগুলি খোলা বা বন্ধ হওয়া সম্পর্কে কলব্যাকগুলি গ্রহণ করার অনুমতি দিন।" + "কোনও ক্যামেরা ডিভাইস খোলার সময় (কোনও অ্যাপ্লিকেশন প্যাকেজের সাহায্যে) বা বন্ধ করার সময় এই সিগনেচার অ্যাপটি কলব্যাকগুলি গ্রহণ করতে পারে।" "ভাইব্রেশন নিয়ন্ত্রণ করুন" "অ্যাপ্লিকেশানকে কম্পক নিয়ন্ত্রণ করতে দেয়৷" "সরাসরি ফোন নম্বরগুলিতে কল করে" diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 34de9e22a44e..857989817110 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -435,7 +435,7 @@ "Bilder und Videos aufnehmen" "Diese App kann mit der Kamera jederzeit Bilder und Videos aufnehmen." "Einer App oder einem Dienst den Empfang von Callbacks erlauben, wenn eine Kamera geöffnet oder geschlossen wird." - "Diese Premium-App kann Callbacks empfangen, wenn eine Kamera mit einem Anwendungspaket geöffnet oder geschlossen wird." + "Diese App kann Callbacks empfangen, wenn eine Kamera mit einem Anwendungspaket geöffnet oder geschlossen wird." "Vibrationsalarm steuern" "Ermöglicht der App, den Vibrationsalarm zu steuern" "Telefonnummern direkt anrufen" diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 9b08e767ae26..0e4934ededb6 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -145,7 +145,7 @@ "Desaktibatuta" "Deitu wifi bidez" "Deitu sare mugikorraren bidez" - "Wi-Fi sarea soilik" + "Wifi-sarea soilik" "{0}: ez da desbideratu" "{0}: {1}" "{0}: {1} zenbakira {2} segundotan" @@ -434,7 +434,7 @@ "Aplikazioak ariketa fisikoa hauteman dezake." "atera argazkiak eta grabatu bideoak" "Aplikazioak edonoiz erabil dezake kamera argazkiak ateratzeko eta bideoak grabatzeko." - "Eman baimena aplikazio edo zerbitzuari jakinarazpenak jasotzeko kamerak ireki edo ixten direnean." + "Eman baimena aplikazioari edo zerbitzuari jakinarazpenak jasotzeko kamerak ireki edo ixten direnean." "Kamera ireki edo itxi dela (eta zer aplikazio-paketerekin) dioten jakinarazpenak jaso ditzake sinatzeko aplikazio honek." "kontrolatu dardara" "Bibragailua kontrolatzeko aukera ematen die aplikazioei." @@ -1253,18 +1253,18 @@ "Ezin da aldatu pribatutasun-ezarpena" "Ez da aurkitu sarea" - Wi-Fi sareak erabilgarri - Wi-Fi sarea erabilgarri + Wifi-sareak erabilgarri + Wifi-sarea erabilgarri - Wi-Fi sare irekiak erabilgarri - Wi-Fi sare irekia erabilgarri + Wifi-sare irekiak erabilgarri + Wifi-sare irekia erabilgarri - "Konektatu Wi‑Fi sare irekira" + "Konektatu wifi-sare irekira" "Konektatu operadorearen Wi‑Fi sarera" "Wi‑Fi sarera konektatzen" "Wi‑Fi sare irekira konektatuta" - "Ezin izan da konektatu Wi‑Fi sare irekira" + "Ezin izan da konektatu wifi-sare irekira" "Sakatu hau sare guztiak ikusteko" "Konektatu" "Sare guztiak" @@ -1300,10 +1300,10 @@ "VPN" "sare mota ezezaguna" - "Ezin izan da Wi-Fi sarera konektatu" + "Ezin izan da wifi-sarera konektatu" " Interneteko konexio txarra du." "Konektatzeko baimena eman nahi diozu?" - "%1$s aplikazioak %2$s Wi-Fi sarera konektatu nahi du" + "%1$s aplikazioak %2$s wifi-sarera konektatu nahi du" "Aplikazio bat" "Wi-Fi Direct" "Hasi Wi-Fi Direct. Wi-Fi bezeroa edo sare publikoa desaktibatuko da." @@ -1318,9 +1318,9 @@ "Hartzailea:" "Idatzi beharrezko PINa:" "PINa:" - "Tableta Wi-Fi saretik deskonektatuko da %1$s gailura konektatuta dagoen bitartean" - "Telebista Wi-Fi saretik deskonektatuko da %1$s gailura konektatuta dagoen bitartean" - "Telefonoa Wi-Fi saretik deskonektatuko da %1$s gailura konektatuta dagoen bitartean" + "Tableta wifi-saretik deskonektatuko da %1$s gailura konektatuta dagoen bitartean" + "Telebista wifi-saretik deskonektatuko da %1$s gailura konektatuta dagoen bitartean" + "Telefonoa wifi-saretik deskonektatuko da %1$s gailura konektatuta dagoen bitartean" "Txertatu karakterea" "SMS mezuak bidaltzen" "<b>%1$s</b> SMS asko ari da bidaltzen. Mezuak bidaltzen jarrai dezan onartu nahi duzu?" diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index ea065a98e965..a001c95cd296 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -435,7 +435,7 @@ "prendre des photos et enregistrer des vidéos" "Cette application peut utiliser l\'appareil photo pour prendre des photos et enregistrer des vidéos à tout moment." "Autoriser une application ou un service à recevoir des rappels liés à l\'ouverture ou à la fermeture de caméras" - "Cette application de signature peut recevoir des rappels lorsqu\'une caméra est ouverte (par un package d\'application) ou fermée." + "Cette application premium peut recevoir des rappels lorsqu\'une caméra est ouverte (par un package d\'application) ou fermée." "contrôler le vibreur" "Permet à l\'application de contrôler le vibreur." "appeler directement les numéros de téléphone" diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 59fd056e8c38..63be55f591f9 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -434,10 +434,8 @@ "આ ઍપ તમારી શારીરિક પ્રવૃત્તિને ઓળખી શકે છે." "ચિત્રો અને વિડિઓઝ લો" "આ ઍપ્લિકેશન, કૅમેરાનો ઉપયોગ કરીને કોઈપણ સમયે ચિત્રો લઈ અને વિડિઓઝ રેકોર્ડ કરી શકે છે." - - - - + "કૅમેરા ડિવાઇસ ચાલુ કે બંધ થવા વિશે કૉલબૅક પ્રાપ્ત કરવાની ઍપ્લિકેશન કે સેવાને મંજૂરી આપો." + "જ્યારે કોઈ કૅમેરા ડિવાઇસ (ક્યા ઍપ્લિકેશન પૅકેજ વડે) ખોલવા કે બંધ કરવામાં આવે, ત્યારે આ વિશેષ ઍપ કૉલબૅક પ્રાપ્ત કરી શકે છે." "વાઇબ્રેશન નિયંત્રિત કરો" "એપ્લિકેશનને વાઇબ્રેટરને નિયંત્રિત કરવાની મંજૂરી આપે છે." "સીધા જ ફોન નંબર્સ પર કૉલ કરો" diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 4f3f735fd7f4..ef0df2d2c10f 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -435,7 +435,7 @@ "acquisizione di foto e video" "Questa app può scattare foto e registrare video tramite la fotocamera in qualsiasi momento." "Consenti a un\'applicazione o a un servizio di ricevere callback relativi all\'apertura o alla chiusura di videocamere." - "Questa app di firma può ricevere callback quando viene aperta (dal pacchetto dell\'applicazione) o chiusa qualsiasi videocamera." + "Questa app di firma può ricevere callback quando viene aperta (da quale pacchetto dell\'applicazione) o chiusa qualsiasi videocamera." "controllo vibrazione" "Consente all\'applicazione di controllare la vibrazione." "chiamata diretta n. telefono" diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index cf5572d6865f..d99f0b077dfb 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -434,10 +434,8 @@ "ಈ ಆ್ಯಪ್‌ ನಿಮ್ಮ ದೈಹಿಕ ಚಟುವಟಿಕೆಯನ್ನು ಗುರುತಿಸಬಹುದು." "ಚಿತ್ರಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳನ್ನು ಸೆರೆಹಿಡಿಯಿರಿ" "ಈ ಅಪ್ಲಿಕೇಶನ್ ಯಾವ ಸಮಯದಲ್ಲಾದರೂ ಕ್ಯಾಮರಾ ಬಳಸಿಕೊಂಡು ಚಿತ್ರಗಳು ಮತ್ತು ವಿಡಿಯೋಗಳನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಬಹುದು." - - - - + "ಕ್ಯಾಮರಾ ಸಾಧನಗಳನ್ನು ತೆರೆಯುತ್ತಿರುವ ಅಥವಾ ಮುಚ್ಚುತ್ತಿರುವ ಕುರಿತು ಕಾಲ್‌ಬ್ಯಾಕ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಆ್ಯಪ್‌ ಅಥವಾ ಸೇವೆಗೆ ಅನುಮತಿಸಿ." + "ಈ ಸಹಿ ಆ್ಯಪ್, ಯಾವುದೇ ಕ್ಯಾಮರಾ ಸಾಧನವನ್ನು ತೆರೆಯುತ್ತಿರುವಾಗ ಅಥವಾ ಮುಚ್ಚುತ್ತಿರುವಾಗ (ಯಾವ ಆ್ಯಪ್‌ ಪ್ಯಾಕೇಜ್‌ನಿಂದ ಎಂಬ ಮಾಹಿತಿಯ ಮೂಲಕ) ಕಾಲ್‌ಬ್ಯಾಕ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಬಹುದು." "ವೈಬ್ರೇಷನ್‌‌ ನಿಯಂತ್ರಿಸಿ" "ವೈಬ್ರೇಟರ್‌ ನಿಯಂತ್ರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ." "ಫೋನ್ ಸಂಖ್ಯೆಗಳಿಗೆ ನೇರವಾಗಿ ಕರೆ ಮಾಡಿ" diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 41569d58215a..e2e19508d392 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -375,7 +375,7 @@ "Колдонмого өзүнүн бөлүктөрүн эстутумда туруктуу кармоого уруксат берет.Бул эстутумдун башка колдонмолорго жетиштүүлүгүн чектеши жана телефондун иштешин жайлатышы мүмкүн." "Колдонмого эстутумдагы өз бөлүктөрүн туруктуу кылуу мүмкүнчүлүгүн берет. Ушуну менен сыналгы жай иштеп, башка колдонмолорго жеткиликтүү эстутум чектелиши мүмкүн." "Колдонмого өзүнүн бөлүктөрүн эстутумда туруктуу кармоого уруксат берет. Бул эстутумдун башка колдонмолорго жетиштүүлүгүн чектеши жана телефондун иштешин жайлатышы мүмкүн." - "алдыңкы пландагы кызматты аткаруу" + "активдүү кызматты иштетүү" "Колдонмолорго алдынкы пландагы кызматтарды колдонууга уруксат берет." "колдонмо сактагычынын мейкиндигин өлчөө" "Колдонмого өз кодун, дайындарын жана кэш өлчөмдөрүн түшүрүп алуу мүмкүнчүлүгүн берет" diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index d474ff59d511..fb19c7e14dd8 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -434,10 +434,8 @@ "നിങ്ങളുടെ ശാരീരിക പ്രവർത്തനം ഈ ആപ്പിന് തിരിച്ചറിയാനാവും." "ചിത്രങ്ങളും വീഡിയോകളും എടുക്കുക" "ഏതുസമയത്തും ക്യാമറ ഉപയോഗിച്ചുകൊണ്ട് ചിത്രങ്ങൾ എടുക്കാനും വീഡിയോകൾ റെക്കോർഡുചെയ്യാനും ഈ ആപ്പിന് കഴിയും." - - - - + "ക്യാമറയുള്ള ഉപകരണങ്ങൾ ഓണാക്കുന്നതിനെയോ അടയ്ക്കുന്നതിനെയോ കുറിച്ചുള്ള കോൾബാക്കുകൾ സ്വീകരിക്കാൻ ആപ്പിനെയോ സേവനത്തെയോ അനുവദിക്കുക." + "ക്യാമറയുള്ള ഏതെങ്കിലും ഉപകരണം ഓണാക്കുമ്പോഴോ (ആപ്പ് പാക്കേജ് മുഖേന) അടയ്ക്കുമ്പോഴോ ഈ സിഗ്‌നേച്ചർ ആപ്പിന് കോൾബാക്കുകൾ സ്വീകരിക്കാനാവും." "വൈബ്രേറ്റുചെയ്യൽ നിയന്ത്രിക്കുക" "വൈബ്രേറ്റർ നിയന്ത്രിക്കുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു." "ഫോൺ നമ്പറുകളിലേക്ക് നേരിട്ട് വിളിക്കുക" diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 1cb979e95107..f0fdc6763126 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -434,10 +434,8 @@ "हे अ‍ॅप तुमच्या शारीरिक ॲक्टिव्हिटी ओळखू शकते." "चित्रे आणि व्हिडिओ घ्या" "हा अ‍ॅप कोणत्याही वेळी कॅमेरा वापरून चित्रेे घेऊ आणि व्ह‍िडिओ रेकॉर्ड करू शकतो." - - - - + "एखाद्या अ‍ॅप्लिकेशन किंवा सेवेला कॅमेरा डिव्हाइस सुरू किंवा बंद केल्याची कॉलबॅक मिळवण्याची अनुमती द्या." + "कोणतेही कॅमेरा डिव्हाइस (कोणत्या अ‍ॅप्लिकेशन पॅकेजने) सुरू किंवा बंद केले जाते तेव्हा हे सिग्नेचर ॲप कॉलबॅक मिळवू शकते." "व्हायब्रेट नियंत्रित करा" "अ‍ॅप ला व्हायब्रेटर नियंत्रित करण्यासाठी अनुमती देते." "फोन नंबरवर प्रत्यक्ष कॉल करा" diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index e1dc55f98f40..642ed571774d 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -434,10 +434,8 @@ "यो अनुप्रयोगले तपाईंको शारीरिक गतिविधिको पहिचान गर्न सक्छ।" "तस्बिरहरू र भिडियोहरू लिनुहोस्।" "यस अनुप्रयोगले जुनसुकै समय क्यामेराको प्रयोग गरी तस्बिर खिच्न र भिडियो रेकर्ड गर्न सक्छ।" - - - - + "कुनै अनुप्रयोग वा सेवालाई खोलिँदै वा बन्द गरिँदै गरेका क्यामेरा यन्त्रहरूका बारेमा कलब्याक प्राप्त गर्ने अनुमति दिनुहोस्।" + "कुनै पनि क्यामेरा यन्त्र खोलिँदै गर्दा (जुनसुकै अनुप्रयोगको प्याकेजबाट) वा बन्द गरिँदै गर्दा यो हस्ताक्षरसम्बन्धी अनुप्रयोगले कलब्याक प्राप्त गर्न सक्छ।" "कम्पन नियन्त्रण गर्नुहोस्" "अनुप्रयोगलाई भाइब्रेटर नियन्त्रण गर्न अनुमति दिन्छ।" "फोन नम्बरहरूमा सीधै कल गर्नुहोस्" diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index 9ef8e0ae71fe..bb1eb2b906f0 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -434,10 +434,8 @@ "ଏହି ଆପ୍‍ଣ ଆପଣଙ୍କ ଶାରୀରିକ ଗତିବିଧିକୁ ଚିହ୍ନଟ କରିପାରେ" "ଫଟୋ ଓ ଭିଡିଓଗୁଡ଼ିକୁ ନିଅନ୍ତୁ" "ଏହି ଆପ୍‍ ଯେକୌଣସି ସମୟରେ କ୍ୟାମେରା ବ୍ୟବହାର କରି ଫଟୋ ଉଠାଇପାରେ ଏବଂ ଭିଡିଓ ରେକର୍ଡ କରିପାରେ।" - - - - + "କ୍ୟାମେରା ଡିଭାଇସଗୁଡ଼ିକ ଖୋଲିବା କିମ୍ବା ବନ୍ଦ କରିବା ବିଷୟରେ କଲବ୍ୟାକଗୁଡ଼ିକ ପାଇବାକୁ ଏକ ଆପ୍ଲିକେସନ୍ କିମ୍ବା ସେବାକୁ ଅନୁମତି ଦିଅନ୍ତୁ।" + "ଯେ କୌଣସି କ୍ୟାମେରା ଡିଭାଇସ୍ ଖୋଲାଗଲେ (କେଉଁ ଆପ୍ଲିକେସନ୍ ପ୍ୟାକେଜ୍ ଦ୍ୱାରା) କିମ୍ବା ବନ୍ଦ କରାଗଲେ ଏହି ସିଗନେଚର୍ ଆପ୍ କଲବ୍ୟାକ୍ ପାଇପାରିବ।" "କମ୍ପନ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ" "ଆପ୍‍କୁ, ଭାଇବ୍ରେଟର୍‍ ନିୟନ୍ତ୍ରଣ କରିବାକୁ ଦେଇଥାଏ।" "ସିଧାସଳଖ ଫୋନ୍ ନମ୍ବରଗୁଡ଼ିକୁ କଲ୍ କରନ୍ତୁ" diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index a9e8f1490e1b..773d6a1ad725 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -435,7 +435,7 @@ "tirar fotos e vídeos" "Esta aplicação pode tirar fotos e gravar vídeos através da câmara em qualquer altura." "Permitir que uma app ou um serviço receba chamadas de retorno sobre dispositivos de câmara que estão a ser abertos ou fechados" - "Esta app de assinatura pode receber chamadas de retorno quando qualquer dispositivo de câmara está a ser aberto (e por que pacote de apps) ou fechado." + "Esta app premium pode receber chamadas de retorno quando qualquer dispositivo de câmara está a ser aberto (e por que pacote de apps) ou fechado." "controlar vibração" "Permite à aplicação controlar o vibrador." "marcar números de telefone diretamente" diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 777da6c64175..5f6127d849fe 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -434,10 +434,8 @@ "یہ ایپ آپ کی جسمانی سرگرمی کی شناخت کر سکتی ہے۔" "تصاویر لیں اور ویڈیوز بنائیں" "یہ ایپ کسی بھی وقت کیمرا استعمال کرتے ہوئے تصاویر لے سکتی ہے اور ویڈیوز ریکارڈ کر سکتی ہے۔" - - - - + "ایپلیکیشن یا سروس کو کیمرا کے آلات کے کُھلنے یا بند ہونے سے متعلق کال بیکس موصول کرنے کی اجازت دیں۔" + "یہ دستخط ایپ کال بیکس وصول کر سکتی ہے جب کوئی بھی کیمرہ کا آلہ (کسی ایپلیکیشن پیکیج سے) کھولا جارہا ہو یا بند کیا جا رہا ہو۔" "ارتعاش کو کنٹرول کریں" "ایپ کو وائبریٹر کنٹرول کرنے کی اجازت دیتا ہے۔" "براہ راست فون نمبرز پر کال کریں" -- GitLab From 890ad2785babd2de642a49a04df89e4d8d07947a Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 17 Mar 2020 23:28:22 -0700 Subject: [PATCH 160/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: Ic35d24997df960aaf30a4f5c8aa3913cfda9b621 --- packages/CarrierDefaultApp/res/values-ky/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/CarrierDefaultApp/res/values-ky/strings.xml b/packages/CarrierDefaultApp/res/values-ky/strings.xml index 066e8f6bcbaf..199476f47be0 100644 --- a/packages/CarrierDefaultApp/res/values-ky/strings.xml +++ b/packages/CarrierDefaultApp/res/values-ky/strings.xml @@ -12,6 +12,6 @@ "Мобилдик Интернеттин абалы" "Мобилдик тармакка кирүү" "Кошулайын деген тармагыңызда коопсуздук көйгөйлөрү бар." - "Мисалы, каттоо эсебине кирүү баракчасы көрсөтүлгөн уюмга таандык эмес болушу мүмкүн." + "Мисалы, аккаунтка кирүү баракчасы көрсөтүлгөн уюмга таандык эмес болушу мүмкүн." "Баары бир серепчи аркылуу улантуу" -- GitLab From 659c76607ecfaad8c5425a0c154baa18b3e3e14a Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 18 Mar 2020 00:36:09 -0700 Subject: [PATCH 161/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: I2b501d4865109a88bcdf89f51ed82cb62c54acc3 --- packages/InputDevices/res/values-mk/strings.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/InputDevices/res/values-mk/strings.xml b/packages/InputDevices/res/values-mk/strings.xml index 44069a25202d..220dd67e0df1 100644 --- a/packages/InputDevices/res/values-mk/strings.xml +++ b/packages/InputDevices/res/values-mk/strings.xml @@ -3,12 +3,12 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Влезни уреди" "Тастатура за Android" - "Англиски (О.К.)" - "Англиски (САД)" - "Англиски (САД), меѓународен стил" - "Англиски (САД), Colemak стил" - "Англиски (САД), Dvorak стил" - "Англиски (САД), Workman стил" + "англиски (О.К.)" + "англиски (САД)" + "англиски (САД), меѓународен стил" + "англиски (САД), Colemak стил" + "англиски (САД), Dvorak стил" + "англиски (САД), Workman стил" "Германски" "Француски" "Француски (Канада)" -- GitLab From b9a0760894c6dd450135f3eaafb9b46898e8a8e7 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 18 Mar 2020 00:53:26 -0700 Subject: [PATCH 162/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: I431a9e3f162b573f99dc1329a088dffd9f63f299 --- packages/MtpDocumentsProvider/res/values-ar/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/MtpDocumentsProvider/res/values-ar/strings.xml b/packages/MtpDocumentsProvider/res/values-ar/strings.xml index 9b9546f0e3f0..66adf32ed935 100644 --- a/packages/MtpDocumentsProvider/res/values-ar/strings.xml +++ b/packages/MtpDocumentsProvider/res/values-ar/strings.xml @@ -17,7 +17,7 @@ "‏مضيف بروتوكول نقل الوسائط (MTP)" - "التنزيلات" + "عمليات التنزيل" "%1$s %2$s" "جارٍ الوصول إلى الملفات من %1$s" "الجهاز الآخر مشغول، ولا يمكنك نقل الملفات إلا بعد أن يصبح متاحًا." -- GitLab From fe51ff5cd68640a7da716e50862d01c470da8b80 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 18 Mar 2020 11:08:13 -0700 Subject: [PATCH 163/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: Ib4eae9455e15c5fab4095a0f6eafc69101d3a3f9 --- packages/PackageInstaller/res/values-bs/strings.xml | 2 +- packages/PackageInstaller/res/values-ca/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/PackageInstaller/res/values-bs/strings.xml b/packages/PackageInstaller/res/values-bs/strings.xml index ebf0685fd295..5c11cb61da6d 100644 --- a/packages/PackageInstaller/res/values-bs/strings.xml +++ b/packages/PackageInstaller/res/values-bs/strings.xml @@ -62,7 +62,7 @@ "Tekuća deinstaliranja" "Neuspjela deinstaliranja" "Deinstaliranje..." - "Deinstaliranje paketa %1$s…" + "Deinstaliranje aplikacije %1$s…" "Deinstaliranje je završeno." "Deinstaliran je paket %1$s" "Deinstaliranje nije uspjelo." diff --git a/packages/PackageInstaller/res/values-ca/strings.xml b/packages/PackageInstaller/res/values-ca/strings.xml index 1490d4841272..27cca2b7e7dd 100644 --- a/packages/PackageInstaller/res/values-ca/strings.xml +++ b/packages/PackageInstaller/res/values-ca/strings.xml @@ -57,7 +57,7 @@ "Vols desinstal·lar aquesta aplicació per a ""tots"" els usuaris? L\'aplicació i les seves dades se suprimiran per a ""tots"" els usuaris del dispositiu." "Vols desinstal·lar aquesta aplicació per a l\'usuari %1$s?" "Vols substituir aquesta aplicació per la versió de fàbrica? Se suprimiran totes les dades." - "Vols substituir aquesta aplicació per la versió de fàbrica? Se suprimiran totes les dades. Això afectarà tots els usuaris d\'aquest dispositiu, inclosos els que tinguin un perfil professional." + "Vols substituir aquesta aplicació per la versió de fàbrica? Se suprimiran totes les dades. Això afectarà tots els usuaris d\'aquest dispositiu, inclosos els que tinguin un perfil de treball." "Conserva %1$s de dades de l\'aplicació." "Desinstal·lacions en curs" "Desinstal·lacions fallides" -- GitLab From 0be79a468b6057b414a58296b1de87a0b0b462eb Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 18 Mar 2020 11:25:29 -0700 Subject: [PATCH 164/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: I50e6560be27f782cd404e81225a71a9751afa6cc --- packages/PrintSpooler/res/values-ar/strings.xml | 2 +- packages/PrintSpooler/res/values-fr-rCA/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/PrintSpooler/res/values-ar/strings.xml b/packages/PrintSpooler/res/values-ar/strings.xml index e309383226bf..a21f2b52c57a 100644 --- a/packages/PrintSpooler/res/values-ar/strings.xml +++ b/packages/PrintSpooler/res/values-ar/strings.xml @@ -75,7 +75,7 @@ "تعذرت إضافة طابعات" "اختر لإضافة طابعة" "حدد للتمكين" - "الخدمات الممكنة" + "الخدمات المفعّلة" "الخدمات الموصى بها" "الخدمات غير المفعّلة" "جميع الخدمات" diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml index bf306ff500b8..3b7775a97dde 100644 --- a/packages/PrintSpooler/res/values-fr-rCA/strings.xml +++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml @@ -16,7 +16,7 @@ - "File d\'att. impr." + "File d\'attente d\'impression" "Plus d\'options" "Destination" "Copies" -- GitLab From 452b3d0550d93db3744b5141505b53745290a762 Mon Sep 17 00:00:00 2001 From: Sarah Chin Date: Thu, 26 Sep 2019 11:37:13 -0700 Subject: [PATCH 165/219] 5G Q backport Meteredness (SubscriptionPlan, CarrierConfig) Bandwidth estimates Bug: 151630253 Test: DcTrackerTest, DataConnectionTest, SubscriptionManagerTest Test: manual testing with cmd phone cc set-value that unmetered values result in NET_CAPABILITY_NOT_METERED Test: manual testing with TestServiceState that NR_NSA and NR_NSA_MMWAVE bandwidths are updated when ServiceState changes Change-Id: I718fb1540892bd3630439a06955d82f6c35dcdfc Merged-In: Idb67fb7676adf9e1158113e7b8b08e655f470920 --- .../android/net/INetworkPolicyListener.aidl | 2 + .../android/net/NetworkPolicyManager.java | 2 + core/res/res/values/config.xml | 6 ++ core/res/res/values/symbols.xml | 1 + .../net/NetworkPolicyManagerService.java | 69 +++++++++++++++++ .../telephony/CarrierConfigManager.java | 55 +++++++++++++ .../telephony/SubscriptionManager.java | 4 + .../android/telephony/SubscriptionPlan.java | 77 ++++++++++++++++++- .../internal/telephony/DctConstants.java | 9 +++ 9 files changed, 223 insertions(+), 2 deletions(-) diff --git a/core/java/android/net/INetworkPolicyListener.aidl b/core/java/android/net/INetworkPolicyListener.aidl index 10667aecd128..fe9141cb6a20 100644 --- a/core/java/android/net/INetworkPolicyListener.aidl +++ b/core/java/android/net/INetworkPolicyListener.aidl @@ -15,6 +15,7 @@ */ package android.net; +import android.telephony.SubscriptionPlan; /** {@hide} */ oneway interface INetworkPolicyListener { @@ -23,4 +24,5 @@ oneway interface INetworkPolicyListener { void onRestrictBackgroundChanged(boolean restrictBackground); void onUidPoliciesChanged(int uid, int uidPolicies); void onSubscriptionOverride(int subId, int overrideMask, int overrideValue); + void onSubscriptionPlansChanged(int subId, in SubscriptionPlan[] plans); } diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index bf272625e713..a9f5f7845775 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -31,6 +31,7 @@ import android.net.wifi.WifiInfo; import android.os.Build; import android.os.RemoteException; import android.os.UserHandle; +import android.telephony.SubscriptionPlan; import android.util.DebugUtils; import android.util.Pair; import android.util.Range; @@ -381,5 +382,6 @@ public class NetworkPolicyManager { @Override public void onRestrictBackgroundChanged(boolean restrictBackground) { } @Override public void onUidPoliciesChanged(int uid, int uidPolicies) { } @Override public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue) { } + @Override public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) { } } } diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index d1eef085a506..f005c364ccdd 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2571,6 +2571,12 @@ rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max --> 524288,1048576,2097152,262144,524288,1048576 + + carrier_config + + + + false diff --git a/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt b/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt index 284074e76ae2..3015710e8a98 100644 --- a/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt +++ b/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt @@ -37,20 +37,22 @@ class CameraAvailabilityListener( private val cameraManager: CameraManager, private val cutoutProtectionPath: Path, private val targetCameraId: String, + excludedPackages: String, private val executor: Executor ) { private var cutoutBounds = Rect() + private val excludedPackageIds: Set private val listeners = mutableListOf() private val availabilityCallback: CameraManager.AvailabilityCallback = object : CameraManager.AvailabilityCallback() { - override fun onCameraAvailable(cameraId: String) { + override fun onCameraClosed(cameraId: String) { if (targetCameraId == cameraId) { notifyCameraInactive() } } - override fun onCameraUnavailable(cameraId: String) { - if (targetCameraId == cameraId) { + override fun onCameraOpened(cameraId: String, packageId: String) { + if (targetCameraId == cameraId && !isExcluded(packageId)) { notifyCameraActive() } } @@ -64,6 +66,7 @@ class CameraAvailabilityListener( computed.top.roundToInt(), computed.right.roundToInt(), computed.bottom.roundToInt()) + excludedPackageIds = excludedPackages.split(",").toSet() } /** @@ -87,6 +90,10 @@ class CameraAvailabilityListener( listeners.remove(callback) } + private fun isExcluded(packageId: String): Boolean { + return excludedPackageIds.contains(packageId) + } + private fun registerCameraListener() { cameraManager.registerAvailabilityCallback(executor, availabilityCallback) } @@ -118,9 +125,10 @@ class CameraAvailabilityListener( val res = context.resources val pathString = res.getString(R.string.config_frontBuiltInDisplayCutoutProtection) val cameraId = res.getString(R.string.config_protectedCameraId) + val excluded = res.getString(R.string.config_cameraProtectionExcludedPackages) return CameraAvailabilityListener( - manager, pathFromString(pathString), cameraId, executor) + manager, pathFromString(pathString), cameraId, excluded, executor) } private fun pathFromString(pathString: String): Path { @@ -135,4 +143,4 @@ class CameraAvailabilityListener( return p } } -} \ No newline at end of file +} -- GitLab From 60023559ea0219273e0680a7b559392230172fd6 Mon Sep 17 00:00:00 2001 From: Beverly Tai Date: Thu, 19 Mar 2020 18:28:44 +0000 Subject: [PATCH 168/219] DO NOT MERGE use left/right insets instead of cutout Icons are being cut off when the app letterboxes (b/151868088) Note: icons will be inset even when the app isn't letterboxing. Fixes: 151868088 Change-Id: I870849628a3ff724fd73f36261c87ea23d858f1a --- .../statusbar/phone/PhoneStatusBarView.java | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index c2317bab891e..66b791d6db0a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -360,7 +360,6 @@ public class PhoneStatusBarView extends PanelBar { * Returns a Pair of integers where * - Pair.first is the left margin inset * - Pair.second is the right margin inset - * This method always assumes the cutout is on the top when the device is in portrait mode. */ public static Pair cornerCutoutMargins(DisplayCutout cutout, Display display) { @@ -375,22 +374,13 @@ public class PhoneStatusBarView extends PanelBar { Point size = new Point(); display.getRealSize(size); - Rect bounds = new Rect(); - switch (rotationOrientation) { - case RotationUtils.ROTATION_LANDSCAPE: - boundsFromDirection(cutout, Gravity.LEFT, bounds); - break; - case RotationUtils.ROTATION_SEASCAPE: - boundsFromDirection(cutout, Gravity.RIGHT, bounds); - break; - case RotationUtils.ROTATION_NONE: - boundsFromDirection(cutout, Gravity.TOP, bounds); - break; - case RotationUtils.ROTATION_UPSIDE_DOWN: - // we assume the cutout is always on top in portrait mode - return null; + if (rotationOrientation != RotationUtils.ROTATION_NONE) { + return new Pair<>(cutout.getSafeInsetLeft(), cutout.getSafeInsetRight()); } + Rect bounds = new Rect(); + boundsFromDirection(cutout, Gravity.TOP, bounds); + if (statusBarHeight >= 0 && bounds.top > statusBarHeight) { return null; } -- GitLab From 631860cfe51d9cf66a7f296825c876e43571e455 Mon Sep 17 00:00:00 2001 From: Calin Juravle Date: Thu, 19 Mar 2020 20:15:57 +0000 Subject: [PATCH 169/219] Revert "Revert "resolve merge conflicts of e6dddc99898fe5da4d24e..." Revert "Revert "resolve merge conflicts of ca3425964ae63a69dc1e8..." Revert submission 10741298-revert-10740208-resolve-merge-MKSMZNBBLX Reason for revert: Fixing the merge-conflict Reverted Changes: I3e29ca490:Revert "resolve merge conflicts of e6dddc99898fe5d... Ifdac4bb18:Revert "resolve merge conflicts of ca3425964ae63a6... Change-Id: Ice5147ced5fbb8c9dd4c0ae9e6bb8d3930220224 --- .../server/am/ActivityManagerService.java | 21 ------------------- .../java/com/android/server/pm/Installer.java | 10 --------- 2 files changed, 31 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 0c69e671a300..3f6fb621d1eb 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -360,7 +360,6 @@ import com.android.server.contentcapture.ContentCaptureManagerInternal; import com.android.server.firewall.IntentFirewall; import com.android.server.job.JobSchedulerInternal; import com.android.server.pm.Installer; -import com.android.server.pm.Installer.InstallerException; import com.android.server.uri.GrantUri; import com.android.server.uri.UriGrantsManagerInternal; import com.android.server.utils.PriorityDump; @@ -5240,26 +5239,6 @@ public class ActivityManagerService extends IActivityManager.Stub mCallFinishBooting = false; } - ArraySet completedIsas = new ArraySet(); - for (String abi : Build.SUPPORTED_ABIS) { - ZYGOTE_PROCESS.establishZygoteConnectionForAbi(abi); - final String instructionSet = VMRuntime.getInstructionSet(abi); - if (!completedIsas.contains(instructionSet)) { - try { - mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)); - } catch (InstallerException e) { - if (!VMRuntime.didPruneDalvikCache()) { - // This is technically not the right filter, as different zygotes may - // have made different pruning decisions. But the log is best effort, - // anyways. - Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" + - e.getMessage() +")"); - } - } - completedIsas.add(instructionSet); - } - } - // Let the ART runtime in zygote and system_server know that the boot completed. ZYGOTE_PROCESS.bootCompleted(); VMRuntime.bootCompleted(); diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java index b3b0029326d5..56910ddbbb75 100644 --- a/services/core/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -434,16 +434,6 @@ public class Installer extends SystemService { } } - public void markBootComplete(String instructionSet) throws InstallerException { - assertValidInstructionSet(instructionSet); - if (!checkBeforeRemote()) return; - try { - mInstalld.markBootComplete(instructionSet); - } catch (Exception e) { - throw InstallerException.from(e); - } - } - public void freeCache(String uuid, long targetFreeBytes, long cacheReservedBytes, int flags) throws InstallerException { if (!checkBeforeRemote()) return; -- GitLab From 937136e5212be0d11ee12432ed07d5279d2adb55 Mon Sep 17 00:00:00 2001 From: Sarah Chin Date: Thu, 19 Mar 2020 14:34:20 -0700 Subject: [PATCH 170/219] Fix broken link Test: build Bug: 151971639 Change-Id: Id77387d41cd4d19661dada0755ab2acd09135447 --- telephony/java/android/telephony/SubscriptionManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 2e4fe5581ecf..f9a955e0cfed 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -2426,7 +2426,7 @@ public class SubscriptionManager { * most important plan. Any additional plans are secondary and * may not be displayed or used by decision making logic. * The list of all plans must meet the requirements defined in - * {@link SubscriptionPlan.Builder#setNetworkTypes(int[])}. + * SubscriptionPlan.Builder#setNetworkTypes(int[]). * @throws SecurityException if the caller doesn't meet the requirements * outlined above. * @throws IllegalArgumentException if plans don't meet the requirements -- GitLab From fa3034f2af782ba1ae7a0c5a5fd2a8615d77273b Mon Sep 17 00:00:00 2001 From: Hall Liu Date: Wed, 18 Mar 2020 16:24:04 -0700 Subject: [PATCH 171/219] DO NOT MERGE Institute limit on PhoneStateListener Limit apps to 50 concurrently registered instances of PhoneStateListener via TelephonyManager#listen Test: atest CtsTelephonyTestCases:PhoneStateListenerTest#testListenerLimit Bug: 151835251 Change-Id: I8486d86773a1e28b4018620c48003855dae75b9d --- .../com/android/server/TelephonyRegistry.java | 30 ++++++++++++++++--- .../android/telephony/PhoneStateListener.java | 11 +++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index f7e825eecc12..84c43591dcdd 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -31,6 +31,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; +import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.telephony.CallAttributes; @@ -469,7 +470,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { synchronized (mRecords) { // register IBinder b = callback.asBinder(); - Record r = add(b); + Record r = add(b, Binder.getCallingPid(), false); if (r == null) { return; @@ -522,7 +523,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { synchronized (mRecords) { // register IBinder b = callback.asBinder(); - Record r = add(b); + Record r = add(b, Binder.getCallingPid(), false); if (r == null) { return; @@ -643,7 +644,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { synchronized (mRecords) { // register IBinder b = callback.asBinder(); - Record r = add(b); + boolean shouldEnforceListenerLimit = + Binder.getCallingUid() != Process.SYSTEM_UID + && Binder.getCallingUid() != Process.PHONE_UID + && Binder.getCallingUid() != Process.myUid(); + Record r = add(b, Binder.getCallingPid(), shouldEnforceListenerLimit); if (r == null) { return; @@ -893,18 +898,35 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { return record.canReadCallLog() ? mCallIncomingNumber[phoneId] : ""; } - private Record add(IBinder binder) { + private Record add(IBinder binder, int callingPid, boolean enforceLimit) { Record r; synchronized (mRecords) { final int N = mRecords.size(); + // While iterating through the records, keep track of how many we have from this pid. + int numRecordsForPid = 0; for (int i = 0; i < N; i++) { r = mRecords.get(i); if (binder == r.binder) { // Already existed. return r; } + if (r.callerPid == callingPid) { + numRecordsForPid++; + } + } + // If we've exceeded the limit for registrations, log a warning and quit. + if (enforceLimit && numRecordsForPid >= PhoneStateListener.PER_PID_REGISTRATION_LIMIT) { + String errorMsg = "Pid " + callingPid + " has exceeded the number of permissible" + + "registered listeners. Ignoring request to add."; + loge(errorMsg); + throw new IllegalStateException(errorMsg); + } else if (enforceLimit + && numRecordsForPid >= PhoneStateListener.PER_PID_REGISTRATION_LIMIT / 2) { + Rlog.w(TAG, "Pid " + callingPid + " has exceeded half the number of permissible" + + "registered listeners. Now at " + numRecordsForPid); } + r = new Record(); r.binder = binder; r.deathRecipient = new TelephonyRegistryDeathRecipient(binder); diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index 271195b78c3e..48bf650e2086 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -60,6 +60,17 @@ public class PhoneStateListener { private static final String LOG_TAG = "PhoneStateListener"; private static final boolean DBG = false; // STOPSHIP if true + /** + * Limit on registrations of {@link PhoneStateListener}s on a per-pid + * basis. When this limit is exceeded, any calls to {@link TelephonyManager#listen} will fail + * with an {@link IllegalStateException}. + * + * {@link android.os.Process#PHONE_UID}, {@link android.os.Process#SYSTEM_UID}, and the uid that + * TelephonyRegistry runs under are exempt from this limit. + * @hide + */ + public static final int PER_PID_REGISTRATION_LIMIT = 50; + /** * Stop listening for updates. * -- GitLab From a5ed3c801619f7146a40dcfa13bb55652bfe8387 Mon Sep 17 00:00:00 2001 From: weichinweng Date: Thu, 5 Mar 2020 10:37:44 +0800 Subject: [PATCH 172/219] Fix bluetooth can't turn off during network reset (2/3) Remove disable Bluetooth action from AdapterService and move to BluetoothManagerService. Add factory reset reason into Bluetooth enable/disable reason list. Bug: 110181479 Test: manual Change-Id: I4bff3c3bb75fbb0d1e13c459c0d9d3fd3b8b3195 Merged-In: I4bff3c3bb75fbb0d1e13c459c0d9d3fd3b8b3195 (cherry picked from commit e547073e7530b840765266703857a5b7aa08c6e6) --- .../android/bluetooth/BluetoothAdapter.java | 7 +- core/proto/android/bluetooth/enums.proto | 1 + .../server/BluetoothManagerService.java | 104 ++++++++++++------ 3 files changed, 75 insertions(+), 37 deletions(-) diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 0a9dbb608b9c..80f901bcced3 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -1219,10 +1219,11 @@ public final class BluetoothAdapter { public boolean factoryReset() { try { mServiceLock.readLock().lock(); - if (mService != null) { - return mService.factoryReset(); + if (mService != null && mService.factoryReset() + && mManagerService != null && mManagerService.onFactoryReset()) { + return true; } - Log.e(TAG, "factoryReset(): IBluetooth Service is null"); + Log.e(TAG, "factoryReset(): Setting persist.bluetooth.factoryreset to retry later"); SystemProperties.set("persist.bluetooth.factoryreset", "true"); } catch (RemoteException e) { Log.e(TAG, "", e); diff --git a/core/proto/android/bluetooth/enums.proto b/core/proto/android/bluetooth/enums.proto index b4f3d1ea5ae4..22f249820b11 100644 --- a/core/proto/android/bluetooth/enums.proto +++ b/core/proto/android/bluetooth/enums.proto @@ -40,6 +40,7 @@ enum EnableDisableReasonEnum { ENABLE_DISABLE_REASON_CRASH = 7; ENABLE_DISABLE_REASON_USER_SWITCH = 8; ENABLE_DISABLE_REASON_RESTORE_USER_SETTING = 9; + ENABLE_DISABLE_REASON_FACTORY_RESET = 10; } enum DirectionEnum { diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index fa8eda54e53c..b92f23573a01 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -79,6 +79,7 @@ import java.util.LinkedList; import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -261,6 +262,46 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } }; + public boolean onFactoryReset() { + // Wait for stable state if bluetooth is temporary state. + int state = getState(); + if (state == BluetoothAdapter.STATE_BLE_TURNING_ON + || state == BluetoothAdapter.STATE_TURNING_ON + || state == BluetoothAdapter.STATE_TURNING_OFF) { + if (!waitForState(Set.of(BluetoothAdapter.STATE_BLE_ON, BluetoothAdapter.STATE_ON))) { + return false; + } + } + + // Clear registered LE apps to force shut-off Bluetooth + clearBleApps(); + state = getState(); + try { + mBluetoothLock.readLock().lock(); + if (mBluetooth == null) { + return false; + } + if (state == BluetoothAdapter.STATE_BLE_ON) { + addActiveLog( + BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET, + mContext.getPackageName(), false); + mBluetooth.onBrEdrDown(); + return true; + } else if (state == BluetoothAdapter.STATE_ON) { + addActiveLog( + BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET, + mContext.getPackageName(), false); + mBluetooth.disable(); + return true; + } + } catch (RemoteException e) { + Slog.e(TAG, "Unable to shutdown Bluetooth", e); + } finally { + mBluetoothLock.readLock().unlock(); + } + return false; + } + public void onAirplaneModeChanged() { synchronized (this) { if (isBluetoothPersistedStateOn()) { @@ -1630,7 +1671,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { // the previous Bluetooth process has exited. The // waiting period has three components: // (a) Wait until the local state is STATE_OFF. This - // is accomplished by "waitForOnOff(false, true)". + // is accomplished by + // "waitForState(Set.of(BluetoothAdapter.STATE_OFF))". // (b) Wait until the STATE_OFF state is updated to // all components. // (c) Wait until the Bluetooth process exits, and @@ -1640,7 +1682,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { // message. The delay time is backed off if Bluetooth // continuously failed to turn on itself. // - waitForOnOff(false, true); + waitForState(Set.of(BluetoothAdapter.STATE_OFF)); Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE); mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs()); @@ -1653,10 +1695,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); if (mEnable && mBluetooth != null) { - waitForOnOff(true, false); + waitForState(Set.of(BluetoothAdapter.STATE_ON)); mEnable = false; handleDisable(); - waitForOnOff(false, false); + waitForState(Set.of(BluetoothAdapter.STATE_OFF, + BluetoothAdapter.STATE_TURNING_ON, + BluetoothAdapter.STATE_TURNING_OFF, + BluetoothAdapter.STATE_BLE_TURNING_ON, + BluetoothAdapter.STATE_BLE_ON, + BluetoothAdapter.STATE_BLE_TURNING_OFF)); } else { mEnable = false; handleDisable(); @@ -1779,9 +1826,14 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } if (!mEnable) { - waitForOnOff(true, false); + waitForState(Set.of(BluetoothAdapter.STATE_ON)); handleDisable(); - waitForOnOff(false, false); + waitForState(Set.of(BluetoothAdapter.STATE_OFF, + BluetoothAdapter.STATE_TURNING_ON, + BluetoothAdapter.STATE_TURNING_OFF, + BluetoothAdapter.STATE_BLE_TURNING_ON, + BluetoothAdapter.STATE_BLE_ON, + BluetoothAdapter.STATE_BLE_TURNING_OFF)); } break; } @@ -1813,7 +1865,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { == BluetoothAdapter.STATE_OFF)) { if (mEnable) { Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting."); - waitForOnOff(false, true); + waitForState(Set.of(BluetoothAdapter.STATE_OFF)); Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE); mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs()); @@ -1942,7 +1994,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { mState = BluetoothAdapter.STATE_TURNING_ON; } - waitForOnOff(true, false); + waitForState(Set.of(BluetoothAdapter.STATE_ON)); if (mState == BluetoothAdapter.STATE_TURNING_ON) { bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON); @@ -1957,7 +2009,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON, BluetoothAdapter.STATE_TURNING_OFF); - boolean didDisableTimeout = !waitForOnOff(false, true); + boolean didDisableTimeout = + !waitForState(Set.of(BluetoothAdapter.STATE_OFF)); bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF, BluetoothAdapter.STATE_OFF); @@ -2203,12 +2256,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } } - /** - * if on is true, wait for state become ON - * if off is true, wait for state become OFF - * if both on and off are false, wait for state not ON - */ - private boolean waitForOnOff(boolean on, boolean off) { + private boolean waitForState(Set states) { int i = 0; while (i < 10) { try { @@ -2216,18 +2264,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (mBluetooth == null) { break; } - if (on) { - if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) { - return true; - } - } else if (off) { - if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) { - return true; - } - } else { - if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) { - return true; - } + if (states.contains(mBluetooth.getState())) { + return true; } } catch (RemoteException e) { Slog.e(TAG, "getState()", e); @@ -2235,14 +2273,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } finally { mBluetoothLock.readLock().unlock(); } - if (on || off) { - SystemClock.sleep(300); - } else { - SystemClock.sleep(50); - } + SystemClock.sleep(300); i++; } - Slog.e(TAG, "waitForOnOff time out"); + Slog.e(TAG, "waitForState " + states + " time out"); return false; } @@ -2303,7 +2337,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { mContext.getPackageName(), false); handleDisable(); - waitForOnOff(false, true); + waitForState(Set.of(BluetoothAdapter.STATE_OFF)); sendBluetoothServiceDownCallback(); @@ -2465,6 +2499,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { return "USER_SWITCH"; case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING: return "RESTORE_USER_SETTING"; + case BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET: + return "FACTORY_RESET"; case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED: default: return "UNKNOWN[" + reason + "]"; } -- GitLab From 010524415762c8d2d1e14d2a22e21fcdc6725f65 Mon Sep 17 00:00:00 2001 From: Chris Tate Date: Fri, 20 Mar 2020 18:12:28 +0000 Subject: [PATCH 173/219] Revert "Revoke 'always' web handler status when not autoverifying" This reverts commit d2a71cc4b8f11688f85f33507b75d00041c14852. Reason for revert: Inadvertently broke link handling stickiness even for well behaved apps Bug: 146204120 Test: install app that handles web urls; set to 'always' in Settings; install same apk again. Verify that app is still in 'always' state via 'adb shell dumpsys package d' Merged-In: If9046cb420961b8ef0333e9f1115eb69fb92242e Change-Id: I36d9c352e741e88b9fc773b084bef3991b6d96ed --- .../server/pm/PackageManagerService.java | 44 +++++-------------- .../java/com/android/server/pm/Settings.java | 1 - 2 files changed, 11 insertions(+), 34 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 9afaae11b39a..04cebb309216 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -18094,48 +18094,36 @@ public class PackageManagerService extends IPackageManager.Stub int count = 0; final String packageName = pkg.packageName; - boolean handlesWebUris = false; - final boolean alreadyVerified; synchronized (mPackages) { // If this is a new install and we see that we've already run verification for this // package, we have nothing to do: it means the state was restored from backup. - final IntentFilterVerificationInfo ivi = - mSettings.getIntentFilterVerificationLPr(packageName); - alreadyVerified = (ivi != null); - if (!replacing && alreadyVerified) { - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.i(TAG, "Package " + packageName + " already verified: status=" - + ivi.getStatusString()); + if (!replacing) { + IntentFilterVerificationInfo ivi = + mSettings.getIntentFilterVerificationLPr(packageName); + if (ivi != null) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Package " + packageName+ " already verified: status=" + + ivi.getStatusString()); + } + return; } - return; } - // If any filters need to be verified, then all need to be. In addition, we need to - // know whether an updating app has any web navigation intent filters, to re- - // examine handling policy even if not re-verifying. + // If any filters need to be verified, then all need to be. boolean needToVerify = false; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { - if (filter.handlesWebUris(true)) { - handlesWebUris = true; - } if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) { Slog.d(TAG, "Intent filter needs verification, so processing all filters"); } needToVerify = true; - // It's safe to break out here because filter.needsVerification() - // can only be true if filter.handlesWebUris(true) returns true, so - // we've already noted that. break; } } } - // Note whether this app publishes any web navigation handling support at all, - // and whether there are any web-nav filters that fit the profile for running - // a verification pass now. if (needToVerify) { final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { @@ -18153,23 +18141,13 @@ public class PackageManagerService extends IPackageManager.Stub } if (count > 0) { - // count > 0 means that we're running a full verification pass if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count + " IntentFilter verification" + (count > 1 ? "s" : "") + " for userId:" + userId); mIntentFilterVerifier.startVerifications(userId); - } else if (alreadyVerified && handlesWebUris) { - // App used autoVerify in the past, no longer does, but still handles web - // navigation starts. - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy"); - } - synchronized (mPackages) { - clearIntentFilterVerificationsLPw(packageName, userId); - } } else { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "No web filters or no prior verify policy for " + packageName); + Slog.d(TAG, "No filters or not all autoVerify for " + packageName); } } } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 169f8cb91e80..d9e4db29de07 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1252,7 +1252,6 @@ public final class Settings { return false; } ps.clearDomainVerificationStatusForUser(userId); - ps.setIntentFilterVerificationInfo(null); return true; } -- GitLab From d27fa8138ba4fa2ba0d4718c4f6adb7455888692 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 20 Mar 2020 14:33:55 -0700 Subject: [PATCH 174/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: Iec8c0d153e95358528f7fe1b2141e739d8277391 --- packages/PackageInstaller/res/values-eu/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml index dbcb2bb431f2..9c23097b7f23 100644 --- a/packages/PackageInstaller/res/values-eu/strings.xml +++ b/packages/PackageInstaller/res/values-eu/strings.xml @@ -83,9 +83,9 @@ "Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak tableta honetan." "Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telebista honetan." "Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telefono honetan." - "Telefonoak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zu zarela hura erabiltzeagatik telefonoak jasan ditzakeen kalteen edo datu-galeren erantzulea." - "Tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zu zarela hura erabiltzeagatik tabletak jasan ditzakeen kalteen edo datu-galeren erantzulea." - "Telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zu zarela hura erabiltzeagatik telebistak jasan ditzakeen kalteen edo datu-galeren erantzulea." + "Telefonoak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telefonoak jasan ditzakeen kalteen edo datu-galeren erantzulea." + "Tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik tabletak jasan ditzakeen kalteen edo datu-galeren erantzulea." + "Telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telebistak jasan ditzakeen kalteen edo datu-galeren erantzulea." "Egin aurrera" "Ezarpenak" "Wear aplikazioak instalatzea/desinstalatzea" -- GitLab From ab9efea9359bea1533b12daa37186f0ec39a3e94 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Thu, 19 Mar 2020 11:59:25 -0700 Subject: [PATCH 175/219] Disable deep press when long press is long If long press timeout is not 'short', we disable deep press. Also InputManagerService.java will now be responsible for keeping track of the feature state. In ViewConfiguration, we update the default value to 400 to match the value in the settings (b/30159825) Bug: 148311342 Bug: 30159825 Test: see the description in the frameworks/native change Change-Id: I88b933e9e863d40e383afdc990e09b848e23192e Merged-In: I88b933e9e863d40e383afdc990e09b848e23192e --- core/java/android/view/ViewConfiguration.java | 3 +- .../server/input/InputManagerService.java | 42 +++++++++++++++++-- ...droid_server_input_InputManagerService.cpp | 15 +++++++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index 9e914d4e7d41..d83bbf6d6abd 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -64,8 +64,9 @@ public class ViewConfiguration { /** * Defines the default duration in milliseconds before a press turns into * a long press + * @hide */ - private static final int DEFAULT_LONG_PRESS_TIMEOUT = 500; + public static final int DEFAULT_LONG_PRESS_TIMEOUT = 400; /** * Defines the default duration in milliseconds between the first tap's up event and the second diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 8fbad4c5910b..86e54f5f7572 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -59,6 +59,7 @@ import android.os.MessageQueue; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; +import android.provider.DeviceConfig; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.text.TextUtils; @@ -126,6 +127,9 @@ public class InputManagerService extends IInputManager.Stub private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml"; private static final String PORT_ASSOCIATIONS_PATH = "etc/input-port-associations.xml"; + // Feature flag name for the deep press feature + private static final String DEEP_PRESS_ENABLED = "deep_press_enabled"; + private static final int MSG_DELIVER_INPUT_DEVICES_CHANGED = 1; private static final int MSG_SWITCH_KEYBOARD_LAYOUT = 2; private static final int MSG_RELOAD_KEYBOARD_LAYOUTS = 3; @@ -241,6 +245,7 @@ public class InputManagerService extends IInputManager.Stub private static native void nativeSetCustomPointerIcon(long ptr, PointerIcon icon); private static native void nativeSetPointerCapture(long ptr, boolean detached); private static native boolean nativeCanDispatchToDisplay(long ptr, int deviceId, int displayId); + private static native void nativeSetMotionClassifierEnabled(long ptr, boolean enabled); // Input event injection constants defined in InputDispatcher.h. private static final int INPUT_EVENT_INJECTION_SUCCEEDED = 0; @@ -346,6 +351,7 @@ public class InputManagerService extends IInputManager.Stub registerPointerSpeedSettingObserver(); registerShowTouchesSettingObserver(); registerAccessibilityLargePointerSettingObserver(); + registerLongPressTimeoutObserver(); mContext.registerReceiver(new BroadcastReceiver() { @Override @@ -353,12 +359,14 @@ public class InputManagerService extends IInputManager.Stub updatePointerSpeedFromSettings(); updateShowTouchesFromSettings(); updateAccessibilityLargePointerFromSettings(); + updateDeepPressStatusFromSettings("user switched"); } }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler); updatePointerSpeedFromSettings(); updateShowTouchesFromSettings(); updateAccessibilityLargePointerFromSettings(); + updateDeepPressStatusFromSettings("just booted"); } // TODO(BT) Pass in parameter for bluetooth system @@ -1572,7 +1580,7 @@ public class InputManagerService extends IInputManager.Stub setPointerSpeedUnchecked(speed); } - public void updatePointerSpeedFromSettings() { + private void updatePointerSpeedFromSettings() { int speed = getPointerSpeedSetting(); setPointerSpeedUnchecked(speed); } @@ -1604,7 +1612,7 @@ public class InputManagerService extends IInputManager.Stub return speed; } - public void updateShowTouchesFromSettings() { + private void updateShowTouchesFromSettings() { int setting = getShowTouchesSetting(0); nativeSetShowTouches(mPtr, setting != 0); } @@ -1620,7 +1628,7 @@ public class InputManagerService extends IInputManager.Stub }, UserHandle.USER_ALL); } - public void updateAccessibilityLargePointerFromSettings() { + private void updateAccessibilityLargePointerFromSettings() { final int accessibilityConfig = Settings.Secure.getIntForUser( mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 0, UserHandle.USER_CURRENT); @@ -1639,6 +1647,34 @@ public class InputManagerService extends IInputManager.Stub }, UserHandle.USER_ALL); } + private void updateDeepPressStatusFromSettings(String reason) { + // Not using ViewConfiguration.getLongPressTimeout here because it may return a stale value + final int timeout = Settings.Secure.getIntForUser(mContext.getContentResolver(), + Settings.Secure.LONG_PRESS_TIMEOUT, ViewConfiguration.DEFAULT_LONG_PRESS_TIMEOUT, + UserHandle.USER_CURRENT); + final boolean featureEnabledFlag = + DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT, + DEEP_PRESS_ENABLED, true /* default */); + final boolean enabled = + featureEnabledFlag && timeout <= ViewConfiguration.DEFAULT_LONG_PRESS_TIMEOUT; + Log.i(TAG, + (enabled ? "Enabling" : "Disabling") + " motion classifier because " + reason + + ": feature " + (featureEnabledFlag ? "enabled" : "disabled") + + ", long press timeout = " + timeout); + nativeSetMotionClassifierEnabled(mPtr, enabled); + } + + private void registerLongPressTimeoutObserver() { + mContext.getContentResolver().registerContentObserver( + Settings.Secure.getUriFor(Settings.Secure.LONG_PRESS_TIMEOUT), true, + new ContentObserver(mHandler) { + @Override + public void onChange(boolean selfChange) { + updateDeepPressStatusFromSettings("timeout changed"); + } + }, UserHandle.USER_ALL); + } + private int getShowTouchesSetting(int defaultValue) { int result = defaultValue; try { diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index d331d1f58b2d..b3f24b8d5b9c 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -227,6 +227,7 @@ public: void reloadPointerIcons(); void setCustomPointerIcon(const SpriteIcon& icon); void setPointerCapture(bool enabled); + void setMotionClassifierEnabled(bool enabled); /* --- InputReaderPolicyInterface implementation --- */ @@ -1312,6 +1313,10 @@ int32_t NativeInputManager::getCustomPointerIconId() { return POINTER_ICON_STYLE_CUSTOM; } +void NativeInputManager::setMotionClassifierEnabled(bool enabled) { + mInputManager->setMotionClassifierEnabled(enabled); +} + // ---------------------------------------------------------------------------- static jlong nativeInit(JNIEnv* env, jclass /* clazz */, @@ -1744,6 +1749,14 @@ static jboolean nativeCanDispatchToDisplay(JNIEnv* env, jclass /* clazz */, jlon return im->getInputManager()->getReader()->canDispatchToDisplay(deviceId, displayId); } +static void nativeSetMotionClassifierEnabled(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, + jboolean enabled) { + NativeInputManager* im = reinterpret_cast(ptr); + + im->setMotionClassifierEnabled(enabled); +} + + // ---------------------------------------------------------------------------- static const JNINativeMethod gInputManagerMethods[] = { @@ -1827,6 +1840,8 @@ static const JNINativeMethod gInputManagerMethods[] = { (void*) nativeSetCustomPointerIcon }, { "nativeCanDispatchToDisplay", "(JII)Z", (void*) nativeCanDispatchToDisplay }, + {"nativeSetMotionClassifierEnabled", "(JZ)V", + (void*) nativeSetMotionClassifierEnabled}, }; #define FIND_CLASS(var, className) \ -- GitLab From 7c64b0da0dca60f73f7827bc68ca250ebea7a297 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 23 Mar 2020 00:44:11 -0700 Subject: [PATCH 176/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: I9243db0d0090c7d2da373cc97b7b820cf23e5a7f --- packages/SettingsLib/res/values-or/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index 3a897966544e..ce0eb4bc0395 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -412,7 +412,7 @@ "ଚାର୍ଜ ସମ୍ପୂର୍ଣ୍ଣ" "ଆଡ୍‌ମିନ୍‌ ଦ୍ୱାରା ନିୟନ୍ତ୍ରିତ" "ଅକ୍ଷମ ହୋଇଛି" - "ଅନୁମୋଦିତ" + "ଅନୁମତି ଦିଆଯାଇଛି" "ଅନୁମତି ନାହିଁ" "ଅଜଣା ଆପ୍‌ ଇନଷ୍ଟଲ୍‌ କରନ୍ତୁ" "ସେଟିଙ୍ଗ ହୋମ୍‌" -- GitLab From 7f0136aac9fc6593c8a057c5e650293075335ebb Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Sat, 25 Jan 2020 06:54:06 -0800 Subject: [PATCH 177/219] Notify all packages is uid-mode is changed Multiple packages might share a UID, but appOpsService might not have cached the uid->package mapping for those yet. Hence the only way to list all packages for a uid is to ask package manager. setUidMode already handled this correctly, hence factor out the code into notifyOpChangedForAllPkgsInUid and reuse it from commitUidStatePendingLocked. Bug: 148180766 Test: (on master) atest CtsAppOpsTestCases:android.app.appops.cts.ForegroundModeTest Change-Id: I99a8f255a60d3523da7eb36a8f2c9426af1a1fea Merged-In: I2d5d6c7aa38d201707349a137c9c29b7987775be (cherry picked from commit 29e092bf290bacb980a47da22f722c1542197565) --- .../android/server/appop/AppOpsService.java | 54 +++++++++++++------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index f0fac67f3494..8529838857e4 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -31,6 +31,7 @@ import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE_LOCATION; import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED; import static android.app.AppOpsManager.UID_STATE_PERSISTENT; import static android.app.AppOpsManager.UID_STATE_TOP; +import static android.app.AppOpsManager.WATCH_FOREGROUND_CHANGES; import static android.app.AppOpsManager.modeToName; import static android.app.AppOpsManager.opToName; import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState; @@ -1285,6 +1286,18 @@ public class AppOpsService extends IAppOpsService.Stub { uidState.evalForegroundOps(mOpModeWatchers); } + notifyOpChangedForAllPkgsInUid(code, uid, false); + notifyOpChangedSync(code, uid, null, mode); + } + + /** + * Notify that an op changed for all packages in an uid. + * + * @param code The op that changed + * @param uid The uid the op was changed for + * @param onlyForeground Only notify watchers that watch for foreground changes + */ + private void notifyOpChangedForAllPkgsInUid(int code, int uid, boolean onlyForeground) { String[] uidPackageNames = getPackagesForUid(uid); ArrayMap> callbackSpecs = null; @@ -1294,6 +1307,10 @@ public class AppOpsService extends IAppOpsService.Stub { final int callbackCount = callbacks.size(); for (int i = 0; i < callbackCount; i++) { ModeCallback callback = callbacks.valueAt(i); + if (onlyForeground && (callback.mFlags & WATCH_FOREGROUND_CHANGES) == 0) { + continue; + } + ArraySet changedPackages = new ArraySet<>(); Collections.addAll(changedPackages, uidPackageNames); if (callbackSpecs == null) { @@ -1312,6 +1329,10 @@ public class AppOpsService extends IAppOpsService.Stub { final int callbackCount = callbacks.size(); for (int i = 0; i < callbackCount; i++) { ModeCallback callback = callbacks.valueAt(i); + if (onlyForeground && (callback.mFlags & WATCH_FOREGROUND_CHANGES) == 0) { + continue; + } + ArraySet changedPackages = callbackSpecs.get(callback); if (changedPackages == null) { changedPackages = new ArraySet<>(); @@ -1324,7 +1345,6 @@ public class AppOpsService extends IAppOpsService.Stub { } if (callbackSpecs == null) { - notifyOpChangedSync(code, uid, null, mode); return; } @@ -1346,8 +1366,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } } - - notifyOpChangedSync(code, uid, null, mode); } private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode) { @@ -2471,24 +2489,28 @@ public class AppOpsService extends IAppOpsService.Stub { if (resolvedLastFg == resolvedNowFg) { continue; } - final ArraySet callbacks = mOpModeWatchers.get(code); - if (callbacks != null) { - for (int cbi = callbacks.size() - 1; cbi >= 0; cbi--) { - final ModeCallback callback = callbacks.valueAt(cbi); - if ((callback.mFlags & AppOpsManager.WATCH_FOREGROUND_CHANGES) == 0 - || !callback.isWatchingUid(uidState.uid)) { - continue; - } - boolean doAllPackages = uidState.opModes != null - && uidState.opModes.indexOfKey(code) >= 0 - && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND; - if (uidState.pkgOps != null) { + + if (uidState.opModes != null + && uidState.opModes.indexOfKey(code) >= 0 + && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND) { + mHandler.sendMessage(PooledLambda.obtainMessage( + AppOpsService::notifyOpChangedForAllPkgsInUid, + this, code, uidState.uid, true)); + } else { + final ArraySet callbacks = mOpModeWatchers.get(code); + if (callbacks != null) { + for (int cbi = callbacks.size() - 1; cbi >= 0; cbi--) { + final ModeCallback callback = callbacks.valueAt(cbi); + if ((callback.mFlags & AppOpsManager.WATCH_FOREGROUND_CHANGES) == 0 + || !callback.isWatchingUid(uidState.uid)) { + continue; + } for (int pkgi = uidState.pkgOps.size() - 1; pkgi >= 0; pkgi--) { final Op op = uidState.pkgOps.valueAt(pkgi).get(code); if (op == null) { continue; } - if (doAllPackages || op.mode == AppOpsManager.MODE_FOREGROUND) { + if (op.mode == AppOpsManager.MODE_FOREGROUND) { mHandler.sendMessage(PooledLambda.obtainMessage( AppOpsService::notifyOpChanged, this, callback, code, uidState.uid, -- GitLab From 40473c4632a5e5803280058dfd29c3db7f13c406 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Sat, 25 Jan 2020 06:57:04 -0800 Subject: [PATCH 178/219] Force update uid state when pending uid state is applied Before the state was update lazily when someone interacted with appopsmanager. Since Q the the uid state might change depending on the procState and hence we might need to trigger the opChanged callbacks when the procState is applied. Bug: 148180766 Test: (on master) atest CtsAppOpsTestCases:android.app.appops.cts.ForegroundModeTest Change-Id: I99720a372db6e79eaba30e4563c09e009cffe86f Merged-In: Id974769a4e9d89c01890b7557dd93f8444a3908f (cherry picked from commit ab9be4fdb63bf30831fd2e05be1315e6c7f067ae) --- .../android/server/appop/AppOpsService.java | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index f0fac67f3494..4e4fff969c7b 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -35,6 +35,8 @@ import static android.app.AppOpsManager.modeToName; import static android.app.AppOpsManager.opToName; import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState; +import static java.lang.Long.max; + import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; @@ -929,6 +931,19 @@ public class AppOpsService extends IAppOpsService.Stub { } } + /** + * Update the pending state for the uid + * + * @param currentTime The current elapsed real time + * @param uid The uid that has a pending state + */ + private void updatePendingState(long currentTime, int uid) { + synchronized (this) { + mLastRealtime = max(currentTime, mLastRealtime); + updatePendingStateIfNeededLocked(mUidStates.get(uid)); + } + } + public void updateUidProcState(int uid, int procState) { synchronized (this) { final UidState uidState = getUidStateLocked(uid, true); @@ -954,7 +969,12 @@ public class AppOpsService extends IAppOpsService.Stub { } else { settleTime = mConstants.BG_STATE_SETTLE_TIME; } - uidState.pendingStateCommitTime = SystemClock.elapsedRealtime() + settleTime; + final long commitTime = SystemClock.elapsedRealtime() + settleTime; + uidState.pendingStateCommitTime = commitTime; + + mHandler.sendMessageDelayed( + PooledLambda.obtainMessage(AppOpsService::updatePendingState, this, + commitTime + 1, uid), settleTime + 1); } if (uidState.startNesting != 0) { // There is some actively running operation... need to find it @@ -2442,6 +2462,18 @@ public class AppOpsService extends IAppOpsService.Stub { uidState = new UidState(uid); mUidStates.put(uid, uidState); } else { + updatePendingStateIfNeededLocked(uidState); + } + return uidState; + } + + /** + * Check if the pending state should be updated and do so if needed + * + * @param uidState The uidState that might have a pending state + */ + private void updatePendingStateIfNeededLocked(@NonNull UidState uidState) { + if (uidState != null) { if (uidState.pendingStateCommitTime != 0) { if (uidState.pendingStateCommitTime < mLastRealtime) { commitUidPendingStateLocked(uidState); @@ -2453,7 +2485,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } } - return uidState; } private void commitUidPendingStateLocked(UidState uidState) { -- GitLab From a1905e9153c552cceeb38ac8afa6fc4297765c1d Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 23 Mar 2020 14:09:59 -0700 Subject: [PATCH 179/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: I8521dc885039e601be78d95fe8a3926194170cef --- core/res/res/values-af/strings.xml | 5 +++-- core/res/res/values-am/strings.xml | 5 +++-- core/res/res/values-ar/strings.xml | 7 ++++--- core/res/res/values-as/strings.xml | 6 ++++-- core/res/res/values-az/strings.xml | 5 +++-- core/res/res/values-b+sr+Latn/strings.xml | 7 ++++--- core/res/res/values-be/strings.xml | 5 +++-- core/res/res/values-bg/strings.xml | 5 +++-- core/res/res/values-bn/strings.xml | 4 ++-- core/res/res/values-bs/strings.xml | 5 +++-- core/res/res/values-ca/strings.xml | 5 +++-- core/res/res/values-cs/strings.xml | 5 +++-- core/res/res/values-da/strings.xml | 5 +++-- core/res/res/values-de/strings.xml | 5 +++-- core/res/res/values-el/strings.xml | 5 +++-- core/res/res/values-en-rAU/strings.xml | 4 ++-- core/res/res/values-en-rCA/strings.xml | 4 ++-- core/res/res/values-en-rGB/strings.xml | 4 ++-- core/res/res/values-en-rIN/strings.xml | 4 ++-- core/res/res/values-en-rXC/strings.xml | 4 ++-- core/res/res/values-es-rUS/strings.xml | 4 ++-- core/res/res/values-es/strings.xml | 9 +++++---- core/res/res/values-et/strings.xml | 5 +++-- core/res/res/values-eu/strings.xml | 24 ++++++++++++----------- core/res/res/values-fa/strings.xml | 5 +++-- core/res/res/values-fi/strings.xml | 5 +++-- core/res/res/values-fr-rCA/strings.xml | 5 +++-- core/res/res/values-fr/strings.xml | 5 +++-- core/res/res/values-gl/strings.xml | 7 ++++--- core/res/res/values-gu/strings.xml | 4 ++-- core/res/res/values-hi/strings.xml | 4 ++-- core/res/res/values-hr/strings.xml | 5 +++-- core/res/res/values-hu/strings.xml | 5 +++-- core/res/res/values-hy/strings.xml | 5 +++-- core/res/res/values-in/strings.xml | 5 +++-- core/res/res/values-is/strings.xml | 5 +++-- core/res/res/values-it/strings.xml | 5 +++-- core/res/res/values-iw/strings.xml | 5 +++-- core/res/res/values-ja/strings.xml | 5 +++-- core/res/res/values-ka/strings.xml | 5 +++-- core/res/res/values-kk/strings.xml | 5 +++-- core/res/res/values-km/strings.xml | 5 +++-- core/res/res/values-kn/strings.xml | 5 +++-- core/res/res/values-ko/strings.xml | 5 +++-- core/res/res/values-ky/strings.xml | 5 +++-- core/res/res/values-lo/strings.xml | 5 +++-- core/res/res/values-lt/strings.xml | 5 +++-- core/res/res/values-lv/strings.xml | 5 +++-- core/res/res/values-mk/strings.xml | 5 +++-- core/res/res/values-ml/strings.xml | 4 ++-- core/res/res/values-mn/strings.xml | 4 ++-- core/res/res/values-mr/strings.xml | 5 +++-- core/res/res/values-ms/strings.xml | 5 +++-- core/res/res/values-my/strings.xml | 4 ++-- core/res/res/values-nb/strings.xml | 5 +++-- core/res/res/values-ne/strings.xml | 5 +++-- core/res/res/values-nl/strings.xml | 5 +++-- core/res/res/values-or/strings.xml | 11 ++++++----- core/res/res/values-pa/strings.xml | 4 ++-- core/res/res/values-pl/strings.xml | 4 ++-- core/res/res/values-pt-rBR/strings.xml | 4 ++-- core/res/res/values-pt-rPT/strings.xml | 5 +++-- core/res/res/values-pt/strings.xml | 4 ++-- core/res/res/values-ro/strings.xml | 5 +++-- core/res/res/values-ru/strings.xml | 5 +++-- core/res/res/values-si/strings.xml | 4 ++-- core/res/res/values-sk/strings.xml | 4 ++-- core/res/res/values-sl/strings.xml | 5 +++-- core/res/res/values-sq/strings.xml | 4 ++-- core/res/res/values-sr/strings.xml | 7 ++++--- core/res/res/values-sv/strings.xml | 5 +++-- core/res/res/values-sw/strings.xml | 7 ++++--- core/res/res/values-ta/strings.xml | 5 +++-- core/res/res/values-te/strings.xml | 7 ++++--- core/res/res/values-th/strings.xml | 5 +++-- core/res/res/values-tl/strings.xml | 6 ++++-- core/res/res/values-tr/strings.xml | 5 +++-- core/res/res/values-uk/strings.xml | 7 ++++--- core/res/res/values-ur/strings.xml | 4 ++-- core/res/res/values-uz/strings.xml | 4 ++-- core/res/res/values-vi/strings.xml | 5 +++-- core/res/res/values-zh-rCN/strings.xml | 5 +++-- core/res/res/values-zh-rHK/strings.xml | 5 +++-- core/res/res/values-zh-rTW/strings.xml | 5 +++-- core/res/res/values-zu/strings.xml | 5 +++-- 85 files changed, 258 insertions(+), 191 deletions(-) diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 807fe648a2d5..cbc76f4260e5 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -435,7 +435,8 @@ "neem foto\'s en video\'s" "Hierdie program kan enige tyd met die kamera foto\'s neem en video\'s opneem." "Laat \'n program of diens toe om terugbeloproepe te ontvang oor kameratoestelle wat oopgemaak of toegemaak word." - "Hierdie handtekeningprogram kan terugbeloproepe ontvang wanneer enige kameratoestel oopgemaak (deur watter programpakket) of toegemaak word." + + "beheer vibrasie" "Laat die program toe om die vibrator te beheer." "skakel foonnommers direk" @@ -1247,7 +1248,7 @@ "Kan nie aan %1$s koppel nie" "Tik om privaatheidinstellings te verander en herprobeer" "Verander privaatheidinstelling?" - "%1$s salk dalk wil koppel met jou toestel se MAC-adres, \'n unieke identifiseerder. Dit kan dit vir toestelle in die omtrek moontlik maak om jou toestel se ligging na te spoor. \n\nAs jy voortgaan, sal %1$s jou privaatheidinstelling verander en weer probeer koppel." + "%1$s moet jou toestel se MAC-adres, \'n unieke identifiseerder, gebruik om te koppel. Jou privaatheidinstelling vir hierdie netwerk gebruik tans \'n verewekansigde identifiseerder. \n\nHierdie verandering kan dit vir toestelle in die omtrek moontlik maak om jou toestel se ligging na te spoor." "Verander instelling" "Instelling is opgedateer. Probeer weer koppel." "Kan nie privaatheidinstelling verander nie" diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index a7102271e4f8..bbd2ca68d46e 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -435,7 +435,8 @@ "ፎቶዎች እና ቪዲዮዎች ያንሱ" "ይህ መተግበሪያ በማናቸውም ጊዜ ካሜራውን በመጠቀም ፎቶ ሊያነሳ እና ቪዲዮዎችን ሊቀርጽ ይችላል።" "አንድ መተግበሪያ ወይም አገልግሎት እየተከፈቱ ወይም እየተዘጉ ስላሉ የካሜራ መሣሪያዎች መልሶ ጥሪዎችን እንዲቀበል ይፍቀዱ።" - "ማንኛውም የካሜራ መሣሪያ እየተከፈተ (በምን የመተግበሪያ ጥቅል) ወይም እየተዘጋ ሲሆን ይህ የፊርማ መተግበሪያ መልሶ ጥሪዎችን መቀበል ይችላል።" + + "ነዛሪ ተቆጣጠር" "ነዛሪውን ለመቆጣጠር ለመተግበሪያው ይፈቅዳሉ።" "በቀጥታ ስልክ ቁጥሮች ደውል" @@ -1247,7 +1248,7 @@ "ከ%1$s ጋር መገናኘት አልተቻለም" "የግላዊነት ቅንብሮችን ለመቀየር መታ ያድርጉ እና ዳግም ይሞክሩ" "የግላዊነት ቅንብር ይቀየር?" - "%1$s ልዩ ለዪ ከሆነው የመሣሪያዎ ማክ አድራሻ ጋር መገናኘት ሊፈልግ ይችላል። ይህ የመሣሪያዎ አካባቢ አቅራቢያ ባሉ መሣሪያዎች ክትትል እንዲደረግበት ሊያደርገው ይችላል። \n\nከቀጠሉ %1$s የግላዊነት ቅንብርዎን ይቀይረውና እንደገና ለመገናኘት ሊሞክር ይችላል።" + "ለማገናኘት %1$s ልዩ ለዪ የሆነው የመሣሪያዎን ማክ አድራሻ መጠቀም አለበት። በአሁኑ ጊዜ የዚህ አውታረ መረብ የግላዊነት ቅንብርዎ የዘፈቀደ ለዪን ነው የሚጠቀመው። \n\nይህ የመሣሪያዎ አካባቢ አቅራቢያ ባሉ መሣሪያዎች ክትትል እንዲደረግበት ሊያደርገው ይችላል።" "ቅንብሮችን ለውጥ" "ቅንብር ተዘምኗል። እንደገና ለማገናኘት ይሞክሩ።" "የግላዊነት ቅንብርን መለወጥ አይቻልም" diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index e78b9f46f304..5caaf1bfab7f 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -315,7 +315,7 @@ "‏هل تريد السماح للتطبيق <b>%1$s</b> بالوصول إلى بيانات نشاطك البدني؟" "الكاميرا" "التقاط صور وتسجيل فيديو" - "‏هل تريد السماح لخدمة <b>%1$s</b> بالتقاط صور وتسجيل فيديو؟" + "‏هل تريد السماح لتطبيق <b>%1$s</b> بالتقاط صور وتسجيل فيديو؟" "سجلّ المكالمات" "قراءة سجلّ المكالمات الهاتفية والكتابة إليه" "‏هل تريد السماح لتطبيق <b>%1$s</b> بالوصول إلى سجلّ مكالماتك الهاتفية؟" @@ -447,7 +447,8 @@ "التقاط صور وفيديوهات" "يمكن لهذا التطبيق التقاط صور وتسجيل فيديوهات باستخدام الكاميرا في أي وقت." "يسمح الإذن لتطبيق أو خدمة بتلقّي استدعاءات عما إذا كانت أجهزة الكاميرات مفتوحة أو مغلقة." - "يمكن أن يتلقّى تطبيق التوقيع هذا استدعاءات عندما يكون جهاز أي كاميرا مفتوحًا (بحزمة تطبيق) أو مغلقًا." + + "التحكم في الاهتزاز" "للسماح للتطبيق بالتحكم في الهزّاز." "اتصال مباشر بأرقام الهواتف" @@ -1327,7 +1328,7 @@ "لا يمكن الاتصال بـ %1$s." "انقر لتغيير إعدادات الخصوصية وإعادة المحاولة." "هل تريد تغيير إعداد الخصوصية؟" - "‏قد يحتاج %1$s إلى الاتصال باستخدام عنوان MAC الخاص بجهازك ومعرّف فريد. وقد يسمح هذا الإجراء للأجهزة القريبة بتتبع الموقع الجغرافي لجهازك. \n\nفي حال مواصلة تنفيذ هذا الإجراء، سيغيّر %1$s إعداد الخصوصية ويحاول إعادة الاتصال." + "‏للاتصال، تحتاج خدمة %1$s إلى استخدام عنوان MAC الخاص بجهازك وهو معرّف فريد. يستخدم إعداد الخصوصية لهذه الشبكة حاليًا معرّفًا عشوائيًا. \n\nقد يسمح هذا التغيير للأجهزة القريبة بتتبع الموقع الجغرافي لجهازك." "تغيير الإعداد" "تم تعديل الإعداد. حاوِل إعادة الاتصال." "لا يمكن تغيير إعداد الخصوصية." diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 81bdd46d7447..a25fd3dfdf44 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -435,7 +435,8 @@ "ফট\' তোলা আৰু ভিডিঅ\' ৰেকৰ্ড কৰা" "এই এপে যিকোনো সময়তে কেমেৰা ব্যৱহাৰ কৰি ফট\' তুলিব আৰু ভিডিঅ\' ৰেকর্ড কৰিব পাৰে।" "কোনো এপ্লিকেশ্বন অথবা সেৱাক কেমেৰা ডিভাইচসমূহ খোলা অথবা বন্ধ কৰাৰ বিষয়ে কলবেকসমূহ গ্ৰহণ কৰিবলৈ অনুমতি দিয়ক।" - "যেতিয়া কোনো কেমেৰা ডিভাইচ খোলা (কোনো এপ্লিকেশ্বন পেকেজৰ দ্বাৰা) অথবা বন্ধ কৰা হয়, তেতিয়া এই স্বাক্ষৰ এপ্‌টোৱে কলবেকসমূহ গ্ৰহণ কৰিব পাৰে।" + + "কম্পন নিয়ন্ত্ৰণ কৰক" "ভাইব্ৰেটৰ নিয়ন্ত্ৰণ কৰিবলৈ এপটোক অনুমতি দিয়ে।" "পোনপটীয়াকৈ ফ\'ন নম্বৰলৈ কল কৰক" @@ -1247,7 +1248,8 @@ "%1$sৰ সৈতে সংযোগ কৰিব নোৱাৰি" "গোপনীয়তাৰ ছেটিংসমূহ সলনি কৰিবলৈ আৰু পুনৰ চেষ্টা কৰিবলৈ টিপক" "গোপনীয়তাৰ ছেটিংটো সলনি কৰিবনে?" - "%1$sএ এটা ব্যতিক্ৰমী আইডেণ্টিফায়াৰ, আপোনাৰ ডিভাইচৰ MAC ঠিকনাটো ব্যৱহাৰ কৰি সংযোগ কৰিবলৈ বিচাৰিব পাৰে। ই নিকটৱৰ্তী ডিভাইচসমূহে আপোনাৰ ডিভাইচটোৰ অৱস্থান ট্ৰেক কৰাৰ অনুমতি দিব পাৰে। \n\nআপুনি যদি অব্যাহত ৰাখে, %1$sএ আপোনাৰ গোপনীয়তাৰ ছেটিংটো সলনি কৰিব আৰু পুনৰ চেষ্টা কৰিবলৈ চেষ্টা কৰিব।" + + "ছেটিংটো সলনি কৰক" "ছেটিংটো আপডে’ট হ’ল। পুনৰ সংযোগ কৰিবলৈ চেষ্টা কৰক।" "গোপনীয়তাৰ ছেটিংটো সলনি কৰিব নোৱাৰি" diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 14a8493c6ad7..1d76a814ab6b 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -435,7 +435,8 @@ "şəkil və video çəkmək" "Bu tətbiq istədiyiniz zaman kameranı istifadə edərək şəkil çəkə və video qeydə ala bilər." "Tətbiqə və ya xidmətə kamera cihazlarının açılması və ya bağlanması haqqında geri zənglər qəbul etməyə icazə verin." - "Hər hansı kamera cihazı açıldıqda (hansı tətbiq paketi tərəfindən) və ya bağlandıqda bu imza tətbiqi geri zənglər qəbul edə bilər." + + "vibrasiyaya nəzarət edir" "Tətbiqə vibratoru idarə etmə icazəsi verir." "telefon nömrələrinə birbaşa zəng edir" @@ -1247,7 +1248,7 @@ "%1$s şəbəkəsinə qoşulmaq mümkün deyil" "Toxunaraq məxfilik ayarını dəyişin və yenidən cəhd edin" "Məxfilik ayarı dəyişdirilsin?" - "%1$s unikal identifikator olan cihazınızın MAC ünvanını istifadə edərək qoşulmaq istəyə bilər. Bu, yaxın cihazların sizin cihazınızın məkanını izləməsinə imkan verə bilər. \n\nDavam etsəniz, %1$s məxfilik ayarınızı dəyişəcək və yenidən qoşulmağa cəhd edəcək." + "Qoşulmaq üçün %1$s unikal identifikator olan cihazınızın MAC ünvanını istifadə etməlidir. Daha doğrusu, bu şəbəkə üçün məxfilik ayarınız təsadüfi identifikator istifadə edir. \n\nBu dəyişiklik yaxın cihazların cihazınızın məkanını izləməsinə imkan verə bilər." "Ayarı dəyişin" "Ayar güncəlləndi. Yenidən qoşulmağa çalışın." "Məxfilik ayarını dəyişmək mümkün deyil" diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 291f54099128..f8e352a0112f 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -306,7 +306,7 @@ "Želite li da dozvolite da <b>%1$s</b> pristupa fizičkim aktivnostima?" "Kamera" "snima slike i video" - "Želite li da omogućite da <b>%1$s</b> snima slike i video snimke?" + "Želite da omogućite da <b>%1$s</b> snima slike i video snimke?" "Evidencije poziva" "čitanje i pisanje evidencije poziva na telefonu" "Želite li da omogućite da <b>%1$s</b> pristupa evidencijama poziva na telefonu?" @@ -438,7 +438,8 @@ "snimanje fotografija i video snimaka" "Ova aplikacija može da snima fotografije i video snimke pomoću kamere u bilo kom trenutku." "Dozvolite aplikaciji ili usluzi da dobija povratne pozive o otvaranju ili zatvaranju uređaja sa kamerom." - "Ova aplikacija za potpise može da dobija povratne pozive kada se bilo koji uređaj sa kamerom otvara ili zatvara (pomoću nekog paketa aplikacija)." + + "kontrola vibracije" "Dozvoljava aplikaciji da kontroliše vibraciju." "direktno pozivanje brojeva telefona" @@ -1267,7 +1268,7 @@ "Povezivanje na mrežu %1$s nije uspelo" "Dodirnite da biste promenili podešavanja privatnosti i probali ponovo" "Želite li da promenite podešavanja privatnosti?" - "%1$s možda želi da se poveže pomoću MAC adrese uređaja, jedinstvenog identifikatora. To može da omogući uređajima u blizini da prate lokaciju uređaja. \n\nAko nastavite, %1$s će promeniti podešavanja privatnosti i ponovo probati da se poveže." + "%1$s treba da se poveže pomoću MAC adrese uređaja, jedinstvenog identifikatora. Podešavanje privatnosti za ovu mrežu trenutno koristi nasumični identifikator. \n\nOva izmena može da omogući uređajima u blizini da prate lokaciju uređaja." "Promeni podešavanje" "Podešavanje je ažurirano. Probajte ponovo da se povežete." "Promena podešavanja privatnosti nije uspela" diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index d0e50aae7de3..202dc3887d2e 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -441,7 +441,8 @@ "рабіць фатаграфіі і відэа" "Гэта праграма можа рабіць фота і запісваць відэа з дапамогай камеры ў любы час." "Дазволіць праграме ці сэрвісу атрымліваць зваротныя выклікі наконт адкрыцця ці закрыцця прылад камеры." - "Гэта праграма для подпісу можа атрымліваць зваротныя вылікі, калі адкрываецца (пакетам праграм) або закрываецца прылада камеры." + + "кіраванне вібрацыяй" "Дазваляе прыкладанням кіраваць вібрацыяй." "непасрэдна набіраць тэлефонныя нумары" @@ -1287,7 +1288,7 @@ "Не ўдалося падключыцца да сеткі \"%1$s\"" "Націсніце, каб змяніць налады прыватнасці, і паўтарыце спробу" "Змяніць наладу прыватнасці?" - "%1$s можа запытваць для падключэння выкарыстанне ўнікальнага ідэнтыфікатара вашай прылады - MAC-адраса. Гэта можа даць магчымасць прыладам паблізу адсочваць месцазнаходжанне вашай прылады. \n\nКалі вы працягнеце, %1$s зменіць наладу прыватнасці і паўторыць спробу падключэння." + "Для падключэння да сеткі \"%1$s\" неабходна ўвесці ўнікальны ідэнтыфікатар – MAC-адрас вашай прылады. Цяпер у наладах прыватнасці гэтай сеткі выкарыстоўваецца выпадковы ідэнтыфікатар. \n\nПасля яго змянення прылады паблізу змогуць адсочваць месцазнаходжанне вашай прылады." "Змяніць наладу" "Налады абноўлены. Паспрабуйце падключыцца яшчэ раз." "Не ўдалося змяніць наладу прыватнасці" diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 9077629f26d4..1f54ef57e7dd 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -435,7 +435,8 @@ "правене на снимки и видеоклипове" "Това приложение може по всяко време да прави снимки и да записва видеоклипове посредством камерата." "Разрешаване на приложение или услуга да получават обратни повиквания за отварянето или затварянето на снимачни устройства." - "Това приложение за подписване може да получава обратни повиквания, когато снимачно устройство бъде отворено (от кой пакет на приложение) или затворено." + + "контролиране на вибрирането" "Разрешава на приложението да контролира устройството за вибрация." "директно обаждане до телефонни номера" @@ -1247,7 +1248,7 @@ "Не може да се установи връзка с(ъс) %1$s" "Докоснете, за да промените настройките за поверителност, и опитайте отново" "Да се промени ли настройката за поверителност?" - "%1$s може да иска да се свърже посредством MAC адреса на устройството – уникален идентификатор. По този начин може да се разреши на устройствата в близост да проследяват местоположението на устройството ви. \n\nАко продължите, %1$s ще промени настройката ви за поверителност и ще опита да се свърже отново." + "За да установи връзка, %1$s трябва да използва MAC адреса (уникален идентификатор) на устройството ви. Понастоящем в настройката ви за поверителност за тази мрежа се използва рандомизиран идентификатор. \n\nТази промяна може да даде възможност на устройствата в близост да проследяват местоположението на устройството ви." "Промяна на настройката" "Настройката е актуализирана. Опитайте да се свържете отново." "Настройката за поверителност не може да се промени" diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index f83e537e6d11..01fbd7ad0663 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -435,7 +435,7 @@ "ছবি এবং ভিডিও তোলে" "এই অ্যাপটি যে কোনো সময় ক্যামেরা ব্যবহার করে ছবি তুলতে বা ভিডিও রেকর্ড করতে পারে৷" "কোনও অ্যাপ্লিকেশন বা পরিষেবাকে ক্যামেরা ডিভাইসগুলি খোলা বা বন্ধ হওয়া সম্পর্কে কলব্যাকগুলি গ্রহণ করার অনুমতি দিন।" - "কোনও ক্যামেরা ডিভাইস খোলার সময় (কোনও অ্যাপ্লিকেশন প্যাকেজের সাহায্যে) বা বন্ধ করার সময় এই সিগনেচার অ্যাপটি কলব্যাকগুলি গ্রহণ করতে পারে।" + "কোনও ক্যামেরা ডিভাইস খোলা (অ্যাপ্লিকেশনের সাহায্যে) বা বন্ধ করা হলে এই অ্যাপ কলব্যাক গ্রহণ করতে পারে।" "ভাইব্রেশন নিয়ন্ত্রণ করুন" "অ্যাপ্লিকেশানকে কম্পক নিয়ন্ত্রণ করতে দেয়৷" "সরাসরি ফোন নম্বরগুলিতে কল করে" @@ -1247,7 +1247,7 @@ "%1$s-এর সাথে কানেক্ট করা যাচ্ছে না" "গোপনীয়তা সেটিংস পরিবর্তন করতে এবং আবার চেষ্টা করতে ট্যাপ করুন" "গোপনীয়তা সেটিংস পরিবর্তন করবেন?" - "%1$s আপনার ডিভাইসের MAC অ্যাড্রেস ব্যবহার করে কানেক্ট করার চেষ্টা করতে পারে, এটি হল একটি অনন্য শনাক্তকারী। এর ফলে আশেপাশে থাকা ডিভাইস থেকে আপনার ডিভাইসের লোকেশন ট্র্যাক করার অনুমতি থাকতে পারে। \n\nআপনি যদি এটি ব্যবহার করা চালিয়ে যান, %1$s আপনার গোপনীয়তা সেটিং পরিবর্তন করে আবার কানেক্ট করার চেষ্টা করবে।" + "কানেক্ট করার জন্য, একটি অনন্য শনাক্তকারী হিসেবে %1$s আপনার ডিভাইসের MAC অ্যাড্রেস ব্যবহার করবে। আপনার গোপনীয়তা সেটিংস এখন এই নেটওয়ার্কের জন্য একটি র‌্যান্ডামাইজ করা শনাক্তকারী ব্যবহার করে। \n\nএই পরিবর্তনটি আশেপাশের ডিভাইসগুলিকে আপনার ডিভাইসের লোকেশন ট্র্যাক করার অনুমতি দিতে পারে।" "সেটিং পরিবর্তন করুন" "সেটিং আপডেট করা হয়েছে। আবার কানেক্ট করার চেষ্টা করুন।" "গোপনীয়তা সেটিং পরিবর্তন করা যাবে না" diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 6a284c94eecc..2e0cd444feae 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -438,7 +438,8 @@ "snimanje slika i videozapisa" "Ova aplikacija može slikati fotografije i snimati videozapise koristeći kameru bilo kada." "Dozvoliti aplikaciji ili usluzi da prima povratne pozive o otvaranju ili zatvaranju kamera." - "Ova aplikacija za potpisivanje može primati povratne pozive kada se otvara ili zatvara bilo koja kamera (kojim paketom aplikacija)." + + "kontrola vibracije" "Dozvoljava aplikaciji upravljanje vibracijom." "izravno zvanje telefonskih brojeva" @@ -1269,7 +1270,7 @@ "Nije se moguće povezati s mrežom %1$s" "Dodirnite da promijenite postavke privatnosti i pokušajte ponovo" "Promijeniti postavku privatnosti?" - "Moguće je da će se mreža %1$s htjeti povezati pomoću MAC adrese vašeg uređaja, koja je jedinstveni identifikator. Na taj način se uređajima u blizini može dozvoliti da prate lokaciju vašeg uređaja. \n\nAko nastavite, mreža %1$s će promijeniti vašu postavku privatnosti i pokušat će se ponovo povezati." + "Za povezivanje, mreža %1$s treba koristiti vašu MAC adresu, koja je jedinstveni identifikator. Vaša postavka privatnosti za ovu mrežu trenutno koristi nasumično odabrani identifikator. \n\nTom se izmjenom uređajima u blizini može dozvoliti da prate lokaciju vašeg uređaja." "Promijeni postavku" "Postavka je ažurirana. Pokušajte se ponovo povezati." "Nije moguće promijeniti postavku privatnosti" diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index e945690f2988..063dddb59717 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -435,7 +435,8 @@ "fer fotos i vídeos" "Aquesta aplicació pot fer fotos i gravar vídeos amb la càmera en qualsevol moment." "Permet que una aplicació o un servei pugui rebre crides de retorn sobre els dispositius de càmera que s\'obren o es tanquen." - "Aquesta aplicació de signatures pot rebre crides de retorn quan s’obre o es tanca un dispositiu de càmera (segons el paquet d’aplicació)." + + "controlar la vibració" "Permet que l\'aplicació controli el vibrador." "trucar directament a números de telèfon" @@ -1247,7 +1248,7 @@ "No es pot connectar a %1$s" "Toca per canviar la configuració de privadesa i torna-ho a provar" "Vols canviar l\'opció de configuració de privadesa?" - "És possible que %1$s vulgui connectar-se utilitzant l\'adreça MAC del teu dispositiu, un identificador únic. Això pot permetre que altres dispositius propers facin un seguiment de la ubicació del teu dispositiu. \n\nSi continues, %1$s canviarà l\'opció de configuració de privadesa i tornarà a provar de connectar-se." + "Per connectar-se, %1$s necessita utilitzar l\'adreça MAC del teu dispositiu, un identificador únic. Actualment, la configuració de privadesa d\'aquesta xarxa utilitza un identificador aleatori. \n\nAquest canvi pot permetre que altres dispositius propers facin un seguiment de la ubicació del teu dispositiu." "Canvia l\'opció de configuració" "S\'ha actualitzat la configuració. Torna a provar de connectar-te." "No es pot canviar l\'opció de configuració de privadesa" diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 5a1851b05431..c64631dfa3f3 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -441,7 +441,8 @@ "pořizování fotografií a videí" "Tato aplikace může pomocí fotoaparátu kdykoli pořídit snímek nebo nahrát video." "Povolte aplikaci nebo službě přijímat zpětná volání o otevření nebo zavření zařízení s fotoaparátem." - "Tato podpisová aplikace může přijímat zpětná volání při otevírání nebo zavírání jakéhokoli zařízení s fotoaparátem (balíčkem příslušné aplikace)." + + "ovládání vibrací" "Umožňuje aplikaci ovládat vibrace." "přímé volání na telefonní čísla" @@ -1287,7 +1288,7 @@ "K síti %1$s se nelze připojit" "Klepnutím změníte nastavení ochrany soukromí a budete opakovat pokus" "Změnit nastavení ochrany soukromí?" - "Síť %1$s se může chtít připojit za pomoci adresy MAC vašeho zařízení, což je unikátní identifikátor. Zařízení v okolí díky tomu mohou sledovat polohu vašeho zařízení. \n\nBudete-li pokračovat, síť %1$s změní nastavení ochrany soukromí a pokusí se znovu připojit." + "K připojení potřebuje síť %1$s použít adresu MAC vašeho zařízení – jedinečný identifikátor. V současné době vaše nastavení ochrany soukromí pro tuto síť používá náhodný identifikátor. \n\nTato změna může zařízením v okolí umožnit sledovat polohu vašeho zařízení." "Změnit nastavení" "Nastavení bylo aktualizováno. Zkuste se připojit znovu." "Nastavení ochrany soukromí se nepodařilo změnit" diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 34c899115883..3516d5360b6f 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -435,7 +435,8 @@ "tage billeder og optage video" "Med denne app kan du tage billeder og optage video med kameraet når som helst." "Tillad, at en app eller tjeneste modtager tilbagekald om kameraenheder, der åbnes eller lukkes." - "Denne signaturapp kan modtage tilbagekald, når en kameraenhed åbnes (efter app-pakke) eller lukkes." + + "administrere vibration" "Tillader, at appen kan administrere vibratoren." "ringe direkte op til telefonnumre" @@ -1247,7 +1248,7 @@ "Der kan ikke oprettes forbindelse til %1$s" "Tryk for at ændre privatlivsindstillingerne, og prøv igen" "Vil du ændre privatlivsindstillingen?" - "%1$s vil muligvis gerne oprette forbindelse via din enheds MAC-adresse, som er et unikt id. Dette kan give enheder i nærheden tilladelse til at spore din enheds placering. \n\nHvis du fortsætter, ændrer %1$s din privatlivsindstilling, og den prøver at oprette forbindelse igen." + "%1$s skal bruge din enheds MAC-adresse (som er et unikt id) for at oprette forbindelse. I øjeblikket bruges et tilfældigt id i henhold til dine privatlivsindstillinger for dette netværk. \n\nDenne ændring kan gøre det muligt for enheder i nærheden at spore din enheds placering." "Skift indstilling" "Indstillingen er opdateret. Prøv at oprette forbindelse igen." "Privatlivsindstillingen kan ikke ændres" diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 857989817110..4f88e8458577 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -435,7 +435,8 @@ "Bilder und Videos aufnehmen" "Diese App kann mit der Kamera jederzeit Bilder und Videos aufnehmen." "Einer App oder einem Dienst den Empfang von Callbacks erlauben, wenn eine Kamera geöffnet oder geschlossen wird." - "Diese App kann Callbacks empfangen, wenn eine Kamera mit einem Anwendungspaket geöffnet oder geschlossen wird." + + "Vibrationsalarm steuern" "Ermöglicht der App, den Vibrationsalarm zu steuern" "Telefonnummern direkt anrufen" @@ -1247,7 +1248,7 @@ "Verbindung zu %1$s nicht möglich" "Tippe, um die Datenschutzeinstellung zu ändern und es noch einmal zu versuchen" "Datenschutzeinstellung ändern?" - "%1$s möchte möglicherweise eine Verbindung über die MAC-Adresse deines Geräts herstellen; die MAC-Adresse ist eine Kennung, mit der das Gerät eindeutig identifiziert werden kann. Das kann dazu führen, dass andere Geräte in der Nähe den Standort deines Geräts verfolgen können. \n\nWenn du fortfährst, wird %1$s deine Datenschutzeinstellung ändern und den Verbindungsversuch wiederholen." + "Wenn du eine Verbindung herstellen möchtest, muss %1$s die MAC-Adresse deines Geräts verwenden; die MAC-Adresse ist eine Kennung, mit der das Gerät eindeutig identifiziert werden kann. In deiner Datenschutzeinstellung für dieses Netzwerk wird momentan eine zufällige Kennung genutzt. \n\nDurch diese Änderung können andere Geräte in der Nähe den Standort deines Geräts möglicherweise verfolgen." "Einstellung ändern" "Einstellung aktualisiert. Versuch noch einmal, eine Verbindung herzustellen." "Datenschutzeinstellung kann nicht geändert werden" diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index bf6559c003c9..47e00504383e 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -435,7 +435,8 @@ "κάνει λήψη φωτογραφιών και βίντεο" "Αυτή η εφαρμογή μπορεί να τραβήξει φωτογραφίες και βίντεο χρησιμοποιώντας την κάμερα, ανά πάσα στιγμή." "Επιτρέψτε σε μια εφαρμογή ή μια υπηρεσία να λαμβάνει επανάκλησεις σχετικά με το άνοιγμα ή το κλείσιμο συσκευών κάμερας." - "Αυτή η εφαρμογή υπογραφής μπορεί να λαμβάνει επανακλήσεις κατά το άνοιγμα οποιασδήποτε συσκευής κάμερας (από οποιοδήποτε πακέτο εφαρμογής) ή κατά το κλείσιμο." + + "ελέγχει τη δόνηση" "Επιτρέπει στην εφαρμογή τον έλεγχο της δόνησης." "πραγματοποιεί απευθείας κλήση τηλεφωνικών αριθμών" @@ -1247,7 +1248,7 @@ "Δεν είναι δυνατή η σύνδεση με το %1$s" "Πατήστε για αλλαγή των ρυθμίσεων απορρήτου και δοκιμάστε ξανά" "Αλλαγή της ρύθμισης απορρήτου;" - "Το %1$s μπορεί να θέλει να συνδεθεί χρησιμοποιώντας τη διεύθυνση MAC της συσκευής σας, η οποία είναι ένα μοναδικό αναγνωριστικό. Αυτό μπορεί να επιτρέψει την παρακολούθηση της τοποθεσίας της συσκευής σας από συσκευές σε κοντινή απόσταση. \n\nΕάν συνεχίσετε, το %1$s θα αλλάξει τη ρύθμιση απορρήτου σας και θα δοκιμάσει να συνδεθεί ξανά." + "Για να συνδεθεί, το %1$s θα πρέπει να χρησιμοποιήσει τη διεύθυνση της συσκευής MAC, η οποία είναι ένα μοναδικό αναγνωριστικό. Αυτήν τη στιγμή, η ρύθμιση απορρήτου σας για αυτό το δίκτυο χρησιμοποιεί ένα τυχαίο αναγνωριστικό. \n\nΑυτή η αλλαγή μπορεί να επιτρέψει την παρακολούθηση της τοποθεσίας της συσκευής σας από συσκευές σε κοντινή απόσταση." "Αλλαγή ρύθμισης" "Η ρύθμιση ενημερώθηκε. Δοκιμάστε να συνδεθείτε ξανά." "Δεν είναι δυνατή η αλλαγή της ρύθμισης απορρήτου" diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 1cd734172de6..833b2efc0677 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -435,7 +435,7 @@ "take pictures and videos" "This app can take pictures and record videos using the camera at any time." "Allow an application or service to receive callbacks about camera devices being opened or closed." - "This signature app can receive callbacks when any camera device is being opened (by what application package) or closed." + "This app can receive callbacks when any camera device is being opened (by what application) or closed." "control vibration" "Allows the app to control the vibrator." "directly call phone numbers" @@ -1247,7 +1247,7 @@ "Can’t connect to %1$s" "Tap to change privacy settings and retry" "Change privacy setting?" - "%1$s may want to connect using your device MAC address, a unique identifier. This may allow your device’s location to be tracked by nearby devices. \n\nIf you continue, %1$s will change your privacy setting and try to connect again." + "To connect, %1$s needs to use your device MAC address, a unique identifier. Currently, your privacy setting for this network uses a randomised identifier. \n\nThis change may allow your device’s location to be tracked by nearby devices." "Change setting" "Setting updated. Try connecting again." "Can’t change privacy setting" diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index bd4a247340a5..da3c433f931d 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -435,7 +435,7 @@ "take pictures and videos" "This app can take pictures and record videos using the camera at any time." "Allow an application or service to receive callbacks about camera devices being opened or closed." - "This signature app can receive callbacks when any camera device is being opened (by what application package) or closed." + "This app can receive callbacks when any camera device is being opened (by what application) or closed." "control vibration" "Allows the app to control the vibrator." "directly call phone numbers" @@ -1247,7 +1247,7 @@ "Can’t connect to %1$s" "Tap to change privacy settings and retry" "Change privacy setting?" - "%1$s may want to connect using your device MAC address, a unique identifier. This may allow your device’s location to be tracked by nearby devices. \n\nIf you continue, %1$s will change your privacy setting and try to connect again." + "To connect, %1$s needs to use your device MAC address, a unique identifier. Currently, your privacy setting for this network uses a randomised identifier. \n\nThis change may allow your device’s location to be tracked by nearby devices." "Change setting" "Setting updated. Try connecting again." "Can’t change privacy setting" diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 1cd734172de6..833b2efc0677 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -435,7 +435,7 @@ "take pictures and videos" "This app can take pictures and record videos using the camera at any time." "Allow an application or service to receive callbacks about camera devices being opened or closed." - "This signature app can receive callbacks when any camera device is being opened (by what application package) or closed." + "This app can receive callbacks when any camera device is being opened (by what application) or closed." "control vibration" "Allows the app to control the vibrator." "directly call phone numbers" @@ -1247,7 +1247,7 @@ "Can’t connect to %1$s" "Tap to change privacy settings and retry" "Change privacy setting?" - "%1$s may want to connect using your device MAC address, a unique identifier. This may allow your device’s location to be tracked by nearby devices. \n\nIf you continue, %1$s will change your privacy setting and try to connect again." + "To connect, %1$s needs to use your device MAC address, a unique identifier. Currently, your privacy setting for this network uses a randomised identifier. \n\nThis change may allow your device’s location to be tracked by nearby devices." "Change setting" "Setting updated. Try connecting again." "Can’t change privacy setting" diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 1cd734172de6..833b2efc0677 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -435,7 +435,7 @@ "take pictures and videos" "This app can take pictures and record videos using the camera at any time." "Allow an application or service to receive callbacks about camera devices being opened or closed." - "This signature app can receive callbacks when any camera device is being opened (by what application package) or closed." + "This app can receive callbacks when any camera device is being opened (by what application) or closed." "control vibration" "Allows the app to control the vibrator." "directly call phone numbers" @@ -1247,7 +1247,7 @@ "Can’t connect to %1$s" "Tap to change privacy settings and retry" "Change privacy setting?" - "%1$s may want to connect using your device MAC address, a unique identifier. This may allow your device’s location to be tracked by nearby devices. \n\nIf you continue, %1$s will change your privacy setting and try to connect again." + "To connect, %1$s needs to use your device MAC address, a unique identifier. Currently, your privacy setting for this network uses a randomised identifier. \n\nThis change may allow your device’s location to be tracked by nearby devices." "Change setting" "Setting updated. Try connecting again." "Can’t change privacy setting" diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index dc3a35ed01bf..baaee2022d43 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -435,7 +435,7 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‎take pictures and videos‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‏‏‎‎‏‎‎‎‎‎‎‏‏‎‏‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎This app can take pictures and record videos using the camera at any time.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‎‎‏‏‎Allow an application or service to receive callbacks about camera devices being opened or closed.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎This signature app can receive callbacks when any camera device is being opened (by what application package) or closed.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎This app can receive callbacks when any camera device is being opened (by what application) or closed.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎control vibration‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‏‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‎Allows the app to control the vibrator.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‎‎directly call phone numbers‎‏‎‎‏‎" @@ -1247,7 +1247,7 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‎‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‏‎Can’t connect to ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎Tap to change privacy settings and retry‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‎‏‎‏‏‎‏‎‏‏‏‏‎‏‏‏‏‎‏‎‎‏‎‎Change privacy setting?‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ may want to connect using your device MAC address, a unique identifier. This may allow your device’s location to be tracked by nearby devices. ‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎If you continue, ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ will change your privacy setting and try to connect again.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‎To connect, ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ needs to use your device MAC address, a unique identifier. Currently, your privacy setting for this network uses a randomized identifier. ‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎This change may allow your device’s location to be tracked by nearby devices.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‎Change setting‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‎‏‏‎‎‎‎‏‎‏‎‎‎‏‎‎‎‏‎‏‏‏‎‎‏‎‏‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‏‎Setting updated. Try connecting again.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‎‎‎‏‏‎‎‏‎‏‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎Can’t change privacy setting‎‏‎‎‏‎" diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 373b01ce2543..ce977b1d4d24 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -435,7 +435,7 @@ "tomar fotografías y grabar videos" "Esta app puede tomar fotos y grabar videos con la cámara en cualquier momento." "Permite que una aplicación o un servicio reciba devoluciones de llamada cuando se abren o cierran dispositivos de cámara." - "Esta app de firma puede recibir devoluciones de llamada cuando se cierra o se abre cualquier dispositivo de cámara (y qué paquete de aplicación lo hace)." + "Esta app puede recibir devoluciones de llamada cuando se cierra o se abre cualquier dispositivo de cámara (y qué aplicación lo hace)." "controlar la vibración" "Permite que la aplicación controle la vibración." "llamar directamente a números de teléfono" @@ -1247,7 +1247,7 @@ "No se puede establecer conexión con %1$s" "Presiona para cambiar la configuración de privacidad y volver a intentarlo" "¿Quieres cambiar la configuración de privacidad?" - "Es posible que %1$s quiera conectarse mediante la dirección MAC (un identificador único) de tu dispositivo. Eso podría permitir que dispositivos cercanos registren la ubicación de tu dispositivo. \n\nSi continúas, %1$s cambiará la configuración de privacidad e intentará volver a establecer conexión." + "Para conectarse, %1$s necesita usar la dirección MAC (identificador único) de tu dispositivo. Actualmente, tu configuración de privacidad para esta red usa un identificador aleatorio. \n\nEste cambio podría permitir que dispositivos cercanos registren la ubicación del tuyo." "Cambiar configuración" "Se actualizó la configuración. Intenta conectarte de nuevo." "No se puede cambiar la configuración de privacidad" diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 0581942dad9f..f9150e9bb25a 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -435,7 +435,8 @@ "realizar fotografías y vídeos" "Esta aplicación puede hacer fotografías y grabar vídeos con la cámara en cualquier momento." "Permitir que una aplicación o servicio reciba retrollamadas cada vez que se abra o cierre una cámara." - "Esta aplicación especial puede recibir retrollamadas cada vez que se abre o se cierra una cámara mediante cualquier paquete de aplicaciones." + + "controlar la vibración" "Permite que la aplicación controle la función de vibración." "llamar directamente a números de teléfono" @@ -1247,7 +1248,7 @@ "No se ha podido conectar a %1$s" "Toca para cambiar los ajustes de privacidad y vuelve a intentarlo" "¿Quieres cambiar el ajuste de privacidad?" - "Puede que %1$s vaya conectarse mediante la dirección MAC de tu dispositivo, un identificador único. De esta forma, es posible que se permita que dispositivos cercanos registren la ubicación de tu dispositivo. \n\nSi continúas, %1$s cambiará tu ajuste de privacidad e intentará conectarse de nuevo." + "Para conectarse, %1$s necesita la dirección MAC de tu dispositivo, que es un identificador único; no obstante, el ajuste de privacidad de esta red utiliza un identificador aleatorio. \n\nEs posible que este cambio permita que los dispositivos cercanos conozcan la ubicación de tu dispositivo." "Cambiar ajuste" "Se ha cambiado el ajuste. Prueba a conectarte de nuevo." "No se ha podido cambiar el ajuste de privacidad" @@ -1821,8 +1822,8 @@ "Actualizado por el administrador" "Eliminado por el administrador" "Aceptar" - "Para que la batería dure más, Ahorro de batería:\nActiva el tema oscuro\nDesactiva o restringe actividad en segundo plano, algunos efectos visuales y otras funciones como \"Ok Google\"\n\n""Más información" - "Para que la batería dure más, Ahorro de batería:\nActiva el tema oscuro\nDesactiva o restringe actividad en segundo plano, algunos efectos visuales y otras funciones como \"Ok Google\"" + "Para que la batería dure más, Ahorro de batería:\n· Activa el tema oscuro\n· Desactiva o restringe actividad en segundo plano, algunos efectos visuales y otras funciones como \"Ok Google\"\n\n""Más información" + "Para que la batería dure más, Ahorro de batería:\n· Activa el tema oscuro\n· Desactiva o restringe actividad en segundo plano, algunos efectos visuales y otras funciones como \"Ok Google\"" "El ahorro de datos evita que algunas aplicaciones envíen o reciban datos en segundo plano, lo que permite reducir el uso de datos. Una aplicación activa podrá acceder a los datos, aunque con menos frecuencia. Esto significa que, por ejemplo, algunas imágenes no se mostrarán hasta que las toques." "¿Activar ahorro de datos?" "Activar" diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 9e85c5e3b178..0a194596ed2c 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -435,7 +435,8 @@ "piltide ja videote tegemine" "See rakendus saab mis tahes ajal kaameraga pildistada ja videoid salvestada." "Lubab rakendusel või teenusel kaameraseadmete avamise või sulgemise kohta tagasikutseid vastu võtta." - "See allkirjarakendus saab mis tahes kaameraseadme avamisel (vastava rakendusepaketiga) või sulgemisel tagasikutseid vastu võtta." + + "juhtige vibreerimist" "Võimaldab rakendusel juhtida vibreerimist." "helista otse telefoninumbritele" @@ -1247,7 +1248,7 @@ "Võrguga %1$s ei õnnestu ühendada" "Puudutage privaatsusseadete muutmiseks ja uuesti proovimiseks" "Kas muuta privaatsusseadet?" - "%1$s võib soovida luua ühenduse teie seadme kordumatu identifikaatori ehk MAC-aadressi abil. See võib võimaldada läheduses asuvatel seadmetel jälgida teie seadme asukohta. \n\nKui jätkate, muudab %1$s teie privaatsusseadet ja proovib uuesti ühendada." + "Ühendamiseks peab %1$s kasutama teie seadme MAC-aadressi, mis on teie kordumatu ID. Praegu kasutab teie privaatsusseade selle võrgu puhul juhuslikku ID-d. \n\nSee muudatus võib võimaldada läheduses asuvatel seadmetel jälgida teie seadme asukohta." "Muuda seadet" "Seadet muudeti. Proovige uuesti ühendada." "Privaatsusseadet ei saa muuta" diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 0e4934ededb6..53fb56e4986f 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -375,7 +375,7 @@ "Beren zati batzuk memoria modu iraunkorrean ezartzeko baimena ematen die aplikazioei. Horrela, beste aplikazioek erabilgarri duten memoria murritz daiteke eta tableta motel daiteke." "Beren zati batzuk memorian modu iraunkorrean aktibo uztea baimentzen die aplikazioei. Horrela, beste aplikazioek memoria gutxiago izan lezakete erabilgarri eta telebistak motelago funtziona lezake." "Beren zati batzuk memoria modu iraunkorrean ezartzeko baimena ematen die aplikazioei. Horrela, beste aplikazioek erabilgarri duten memoria murritz daiteke eta telefonoa motel daiteke." - "Abiarazi zerbitzuak aurreko planoan" + "abiarazi zerbitzuak aurreko planoan" "Aurreko planoko zerbitzuak erabiltzea baimentzen dio aplikazioari." "neurtu aplikazioen biltegiratzeko tokia" "Bere kodea, datuak eta cache-tamainak eskuratzeko baimena ematen die aplikazioei." @@ -422,7 +422,7 @@ "Aplikazioa aurreko planoan dagoenean, zure kokapenaren berri izan dezake sareen iturburuak erabilita; adibidez, telefonia mugikorreko dorreak eta Wi-Fi sareak. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu telebistan, aplikazioak erabil ditzan." "Aplikazioak aurreko planoan funtzionatzen duenean bakarrik lor dezake zure gutxi gorabeherako kokapena. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu autoan, aplikazioak erabil ditzan." "Aplikazioa aurreko planoan dagoenean, zure kokapenaren berri izan dezake sareen iturburuak erabilita; adibidez, telefonia mugikorreko dorreak eta Wi-Fi sareak. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu telefonoan, aplikazioak erabil ditzan." - "Atzitu kokapena atzeko planoan" + "atzitu kokapena atzeko planoan" "Baimen hau ematen bada kokapen zehatz edo gutxi gorabeherakorako sarbideaz gain, atzeko planoan abian den bitartean atzitu ahalko du aplikazioak kokapena." "aldatu audio-ezarpenak" "Audio-ezarpen orokorrak aldatzeko baimena ematen dio; besteak beste, bolumena eta irteerarako zer bozgorailu erabiltzen den." @@ -434,8 +434,9 @@ "Aplikazioak ariketa fisikoa hauteman dezake." "atera argazkiak eta grabatu bideoak" "Aplikazioak edonoiz erabil dezake kamera argazkiak ateratzeko eta bideoak grabatzeko." - "Eman baimena aplikazioari edo zerbitzuari jakinarazpenak jasotzeko kamerak ireki edo ixten direnean." - "Kamera ireki edo itxi dela (eta zer aplikazio-paketerekin) dioten jakinarazpenak jaso ditzake sinatzeko aplikazio honek." + "eman jakinarazpenak jasotzeko baimena aplikazioari edo zerbitzuari kamerak ireki edo ixten direnean." + + "kontrolatu dardara" "Bibragailua kontrolatzeko aukera ematen die aplikazioei." "deitu zuzenean telefono-zenbakietara" @@ -448,7 +449,7 @@ "Deiak sistemaren bidez bideratzea baimentzen die aplikazioei, deien zerbitzua ahal bezain ona izan dadin." "ikusi eta kontrolatu deiak sistemaren bidez." "Gailuan abian diren deiak eta deion informazioa ikusi eta kontrolatzeko baimena ematen dio aplikazioari; besteak beste, deien zenbakiak eta deien egoera." - "Jarraitu beste aplikazio batean hasitako deia" + "jarraitu beste aplikazio batean hasitako deia" "Beste aplikazio batean hasitako dei bat jarraitzea baimentzen dio aplikazioari." "irakurri telefono-zenbakiak" "Gailuaren telefono-zenbakiak atzitzeko baimena ematen die aplikazioei." @@ -484,9 +485,9 @@ "Sarearen konexioaren egoera aldatzeko baimena ematen die aplikazioei." "aldatu telefono bidezko konektagarritasuna" "Partekatutako Interneterako konexioaren egoera aldatzeko baimena ematen die aplikazioei." - "ikusi Wi-Fi konexioak" + "ikusi wifi bidezko konexioak" "Wi-Fi sareei buruzko informazioa ikusteko baimena ematen die aplikazioei, adibidez, Wi-Fi konexioa aktibatuta dagoen eta konektatutako Wi-Fi gailuen izenak zein diren." - "konektatu Wi-Fira edo deskonektatu bertatik" + "konektatu wifira edo deskonektatu bertatik" "Wi-Fi sarbide-puntuetara konektatzeko edo haietatik deskonektatzeko baimena ematen die aplikazioei, baita Wi-Fi sareen gailu-konfigurazioari aldaketak egitekoa ere." "onartu Wi-Fi Multicast harrera" "Wi-Fi sarearen bidez gailu guztiei bidalitako paketeak jasotzeko baimena ematen die aplikazioei multidifusio-helbideak erabilita, ez tableta soilik. Multidifusiokoa ez den moduak baino bateria gehiago erabiltzen du." @@ -510,9 +511,9 @@ "Near Field Communication (NFC) etiketekin, txartelekin eta irakurgailuekin komunikatzea baimentzen die aplikazioei." "desgaitu pantailaren blokeoa" "Teklen blokeoa eta erlazionatutako pasahitz-segurtasuna desgaitzeko baimena ematen die aplikazioei. Adibidez, telefonoak teklen blokeoa desgaitzen du telefono-deiak jasotzen dituenean, eta berriro gaitzen du deiak amaitzean." - "Eskatu pantailaren blokeoa konplexua izatea" + "eskatu pantailaren blokeoa konplexua izatea" "Pantailaren blokeoaren konplexutasun-maila (handia, ertaina, txikia edo bat ere ez) jakiteko aukera ematen dio aplikazioari. Informazio horrekin, pantailaren blokeoaren luzera-barruti edo mota posiblea ondoriozta liteke. Halaber, pantailaren blokeoa maila jakin batera igotzeko iradoki diezaieke aplikazioak erabiltzaileei, baina horri ez ikusi egin eta aplikazioa erabiltzen jarraitzeko aukera dute erabiltzaileek. Kontuan izan pantailaren blokeoa ez dela gordetzen testu arrunt gisa; beraz, aplikazioak ez du jakingo pasahitz zehatza zein den." - "Erabili hardware biometrikoa" + "erabili hardware biometrikoa" "Autentifikatzeko hardware biometrikoa erabiltzeko baimena ematen die aplikazioei." "kudeatu hatz-marken hardwarea" "Erreferentzia-gako digitalen txantiloiak gehitzeko eta ezabatzeko metodoei dei egitea baimentzen die aplikazioei." @@ -607,7 +608,7 @@ "Kontu baten sinkronizazio-estatistikak irakurtzeko baimena ematen dio; besteak beste, sinkronizazio-gertaeren historia eta sinkronizatutako datu kopurua." "Irakurri biltegiratze partekatuko edukia" "Biltegiratze partekatuko edukia irakurtzeko baimena ematen die aplikazioei." - "Aldatu edo ezabatu biltegiratze partekatuko edukia" + "aldatu edo ezabatu biltegiratze partekatuko edukia" "Biltegiratze partekatuko edukian idazteko baimena ematen die aplikazioei." "egin/jaso SIP deiak" "SIP deiak egitea eta jasotzeko baimena ematen die aplikazioei." @@ -1247,7 +1248,8 @@ "Ezin da konektatu %1$s sarera" "Sakatu hau pribatutasun-ezarpenak aldatzeko, eta saiatu berriro" "Pribatutasun-ezarpena aldatu nahi duzu?" - "Baliteke %1$s sareak gailuaren MAC helbidea erabilita konektatu nahi izatea; izan ere, identifikatzaile esklusibo bat da hori. Hori eginez gero, bailiteke inguruko gailuek zure gailuaren kokapenaren jarraipena egitea. \n\nAurrera egiten baduzu, %1$s sareak zure pribatutasun-ezarpena aldatuko du eta berriro saiatuko da konektatzen." + + "Aldatu ezarpena" "Eguneratu da ezarpena. Saiatu berriro konektatzen." "Ezin da aldatu pribatutasun-ezarpena" diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 94f9766253e7..fed10e271d55 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -435,7 +435,8 @@ "عکسبرداری و فیلمبرداری" "این برنامه می‌تواند در هرزمانی با استفاده از دوربین عکس و فیلم بگیرد." "مجاز کردن برنامه یا سرویس برای دریافت پاسخ تماس درباره دستگاه‌های دوربینی که باز یا بسته می‌شوند." - "این برنامهٔ امضا می‌تواند هروقت دستگاه دوربین باز (براساس بسته برنامه) یا بسته می‌شود، پاسخ تماس دریافت کند." + + "کنترل لرزش" "‏به برنامه اجازه می‎دهد تا لرزاننده را کنترل کند." "تماس مستقیم با شماره تلفن‌ها" @@ -1247,7 +1248,7 @@ "برقراری اتصال به %1$s ممکن نیست" "برای تغییر تنظیم حریم‌خصوصی ضربه بزنید و دوباره امتحان کنید" "تنظیم حریم‌خصوصی تغییر کند؟" - "‏%1$s ممکن است بخواهد بااستفاده از نشانی MAC دستگاه شما که شناسه منحصربه‌فردی است متصل شود. این کار ممکن است به دستگاه‌های اطراف امکان دهد مکان دستگاهتان را ردیابی کنند. \n\nاگر ادامه دهید، %1$s تنظیم حریم‌خصوصی شما را تغییر می‌دهد و دوباره سعی می‌کند متصل شود." + "‏برای اتصال، %1$s باید از نشانی MAC دستگاهتان که شناسه‌ای منحصربه‌فرد است استفاده کند. درحال‌حاضر، تنظیم حریم‌خصوصی شما برای این شبکه از شناسه تصادفی استفاده می‌کند. \n\nاین تغییر ممکن است به دستگاه‌های اطراف امکان دهد مکان دستگاهتان را ردیابی کنند." "تغییر تنظیم" "تنظیم به‌روزرسانی شد. دوباره وصل شوید." "تنظیم حریم‌خصوصی را نمی‌توان تغییر داد" diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 34ec6028f957..14ff6d4eff8b 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -435,7 +435,8 @@ "ota kuvia ja videoita" "Tämä sovellus voi ottaa kameralla kuvia ja videoita koska tahansa." "Salli sovelluksen tai palvelun vastaanottaa vastakutsuja kameralaitteiden avaamisesta tai sulkemisesta." - "Tämä allekirjoitussovellus voi vastaanottaa vastakutsuja, kun mikä tahansa kameralaite avataan tai suljetaan (jollakin sovelluspaketilla)" + + "hallita värinää" "Antaa sovelluksen hallita värinää." "soittaa puhelinnumeroihin suoraan" @@ -1247,7 +1248,7 @@ "Ei yhteyttä: %1$s" "Napauta muuttaaksesi yksityisyysasetusta ja yritä uudelleen" "Muutetaanko yksityisyysasetus?" - "%1$s halua mahdollisesti yhdistää laitteen MAC-osoitteen, eli yksilöllisen tunnisteen, kautta. Tämä voi antaa lähellä olevien laitteiden seurata laitteesi sijaintia. \n\nJos jatkat, %1$s muuttaa yksityisyysasetustasi ja yrittää yhdistää uudelleen." + "Yhteyden muodostaminen edellyttää, että %1$s voi käyttää MAC-osoitetta eli yksilöllistä tunnistetta. Tällä hetkellä verkon yksityisyysasetuksesi käyttää satunnaistettua tunnistetta. \n\nTämä muutos voi antaa lähellä oleville laitteille mahdollisuuden seurata laitteesi sijaintia." "Muuta asetusta" "Asetus päivitetty. Yritä muodostaa yhteys uudelleen." "Yksityisyysasetusta ei voi muuttaa" diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 0ec2ef977723..3d4a4bd80e6a 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -435,7 +435,8 @@ "prendre des photos et filmer des vidéos" "Cette application peut prendre des photos et enregistrer des vidéos à l\'aide de l\'appareil photo en tout temps." "Autoriser une application ou un service de recevoir des rappels relatifs à l\'ouverture ou à la fermeture des appareils photos." - "Cette application signature peut recevoir des rappels lorsque l\'appareil photo est ouvert ou fermé (par le paquet d\'application) en question." + + "gérer le vibreur" "Permet à l\'application de gérer le vibreur de l\'appareil." "appeler directement des numéros de téléphone" @@ -1247,7 +1248,7 @@ "Impossible de se connecter à %1$s" "Touchez pour modifier les paramètres de confidentialité et réessayer" "Modifier le paramètre de confidentialité?" - "%1$s pourrait vouloir se connecter à l\'aide de l\'adresse MAC de votre appareil, un identifiant unique. Il se peut que cela permette à des appareils à proximité de suivre la position de votre appareil. \n\nSi vous continuez, %1$s modifiera votre paramètre de confidentialité et tentera de se connecter à nouveau." + "Pour autoriser la connexion, le réseau %1$s a besoin d\'utiliser l\'adresse MAC de votre appareil, un identifiant unique. En ce moment, votre paramètre de confidentialité pour ce réseau utilise un identifiant aléatoire. \n\nIl se peut que ce changement permette à des appareils à proximité de suivre la position de votre appareil." "Modifier le paramètre" "Paramètre mis à jour. Réessayez de vous connecter." "Impossible de modifier les paramètres de confidentialité" diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index a001c95cd296..739068cd351b 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -435,7 +435,8 @@ "prendre des photos et enregistrer des vidéos" "Cette application peut utiliser l\'appareil photo pour prendre des photos et enregistrer des vidéos à tout moment." "Autoriser une application ou un service à recevoir des rappels liés à l\'ouverture ou à la fermeture de caméras" - "Cette application premium peut recevoir des rappels lorsqu\'une caméra est ouverte (par un package d\'application) ou fermée." + + "contrôler le vibreur" "Permet à l\'application de contrôler le vibreur." "appeler directement les numéros de téléphone" @@ -1247,7 +1248,7 @@ "Impossible de se connecter au réseau \"%1$s\"" "Appuyez pour modifier les paramètres de confidentialité, puis réessayez" "Modifier le paramètre de confidentialité ?" - "%1$s peut tenter de se connecter avec l\'adresse MAC de votre appareil, un identifiant unique. Cela risque de permettre à des appareils à proximité d\'effectuer le suivi de votre position. \n\nSi vous continuez, %1$s modifiera votre paramètre de confidentialité et essaiera à nouveau de se connecter." + "Pour établir la connexion, %1$s doit utiliser l\'adresse MAC de votre appareil (un identifiant unique). À l\'heure actuelle, votre paramètre de confidentialité pour ce réseau utilise un identifiant aléatoire. \n\nCela risque de permettre à des appareils à proximité d\'effectuer le suivi de votre position." "Modifier le paramètre" "Paramètre mis à jour. Essayez de vous reconnecter." "Impossible de modifier le paramètre de confidentialité" diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index f4b9308d486c..290db459793a 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -303,7 +303,7 @@ "Queres permitir que <b>%1$s</b> acceda á túa actividade física?" "Cámara" "tirar fotos e gravar vídeos" - "Queres permitir que a aplicación <b>%1$s</b> realice fotos e grave vídeos?" + "Queres permitir que <b>%1$s</b> realice fotos e grave vídeos?" "Rexistros de chamadas" "ler e editar o rexistro de chamadas do teléfono" "Queres permitir que <b>%1$s</b> acceda aos rexistros de chamadas do teléfono?" @@ -435,7 +435,8 @@ "facer fotos e vídeos" "Esta aplicación pode utilizar a cámara en calquera momento para sacar fotos e gravar vídeos." "Permitir que unha aplicación ou servizo reciba retrochamadas cando se abran ou se pechen dispositivos con cámara." - "Esta aplicación de sinaturas pode recibir retrochamadas cando un paquete de aplicacións abra ou peche un dispositivo con cámara." + + "controlar a vibración" "Permite á aplicación controlar o vibrador." "chamar directamente aos números de teléfono" @@ -1247,7 +1248,7 @@ "Non se puido establecer conexión co %1$s" "Toca para cambiar a configuración de privacidade e tentalo de novo" "Queres cambiar a configuración de privacidade?" - "O %1$s pode querer conectarse usando o enderezo MAC do teu dispositivo, un identificador único. Deste modo, os dispositivos próximos poden facer un seguimento da localización do teu dispositivo. \n\nSe continúas, o %1$s cambiará a configuración de privacidade e tentará establecer conexión de novo." + "Para conectarse, %1$s ten que usar o enderezo MAC (un identificador único) do teu dispositivo. Actualmente, a configuración de privacidade desta rede usa un identificador aleatorio. \n\nCon este cambio, os dispositivos próximos poden facer un seguimento da localización do teu dispositivo." "Cambiar configuración" "Actualizouse a opción de configuración. Proba a conectarte de novo." "Non se puido cambiar a configuración de privacidade" diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 63be55f591f9..5ab36e631ad0 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -435,7 +435,7 @@ "ચિત્રો અને વિડિઓઝ લો" "આ ઍપ્લિકેશન, કૅમેરાનો ઉપયોગ કરીને કોઈપણ સમયે ચિત્રો લઈ અને વિડિઓઝ રેકોર્ડ કરી શકે છે." "કૅમેરા ડિવાઇસ ચાલુ કે બંધ થવા વિશે કૉલબૅક પ્રાપ્ત કરવાની ઍપ્લિકેશન કે સેવાને મંજૂરી આપો." - "જ્યારે કોઈ કૅમેરા ડિવાઇસ (ક્યા ઍપ્લિકેશન પૅકેજ વડે) ખોલવા કે બંધ કરવામાં આવે, ત્યારે આ વિશેષ ઍપ કૉલબૅક પ્રાપ્ત કરી શકે છે." + "જ્યારે કોઈ કૅમેરા ડિવાઇસ (કયા ઍપ્લિકેશન વડે) ખોલવા કે બંધ કરવામાં આવે, ત્યારે આ વિશેષ ઍપ કૉલબૅક પ્રાપ્ત કરી શકે છે." "વાઇબ્રેશન નિયંત્રિત કરો" "એપ્લિકેશનને વાઇબ્રેટરને નિયંત્રિત કરવાની મંજૂરી આપે છે." "સીધા જ ફોન નંબર્સ પર કૉલ કરો" @@ -1247,7 +1247,7 @@ "%1$s સાથે કનેક્ટ કરી શકાતું નથી" "પ્રાઇવસી સેટિંગ બદલવા અને ફરી પ્રયાસ કરવા ટૅપ કરો" "પ્રાઇવસી સેટિંગ બદલીએ?" - "%1$s, કોઈ વિશિષ્ટ ઓળખકર્તા એવા તમારા ડિવાઇસના MAC ઍડ્રેસ વડે કનેક્ટ કરવા ઇચ્છતા હોઈ શકે છે. આમ કરવાથી, તમારા ડિવાઇસનું સ્થાન ટ્રૅક કરવાની મંજૂરી નજીકના કોઈ ડિવાઇસ દ્વારા મેળવવામાં આવી શકે છે. \n\nજો તમે ચાલુ રાખશો, તો %1$s તમારા પ્રાઇવસી સેટિંગમાં ફેરફાર કરશે અને ફરીથી કનેક્ટ કરવાનો પ્રયાસ કરશે." + "કનેક્ટ કરવા માટે, %1$sને વિશિષ્ટ ઓળખકર્તા એવા તમારા ડિવાઇસના MAC ઍડ્રેસનો ઉપયોગ કરવો જરૂરી છે. હાલમાં, આ નેટવર્ક માટે તમારું પ્રાઇવસી સેટિંગ રેન્ડમ કરેલા ઓળખકર્તાનો ઉપયોગ કરે છે. \n\nઆ ફેરફારથી, તમારા ડિવાઇસનું સ્થાન ટ્રૅક કરવાની મંજૂરી નજીકના કોઈ ડિવાઇસ દ્વારા મેળવવામાં આવી શકે છે." "સેટિંગ બદલો" "સેટિંગ અપડેટ કર્યું. ફરીથી કનેક્ટ કરવાનો પ્રયાસ કરો." "પ્રાઇવસી સેટિંગમાં ફેરફાર કરી શકાતો નથી" diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 9e4e6d9e5b1c..4fe032718cce 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -436,7 +436,7 @@ "यह ऐप्लिकेशन किसी भी समय कैमरे का उपयोग करके चित्र ले सकता है और वीडियो रिकॉर्ड कर सकता है." - + "कंपन (वाइब्रेशन) को नियंत्रित करें" "ऐप्स को कंपनकर्ता नियंत्रित करने देता है." @@ -1249,7 +1249,7 @@ "%1$s से कनेक्ट नहीं किया जा सकता" "निजता सेटिंग बदलने और फिर से कोशिश करने के लिए टैप करें" "निजता सेटिंग बदलना चाहते हैं?" - "%1$s आपके डिवाइस के मैक पते (एक खास पहचानकर्ता) का इस्तेमाल करके आपके डिवाइस से कनेक्ट कर सकता है. इससे आस-पास के डिवाइस आपके डिवाइस की जगह की जानकारी को ट्रैक कर सकते हैं. \n\nअगर आप इसे जारी रखते हैं, तो %1$s आपकी निजता सेटिंग बदल देगा और फिर से कनेक्ट करने की कोशिश करेगा." + "कनेक्ट करने के लिए, %1$s को आपके डिवाइस के मैक पते (एक खास पहचानकर्ता) का इस्तेमाल करने की ज़रूरत पड़ेगी. फ़िलहाल, इस नेटवर्क के लिए आपकी निजता सेटिंग, किसी भी क्रम में लगाए गए पहचानकर्ता का इस्तेमाल करती है. \n\nइस बदलाव से, आपके डिवाइस की जगह की जानकारी को आस-पास के डिवाइस ट्रैक कर सकते हैं." "सेटिंग बदलें" "सेटिंग अपडेट की गई है. फिर से कनेक्ट करने की कोशिश करें." "निजता सेटिंग नहीं बदली जा सकती" diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 3c612f0ac50c..f4f27bd7aaec 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -438,7 +438,8 @@ "snimi fotografije i videozapise" "Aplikacija u svakom trenutku može snimati fotografije i videozapise fotoaparatom." "Dopustite aplikaciji ili usluzi da prima povratne pozive o otvaranju ili zatvaranju fotoaparata." - "Aplikacija za potpise može primati povratne pozive prilikom otvaranja (putem nekog paketa aplikacija) ili zatvaranja fotoaparata." + + "upravljanje vibracijom" "Aplikaciji omogućuje nadzor nad vibratorom." "izravno pozivanje telefonskog broja" @@ -1267,7 +1268,7 @@ "Povezivanje s mrežom %1$s nije uspjelo" "Dodirnite da biste promijenili postavke privatnosti i pokušajte ponovo" "Želite li promijeniti postavku privatnosti?" - "Mreža %1$s možda će se htjeti povezati pomoću MAC adrese, jedinstvenog identifikatora, vašeg uređaja. To može omogućiti uređajima u blizini da prate lokaciju vašeg uređaja. \n\nAko nastavite, mreža %1$s promijenit će vašu postavku privatnosti i pokušati se povezati ponovo." + "Da biste se povezali, %1$s treba upotrijebiti MAC adresu, jedinstveni identifikator vašeg uređaja. Vaša postavka privatnosti za tu mrežu trenutačno upotrebljava nasumični identifikator. \n\nTa promjena može omogućiti uređajima u blizini da prate lokaciju vašeg uređaja." "Promijenite postavku" "Postavka je ažurirana. Pokušajte se ponovo povezati." "Promjena postavke privatnosti nije uspjela" diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 315f0f8c6e1f..a2e982db1e60 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -435,7 +435,8 @@ "fotók és videók készítése" "Az alkalmazás a kamera használatával bármikor készíthet fényképeket és rögzíthet videókat." "Visszahívás fogadásának engedélyezése alkalmazás vagy szolgáltatás számára, ha a kamerákat megnyitják vagy bezárják." - "Az aláíró alkalmazás fogadhat visszahívásokat bármelyik kamera (adott alkalmazáscsomag általi) megnyitásakor vagy bezárásakor." + + "rezgés szabályozása" "Lehetővé teszi az alkalmazás számára a rezgés vezérlését." "telefonszámok közvetlen hívása" @@ -1247,7 +1248,7 @@ "Nem lehet csatlakozni a következőhöz: %1$s" "Koppintson az adatvédelmi beállítások módosításához, majd próbálja újra" "Módosítja az adatvédelmi beállítást?" - "Lehet, hogy a(z) %1$s az eszköz egyedi azonosítójaként szolgáló MAC-címmel próbál kapcsolatot létrehozni. Így más közeli eszközök megfigyelhetik saját eszköze helyzetét. \n\nHa továbblép, a(z) %1$s módosítja a vonatkozó adatvédelmi beállítást, majd ismét megkísérli a kapcsolódást." + "A kapcsolódáshoz a(z) %1$s számára szükséges az eszköz egyedi azonosítójaként szolgáló MAC-cím használata. Az adatvédelmi beállításnak megfelelően a rendszer ehhez a hálózathoz jelenleg véletlenszerű azonosítót használ. \n\nEz a módosítás lehetővé teheti, hogy más közeli eszközök megfigyelhessék az Ön eszközének helyzetét." "Beállítás módosítása" "Beállítás frissítve. Próbáljon ismét csatlakozni." "Nem lehet módosítani az adatvédelmi beállítást" diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 67ac61a6dd50..d3a9289ca520 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -435,7 +435,8 @@ "լուսանկարել և տեսանկարել" "Այս հավելվածը կարող է ցանկացած պահի լուսանկարել և տեսագրել՝ օգտագործելով տեսախցիկը:" "Թույլատրել հավելվածին կամ ծառայությանը հետզանգեր ստանալ՝ տեսախցիկների բացվելու և փակվելու դեպքում։" - "Ստորագրությունների այս հավելվածը կարող է հետզանգեր ստանալ՝ ցանկացած տեսախցիկի բացվելու (կնշվի բացող հավելվածը) և փակվելու դեպքում։" + + "կառավարել թրթռումը" "Թույլ է տալիս հավելվածին կառավարել թրթռոցը:" "ուղղակիորեն զանգել հեռախոսահամարներին" @@ -1247,7 +1248,7 @@ "Չհաջողվեց միանալ %1$s սարքին" "Հպեք՝ գաղտնիության կարգավորումները փոփոխելու և նորից փորձելու համար։" "Փոխե՞լ գաղտնիության կարգավորումը" - "%1$s սարքը կարող է միանալ ձեր սարքի MAC հասցեի (եզակի նույնացուցիչի) միջոցով։ Մոտակայքում գտնվող սարքերը կկարողանան հետագծել ձեր սարքի տեղադրությունը։ \n\nԵթե շարունակեք, %1$s սարքը կփոխի գաղտնիության կարգավորումներն ու կփորձի ևս մեկ անգամ միանալ։" + "Միանալու համար %1$s ցանցը պետք է օգտագործի ձեր սարքի MAC հասցեն (եզակի նույնացուցիչը)։ Ներկայումս այս ցանցի ձեր գաղտնիության կարգավորումն օգտագործում է պատահական նույնացուցիչ։ \n\nՄոտակայքում գտնվող սարքերը կկարողանան հետագծել ձեր սարքի տեղադրությունը։" "Փոխել կարգավորումը" "Կարգավորումը թարմացվեց։ Փորձեք նորից միանալ։" "Չհաջողվեց փոփոխել գաղտնիության կարգավորումները" diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 4f32666363b5..afb77bcdb983 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -435,7 +435,8 @@ "ambil gambar dan video" "Aplikasi ini dapat mengambil foto dan merekam video menggunakan kamera kapan saja." "Izinkan aplikasi atau layanan untuk menerima callback tentang perangkat kamera yang sedang dibuka atau ditutup." - "Aplikasi tanda tangan ini dapat menerima callback saat perangkat kamera sedang dibuka (oleh paket aplikasi) atau ditutup." + + "kontrol getaran" "Mengizinkan aplikasi untuk mengendalikan vibrator." "panggil nomor telepon secara langsung" @@ -1247,7 +1248,7 @@ "Tidak dapat terhubung ke %1$s" "Ketuk untuk mengubah setelan privasi dan coba lagi" "Ubah setelan privasi?" - "%1$s mungkin ingin terhubung menggunakan alamat MAC perangkat Anda, yaitu ID unik. Alamat ini memungkinkan lokasi perangkat dilacak oleh perangkat di sekitar. \n\nJika Anda melanjutkan, %1$s akan mengubah setelan privasi dan mencoba terhubung lagi." + "Untuk terhubung, %1$s perlu menggunakan alamat MAC perangkat, yaitu ID unik. Saat ini, setelan privasi untuk jaringan ini menggunakan ID yang diacak. \n\nPerubahan ini memungkinkan lokasi perangkat dilacak oleh perangkat di sekitar." "Ganti setelan" "Setelan diperbarui. Coba hubungkan lagi." "Tidak dapat mengubah setelan privasi" diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 340d8a5067de..a6793f47238c 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -435,7 +435,8 @@ "taka myndir og myndskeið" "Þetta forrit getur tekið myndir og tekið upp myndskeið með myndavélinni hvenær sem er." "Leyfa forriti eða þjónustu að taka við svörum um myndavélar sem verið er að opna eða loka." - "Þetta undirritunarforrit getur tekið við svörum þegar verið er að opna (með forritapakka) eða loka hvaða myndavél sem er." + + "stjórna titringi" "Leyfir forriti að stjórna titraranum." "hringja beint í símanúmer" @@ -1247,7 +1248,7 @@ "Ekki hægt að tengjast %1$s" "Ýttu til að breyta persónuverndarstillingum og reyna aftur" "Viltu breyta persónuverndarstillingunni?" - "%1$s gæti viljað tengjast með því að nota MAC-vistfang tækisins, sem er einkvæmt auðkenni þess. Þetta getur gert nálægum tækjum kleift að rekja staðsetningu tækisins. \n\nEf þú heldur áfram mun %1$s breyta persónuverndarstillingu þinni og reyna aftur að tengjast." + "Til að tengjast þarf %1$s að nota MAC-vistfang tækisins, sem er einkvæmt auðkenni þess. Núverandi persónuverndarstillingar þínar fyrir þetta net nota auðkenni sem valið er af handahófi. \n\nÞessi breyting getur gert nálægum tækjum kleift að rekja staðsetningu tækisins." "Breyta stillingu" "Stilling uppfærð. Reyndu aftur að tengja." "Ekki er hægt að breyta persónuverndarstillingu" diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index ef0df2d2c10f..b0b206173cb6 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -435,7 +435,8 @@ "acquisizione di foto e video" "Questa app può scattare foto e registrare video tramite la fotocamera in qualsiasi momento." "Consenti a un\'applicazione o a un servizio di ricevere callback relativi all\'apertura o alla chiusura di videocamere." - "Questa app di firma può ricevere callback quando viene aperta (da quale pacchetto dell\'applicazione) o chiusa qualsiasi videocamera." + + "controllo vibrazione" "Consente all\'applicazione di controllare la vibrazione." "chiamata diretta n. telefono" @@ -1247,7 +1248,7 @@ "Impossibile connettersi alla rete %1$s" "Tocca per cambiare le impostazioni sulla privacy e riprova" "Vuoi cambiare l\'impostazione sulla privacy?" - "%1$s potrebbe richiedere la connessione usando l\'indirizzo MAC del dispositivo, ossia un identificatore univoco. In questo caso la posizione del dispositivo potrebbe essere monitorata da dispositivi nelle vicinanze. \n\nSe continui, %1$s cambierà la tua impostazione sulla privacy e riproverà a connettersi." + "Per la connessione, la rete %1$s deve usare l\'indirizzo MAC del dispositivo, ossia un identificatore univoco. L\'impostazione sulla privacy attuale relativa a questa rete prevede l\'uso di un identificatore casuale. \n\nQuesta modifica potrebbe consentire il monitoraggio della posizione del tuo dispositivo da parte di dispositivi nelle vicinanze." "Cambia l\'impostazione" "Impostazione aggiornata. Riprova a connetterti." "Impossibile cambiare l\'impostazione sulla privacy" diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 196cf46b2356..7a954911600b 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -441,7 +441,8 @@ "צלם תמונות וסרטונים" "אפליקציה זו יכולה להשתמש במצלמה כדי לצלם תמונות ולהקליט סרטונים בכל עת." "‏אפליקציה או שירות יוכלו לקבל קריאות חוזרות (callback) כשמכשירי מצלמה ייפתחו או ייסגרו." - "‏אפליקציית הפרימיום הזו יכולה לקבל קריאות חוזרות (callback) כשמכשיר מצלמה כלשהו נפתח (באמצעות חבילת אפליקציה) או נסגר." + + "שליטה ברטט" "מאפשר לאפליקציה לשלוט ברטט." "התקשר ישירות למספרי טלפון" @@ -1287,7 +1288,7 @@ "לא ניתן להתחבר אל %1$s" "יש להקיש כדי לשנות את הגדרות הפרטיות ולנסות שוב" "לשנות את הגדרות הפרטיות?" - "‏ייתכן שיידרש ל-%1$s חיבור באמצעות כתובת ה-MAC של המכשיר, שמהווה מזהה ייחודי. באופן זה, מכשירים בקרבת מקום עשויים לקבל הרשאה לעקוב אחר מיקום המכשיר שלך. \n\nהמשך הפעולה יאפשר ל-%1$s לשנות את הגדרות הפרטיות ולנסות להתחבר שוב." + "‏כדי לחבר, עליך לאפשר ל-%1$s להשתמש בכתובת ה-MAC של המכשיר, מזהה ייחודי. הגדרת הפרטיות לרשת זו משתמשת כרגע במזהה רנדומלי. \n\nשינוי זה עשוי לאפשר למכשירים בקרבת מקום לעקוב אחר מיקום המכשיר שלך." "שינוי ההגדרות" "ההגדרה עודכנה. אפשר לנסות שוב להתחבר." "לא ניתן לשנות את הגדרות הפרטיות" diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index ef64d4403f4e..16da3ac4b1a3 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -435,7 +435,8 @@ "写真と動画の撮影" "このアプリは、いつでもカメラを使用して写真や動画を撮影できます。" "カメラデバイスが起動または終了したときにコールバックを受け取ることを、アプリまたはサービスに許可してください。" - "この署名アプリを使用すると、カメラデバイスが(なんらかのアプリ パッケージによって)起動するとき、または終了するときにコールバックを受け取ることができます。" + + "バイブレーションの制御" "バイブレーションの制御をアプリに許可します。" "電話番号発信" @@ -1247,7 +1248,7 @@ "%1$s に接続できません" "タップしてプライバシー設定を変更し、もう一度お試しください" "プライバシー設定を変更しますか?" - "%1$s があなたのデバイスの MAC アドレス(固有の識別番号)を使用して接続できるようになります。これにより、付近のデバイスがあなたのデバイスの位置情報を追跡できるようになる可能性があります。\n\n続行すると、%1$s があなたのプライバシー設定を変更し、もう一度接続を試みます。" + "%1$s は接続のために、あなたのデバイスの MAC アドレス(固有の識別番号)を使用する必要があります。現在、このネットワークのプライバシー設定では、ランダム ID を使用しています。\n\nこの変更により、付近のデバイスがあなたのデバイスの位置情報を追跡できるようになる可能性があります。" "設定を変更" "設定を更新しました。もう一度接続してみてください。" "プライバシー設定を変更できません" diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 2d6c9f65e855..467718cafb24 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -435,7 +435,8 @@ "სურათებისა და ვიდეოების გადაღება" "ამ აპს ნებისმიერ დროს შეუძლია კამერით სურათების გადაღება და ვიდეოების ჩაწერა." "ნება დაერთოს აპლიკაციას ან სერვისს, მიიღოს გადმორეკვები კამერის მოწყობილობის გახსნის ან დახურვისას." - "ამ მინაწერის აპს შეუძლია მიიღოს გადმორეკვები, როდესაც რომელიმე კამერის მოწყობილობა იხსნება (რომელიმე აპლიკაციის პაკეტით) ან იხურება." + + "ვიბრაციის კონტროლი" "აპს შეეძლება, მართოს ვიბრირება." "პირდაპირი დარეკვა ტელეფონის ნომრებზე" @@ -1247,7 +1248,7 @@ "%1$s-თან დაკავშირება ვერ ხერხდება" "შეეხეთ კონფიდენციალურობის პარამეტრების შესაცვლელად და ცადეთ ხელახლა" "შეიცვალოს კონფიდენციალურობის პარამეტრი?" - "%1$s-ს შეიძლება სურდეს დაკავშირება თქვენი მოწყობილობის MAC მისამართის, უნიკალური იდენტიფიკატორის, გამოყენებით. ამან შიძლება თქვენი მოწყობილობის მდებარეობა ახლომახლო მოწყობილობებისთვის ხილული გახადოს. \n\nთუ განაგრძობთ, %1$s შეცვლის თქვენს კონფიდენციალურობის პარამეტრს და ხელახლა შეეცდება დაკავშირებას." + "დასაკავშირებლად %1$s საჭიროებს თქვენი მოწყობილობის MAC მისამართის, უნიკალური იდენტიფიკატორის, გამოყენებას. ამჟამად თქვენი კონფიდენციალურობის პარამეტრი ამ ქსელისთვის შემთხვევით იდენტიფიკატორს იყენებს. \n\nამ ცვლილებამ შეიძლება თქვენი მოწყობილობის მდებარეობა ახლომახლო მოწყობილობებისთვის ხილული გახადოს." "პარამეტრის შეცვლა" "პარამეტრი განახლდა. ცადეთ ხელახლა დაკავშირება." "კონფიდენციალურობის პარამეტრის შეცვლა ვერ ხერხდება" diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index e56670b4aefc..8d9d3ec0ebdd 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -435,7 +435,8 @@ "фотосурет жасау және бейне жазу" "Бұл қолданба кез келген уақытта камерамен суретке түсіруі және бейнелерді жазуы мүмкін." "Қолданбаға не қызметке ашылып не жабылып жатқан камера құрылғылары туралы кері шақыру алуға рұқсат ету" - "Кез келген камера ашылып (көрсетілген қолданба пакеті арқылы) не жабылып жатқанда, бұл қолтаңба қолданбасы кері шақыру алады." + + "тербелісті басқару" "Қолданбаға вибраторды басқаруға рұқсат береді." "нөмірлерге тікелей телефон шалу" @@ -1247,7 +1248,7 @@ "%1$s желісіне қосылу мүмкін емес." "Құпиялылық параметрін өзгерту үшін түртіп, әрекетті қайталаңыз." "Құпиялылық параметрі өзгертілсін бе?" - "%1$s бірегей идентификатор болып саналатын құрылғыңыздың MAC мекенжайы арқылы қосылғысы келуі мүмкін. Бұл маңайдағы құрылғыларға құрылғыңыздың орнын қадағалауға мүмкіндік береді. \n\nӘрекетті жалғастырсаңыз, %1$s желісі құпиялылық параметрін өзгертіп, қайта қосылып көреді." + "Қосылу үшін %1$s құрылғының MAC мекенжайын, бірегей идентификаторын қажет етеді. Қазір желінің құпиялылық параметрі рандомизацияланған идентификаторды пайдаланады. \n\nБұл өзгеріс маңайдағы құрылғыларға сіздің құрылғыңыздың орнын қадағалауға мүмкіндік береді." "Параметрді өзгерту" "Параметр жаңартылды. Қайта қосылып көріңіз." "Құпиялылық параметрі өзгертілмейді." diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 946c99144444..dbcdeb14d47b 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -435,7 +435,8 @@ "ថត​រូប និងវីដេអូ" "កម្មវិធី​នេះ​អាច​ថត​រូប​ និង​ថត​វីដេអូ​ ដោយ​ប្រើ​កាមេរ៉ា​បាន​គ្រប់​ពេល​។" "អនុញ្ញាតឱ្យកម្មវិធី ឬសេវាកម្ម​ទទួលការហៅត្រឡប់វិញអំពី​កាមេរ៉ាដែលកំពុងបិទ ឬបើក។" - "កម្មវិធីពិសេសនេះ​អាចទទួលការហៅត្រឡប់វិញបាន នៅពេលកំពុងបិទ ឬបើកកាមេរ៉ា (ដោយកញ្ចប់កម្មវិធី)។" + + "ពិនិត្យ​ការ​ញ័រ" "ឲ្យ​កម្មវិធី​គ្រប់គ្រង​កម្មវិធី​ញ័រ។" "ហៅ​លេខ​ទូរស័ព្ទ​ដោយ​ផ្ទាល់" @@ -1249,7 +1250,7 @@ "មិនអាច​ភ្ជាប់​ជាមួយ %1$s បានទេ" "ចុច ដើម្បី​ប្ដូរ​ការកំណត់​ឯកជនភាព រួច​ព្យាយាម​ម្ដងទៀត" "ប្ដូរ​ការកំណត់​ឯកជនភាព​ឬ?" - "%1$s ប្រហែលជា​ចង់ភ្ជាប់ ដោយប្រើ​អាសយដ្ឋាន MAC របស់​ឧបករណ៍អ្នក ដែលជា​ព័ត៌មាន​សម្គាល់​ពិសេស។ សកម្មភាពនេះ​អាចអនុញ្ញាតឱ្យ​ឧបករណ៍​នៅជិត​តាមដាន​ទីតាំង​ឧបករណ៍​របស់អ្នក។ \n\nប្រសិនបើអ្នកបន្ត %1$s នឹងប្ដូរការកំណត់​ឯកជនភាព​របស់អ្នក រួចព្យាយាមភ្ជាប់ម្ដងទៀត។" + "ដើម្បីភ្ជាប់ %1$s ត្រូវការប្រើ​អាសយដ្ឋាន MAC របស់​ឧបករណ៍អ្នក ដែលជា​ព័ត៌មាន​សម្គាល់​ពិសេស។ បច្ចុប្បន្ន ការកំណត់​ឯកជនភាពរបស់អ្នកសម្រាប់បណ្ដាញនេះប្រើព័ត៌មានសម្គាល់ចៃដន្យ។ \n\nការផ្លាស់ប្ដូរនេះ​អាចអនុញ្ញាតឱ្យ​ឧបករណ៍​នៅជិតតាមដានទីតាំង​ឧបករណ៍​របស់អ្នក។" "ប្ដូរការ​កំណត់" "បាន​ធ្វើ​បច្ចុប្បន្នភាព​ការ​កំណត់។ សូម​សាកល្បង​ភ្ជាប់ម្ដងទៀត។" "មិនអាច​ប្ដូរ​ការកំណត់​ឯកជនភាព​បានទេ" diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index d99f0b077dfb..2038719b1c22 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -435,7 +435,8 @@ "ಚಿತ್ರಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳನ್ನು ಸೆರೆಹಿಡಿಯಿರಿ" "ಈ ಅಪ್ಲಿಕೇಶನ್ ಯಾವ ಸಮಯದಲ್ಲಾದರೂ ಕ್ಯಾಮರಾ ಬಳಸಿಕೊಂಡು ಚಿತ್ರಗಳು ಮತ್ತು ವಿಡಿಯೋಗಳನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಬಹುದು." "ಕ್ಯಾಮರಾ ಸಾಧನಗಳನ್ನು ತೆರೆಯುತ್ತಿರುವ ಅಥವಾ ಮುಚ್ಚುತ್ತಿರುವ ಕುರಿತು ಕಾಲ್‌ಬ್ಯಾಕ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಆ್ಯಪ್‌ ಅಥವಾ ಸೇವೆಗೆ ಅನುಮತಿಸಿ." - "ಈ ಸಹಿ ಆ್ಯಪ್, ಯಾವುದೇ ಕ್ಯಾಮರಾ ಸಾಧನವನ್ನು ತೆರೆಯುತ್ತಿರುವಾಗ ಅಥವಾ ಮುಚ್ಚುತ್ತಿರುವಾಗ (ಯಾವ ಆ್ಯಪ್‌ ಪ್ಯಾಕೇಜ್‌ನಿಂದ ಎಂಬ ಮಾಹಿತಿಯ ಮೂಲಕ) ಕಾಲ್‌ಬ್ಯಾಕ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಬಹುದು." + + "ವೈಬ್ರೇಷನ್‌‌ ನಿಯಂತ್ರಿಸಿ" "ವೈಬ್ರೇಟರ್‌ ನಿಯಂತ್ರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ." "ಫೋನ್ ಸಂಖ್ಯೆಗಳಿಗೆ ನೇರವಾಗಿ ಕರೆ ಮಾಡಿ" @@ -1247,7 +1248,7 @@ "%1$s ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ" "ಗೌಪ್ಯತೆ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಮರುಪ್ರಯತ್ನಿಸಿ" "ಗೌಪ್ಯತೆ ಸೆಟ್ಟಿಂಗ್ ಅನ್ನು ಬದಲಾಯಿಸಬೇಕೆ?" - "%1$s ನಿಮ್ಮ ಸಾಧನದ MAC ವಿಳಾಸವನ್ನು ಬಳಸಿಕೊಂಡು ಕನೆಕ್ಟ್ ಮಾಡಲು ಬಯಸಬಹುದು, ಅದು ಅನನ್ಯ ಗುರುತಿಸುವಿಕೆಯಾಗಿದೆ. ನಿಮ್ಮ ಸಾಧನದ ಸ್ಥಳವನ್ನು ಪತ್ತೆಹಚ್ಚಲು ಹತ್ತಿರದ ಸಾಧನವನ್ನು ಇದು ಅನುಮತಿಸಬಹುದು. \n\nನೀವು ಮುಂದುವರಿಸಿದರೆ, %1$s ನಿಮ್ಮ ಗೌಪ್ಯತೆ ಸೆಟ್ಟಿಂಗ್ ಅನ್ನು ಬದಲಾಯಿಸುತ್ತದೆ ಮತ್ತು ಪುನಃ ಕನೆಕ್ಟ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸುತ್ತದೆ." + "ಕನೆಕ್ಟ್ ಮಾಡಲು, %1$s ಗೆ ನಿಮ್ಮ ಸಾಧನದ ಅನನ್ಯ ಗುರುತು MAC ವಿಳಾಸವನ್ನು ಬಳಸುವ ಅಗತ್ಯವಿದೆ. ಪ್ರಸ್ತುತವಾಗಿ, ಈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಬಂಧಿಸಿದ ಗೌಪ್ಯತೆಯ ಸೆಟ್ಟಿಂಗ್ \'ಯಾದೃಚ್ಛಿಕ\' ಗುರುತಿಸುವಿಕೆಯನ್ನು ಬಳಸುತ್ತದೆ. \n\nಈ ಬದಲಾವಣೆಯು, ನಿಮ್ಮ ಸಾಧನದ ಸ್ಥಳವನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಲು, ಸಮೀಪದಲ್ಲಿನ ಸಾಧನಗಳಿಗೆ ಅನುಮತಿಸಬಹುದು." "ಸೆಟ್ಟಿಂಗ್‌‌ ಬದಲಾಯಿಸಿ" "ಸೆಟ್ಟಿಂಗ್ ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಲಾಗಿದೆ. ಪುನಃ ಕನೆಕ್ಟ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿ." "ಗೌಪ್ಯತೆ ಸೆಟ್ಟಿಂಗ್‌ ಅನ್ನು ಬದಲಾಯಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ" diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 712226c4d5b8..de28f99bcd9d 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -435,7 +435,8 @@ "사진과 동영상 찍기" "이 앱은 언제든지 카메라를 사용하여 사진을 촬영하고 동영상을 녹화할 수 있습니다." "애플리케이션 또는 서비스에서 카메라 기기 열림 또는 닫힘에 대한 콜백을 수신하도록 허용" - "이 서명 앱은 사용되는 애플리케이션 패키지와 관련 없이 카메라 기기가 열릴 때나 닫힐 때 콜백을 수신할 수 있습니다." + + "진동 제어" "앱이 진동을 제어할 수 있도록 허용합니다." "전화번호 자동 연결" @@ -1247,7 +1248,7 @@ "\'%1$s\'에 연결할 수 없음" "탭하여 개인정보 보호 설정을 변경하고 다시 시도하세요." "개인정보 보호 설정을 변경하시겠습니까?" - "%1$s에서 기기의 고유한 식별자인 MAC 주소를 사용하여 연결을 시도할 수도 있습니다. 이 경우 근처 기기가 내 기기의 위치를 추적할 수도 있습니다. \n\n계속하면 %1$s에서 개인정보 보호 설정을 변경한 다음 연결을 다시 시도합니다." + "연결하려면 %1$s에서 기기의 고유 식별자인 MAC 주소를 사용해야 합니다. 현재 이 네트워크의 개인정보 보호 설정에서는 무작위 식별자를 사용합니다. \n\n변경할 경우 근처 기기가 내 기기의 위치 정보를 추적할 수도 있습니다." "설정 변경" "설정이 업데이트되었습니다. 다시 연결해 보세요." "개인정보 보호 설정을 변경할 수 없습니다." diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index e2e19508d392..b6cff08122d4 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -435,7 +435,8 @@ "сүрөт жана видео тартуу" "Бул колдонмо каалаган убакта камера менен сүрөт же видеолорду тарта алат." "Колдонмого же кызматка камера ачылып же жабылып жатканда чалууларды кабыл алууга уруксат берүү." - "Бул колдонмо камера ачылып же жабылып жатканда (колдонмонун таңгагы) чалууларды кабыл алат." + + "титирөөнү башкаруу" "Колдонмого дирилдегичти көзөмөлдөө мүмкүнчүлүгүн берет." "телефон номерлерине түз чалуу" @@ -1247,7 +1248,7 @@ "\"%1$s\" тармагына туташпай койду" "Купуялык жөндөөлөрүн өзгөртүү үчүн таптап, кайталап көрүңүз" "Купуялык жөндөөлөрүн өзгөртөсүзбү?" - "%1$s түзмөгүңүздүн MAC дарегин, уникалдуу идентификаторуңузду колдонуп туташканы жатат. Ушуну менен түзмөгүңүздүн жайгашкан жерине жакын жердеги түзмөктөр көз сала алышат. \n\nЭгер улантсаңыз, %1$s купуялык жөндөөлөрүңүздү өзгөртүп, кайра туташууга аракет кылат." + "Туташуу үчүн %1$s MAC дарегиңизди – уникалдуу идентификаторду колдонушу керек. Учурда бул тармактын купуялык жөндөөсү башаламан иретте түзүлгөн идентификаторду колдонууда. \n\nУшуну менен түзмөгүңүздүн жайгашкан жерине жакын жердеги түзмөктөр көз сала алышат." "Жөндөөнү өзгөртүү" "Жөндөө жаңырды. Кайра туташып көрүңүз." "Купуялык жөндөөлөрүн өзгөртүүгө болбойт" diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 3367722c867d..9396d3eafc2f 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -435,7 +435,8 @@ "ຖ່າຍຮູບ ແລະວິດີໂອ" "This app can take pictures and record videos using the camera at any time." "ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ຫຼື ບໍລິການຮັບການເອີ້ນກັບກ່ຽວກັບອຸປະກອນກ້ອງຖືກເປີດ ຫຼື ປິດໄດ້." - "ແອັບລາຍເຊັນນີ້ສາມາດຮັບການເອີ້ນກັບໄດ້ເມື່ອມີອຸປະກອນກ້ອງໃດຖືກເປີດ (ໂດຍແພັກເກດແອັບພລິເຄຊັນຫຍັງ) ຫຼື ຖືກປິດ." + + "ຄວບຄຸມການສັ່ນ" "ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມໂຕສັ່ນ." "ໂທຫາເບີໂທລະສັບໂດຍກົງ" @@ -1247,7 +1248,7 @@ "ບໍ່ສາມາດເຊື່ອມຕໍ່ຫາ %1$s ໄດ້" "ແຕະເພື່ອປ່ຽນການຕັ້ງຄ່າຄວາມເປັນສ່ວນຕົວແລ້ວລອງໃໝ່" "ປ່ຽນການຕັ້ງຄ່າຄວາມເປັນສ່ວນຕົວບໍ?" - "%1$s ອາດຕ້ອງການເຊື່ອມຕໍ່ໂດຍໃຊ້ທີ່ຢູ່ MAC ອຸປະກອນຂອງທ່ານ, ເຊິ່ງເປັນຕົວລະບຸທີ່ບໍ່ຊ້ຳກັນ. ນີ້ອາດອະນຸຍາດໃຫ້ອຸປະກອນໃກ້ຄຽງສາມາດຕິດຕາມສະຖານທີ່ຂອງອຸປະກອນທ່ານໄດ້. \n\nຫາກທ່ານສືບຕໍ່, %1$s ຈະປ່ຽນການຕັ້ງຄ່າຄວາມເປັນສ່ວນຕົວຂອງທ່ານ ແລະ ລອງເຊື່ອມຕໍ່ອີກເທື່ອໜຶ່ງ." + "ເພື່ອເຊື່ອມຕໍ່, %1$s ຈຳເປັນຕ້ອງໃຊ້ທີ່ຢູ່ MAC ອຸປະກອນຂອງທ່ານ, ເຊິ່ງເປັນຕົວລະບຸແບບບໍ່ຊ້ຳກັນ. ຕອນນີ້, ການຕັ້ງຄ່າຄວາມເປັນສ່ວນຕົວຂອງທ່ານສຳລັບເຄືອຂ່າຍນີ້ໃຊ້ຕົວລະບຸແບບສຸ່ມຢູ່. \n\nການປ່ຽນແປງນີ້ອາດຈະເຮັດໃຫ້ອຸປະກອນໃກ້ຄຽງສາມາດຕິດຕາມສະຖານທີ່ຂອງອຸປະກອນທ່ານໄດ້." "ປ່ຽນການຕັ້ງຄ່າ" "ອັບເດດການຕັ້ງຄ່າແລ້ວ ລອງເຊື່ອມຕໍ່ໃໝ່." "ບໍ່ສາມາດປ່ຽນການຕັ້ງຄ່າຄວາມເປັນສ່ວນຕົວໄດ້" diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 282fa238ab56..0ce61bad2f57 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -441,7 +441,8 @@ "fotografuoti ir filmuoti" "Ši programa gali bet kada fotografuoti ir įrašyti vaizdo įrašų naudodama fotoaparatą." "Leisti programai ar paslaugai sulaukti atgalinio skambinimo, kai atidaromas ar uždaromas fotoaparatas." - "Ši pasirašymo programa gali sulaukti atgalinio skambinimo, kai atidaromas ar uždaromas (kurio nors programos paketo) koks nors fotoaparatas." + + "valdyti vibraciją" "Leidžiama programai valdyti vibravimą." "skambinti tiesiogiai telefono numeriais" @@ -1287,7 +1288,7 @@ "Nepavyksta prisijungti prie „%1$s“" "Palieskite, kad pakeistumėte privatumo nustatymus, ir bandykite dar kartą" "Keisti privatumo nustatymą?" - "„%1$s“ gali norėti prisijungti naudodamas jūsų įrenginio MAC adresą – unikalų identifikatorių. Gali būti, kad tokiu atveju įrenginio vietovę galės stebėti netoliese esantys įrenginiai. \n\nJei tęsite, „%1$s“ pakeis jūsų privatumo nustatymus ir bandys prisijungti iš naujo." + "Kad galėtų prisijungti, %1$s reikia jūsų įrenginio MAC adreso, unikaliojo identifikatoriaus. Šiuo metu šio tinklo privatumo nustatymas naudoja atsitiktinio parinkimo identifikatorių. \n\nGali būti, kad atlikus šį pakeitimą įrenginio vietovę galės stebėti netoliese esantys įrenginiai." "Keisti nustatymą" "Nustatymas atnaujintas. Bandykite prisijungti dar kartą." "Nepavyko pakeisti privatumo nustatymo" diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 17dfeaa04772..671be2600580 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -438,7 +438,8 @@ "uzņemt attēlus un videoklipus" "Šī lietotne jebkurā brīdī var uzņemt attēlus un ierakstīt videoklipus, izmantojot kameru." "Atļaut lietojumprogrammai vai pakalpojumam saņemt atzvanus par kameras ierīču atvēršanu vai aizvēršanu" - "Šajā parakstu lietotnē var saņemt atzvanus, ja tiek atvērta vai aizvērta jebkāda kameras ierīce (atkarībā no lietojumprogrammas pakotnes)." + + "kontrolēt vibrosignālu" "Ļauj lietotnei kontrolēt vibrosignālu." "tieši zvanīt uz tālruņa numuriem" @@ -1267,7 +1268,7 @@ "Nevar izveidot savienojumu ar tīklu %1$s" "Pieskarieties, lai mainītu konfidencialitātes iestatījumus un mēģinātu vēlreiz" "Vai mainīt konfidencialitātes iestatījumu?" - "%1$s vēlas izveidot savienojumu, izmantojot jūsu ierīces MAC adresi, unikālu identifikatoru. Tādējādi tuvumā esošās ierīces var izsekot jūsu ierīces atrašanās vietu. \n\nJa turpināsiet, %1$s mainīs jūsu konfidencialitātes iestatījumu un vēlreiz mēģinās izveidot savienojumu." + "Lai varētu izveidot savienojumu, %1$s vēlas izmantot jūsu ierīces MAC adresi, unikālu identifikatoru. Pašlaik šī tīkla konfidencialitātes iestatījumam tiek izmantots nejauši atlasīts identifikators. \n\nTādējādi tuvumā esošās ierīces var izsekot jūsu ierīces atrašanās vietu." "Mainīt iestatījumu" "Iestatījums ir atjaunināts. Mēģiniet izveidot savienojumu vēlreiz." "Nevar mainīt konfidencialitātes iestatījumu." diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index fcfa19500706..1d1d4bbdb124 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -435,7 +435,8 @@ "снимај слики и видеа" "Апликацијава може да фотографира и да снима видеа со камерата во секое време." "Дозволете апликацијатa или услугата да прима повратни повици за отворањето или затворањето на уредите со камера." - "Оваа апликација за потпис може да прима повратни повици кога кој било уред со камера (од некој пакет за апликации) е отворен или затворен." + + "контролирај вибрации" "Дозволува апликацијата да ги контролира вибрациите." "директно избирај телефонски броеви" @@ -1247,7 +1248,7 @@ "Не може да се поврзе на „%1$s“" "Допрете за да ги промените поставките за приватност и обидете се повторно" "Да се променат поставките за приватност?" - "%1$s можно е да сака да се поврзе со MAC-адресата на вашиот уред, којашто е уникатен идентификатор. Ова може да дозволи уреди во близина да ја следат локацијата на вашиот уред. \n\nАко продолжите, „%1$s“ ќе ги промени поставките за приватност и ќе се обиде да се поврзе повторно." + "За да се поврзе, %1$s треба да ја користи MAC-адресата на вашиот уред, којашто е уникатен идентификатор. Поставките за приватност за мрежава користат рандомизиран идентификатор во моментов. \n\nПроменава може да им дозволи на уредите во близина да ја следат локацијата на вашиот уред." "Променете ги поставките" "Поставките се ажурирани. Обидете се да се поврзете повторно." "Не може да се променат поставките за приватност" diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index fb19c7e14dd8..d9c97afb841f 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -435,7 +435,7 @@ "ചിത്രങ്ങളും വീഡിയോകളും എടുക്കുക" "ഏതുസമയത്തും ക്യാമറ ഉപയോഗിച്ചുകൊണ്ട് ചിത്രങ്ങൾ എടുക്കാനും വീഡിയോകൾ റെക്കോർഡുചെയ്യാനും ഈ ആപ്പിന് കഴിയും." "ക്യാമറയുള്ള ഉപകരണങ്ങൾ ഓണാക്കുന്നതിനെയോ അടയ്ക്കുന്നതിനെയോ കുറിച്ചുള്ള കോൾബാക്കുകൾ സ്വീകരിക്കാൻ ആപ്പിനെയോ സേവനത്തെയോ അനുവദിക്കുക." - "ക്യാമറയുള്ള ഏതെങ്കിലും ഉപകരണം ഓണാക്കുമ്പോഴോ (ആപ്പ് പാക്കേജ് മുഖേന) അടയ്ക്കുമ്പോഴോ ഈ സിഗ്‌നേച്ചർ ആപ്പിന് കോൾബാക്കുകൾ സ്വീകരിക്കാനാവും." + "ക്യാമറയുള്ള ഏതെങ്കിലും ഉപകരണം ഓണാക്കുമ്പോഴോ (ആപ്പ് മുഖേന) അടയ്ക്കുമ്പോഴോ ഈ ആപ്പിന് കോൾബാക്കുകൾ സ്വീകരിക്കാനാവും." "വൈബ്രേറ്റുചെയ്യൽ നിയന്ത്രിക്കുക" "വൈബ്രേറ്റർ നിയന്ത്രിക്കുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു." "ഫോൺ നമ്പറുകളിലേക്ക് നേരിട്ട് വിളിക്കുക" @@ -1247,7 +1247,7 @@ "%1$s-ലേക്ക് കണക്‌റ്റ് ചെയ്യാനാവുന്നില്ല" "സ്വകാര്യതാ ക്രമീകരണം മാറ്റാൻ ടാപ്പ് ചെയ്യുക, വീണ്ടും ശ്രമിക്കുക" "സ്വകാര്യതാ ക്രമീകരണം മാറ്റണോ?" - "ഒരു തനത് ഐഡന്റിഫയറായ നിങ്ങളുടെ ഉപകരണ MAC വിലാസം ഉപയോഗിച്ച് കണക്റ്റ് ചെയ്യാൻ %1$s താൽപ്പര്യപ്പെട്ടേക്കാം. നിങ്ങളുടെ ഉപകരണത്തിന്റെ സ്ഥാനം ട്രാക്ക് ചെയ്യാൻ സമീപത്തുള്ള ഉപകരണങ്ങളെ ഇത് അനുവദിച്ചേക്കാം. \n\nനിങ്ങൾ തുടരുന്നെങ്കിൽ, %1$s നിങ്ങളുടെ സ്വകാര്യതാ ക്രമീകരണം മാറ്റി വീണ്ടും ബന്ധിപ്പിക്കാൻ ശ്രമിക്കും." + "കണക്‌റ്റ് ചെയ്യാൻ, തനത് ഐഡന്റിഫയറായ MAC വിലാസം %1$s ഉപയോഗിക്കിക്കേണ്ടതുണ്ട്. നിലവിൽ, ക്രമരഹിതമാക്കിയ ഐഡന്റിഫയർ ആണ് ഈ നെറ്റ്‌വർക്കിന്റെ സ്വകാര്യതാ ക്രമീകരണം ഉപയോഗിക്കുന്നത്. \n\nനിങ്ങളുടെ ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ട്രാക്ക് ചെയ്യാൻ സമീപത്തുള്ള ഉപകരണങ്ങളെ ഈ മാറ്റം അനുവദിച്ചേക്കാം." "ക്രമീകരണം മാറ്റുക" "ക്രമീകരണം അപ്‌ഡേറ്റ് ചെയ്തു. വീണ്ടും കണക്‌റ്റ് ചെയ്യാൻ ശ്രമിക്കുക." "സ്വകാര്യതാ ക്രമീകരണം മാറ്റാനാവില്ല" diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 0234996f8587..c06c48251a7d 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -435,7 +435,7 @@ "зураг авах болон видео бичих" "Энэ апп ямар ч үед камер ашиглан зураг авж, видео хийх боломжтой." "Аппликэйшн эсвэл үйлчилгээнд камерын төхөөрөмжүүдийг нээж эсвэл хааж байгаа тухай залгасан дуудлага хүлээн авахыг зөвшөөрөх." - "Гарын үсгийн энэ апп нь дурын камерын төхөөрөмжийг нээх (ямар аппликэйшний багцаар болох) эсвэл хаах үед буцааж залгасан дуудлага хүлээн авах боломжтой." + "Энэ апп нь дурын камерын төхөөрөмжийг нээх (ямар аппликэйшнээр болох) эсвэл хаах үед буцааж залгасан дуудлага хүлээн авах боломжтой." "чичиргээг удирдах" "Апп нь чичиргээг удирдах боломжтой." "утасны дугаарт шууд дуудлага хийх" @@ -1247,7 +1247,7 @@ "%1$s-д холбогдож чадсангүй" "Нууцлалын тохиргоог өөрчлөхийн тулд товшоод, дахин оролдоно уу" "Нууцлалын тохиргоог өөрчлөх үү?" - "%1$s нь өвөрмөц таниулбар болох таны төхөөрөмжийн MAC хаягийг ашиглан холбогдохыг хүсэж болзошгүй. Энэ нь ойролцоох төхөөрөмжүүдэд таны төхөөрөмжийн байршлыг тандахыг зөвшөөрч болзошгүй. \n\nХэрэв та үргэлжлүүлбэл %1$s нь таны нууцлалын тохиргоог өөрчилж, дахин холбогдохыг оролдоно." + "Холбогдохын тулд %1$s нь таны төхөөрөмжийн өвөрмөц таниулбар болох MAC хаягийг ашиглах хэрэгтэй байна. Одоогоор энэ сүлжээнд зориулсан таны нууцлалын тохиргоо нь санамсаргүй сонгосон таниулбарыг ашиглаж байна. \n\nЭнэ өөрчлөлт нь ойролцоох төхөөрөмжүүдэд таны төхөөрөмжийн байршлыг тандахыг зөвшөөрч болзошгүй." "Тохиргоог өөрчлөх" "Тохиргоог шинэчиллээ. Дахин холбогдохыг оролдоно уу." "Нууцлалын тохиргоог өөрчлөх боломжгүй байна" diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index f0fdc6763126..0b930054a498 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -435,7 +435,8 @@ "चित्रे आणि व्हिडिओ घ्या" "हा अ‍ॅप कोणत्याही वेळी कॅमेरा वापरून चित्रेे घेऊ आणि व्ह‍िडिओ रेकॉर्ड करू शकतो." "एखाद्या अ‍ॅप्लिकेशन किंवा सेवेला कॅमेरा डिव्हाइस सुरू किंवा बंद केल्याची कॉलबॅक मिळवण्याची अनुमती द्या." - "कोणतेही कॅमेरा डिव्हाइस (कोणत्या अ‍ॅप्लिकेशन पॅकेजने) सुरू किंवा बंद केले जाते तेव्हा हे सिग्नेचर ॲप कॉलबॅक मिळवू शकते." + + "व्हायब्रेट नियंत्रित करा" "अ‍ॅप ला व्हायब्रेटर नियंत्रित करण्यासाठी अनुमती देते." "फोन नंबरवर प्रत्यक्ष कॉल करा" @@ -1247,7 +1248,7 @@ "%1$s शी कनेक्ट करता आले नाही" "गोपनीयता सेटिंग्ज बदलण्यासाठी टॅप करा आणि पुन्हा प्रयत्न करा" "गोपनीयता सेटिंग्ज बदलायची आहे का?" - "%1$s ला तुमच्या डिव्हाइसला MAC अ‍ॅड्रेस (एक युनिक आयडेंटिफायर) वापरून कदाचित कनेक्ट करायचे आहे. यामुळे तुमच्या डिव्हाइसचे स्थान जवळपासच्या डिव्हाइसद्वारे ट्रॅक करण्यास अनुमती देऊ शकते. \n\nतुम्ही पुढे सुरू ठेवल्यास, %1$s तुमची गोपनीयता सेटिंग्ज बदलेल आणि पुन्हा कनेक्ट करण्याचा प्रयत्न करेल." + "कनेक्ट करण्यासाठी %1$s ला तुमच्या डिव्हाइसचा MAC अ‍ॅड्रेस, एक युनिक आयडेंटिफायर वापरणे आवश्यक आहे. सध्या, या नेटवर्कसाठी तुमचे गोपनीयता सेटिंग रँडमाइझ केलेला आयडेंटिफायर वापरत आहे. \n\nहा बदल कदाचित जवळपासच्या डिव्हाइसना तुमच्या डिव्हाइसचे स्थान ट्रॅक करण्याची अनुमती देऊ शकतो." "सेटिंग बदला" "सेटिंग अपडेट केले. पुन्हा कनेक्ट करण्याचा प्रयत्न करा." "गोपनीयता सेटिंग्ज बदलू शकत नाही" diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 2c7be25fadbd..f6e9d8a57e46 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -435,7 +435,8 @@ "ambil gambar dan video" "Apl ini boleh mengambil gambar dan merakam video menggunakan kamera pada bila-bila masa." "Benarkan aplikasi atau perkhidmatan menerima panggilan balik tentang peranti kamera yang dibuka atau ditutup." - "Apl tandatangan ini boleh menerima panggilan balik apabila mana-mana peranti kamera dibuka (oleh pakej aplikasi tertentu) atau ditutup." + + "kawal getaran" "Membenarkan apl mengawal penggetar." "panggil terus nombor telefon" @@ -1247,7 +1248,7 @@ "Tidak dapat menyambung ke %1$s" "Ketik untuk menukar tetapan privasi, kemudian cuba semula" "Tukar tetapan privasi?" - "%1$s mungkin mahu menyambung menggunakan alamat MAC peranti anda, iaitu pengecam unik. Tindakan ini mungkin membenarkan lokasi peranti anda dijejaki oleh peranti yang berdekatan. \n\nJika anda meneruskan, %1$s akan menukar tetapan privasi anda dan cuba menyambung lagi." + "Untuk bersambung, %1$s perlu menggunakan alamat MAC peranti anda, iaitu pengecam unik. Pada masa ini, tetapan privasi anda untuk rangkaian ini menggunakan pengecam terawak. \n\nPerubahan ini mungkin membenarkan lokasi peranti anda dijejaki oleh peranti yang berdekatan." "Tukar tetapan" "Tetapan dikemas kini. Cuba sambung lagi." "Tidak boleh menukar tetapan privasi" diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index b43add50b95b..4882eb311c5b 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -435,7 +435,7 @@ "ဓါတ်ပုံနှင့်ဗွီဒီယိုရိုက်ခြင်း" "ဤအက်ပ်သည် ကင်မရာကို အသုံးပြု၍ ဓာတ်ပုံနှင့် ဗီဒီယိုများကို အချိန်မရွေး ရိုက်ကူးနိုင်ပါသည်။" "ကင်မရာစက်များ ပွင့်နေခြင်း သို့မဟုတ် ပိတ်နေခြင်းနှင့် ပတ်သက်ပြီး ပြန်လည်ခေါ်ဆိုမှုများ ရယူရန် အပလီကေးရှင်း သို့မဟုတ် ဝန်ဆောင်မှုကို ခွင့်ပြုခြင်း။" - "(မည်သည့် အပလီကေးရှင်းပက်ကေ့ဂျ်ကြောင့်) ကင်မရာစက်တစ်ခုခု ပွင့်နေသည့်အခါ သို့မဟုတ် ပိတ်နေသည့်အခါ ဤအထူးသီးသန့်အက်ပ်က ပြန်လည်ခေါ်ဆိုမှုများ ရယူနိုင်သည်။" + "(မည်သည့် အပလီကေးရှင်းကြောင့်) ကင်မရာစက်တစ်ခုခု ပွင့်နေသည့်အခါ သို့မဟုတ် ပိတ်နေသည့်အခါ ဤအက်ပ်က ပြန်လည်ခေါ်ဆိုမှုများ ရယူနိုင်သည်။" "တုန်ခုန်မှုအား ထိန်းချုပ်ခြင်း" "အက်ပ်အား တုန်ခါစက်ကို ထိန်းချုပ်ခွင့် ပြုသည်။" "ဖုန်းနံပါတ်များကိုတိုက်ရိုက်ခေါ်ဆိုခြင်း" @@ -1247,7 +1247,7 @@ "\'%1$s\' နှင့် ချိတ်ဆက်၍ မရပါ" "သင့်ကိုယ်ရေးလုံခြုံမှုဆက်တင်ကို ပြောင်းရန် တို့ပြီးနောက် ပြန်၍ကြိုးစားကြည့်ပါ" "ကိုယ်ရေးလုံခြုံမှုဆက်တင်ကို ပြောင်းမလား။" - "%1$s သည် သင့်စက်ပစ္စည်း၏ သီးသန့်သတ်မှတ်မှုစနစ် ဖြစ်သည့် MAC လိပ်စာကို အသုံးပြု၍ ချိတ်ဆက်လိုသည်။ ဤသို့လုပ်ခြင်းဖြင့် သင့်စက်ပစ္စည်း၏ တည်နေရာကို ခြေရာခံရန် အနီးတစ်ဝိုက်ရှိ စက်ပစ္စည်းများကို ခွင့်ပြုနိုင်သည်။ \n\n သင် ရှေ့ဆက်လုပ်ပါက %1$s သည် သင်၏ ကိုယ်ရေးလုံခြုံမှုဆက်တင်ကို ပြောင်းပြီး ပြန်လည်ချိတ်ဆက်ရန် ကြိုးစားလိမ့်မည်။" + "ချိတ်ဆက်ရန်အတွက် %1$s သည် သင့်စက်၏ သီးသန့်သတ်မှတ်မှုစနစ် ဖြစ်သည့် MAC လိပ်စာကို အသုံးပြုရန်လိုသည်။ လက်ရှိတွင် ဤကွန်ရက်အတွက် သင်၏ကိုယ်ရေးလုံခြုံမှုဆက်တင်က ကျပန်းသတ်မှတ်မှုစနစ်ကို အသုံးပြုပါသည်။ \n\nဤအပြောင်းအလဲက သင့်စက်၏တည်နေရာကို ခြေရာခံရန် အနီးတစ်ဝိုက်ရှိ စက်များအား ခွင့်ပြုနိုင်သည်။" "ဆက်တင် ပြောင်းရန်" "ဆက်တင်ကို အပ်ဒိတ်လုပ်ပြီးပါပြီ။ ထပ်ချိတ်ဆက်ကြည့်ပါ။" "ကိုယ်ရေးလုံခြုံမှုဆက်တင်ကို ပြောင်းလဲ၍မရပါ" diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 74bf9d73aa1f..8d4b8e5e2aeb 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -435,7 +435,8 @@ "ta bilder og videoer" "Denne appen kan når som helst ta bilder og spille inn videoer ved hjelp av kameraet." "Tillat at en app eller tjeneste mottar tilbakekallinger om kameraenheter som åpnes eller lukkes." - "Denne signaturappen kan motta tilbakekallinger når en kameraenhet blir åpnet (av hvilken app-pakke) eller lukket." + + "kontrollere vibreringen" "Lar appen kontrollere vibreringsfunksjonen." "ringe telefonnummer direkte" @@ -1247,7 +1248,7 @@ "Kan ikke koble til %1$s" "Trykk for å endre personverninnstillingene og prøve på nytt" "Vil du endre personverninnstillingen?" - "%1$s vil muligens koble seg til med enhetens MAC-adresse, en unik identifikator. Dette gjør at enhetens posisjon kan spores av enheter i nærheten. \n\nHvis du fortsetter, kommer %1$s til å endre personverninnstillingen din og prøve å koble til igjen." + "For å koble til må %1$s bruke enhetens MAC-adresse, en unik identifikator. Foreløpig bruker personverninnstillingene dine for dette nettverket en tilfeldig valgt identifikator. \n\nDenne endringen gjør at enhetens posisjon kan spores av enheter i nærheten." "Endre innstillingen" "Innstillingen er oppdatert. Prøv å koble til igjen." "Kan ikke endre personverninnstillingen" diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 642ed571774d..17f091fb148e 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -435,7 +435,8 @@ "तस्बिरहरू र भिडियोहरू लिनुहोस्।" "यस अनुप्रयोगले जुनसुकै समय क्यामेराको प्रयोग गरी तस्बिर खिच्न र भिडियो रेकर्ड गर्न सक्छ।" "कुनै अनुप्रयोग वा सेवालाई खोलिँदै वा बन्द गरिँदै गरेका क्यामेरा यन्त्रहरूका बारेमा कलब्याक प्राप्त गर्ने अनुमति दिनुहोस्।" - "कुनै पनि क्यामेरा यन्त्र खोलिँदै गर्दा (जुनसुकै अनुप्रयोगको प्याकेजबाट) वा बन्द गरिँदै गर्दा यो हस्ताक्षरसम्बन्धी अनुप्रयोगले कलब्याक प्राप्त गर्न सक्छ।" + + "कम्पन नियन्त्रण गर्नुहोस्" "अनुप्रयोगलाई भाइब्रेटर नियन्त्रण गर्न अनुमति दिन्छ।" "फोन नम्बरहरूमा सीधै कल गर्नुहोस्" @@ -1253,7 +1254,7 @@ "%1$s मा जोड्न सकिएन" "गोपनीयता सेटिङ परिवर्तन गर्न ट्याप गरेर फेरि प्रयास गर्नुहोस्" "गोपनीयतासम्बन्धी सेटिङ परिवर्तन गर्ने हो?" - "%1$s ले तपाईंका यन्त्रको MAC ठेगाना अर्थात् अद्वितीय पहिचानकर्ता प्रयोग गरेर सम्पर्क गर्न सक्ने सम्भावना छ। यसो गर्नाले तपाईंका यन्त्रको स्थान वरपरका यन्त्रहरूले ट्र्याक गर्न सक्ने सम्भावना छ। \n\nतपाईंले यो कार्य जारी राख्नुभएमा, %1$s ले तपाईंको गोपनीयता सेटिङ परिवर्तन गरेर फेरि जोडिन प्रयास गर्ने छ।" + "Wi-Fi मा जोड्नका लागि %1$s ले तपाईंको यन्त्रको MAC ठेगाना अर्थात् एउटा अद्वितीय पहिचानकर्ता प्रयोग गर्नु पर्ने हुन्छ। हाल, यो नेटवर्कमा लागू हुने तपाईंको गोपनीयतासम्बन्धी सेटिङले अनियमित पहिचानकर्ताको प्रयोग गर्छ। \n\nयो परिवर्तन गर्नाले वरपरका यन्त्रहरूलाई तपाईंको यन्त्रको स्थान ट्र्याक गर्न दिने सम्भावना हुन्छ।" "सेटिङ परिवर्तन गर्नुहोस्" "सेटिङ अद्यावधिक गरियो। फेरि जोडी हेर्नुहोस्" "गोपनीयता सेटिङ परिवर्तन गर्न सकिएन" diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index cc35c8ee44ce..611fd9ef71a2 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -435,7 +435,8 @@ "foto\'s en video\'s maken" "Deze app kan op elk moment foto\'s maken en video\'s opnemen met de camera." "Een app of service toestaan callbacks te ontvangen over camera-apparaten die worden geopend of gesloten." - "Deze ondertekeningsapp kan callback ontvangen als een camera-apparaat wordt geopend (en door welk app-pakket) of gesloten." + + "trilling beheren" "Hiermee kan de app de trilstand beheren." "telefoonnummers rechtstreeks bellen" @@ -1247,7 +1248,7 @@ "Kan niet verbinden met %1$s" "Tik om de privacyinstellingen aan te passen en probeer het opnieuw" "Privacyinstelling wijzigen?" - "%1$s wil mogelijk verbinding maken via het MAC-adres van je apparaat (een uniek identificatienummer). Hierdoor kan de locatie van je apparaat worden bijgehouden door apparaten in de buurt. \n\nAls je doorgaat, wijzigt %1$s je privacyinstelling en probeert opnieuw verbinding te maken." + "%1$s moet het MAC-adres van je apparaat gebruiken om verbinding te maken. Dat is een unieke ID. Vanwege je privacyinstelling voor dit netwerk wordt op dit moment een willekeurige ID gebruikt. \n\nDoor deze wijziging kan de locatie van je apparaat worden bijgehouden door apparaten in de buurt." "Instelling wijzigen" "Instelling geüpdatet. Probeer opnieuw verbinding te maken." "Kan privacyinstelling niet wijzigen" diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index bb1eb2b906f0..c5311bd9520c 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -201,7 +201,7 @@ "ୱେୟାରଲେସ୍‌କୁ ଚାଲୁ କରନ୍ତୁ" "ୱେୟାରଲେସ୍‌କୁ ବନ୍ଦ କରନ୍ତୁ" "ସ୍କ୍ରୀନ୍‌ ଲକ୍‌" - "ପାୱାର୍ ଅଫ୍" + "ପାୱାର୍ ବନ୍ଦ" "ରିଙ୍ଗର୍‍ ଅଫ୍‍ ଅଛି" "ରିଙ୍ଗର୍‍ କମ୍ପନ" "ରିଙ୍ଗର୍‍ ଅନ୍‍ ଅଛି" @@ -225,11 +225,11 @@ "ଟିଭିର ବିକଳ୍ପ" "ଫୋନ ବିକଳ୍ପ" "ସ୍କ୍ରୀନ୍‌ ଲକ୍‌" - "ପାୱାର୍ ଅଫ୍" + "ପାୱାର୍ ବନ୍ଦ" "ଜରୁରୀକାଳୀନ" "ବଗ୍‌ ରିପୋର୍ଟ" "ସେସନ୍‍ ଶେଷ କରନ୍ତୁ" - "ସ୍କ୍ରୀନଶଟ୍‌" + "ସ୍କ୍ରିନସଟ୍‌" "ବଗ୍‌ ରିପୋର୍ଟ" "ଇ-ମେଲ୍ ମେସେଜ୍‍ ଭାବରେ ପଠାଇବାକୁ, ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ଡିଭାଇସ୍‌ ବିଷୟରେ ଏହା ସୂଚନା ସଂଗ୍ରହ କରିବ। ବଗ୍ ରିପୋର୍ଟ ଆରମ୍ଭ ହେବାପରଠାରୁ ଏହାକୁ ପଠାଇବା ପାଇଁ କିଛି ସମୟ ଲାଗିବ, ଦୟାକରି ଧୈର୍ଯ୍ୟ ରଖନ୍ତୁ।" "ଇଣ୍ଟରାକ୍ଟିଭ୍‍ ରିପୋର୍ଟ" @@ -435,7 +435,8 @@ "ଫଟୋ ଓ ଭିଡିଓଗୁଡ଼ିକୁ ନିଅନ୍ତୁ" "ଏହି ଆପ୍‍ ଯେକୌଣସି ସମୟରେ କ୍ୟାମେରା ବ୍ୟବହାର କରି ଫଟୋ ଉଠାଇପାରେ ଏବଂ ଭିଡିଓ ରେକର୍ଡ କରିପାରେ।" "କ୍ୟାମେରା ଡିଭାଇସଗୁଡ଼ିକ ଖୋଲିବା କିମ୍ବା ବନ୍ଦ କରିବା ବିଷୟରେ କଲବ୍ୟାକଗୁଡ଼ିକ ପାଇବାକୁ ଏକ ଆପ୍ଲିକେସନ୍ କିମ୍ବା ସେବାକୁ ଅନୁମତି ଦିଅନ୍ତୁ।" - "ଯେ କୌଣସି କ୍ୟାମେରା ଡିଭାଇସ୍ ଖୋଲାଗଲେ (କେଉଁ ଆପ୍ଲିକେସନ୍ ପ୍ୟାକେଜ୍ ଦ୍ୱାରା) କିମ୍ବା ବନ୍ଦ କରାଗଲେ ଏହି ସିଗନେଚର୍ ଆପ୍ କଲବ୍ୟାକ୍ ପାଇପାରିବ।" + + "କମ୍ପନ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ" "ଆପ୍‍କୁ, ଭାଇବ୍ରେଟର୍‍ ନିୟନ୍ତ୍ରଣ କରିବାକୁ ଦେଇଥାଏ।" "ସିଧାସଳଖ ଫୋନ୍ ନମ୍ବରଗୁଡ଼ିକୁ କଲ୍ କରନ୍ତୁ" @@ -1247,7 +1248,7 @@ "%1$s ସହିତ ସଂଯୋଗ କରାଯାଇପାରିବ ନାହିଁ" "ଗୋପନୀୟତା ସେଟିଂସ୍ ବଦଳେଇବାକୁ ଟାପ୍ କରନ୍ତୁ ଏବଂ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ" "ଗୋପନୀୟତା ସେଟିଂ ବଦଳେଇବେ?" - "%1$s ଆପଣଙ୍କ ଡିଭାଇସ୍‌ର ଏକ ସ୍ୱତନ୍ତ୍ର ଚିହ୍ନଟକାରୀ MAC ଠିକଣା ବ୍ୟବହାର କରି ସଂଯୋଗ କରିବାକୁ ଚାହିଁପାରେ। ଏହା ଆପଣଙ୍କର ଡିଭାଇସ୍‌ର ଲୋକେସନ୍‌କୁ ଟ୍ରାକ୍ କରିବାକୁ ଆଖପାଖର ଡିଭାଇସ୍‌ଗୁଡ଼ିକୁ ଅନୁମତି ଦେଇପାରେ। \n\nଯଦି ଆପଣ ଜାରି ରଖନ୍ତି, ତେବେ %1$s ଆପଣଙ୍କର ଗୋପନୀୟତା ସେଟିଂକୁ ବଦଳାଇ ପୁଣି ସଂଯୋଗ କରିବାକୁ ଚେଷ୍ଟା କରିବ।" + "ସଂଯୋଗ କରିବାକୁ, %1$s ଏକ ସ୍ୱତନ୍ତ୍ର ଚିହ୍ନଟକାରୀ ଭାବେ ଆପଣଙ୍କ ଡିଭାଇସର MAC ଠିକଣା ଆବଶ୍ୟକ କରେ। ବର୍ତ୍ତମାନ, ଏହି ନେଟୱାର୍କ ପାଇଁ ଆପଣଙ୍କ ଗୋପନୀୟତା ସେଟିଂ ଏକ ରେଣ୍ଡମାଇଜ୍ ଚିହ୍ନଟକାରୀ ବ୍ୟବହାର କରେ। \n\nଏହି ପରିବର୍ତ୍ତନ ଆଖପାଖର ଡିଭାଇସଗୁଡ଼ିକୁ ଆପଣଙ୍କ ଡିଭାଇସର ଲୋକେସନକୁ ଟ୍ରାକ୍ କରିବାକୁ ଅନୁମତି ଦେଇପାରେ।" "ସେଟିଂକୁ ବଦଳାନ୍ତୁ" "ସେଟିଂକୁ ଅପଡେଟ୍ କରାଯାଇଛି। ପୁଣି ସଂଯୋଗ କରିବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ।" "ଗୋପନୀୟତା ସେଟିଂ ବଦଳିପାରିବ ନାହିଁ" diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 3b264d3147a4..639c9bae3b0c 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -435,7 +435,7 @@ "ਤਸਵੀਰਾਂ ਅਤੇ ਵੀਡੀਓ ਬਣਾਓ" "ਇਹ ਐਪ ਕਿਸੇ ਵੀ ਸਮੇਂ ਕੈਮਰੇ ਨੂੰ ਵਰਤ ਕੇ ਤਸਵੀਰਾਂ ਖਿੱਚ ਸਕਦੀ ਹੈ ਅਤੇ ਵੀਡੀਓ ਫ਼ਾਈਲਾਂ ਰਿਕਾਰਡ ਕਰ ਸਕਦੀ ਹੈ।" "ਐਪਲੀਕੇਸ਼ਨ ਜਾਂ ਸੇਵਾ ਨੂੰ ਕੈਮਰਾ ਡੀਵਾਈਸਾਂ ਦੇ ਚਾਲੂ ਜਾਂ ਬੰਦ ਕੀਤੇ ਜਾਣ ਬਾਰੇ ਕਾਲਬੈਕ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ।" - "ਇਹ ਸਿਗਨੇਚਰ ਐਪ ਕੋਈ ਵੀ ਕੈਮਰਾ ਡੀਵਾਈਸ ਚਾਲੂ ਹੋਣ (ਕਿਸ ਐਪਲੀਕੇਸ਼ਨ ਪੈਕੇਜ ਰਾਹੀਂ) ਜਾਂ ਬੰਦ ਹੋਣ \'ਤੇ ਕਾਲਬੈਕ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੀ ਹੈ।" + "ਇਹ ਐਪ ਕੋਈ ਵੀ ਕੈਮਰਾ ਡੀਵਾਈਸ ਚਾਲੂ ਹੋਣ (ਕਿਸ ਐਪਲੀਕੇਸ਼ਨ ਰਾਹੀਂ) ਜਾਂ ਬੰਦ ਹੋਣ \'ਤੇ ਕਾਲਬੈਕ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੀ ਹੈ।" "ਵਾਈਬ੍ਰੇਸ਼ਨ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ" "ਐਪ ਨੂੰ ਵਾਈਬ੍ਰੇਟਰ ਤੇ ਨਿਯੰਤਰਣ ਪਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।" "ਫ਼ੋਨ ਨੰਬਰਾਂ ਤੇ ਸਿੱਧੇ ਕਾਲ ਕਰੋ" @@ -1247,7 +1247,7 @@ "%1$s ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ" "ਪਰਦੇਦਾਰੀ ਸੈਟਿੰਗਾਂ ਬਦਲਣ ਲਈ ਟੈਪ ਕਰਕੇ ਮੁੜ-ਕੋਸ਼ਿਸ਼ ਕਰੋ" "ਕੀ ਪਰਦੇਦਾਰੀ ਸੈਟਿੰਗ ਬਦਲਣੀ ਹੈ?" - "%1$s ਸ਼ਾਇਦ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ MAC ਪਤਾ, ਇੱਕ ਵਿਲੱਖਣ ਪਛਾਣਕਰਤਾ ਵਰਤ ਕੇ ਕਨੈਕਟ ਹੋਣਾ ਚਾਹੇ। ਇੰਝ ਕਰਨ ਨਾਲ ਸ਼ਾਇਦ ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੇ ਟਿਕਾਣੇ ਨੂੰ ਟਰੈਕ ਕਰ ਸਕਣ। \n\nਜੇ ਤੁਸੀਂ ਜਾਰੀ ਰੱਖਦੇ ਹੋ, ਤਾਂ %1$s ਤੁਹਾਡੀ ਪਰਦੇਦਾਰੀ ਸੈਟਿੰਗ ਨੂੰ ਬਦਲ ਕੇ ਤੁਹਾਡੇ ਨਾਲ ਦੁਬਾਰਾ ਕਨੈਕਟ ਹੋਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੇਗਾ।" + "ਕਨੈਕਟ ਕਰਨ ਲਈ, %1$s ਨੂੰ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ MAC ਪਤਾ ਵਰਤਣ ਦੀ ਲੋੜ ਹੈ, ਜੋ ਕਿ ਇੱਕ ਵਿਲੱਖਣ ਪਛਾਣਕਰਤਾ ਹੈ। ਫ਼ਿਲਹਾਲ, ਇਸ ਨੈੱਟਵਰਕ ਲਈ ਤੁਹਾਡੀ ਪਰਦੇਦਾਰੀ ਸੈਟਿੰਗ ਇੱਕ ਬੇਤਰਤੀਬੇ ਪਛਾਣਕਰਤਾ ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ। \n\nਇਸ ਤਬਦੀਲੀ ਨਾਲ ਸ਼ਾਇਦ ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੇ ਟਿਕਾਣੇ ਨੂੰ ਟਰੈਕ ਕਰ ਸਕਣ।" "ਸੈਟਿੰਗ ਬਦਲੋ" "ਸੈਟਿੰਗ ਅੱਪਡੇਟ ਕੀਤੀ ਗਈ। ਦੁਬਾਰਾ ਕਨੈਕਟ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ।" "ਪਰਦੇਦਾਰੀ ਸੈਟਿੰਗ ਨੂੰ ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ" diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 3273578d597a..a60192851940 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -441,7 +441,7 @@ "wykonywanie zdjęć i filmów wideo" "Ta aplikacja może w dowolnym momencie robić zdjęcia i nagrywać filmy przy użyciu aparatu." "Zezwól na dostęp aplikacji lub usługi na otrzymywanie wywoływania zwrotnego o urządzeniach z aparatem, kiedy są one uruchamiane lub zamykane." - "Aplikacja z podpisami może korzystać z wywoływania zwrotnego, kiedy urządzenie z aparatem jest uruchamiane (przez jaki pakiet aplikacji) albo zamykane." + "Ta aplikacja może korzystać z wywoływania zwrotnego, kiedy urządzenie z aparatem jest uruchamiane (przez jaką aplikację) albo zamykane." "sterowanie wibracjami" "Pozwala aplikacji na sterowanie wibracjami." "bezpośrednie wybieranie numerów telefonów" @@ -1287,7 +1287,7 @@ "Nie można połączyć się z siecią %1$s" "Kliknij, by zmienić ustawienia prywatności, i spróbuj jeszcze raz" "Zmienić ustawienie prywatności?" - "Sieć %1$s może chcieć nawiązać połączenie z wykorzystaniem adresu MAC Twojego urządzenia, czyli jego unikalnego identyfikatora. Urządzenia w pobliżu mogą w ten sposób zyskać możliwość monitorowania lokalizacji Twojego urządzenia. \n\nJeśli przejdziesz dalej, sieć %1$s zmieni Twoje ustawienie prywatności i ponownie spróbuje nawiązać połączenie." + "Aby nawiązać połączenie, sieć %1$s musi użyć adresu MAC Twojego urządzenia, który jest jego unikalnym identyfikatorem. Obecnie ustawienia prywatności w tej sieci używają randomizowanego identyfikatora. \n\nUrządzenia w pobliżu mogą w ten sposób zyskać możliwość monitorowania lokalizacji Twojego urządzenia." "Zmień ustawienie" "Zaktualizowano ustawienie. Spróbuj połączyć się ponownie." "Nie można zmienić ustawienia prywatności" diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index e050d50c0626..0ac038301414 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -435,7 +435,7 @@ "tirar fotos e gravar vídeos" "Este app pode tirar fotos e gravar vídeos usando a câmera a qualquer momento." "Permitir que um aplicativo ou serviço receba callbacks sobre dispositivos de câmera sendo abertos ou fechados." - "Esse app de assinatura pode receber callbacks quando um dispositivo de câmera é aberto (por qualquer pacote de apps) ou fechado." + "Esse app pode receber callbacks quando um dispositivo de câmera é aberto (por qualquer app) ou fechado." "controlar vibração" "Permite que o app controle a vibração." "ligar diretamente para números de telefone" @@ -1247,7 +1247,7 @@ "Não foi possível se conectar à rede %1$s" "Toque para mudar as configurações de privacidade e tentar novamente" "Mudar configuração de privacidade?" - "%1$s pode querer se conectar usando o endereço MAC do seu dispositivo, um identificador único. Isso pode permitir que o local do dispositivo seja monitorado por dispositivos próximos. \n\nSe você continuar, %1$s mudará sua configuração de privacidade e tentará se conectar novamente." + "Para se conectar, %1$s precisa usar o endereço MAC do seu dispositivo, um identificador exclusivo. Atualmente, sua configuração de privacidade para esta rede usa um identificador aleatório. \n\nEssa mudança pode permitir que o local do dispositivo seja monitorado por dispositivos próximos." "Mudar configuração" "Configuração atualizada. Tente conectar novamente." "Não foi possível mudar as configurações de privacidade" diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 773d6a1ad725..7d56530aeeb7 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -435,7 +435,8 @@ "tirar fotos e vídeos" "Esta aplicação pode tirar fotos e gravar vídeos através da câmara em qualquer altura." "Permitir que uma app ou um serviço receba chamadas de retorno sobre dispositivos de câmara que estão a ser abertos ou fechados" - "Esta app premium pode receber chamadas de retorno quando qualquer dispositivo de câmara está a ser aberto (e por que pacote de apps) ou fechado." + + "controlar vibração" "Permite à aplicação controlar o vibrador." "marcar números de telefone diretamente" @@ -1247,7 +1248,7 @@ "Não é possível ligar a %1$s" "Toque para alterar as definições de privacidade e tente novamente." "Pretende alterar a definição de privacidade?" - "%1$s pode pretender estabelecer ligação através do endereço MAC do dispositivo, um identificador exclusivo. Isto pode permitir que a localização do seu dispositivo seja monitorizada por dispositivos próximos. \n\nSe continuar, %1$s irá alterar a definição de privacidade e tentar estabelecer ligação novamente." + "Para associar, o %1$s tem de utilizar o endereço MAC do seu dispositivo, um identificador único. Atualmente, a sua definição de privacidade para esta rede utiliza um identificador aleatorizado. \n\nEsta alteração pode permitir que a localização do seu dispositivo seja monitorizada por dispositivos próximos." "Alterar definição" "Definição atualizada. Tente ligar novamente." "Não é possível alterar a definição de privacidade." diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index e050d50c0626..0ac038301414 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -435,7 +435,7 @@ "tirar fotos e gravar vídeos" "Este app pode tirar fotos e gravar vídeos usando a câmera a qualquer momento." "Permitir que um aplicativo ou serviço receba callbacks sobre dispositivos de câmera sendo abertos ou fechados." - "Esse app de assinatura pode receber callbacks quando um dispositivo de câmera é aberto (por qualquer pacote de apps) ou fechado." + "Esse app pode receber callbacks quando um dispositivo de câmera é aberto (por qualquer app) ou fechado." "controlar vibração" "Permite que o app controle a vibração." "ligar diretamente para números de telefone" @@ -1247,7 +1247,7 @@ "Não foi possível se conectar à rede %1$s" "Toque para mudar as configurações de privacidade e tentar novamente" "Mudar configuração de privacidade?" - "%1$s pode querer se conectar usando o endereço MAC do seu dispositivo, um identificador único. Isso pode permitir que o local do dispositivo seja monitorado por dispositivos próximos. \n\nSe você continuar, %1$s mudará sua configuração de privacidade e tentará se conectar novamente." + "Para se conectar, %1$s precisa usar o endereço MAC do seu dispositivo, um identificador exclusivo. Atualmente, sua configuração de privacidade para esta rede usa um identificador aleatório. \n\nEssa mudança pode permitir que o local do dispositivo seja monitorado por dispositivos próximos." "Mudar configuração" "Configuração atualizada. Tente conectar novamente." "Não foi possível mudar as configurações de privacidade" diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index c31fd4676721..9364376bc66d 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -438,7 +438,8 @@ "realizarea de fotografii și videoclipuri" "Această aplicație poate să facă fotografii și să înregistreze videoclipuri folosind camera foto în orice moment." "Permiteți unei aplicații sau unui serviciu să primească apeluri inverse atunci când sunt deschise sau închise dispozitive cu cameră." - "Această aplicație cu semnătură poate primi apeluri inverse atunci când este deschis (de un pachet al aplicației) sau închis orice dispozitiv cu cameră." + + "controlează vibrarea" "Permite aplicației să controleze mecanismul de vibrare." "apelare directă numere de telefon" @@ -1267,7 +1268,7 @@ "Nu se poate conecta la %1$s" "Atingeți pentru a modifica setările de confidențialitate și a încerca din nou" "Modificați setările de confidențialitate?" - "%1$s poate dori să se conecteze folosind adresa MAC a dispozitivului, un identificator unic. Astfel, locația dispozitivului poate fi urmărită de dispozitivele din apropiere. \n\nDacă alegeți să continuați, %1$s vă va modifica setarea de confidențialitate și va încerca din nou să se conecteze." + "Pentru a se conecta, %1$s trebuie să folosească adresa MAC a dispozitivului, un identificator unic. Setarea de confidențialitate pentru această rețea folosește un identificator aleatoriu. \n\nAceastă modificare poate permite ca locația dispozitivului să fie urmărită de dispozitivele din apropiere." "Modificați setarea" "Setarea a fost actualizată. Încercați să vă conectați din nou." "Nu puteți modifica setarea de confidențialitate" diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 1d4d9b2c9eed..9c58276fff81 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -441,7 +441,8 @@ "Фото- и видеосъемка" "Приложение может в любое время делать фотографии и снимать видео с помощью камеры." "Разрешить приложению или сервису получать обратные вызовы при открытии и закрытии камер" - "Это приложение для создания подписей сможет получать обратные вызовы при открытии (с указанием открывающего приложения) и закрытии любых камер." + + "Управление функцией вибросигнала" "Приложение сможет контролировать вибросигналы." "Осуществление телефонных вызовов" @@ -1287,7 +1288,7 @@ "Не удалось подключиться к сети %1$s" "Нажмите, чтобы изменить настройки конфиденциальности и повторить попытку." "Изменить настройки конфиденциальности?" - "Сеть %1$s может подключиться, используя MAC-адрес вашего устройства (уникальный идентификатор). Таким образом, устройствам поблизости будут доступны данные о вашем местоположении. \n\nЕсли вы продолжите, сеть %1$s изменит настройки конфиденциальности и попробует подключиться ещё раз." + "Для подключения сети %1$s необходим MAC-адрес вашего устройства (уникальный идентификатор). Сейчас ваша настройка конфиденциальности для этой сети использует случайный идентификатор. \n\nЭто изменение может привести к тому, что устройства поблизости смогут отслеживать ваше местоположение." "Изменить настройки" "Настройки сохранены Попробуйте подключиться ещё раз." "Не удается изменить настройки конфиденциальности." diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 973571a8844f..0de9dac503c9 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -435,7 +435,7 @@ "පින්තූර සහ වීඩියෝ ගන්න" "මෙම යෙදුමට ඕනෑම වේලාවක කැමරාව භාවිත කර පින්තූර ගැනීමට සහ වීඩියෝ පටිගත කිරීමට හැකිය." "විවෘත වෙමින් හෝ වැසෙමින් පවතින කැමරා උපාංග පිළිබඳ පසු ඇමතුම් ලබා ගැනීමට යෙදුමකට හෝ සේවාවකට ඉඩ දෙන්න." - "මෙම අත්සන් යෙදුමට ඕනෑම කැමරා යෙදුමක් විවෘත වෙමින් හෝ වැසෙමින් (කුමන යෙදුම් පැකේජයෙන්ද) පවතින විට පසු ඇමතුම් ලබා ගැනීමට හැකිය." + "මෙම යෙදුමට ඕනෑම කැමරා උපාංගයක් විවෘත වෙමින් පවතින විට (කුමන යෙදුමකින්) හෝ වැසෙමින් පවතින විට පසු ඇමතුම් ලබා ගැනීමට හැකිය." "කම්පනය පාලනය කිරීම" "කම්පකය පාලනයට යෙදුමට අවසර දෙන්න." "දුරකථන අංක වෙත ඍජුවම අමතන්න" @@ -1249,7 +1249,7 @@ "%1$s වෙත සම්බන්ධ විය නොහැකිය" "රහස්‍යතා සැකසීම් වෙනස් කිරීමට තට්ටු කර යළි උත්සාහ කරන්න" "රහස්‍යතා සැකසීම වෙනස් කරන්නද?" - "අනුපම අනන්‍යකාරකයක් වන ඔබේ උපාංග MAC ලිපිනය භාවිතයෙන් %1$s හට සම්බන්ධ වීමට අවශ්‍ය විය හැකිය. මෙය ඔබේ උපාංගයේ ස්ථානය අවට උපාංග මගින් නිරීක්ෂණය කිරීමට ඉඩ දිය හැකිය. \n\nඔබ ඉදිරියට යන්නේ නම්, %1$s මගින් ඔබේ රහස්‍යතා සැකසීම වෙනස් කර නැවත සම්බන්ධ වීමට උත්සාහ කරනු ඇත." + "සම්බන්ධ වීමට, %1$s හට ඔබේ උපාංග MAC ලිපිනය, අනන්‍ය අනන්‍යකාරකයක් භාවිත කිරීමට අවශ්‍යය. දැනට, මෙම ජාලය සඳහා ඔබේ රහස්‍යතා සැකසීම සසම්භාවීකරණය කළ අනන්‍යකාරකයක් භාවිත කරයි. \n\nමෙය ඔබේ උපාංගයේ ස්ථානය අවට උපාංග මගින් නිරීක්ෂණය කිරීමට ඉඩ දිය හැකිය." "සැකසීම වෙනස් කරන්න" "සැකසීම යාවත්කාලීනයි. නැවත සබැඳීමට උත්සාහ කරන්න." "රහස්‍යතා සැකසීම වෙනස් කළ නොහැකිය" diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 4b14c49a0c08..2969ece60a16 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -441,7 +441,7 @@ "fotiť a nakrúcať videá" "Táto aplikácia môže kedykoľvek fotografovať a zaznamenávať videá pomocou fotoaparátu." "Povoliť aplikácii alebo službe prijímať spätné volanie, keď sú zariadenia s kamerou otvorené alebo zatvorené." - "Táto podpisová aplikácia môže prijímať spätné volanie, keď je ľubovoľné zariadenie s kamerou otvorené (balíkom aplikácie, ktorý určíte) alebo zatvorené." + "Táto aplikácia môže prijímať spätné volanie, keď je ľubovoľné zariadenie s kamerou otvorené (aplikáciou, ktorú určíte) alebo zatvorené." "ovládať vibrovanie" "Umožňuje aplikácii ovládať vibrácie." "priamo volať na telefónne čísla" @@ -1287,7 +1287,7 @@ "K sieti %1$s sa nedá pripojiť" "Klepnutím zmeňte nastavenia ochrany súkromia a skúste to znova" "Chcete zmeniť nastavenie ochrany súkromia?" - "%1$s sa môže pokúsiť pripojiť pomocou jedinečného identifikátora, ktorým je adresa MAC vášho zariadenia. Zariadenia v okolí tak budú môcť sledovať jeho polohu. \n\nAk budete pokračovať, %1$s zmení vaše nastavenie ochrany súkromia a skúsi sa znova pripojiť." + "%1$s potrebuje na pripojenie jedinečný identifikátor, ktorým je adresa MAC vášho zariadenia. Vaše nastavenie ochrany súkromia pre túto sieť momentálne používa náhodný identifikátor. \n\nZariadenia v okolí tak budú môcť sledovať polohu vášho zariadenia." "Zmeniť nastavenie" "Nastavenie bolo aktualizované. Skúste sa znova pripojiť." "Nastavenie ochrany súkromia sa nepodarilo zmeniť" diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 8a1579e77462..c20f71f2a26e 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -441,7 +441,8 @@ "fotografiranje in snemanje videoposnetkov" "Ta aplikacija lahko poljubno uporablja fotoaparat za snemanje fotografij ali videoposnetkov." "Aplikaciji ali storitvi dovoli prejemanje povratnih klicev o odpiranju ali zapiranju naprav s fotoaparati." - "Ta aplikacija za podpise lahko prejema povratne klice, ko se odpira (s katerim paketom aplikacij) ali zapira katera koli naprava s fotoaparatom." + + "nadzor vibriranja" "Aplikaciji omogoča nadzor vibriranja." "neposredno klicanje telefonskih številk" @@ -1287,7 +1288,7 @@ "Povezava z omrežjem %1$s ni mogoča" "Dotaknite se za spremembo nastavitev zasebnosti in poskusite znova" "Želite spremeniti nastavitev zasebnosti?" - "Omrežje %1$s bo za vzpostavitev povezave morda želelo uporabiti naslov MAC naprave, ki je enolični identifikator. To lahko napravam v bližini omogoči spremljanje lokacije vaše naprave. \n\nČe nadaljujete, bo omrežje %1$s spremenilo nastavitev zasebnosti in se poskusilo znova povezati." + "Za vzpostavitev povezave mora omrežje %1$s uporabiti naslov MAC naprave, ki je enolični identifikator. Glede na nastavitev zasebnosti za to omrežje se trenutno uporablja naključno določen identifikator. \n\nTa sprememba lahko napravam v bližini omogoči spremljanje lokacije vaše naprave." "Spremeni nastavitev" "Nastavitev je posodobljena. Poskusite znova vzpostaviti povezavo." "Nastavitve zasebnosti ni mogoče spremeniti" diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index decc3387a4d6..9e05a605b2e8 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -435,7 +435,7 @@ "bëj fotografi dhe video" "Ky aplikacion mund të nxjerrë fotografi dhe të regjistrojë video me kamerën tënde në çdo kohë." "Lejo që një aplikacion ose shërbim të marrë telefonata mbrapsht për pajisjet e kamerës që hapen ose mbyllen." - "Ky aplikacion i nënshkrimit mund të marrë telefonata mbrapsht kur hapet ose mbyllet një pajisje e kamerës (nga një paketë e aplikacionit)." + "Ky aplikacion mund të marrë telefonata mbrapsht kur hapet ose mbyllet një pajisje e kamerës (nga një aplikacion)." "kontrollo dridhjen" "Lejon aplikacionin të kontrollojë dridhësin." "telefono drejtpërdrejt numrat e telefonit" @@ -1247,7 +1247,7 @@ "Nuk mund të lidhet me %1$s" "Trokit për të ndryshuar cilësimet e privatësisë dhe provo përsëri" "Do ta ndryshosh cilësimin e privatësisë?" - "%1$s mund të dëshirojë të lidhet duke përdorur adresën MAC të pajisjes sate, një identifikues unik. Kjo mund të lejojë monitorimin e vendndodhjes së pajisjes sate nga pajisjet në afërsi. \n\nNëse vazhdon, %1$s do të ndryshojë cilësimin tënd të privatësisë dhe do të provojë të lidhet përsëri." + "Për t\'u lidhur, %1$s ka nevojë të përdorë adresën MAC të pajisjes sate, një identifikues unik. Aktualisht, cilësimi yt i privatësisë për këtë rrjet përdor një identifikues të rastësishëm. \n\nKy ndryshim mund të lejojë monitorimin e vendndodhjes së pajisjes sate nga pajisjet në afërsi." "Ndrysho cilësimin" "Cilësimi u përditësua. Provo të lidhesh përsëri." "Cilësimi i privatësisë nuk mund të ndryshohet" diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index e7110fe6ed02..afcb671869c1 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -306,7 +306,7 @@ "Желите ли да дозволите да <b>%1$s</b> приступа физичким активностима?" "Камера" "снима слике и видео" - "Желите ли да омогућите да <b>%1$s</b> снима слике и видео снимке?" + "Желите да омогућите да <b>%1$s</b> снима слике и видео снимке?" "Евиденције позива" "читање и писање евиденције позива на телефону" "Желите ли да омогућите да <b>%1$s</b> приступа евиденцијама позива на телефону?" @@ -438,7 +438,8 @@ "снимање фотографија и видео снимака" "Ова апликација може да снима фотографије и видео снимке помоћу камере у било ком тренутку." "Дозволите апликацији или услузи да добија повратне позиве о отварању или затварању уређаја са камером." - "Ова апликација за потписе може да добија повратне позиве када се било који уређај са камером отвара или затвара (помоћу неког пакета апликација)." + + "контрола вибрације" "Дозвољава апликацији да контролише вибрацију." "директно позивање бројева телефона" @@ -1267,7 +1268,7 @@ "Повезивање на мрежу %1$s није успело" "Додирните да бисте променили подешавања приватности и пробали поново" "Желите ли да промените подешавања приватности?" - "%1$s можда жели да се повеже помоћу MAC адресе уређаја, јединственог идентификатора. То може да омогући уређајима у близини да прате локацију уређаја. \n\nАко наставите, %1$s ће променити подешавања приватности и поново пробати да се повеже." + "%1$s треба да се повеже помоћу MAC адресе уређаја, јединственог идентификатора. Подешавање приватности за ову мрежу тренутно користи насумични идентификатор. \n\nОва измена може да омогући уређајима у близини да прате локацију уређаја." "Промени подешавање" "Подешавање је ажурирано. Пробајте поново да се повежете." "Промена подешавања приватности није успела" diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 82c1336e6d67..692550e56e63 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -435,7 +435,8 @@ "ta bilder och spela in videoklipp" "Appen kan ta kort och spela in video med kameran när som helst." "Tillåt att en app eller tjänst får återanrop när en kameraenhet öppnas eller stängs." - "Den här signerade appen kan få återanrop när en kameraenhet öppnas (efter applikationspaket) eller stängs." + + "styra vibration" "Tillåter att appen styr vibrationen." "ringa telefonnummer direkt" @@ -1247,7 +1248,7 @@ "Det gick inte att ansluta till %1$s" "Tryck för att ändra sekretessinställningar och försök igen" "Vill du ändra sekretessinställningar?" - "Det kan vara så att enhetens MAC-adress (en unik identifierare) används vid anslutningen till %1$s. Det kan göra det möjligt för enheter i närheten att spåra enhetens plats. \n\nOm du fortsätter ändras sekretessinställningen och %1$s testar att ansluta på nytt." + "%1$s måste använda enhetens MAC-adress (en unik identifierare) vid anslutningen. Just nu används en slumpgenererad identifierare enligt integritetsinställningarna för nätverket. \n\nDetta kan göra det möjligt för enheter i närheten att spåra enhetens plats." "Ändra inställning" "Inställningen har uppdaterats. Försök att ansluta igen." "Det gick inte att ändra sekretessinställningen" diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 90ef9489adb9..b1b29c394361 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -303,7 +303,7 @@ "Ungependa kuruhusu <b>%1$s</b> ifikie shughuli zako za kimwili?" "Kamera" "ipige picha na kurekodi video" - "Ungependa kuruhusu <b>%1$s</b> kupiga picha na kurekodi video?" + "Ungependa kuruhusu <b>%1$s</b> ipige picha na irekodi video?" "Rekodi ya nambari za simu" "kusoma na kuandika rekodi ya nambari za simu" "Ungependa kuiruhusu <b>%1$s</b> ifikie rekodi zako za nambari za simu?" @@ -435,7 +435,8 @@ "Kupiga picha na kurekodi video" "Programu hii inaweza kupiga picha na kurekodi video kwa kutumia kamera wakati wowote." "Ruhusu programu au huduma ipokee simu zinazopigwa tena kuhusu vifaa vya kamera kufunguliwa au kufungwa." - "Programu ya sahihi inaweza kupokea simu zinazopigwa tena wakati kifaa chochote cha kamera kinafunguliwa (kulingana na kifurushi cha programu) au kufungwa." + + "Kudhibiti mtetemo" "Inaruhusu programu kudhibiti kitingishi." "piga simu moja kwa moja kwa nambari za simu" @@ -1247,7 +1248,7 @@ "Imeshindwa kuunganisha kwenye %1$s" "Gusa ili ubadilishe mipangilio ya faragha na ujaribu tena" "Ungependa kubadilisha mipangilio ya faragha?" - "Huenda %1$s ikataka kuunganisha ikitumia anwani ya MAC ya kifaa chako, kitambulishi cha kipekee. Hatua hii inaweza kuruhusu vifaa vilivyo karibu nawe vifuatilie mahali kifaa chako kilipo. \n\nUkiendelea, %1$s itabadilisha mipangilio yako ya faragha na ijaribu kuunganisha tena." + "Ili kuunganisha, %1$s inahitaji kutumia anwani ya MAC ya kifaa chako, kitambulishi cha kipekee. Kwa sasa, mipangilio yako ya faragha ya mtandao huu inatumia kitambulishi kwa nasibu. \n\nMabadiliko haya yanaweza kuruhusu vifaa vilivyo karibu nawe vifuatilie mahali kifaa chako kilipo." "Badilisha mipangilio" "Imesasisha mipangilio. Jaribu kuunganisha tena." "Imeshindwa kubadilisha mipangilio ya faragha" diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index c21f9ce6643e..97212ffd54e0 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -436,7 +436,7 @@ "இந்த ஆப்ஸ் எப்போது வேண்டுமானாலும் கேமராவைப் பயன்படுத்தி படங்களை எடுக்கலாம், வீடியோக்களை ரெக்கார்டு செய்யலாம்." - + "அதிர்வைக் கட்டுப்படுத்துதல்" "அதிர்வைக் கட்டுப்படுத்தப் ஆப்ஸை அனுமதிக்கிறது." @@ -1249,7 +1249,8 @@ "%1$s உடன் இணைக்க முடியவில்லை" "தனியுரிமை அமைப்புகளை மாற்ற தட்டி மீண்டும் முயலவும்" "தனியுரிமை அமைப்பை மாற்றவா?" - "தனித்துவமான அடையாளங்காட்டியான MAC முகவரியைப் பயன்படுத்தி இணைக்க %1$s விரும்பக்கூடும். இதனால் உங்கள் சாதனத்தின் இருப்பிடத்தை அருகில் இருக்கும் சாதனங்கள் டிராக் செய்ய அனுமதிக்கப்படும். \n\nநீங்கள் தொடரும்பட்சத்தில் %1$s உங்கள் தனியுரிம அமைப்பை மாற்றி மீண்டும் இணைய முயலும்." + + "அமைப்பை மாற்று" "அமைப்பு புதுப்பிக்கப்பட்டது. மீண்டும் இணைக்கவும்." "தனியுரிமை அமைப்பை மாற்ற இயலவில்லை" diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 9064c06f2b05..bd0ccf9db55c 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -303,7 +303,7 @@ "మీ భౌతిక కార్యకలాపాన్ని యాక్సెస్ చేయడానికి <b>%1$s</b>ను అనుమతించాలా?" "కెమెరా" "చిత్రాలను తీయడానికి మరియు వీడియోను రికార్డ్ చేయడానికి" - "చిత్రాలు తీయడానికి మరియు వీడియో రికార్డ్ చేయడానికి <b>%1$s</b>ని అనుమతించాలా?" + "ఫోటోలు తీయడానికి, వీడియో రికార్డ్ చేయడానికి <b>%1$s</b>ను అనుమతించాలా?" "కాల్ లాగ్‌లు" "ఫోన్ కాల్ లాగ్‌ని చదవండి మరియు రాయండి" "మీ ఫోన్ కాల్ లాగ్‌లను యాక్సెస్ చేయడానికి <b>%1$s</b>ని అనుమతించాలా?" @@ -435,7 +435,8 @@ "చిత్రాలు మరియు వీడియోలు తీయడం" "ఈ యాప్‌ కెమెరాను ఉపయోగించి ఎప్పుడైనా చిత్రాలను తీయగలదు మరియు వీడియోలను రికార్డ్ చేయగలదు." "కెమెరా పరికరాలు తెరుచుకుంటున్నప్పుడు లేదా మూసుకుంటున్నప్పుడు కాల్‌బ్యాక్‌లను స్వీకరించడానికి యాప్‌ను లేదా సర్వీస్‌ను అనుమతించండి." - "ఏదైనా కెమెరా పరికరం తెరుచుకుంటున్నప్పుడు (ఏదైనా యాప్ ప్యాకేజీ ద్వారా) లేదా మూసుకుంటున్నప్పుడు ఈ సిగ్నేచర్ యాప్ కాల్‌బ్యాక్‌లను అందుకోగలదు." + + "వైబ్రేషన్‌ను నియంత్రించడం" "వైబ్రేటర్‌ను నియంత్రించడానికి యాప్‌ను అనుమతిస్తుంది." "నేరుగా కాల్ చేసే ఫోన్ నంబర్‌లు" @@ -1247,7 +1248,7 @@ "%1$sకు కనెక్ట్ చేయడం సాధ్యం కాదు" "మీ గోప్యతా సెట్టింగ్‌లను మార్చడానికి నొక్కి, మళ్లీ ప్రయత్నించండి" "గోప్యతా సెట్టింగ్‌ను మార్చాలా?" - "%1$s అనేది ప్రత్యేకమైన ఐడెంటిఫయర్ అయిన మీ పరికరం MAC చిరునామాను ఉపయోగించి కనెక్ట్ చేయాల్సి రావచ్చు. అలా చేయడం వలన మీ లొకేషన్‌ను ట్రాక్ చేయడానికి సమీప పరికరాలకు అనుమతి లభించవచ్చు. \n\nఒకవేళ మీరు కొనసాగితే, మీ గోప్యతా సెట్టింగ్‌ను %1$s మారుస్తుంది, అప్పుడు తిరిగి కనెక్ట్ చేయడానికి ప్రయత్నిస్తుంది." + "కనెక్ట్ చేయడానికి, %1$s అనేది ప్రత్యేకమైన ఐడెంటిఫయర్ అయిన మీ పరికరం యొక్క MAC చిరునామాను ఉపయోగించాల్సి ఉంటుంది. ప్రస్తుతం, ఈ నెట్‌వర్క్ కోసం మీ గోప్యతా సెట్టింగ్ అనేది యాదృచ్ఛిక ఐడెంటిఫయర్‌ను ఉపయోగిస్తుంది. \n\nఈ మార్పు వలన మీ పరికరం యొక్క లొకేషన్‌ను ట్రాక్ చేయడానికి సమీప పరికరాలకు అనుమతి లభించవచ్చు." "సెట్టింగ్‌ను మార్చండి" "సెట్టింగ్ అప్‌డేట్ చేయబడింది. మళ్లీ కనెక్ట్ చేయడానికి ప్రయత్నించండి." "గోప్యతా సెట్టింగ్‌లను మార్చడం సాధ్యం కాదు" diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index b1d6e10495ea..cbd083af83d7 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -435,7 +435,8 @@ "ถ่ายภาพและวิดีโอ" "แอปนี้สามารถถ่ายภาพและวิดีโอด้วยกล้องได้ทุกเมื่อ" "อนุญาตให้แอปพลิเคชันหรือบริการได้รับโค้ดเรียกกลับเมื่อมีการเปิดหรือปิดอุปกรณ์กล้อง" - "แอปลายเซ็นนี้จะได้รับโค้ดเรียกกลับเมื่อมีการปิดหรือเปิดอุปกรณ์กล้อง (แพ็กเกจแอปพลิเคชันที่เปิด)" + + "ควบคุมการสั่นเตือน" "อนุญาตให้แอปพลิเคชันควบคุมการสั่นเตือน" "โทรติดต่อหมายเลขโทรศัพท์โดยตรง" @@ -1247,7 +1248,7 @@ "เชื่อมต่อกับ %1$s ไม่ได้" "แตะเพื่อเปลี่ยนการตั้งค่าความเป็นส่วนตัวแล้วลองใหม่" "เปลี่ยนการตั้งค่าความเป็นส่วนตัวใช่ไหม" - "%1$s อาจต้องการเชื่อมต่อโดยใช้ที่อยู่ MAC ของอุปกรณ์ ซึ่งเป็นตัวระบุที่ไม่ซ้ำกัน วิธีนี้อาจทำให้อุปกรณ์ใกล้เคียงติดตามตำแหน่งของอุปกรณ์ของคุณได้ \n\nหากดำเนินการต่อ %1$s จะเปลี่ยนการตั้งค่าความเป็นส่วนตัวของคุณแล้วลองเชื่อมต่ออีกครั้ง" + "%1$s ต้องเชื่อมต่อโดยใช้ที่อยู่ MAC ของอุปกรณ์ ซึ่งเป็นตัวระบุที่ไม่ซ้ำกัน การตั้งค่าความเป็นส่วนตัวในปัจจุบันของคุณสำหรับเครือข่ายนี้ใช้ตัวระบุแบบสุ่มอยู่ \n\nวิธีนี้อาจทำให้อุปกรณ์ใกล้เคียงติดตามตำแหน่งอุปกรณ์ของคุณได้" "เปลี่ยนการตั้งค่า" "อัปเดตการตั้งค่าแล้ว ลองเชื่อมต่ออีกครั้ง" "เปลี่ยนการตั้งค่าความเป็นส่วนตัวไม่ได้" diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 97209a71d781..f40404fc3059 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -435,7 +435,8 @@ "kumuha ng mga larawan at video" "Makakakuha ng mga larawan at makakapag-record ng mga video ang app na ito gamit ang camera anumang oras." "Payagan ang isang application o serbisyo na makatanggap ng mga callback tungkol sa pagbubukas o pagsasara ng mga camera device." - "Ang signature app na ito ay makakatanggap ng mga callback kapag binubuksan (ng anumang application package) o isinasara ng anumang camera device." + + "kontrolin ang pag-vibrate" "Pinapayagan ang app na kontrolin ang vibrator." "direktang tawagan ang mga numero ng telepono" @@ -1247,7 +1248,8 @@ "Hindi makakonekta sa %1$s" "I-tap para baguhin ang mga setting ng privacy at subukan ulit" "Baguhin ang setting ng privacy?" - "Baka gusto ng %1$s na kumonekta gamit ang MAC address, na isang natatanging pagkakakilanlan, ng iyong device. Dahil dito, baka masubaybayan ng mga kalapit na device ang lokasyon ng iyong device. \n\nKung magpapatuloy ka, babaguhin ng %1$s ang setting ng iyong privacy at susubukan nitong kumonekta ulit." + + "Baguhin ang setting" "Na-update ang setting. Subukang kumonekta ulit." "Hindi puwedeng baguhin ang setting ng privacy" diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 84cbacdf01cb..91129f6b4507 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -435,7 +435,8 @@ "resim çekme ve görüntü kaydetme" "Bu uygulama, herhangi bir zamanda kamerayı kullanarak fotoğraf ve video çekebilir." "Bir uygulama veya hizmetin açılıp kapatılan kamera cihazları hakkında geri çağırmalar almasına izin verin." - "Bu imza uygulaması, herhangi bir kamera cihazı açıldığında (herhangi bir uygulama paketi tarafından) veya kapatıldığında geri çağırmalar alabilir." + + "titreşimi denetleme" "Uygulamaya, titreşimi denetleme izni verir." "telefon numaralarına doğrudan çağrı yap" @@ -1247,7 +1248,7 @@ "%1$s ağına bağlanılamıyor" "Gizlilik ayarını değiştirip tekrar denemek için dokunun" "Gizlilik ayarı değiştirilsin mi?" - "%1$s, benzersiz bir tanımlayıcı olan, cihazınızın MAC adresini kullanarak bağlanmak isteyebilir. Bu, cihazınızın konumunun etraftaki cihazlar tarafından izlenmesine olanak sağlayabilir. \n\nDevam ederseniz %1$s, gizlilik ayarınızı değiştirip tekrar bağlanmayı deneyecektir." + "%1$s bağlanmak için benzersiz bir tanımlayıcı olan, cihazınızın MAC adresini kullanmaya ihtiyaç duyuyor. Bu ağa ait gizlilik ayarınız şu anda rastgele bir tanımlayıcı kullanıyor. \n\nBu değişiklik, cihazınızın konumunun etraftaki cihazlar tarafından izlenmesine olanak sağlayabilir." "Ayarı değiştir" "Ayar güncellendi. Tekrar bağlanmayı deneyin." "Gizlilik ayarı değiştirilemiyor" diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 158696503519..0cdb607fbf03 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -441,7 +441,8 @@ "фотограф. та знімати відео" "Цей додаток може будь-коли робити фотографії та записувати відео за допомогою камери." "Дозволити додатку або сервісу отримувати зворотні виклики щодо відкриття чи закриття камер." - "Цей додаток для підпису може отримувати зворотні виклики, коли будь-яка камера відкривається (з указанням пакета додатка) чи закривається." + + "контролювати вібросигнал" "Дозволяє програмі контролювати вібросигнал." "прямо набирати номери тел." @@ -1287,7 +1288,7 @@ "Не вдалося підключитися до мережі \"%1$s\"" "Натисніть, щоб змінити налаштування конфіденційності й повторити спробу" "Змінити налаштування конфіденційності?" - "%1$s може підключитися за допомогою унікального ідентифікатора вашого пристрою – його MAC-адреси. Через це пристрої поруч зможуть відстежувати місцеположення вашого пристрою. \n\nЯкщо продовжити, %1$s змінить ваші налаштування конфіденційності й повторить спробу підключення." + "Щоб підключитися, мережі %1$s потрібен унікальний ідентифікатор пристрою – його MAC-адреса. Згідно з налаштуваннями конфіденційності, ваша мережа зараз використовує випадкові ідентифікатори. \n\nПісля цієї зміни пристрої поруч, імовірно, зможуть відстежувати місцезнаходження вашого пристрою." "Змінити налаштування" "Налаштування оновлено. Спробуйте підключитися знову." "Не вдалося змінити налаштування конфіденційності" @@ -1369,7 +1370,7 @@ "Надсил. SMS повідомлень" "Програма <b>%1$s</b> надсилає велику кількість SMS-повідомлень. Дозволити цій програмі й надалі надсилати повідомлення?" "Дозволити" - "Відмовити" + "Заборонити" "<b>%1$s</b> хоче надіслати повідомлення на таку адресу: <b>%2$s</b>." "Можуть стягуватися кошти"" з вашого мобільного рахунку." "Буде стягнено кошти з вашого мобільного рахунку." diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 5f6127d849fe..941ac4aeaf57 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -435,7 +435,7 @@ "تصاویر لیں اور ویڈیوز بنائیں" "یہ ایپ کسی بھی وقت کیمرا استعمال کرتے ہوئے تصاویر لے سکتی ہے اور ویڈیوز ریکارڈ کر سکتی ہے۔" "ایپلیکیشن یا سروس کو کیمرا کے آلات کے کُھلنے یا بند ہونے سے متعلق کال بیکس موصول کرنے کی اجازت دیں۔" - "یہ دستخط ایپ کال بیکس وصول کر سکتی ہے جب کوئی بھی کیمرہ کا آلہ (کسی ایپلیکیشن پیکیج سے) کھولا جارہا ہو یا بند کیا جا رہا ہو۔" + "یہ ایپ کال بیکس موصول کر سکتی ہے جب کوئی بھی کیمرا کا آلہ (کسی ایپلیکیشن سے) کھولا جا رہا ہو یا بند کیا جا رہا ہو۔" "ارتعاش کو کنٹرول کریں" "ایپ کو وائبریٹر کنٹرول کرنے کی اجازت دیتا ہے۔" "براہ راست فون نمبرز پر کال کریں" @@ -1247,7 +1247,7 @@ "%1$s سے منسلک نہیں کر سکتے" "رازداری کی ترتیبات تبدیل کرنے اور دوبارہ کوشش کرنے کے لیے تھپتھپائیں" "رازداری کی ترتیب تبدیل کریں؟" - "‏%1$s آپ کے آلہ MAC پتہ، منفرد شناخت کار کے ذریعے منسلک ہونا چاہتا ہے۔ یہ آپ کے آلے کے مقام کو قریبی آلات کے ذریعہ ٹریک کرنے کی اجازت دے سکتا ہے۔ \n\nاگر آپ جاری رکھتے ہیں، تو %1$s آپ کی رازداری کی ترتیب کو تبدیل کر دے گا اور دوبارہ منسلک ہونے کی کوشش کرے گا۔" + "‏منسلک کرنے کے ليے، %1$s کو آپ کے آلہ کا MAC پتہ استعمال کرنے کی ضرورت ہے، ایک منفرد شناخت کار ہے۔ فی الحال، اس نیٹ ورک کے ليے آپ کی رازداری کی ترتیب بے ترتیب شناخت کار استعمال کرتی ہے۔ \n\nیہ تبدیلی آپ کے آلہ کے مقام کو قریبی آلات کے ذریعے ٹریک کرنے کی اجازت دے سکتی ہے۔" "ترتیب تبدیل کریں" "ترتیبات اپ ڈیٹ کر دی گئی۔ دوبارہ منسلک کرنے کی کوشش کریں۔" "رازداری کی ترتیب تبدیل نہیں ہو سکتی" diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index 4d0e33042bb4..6e27035a5c56 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -435,7 +435,7 @@ "rasm va videoga olish" "Bu ilova xohlagan vaqtda kamera orqali suratga olishi va video yozib olishi mumkin." "Ilova yoki xizmatga kamera qurilmalari ochilayotgani yoki yopilayotgani haqida qayta chaqiruvlar qabul qilishi uchun ruxsat berish." - "Bu imzo ilovasi har qanday kamera qurilmasi ochilayotganda (istalgan ilova paketi tarafidan) yoki yopilayotganda qayta chaqiruvlar qabul qilishi mumkin." + "Bu ilova har qanday kamera qurilmasi ochilayotganda (istalgan ilova tarafidan) yoki yopilayotganda qayta chaqiruvlar qabul qilishi mumkin." "tebranishni boshqarish" "Ilova tebranishli signallarni boshqarishi mumkin." "telefon raqamlariga tog‘ridan to‘g‘ri qo‘ng‘iroq qilish" @@ -1247,7 +1247,7 @@ "“%1$s” nomli tarmoqqa ulanilmadi" "Maxfiylik sozlamalarini oʻzgartirish uchun bosing va qayta urining" "Maxfiylik sozlamalari oʻzgartirilsinmi?" - "%1$s qurilmangizning MAC manzilidan (unikal identifikator) foydalanib, ulanishi mumkin. Bunday holda yaqin-atrofingizdagi qurilmalar qurilmangiz joylashuvini kuzatishi mumkin. \n\nDavom etsangiz, %1$s xavfsizlik sozlamalaringizni oʻzgartiradi va yana urinishga harakat qiladi." + "Ulanish uchun %1$s qurilmangizning MAC manzilidan (unikal identifikator) foydalanishi lozim. Hozirda bu tarmoq uchun maxfiylik sozlamalari tasodifiy identifikatordan foydalanmoqda. \n\nBunday holda yaqin-atrofingizdagi qurilmalar qurilmangiz joylashuvini kuzatishi mumkin." "Sozlamani oʻzgartirish" "Sozlama yangilandi. Qaytadan ulaning." "Maxfiylik sozlamasi oʻzgartirilmadi" diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index f05cd214a351..3dea941ce4df 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -435,7 +435,8 @@ "chụp ảnh và quay video" "Ứng dụng này có thể chụp ảnh và quay video bằng máy ảnh bất cứ lúc nào." "Cho phép một ứng dụng hoặc dịch vụ nhận lệnh gọi lại khi các thiết bị máy ảnh đang được mở/đóng." - "Ứng dụng chữ ký này có thể nhận các lệnh gọi lại khi có bất kỳ thiết bị máy ảnh nào đang được mở (bằng gói ứng dụng) hoặc đóng." + + "kiểm soát rung" "Cho phép ứng dụng kiểm soát bộ rung." "gọi trực tiếp số điện thoại" @@ -1247,7 +1248,7 @@ "Không kết nối được với %1$s" "Nhấn để thay đổi các tùy chọn cài đặt quyền riêng tư rồi thử lại" "Thay đổi tùy chọn cài đặt quyền riêng tư?" - "%1$s có thể muốn kết nối bằng địa chỉ MAC (một mã nhận dạng duy nhất) của thiết bị. Nhờ đó, các thiết bị lân cận có thể theo dõi vị trí thiết bị của bạn. \n\nNếu bạn tiếp tục, %1$s sẽ thay đổi tùy chọn cài đặt quyền riêng tư của bạn rồi tìm cách kết nối lại." + "Để kết nối, %1$s cần phải dùng địa chỉ MAC (mã nhận dạng duy nhất) của thiết bị. Hiện tại, tùy chọn cài đặt quyền riêng tư của mạng này đang dùng mã nhận dạng ngẫu nhiên. \n\nVới sự thay đổi này, các thiết bị ở gần có thể theo dõi vị trí thiết bị của bạn." "Thay đổi tùy chọn cài đặt" "Đã cập nhật tùy chọn cài đặt. Hãy thử kết nối lại." "Không thể thay đổi tùy chọn cài đặt quyền riêng tư" diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index fee0eab260e5..85e5b358d856 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -435,7 +435,8 @@ "拍摄照片和视频" "此应用可随时使用相机拍摄照片和录制视频。" "允许应用或服务接收与打开或关闭摄像头设备有关的回调。" - "此签名应用可在任何摄像头设备(被某些应用软件包)打开或关闭时接收相应回调。" + + "控制振动" "允许应用控制振动器。" "拨打电话" @@ -1247,7 +1248,7 @@ "无法连接到“%1$s”" "点按以更改隐私设置并重试" "要更改隐私设置吗?" - "“%1$s”可能想使用您设备的 MAC 地址(一个唯一标识符)来进行连接。这可能会让附近的设备可以跟踪您设备的位置信息。\n\n如果您继续操作,“%1$s”将会更改您的隐私设置并尝试重新连接。" + "“%1$s”需要使用您设备的 MAC 地址(一个唯一标识符)才能连接。目前,该网络的隐私设置使用的是随机标识符。\n\n这项变更可能会让附近的设备可以跟踪您设备的位置信息。" "更改设置" "设置已更新。请尝试重新连接。" "无法更改隐私设置" diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 413be2c28315..8f34ca3125cd 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -435,7 +435,8 @@ "拍照和拍攝影片" "此應用程式可以隨時使用相機拍照和攝錄。" "允許應用程式或服務接收相機裝置開啟或關閉的相關回電。" - "當任何相機裝置在開啟 (由應用程式套件) 或關閉時,此簽名應用程式就能接收回電。" + + "控制震動" "允許應用程式控制震動。" "直接撥打電話號碼" @@ -1247,7 +1248,7 @@ "無法連接「%1$s」" "輕按以更改私隱設定,然後重試" "要更改私隱設定嗎?" - "「%1$s」可能想透過您裝置的 MAC 位址 (不重複的識別碼) 連接。這可能會令附近裝置能夠追蹤您裝置的位置。\n\n如果繼續操作,「%1$s」會更改您的私隱設定並再嘗試連接。" + "%1$s 需要使用您裝置的 MAC 位址 (不重複的識別碼) 連接。此網絡的私隱設定目前使用隨機識別碼。\n\n此變更可能會令附近裝置能夠追蹤您裝置的位置。" "更改設定" "已更新設定,請嘗試重新連線。" "無法更改私隱設定" diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index ebbfdf1abbc5..543cf893276d 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -435,7 +435,8 @@ "拍攝相片和影片" "這個應用程式隨時可使用相機拍照及錄影。" "允許應用程式或服務接收相機裝置開啟或關閉的相關回呼。" - "當任何相機裝置在開啟 (由應用程式套件) 或關閉時,這個簽名應用程式就能接收回呼。" + + "控制震動" "允許應用程式控制震動。" "直接撥打電話號碼" @@ -1247,7 +1248,7 @@ "無法連線至「%1$s」" "輕觸即可變更隱私權設定並重試" "要變更隱私權設定嗎?" - "「%1$s」可能會要求使用裝置 MAC 位址 (即專屬 ID) 進行連線。如果你允許,附近的裝置或許將可追蹤你的裝置所在位置。\n\n如要繼續,「%1$s」將變更你的隱私權設定並再次嘗試連線。" + "「%1$s」要求使用裝置 MAC 位址 (即專屬 ID) 進行連線。你目前在這個網路的隱私權設定是使用隨機 ID。\n\n如果進行這項變更,附近的裝置或許可以追蹤你的裝置所在位置。" "變更設定" "設定已更新,請再次嘗試連線。" "無法變更隱私權設定" diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index dc51f2ee0e41..61a9b76667e7 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -435,7 +435,8 @@ "thatha izithombe namavidiyo" "Lolu hlelo lokusebenza lungathatha izithombe futhi lirekhode amavidiyo lusebenzisa ikhamera noma kunini." "Vumela uhlelo lokusebenza noma isevisi ukwamukela ukuphinda ufonelwe mayelana namadivayisi wekhamera avuliwe noma avaliwe." - "Lolu hlelo lokusebenza lesiginesha lungakwazi ukuthola ukuphinda ufonelwe uma noma iyiphi idivayisi yekhamera ivuliwe (ngephakheji yohlelo lokusebenza) noma ivaliwe." + + "lawula ukudlidliza" "Ivumela uhlelo lokusebenza ukulawula isidlidlizi." "ngokuqondile shayela izinombolo zocingo" @@ -1247,7 +1248,7 @@ "Ayikwazi ukuxhumeka ku-%1$s" "Thepha ukuze ushintshe izilungiselelo zobumfihlo uphinde uzame futhi" "Shintsha isilungiselelo sobumfihlo?" - "I-%1$s ingafuna ukuxhumeka isebenzisa ikheli lakho ledivayisi ye-MAC, inkomba ehlukile. Lokhu kungavumela indawo yedivayisi yakho ukuthi ilandelelwe amadivayisi aseduze. \n\nUma uqhubeka, i-%1$s izoshintsha isilungiselelo sakho sobumfihlo iphinde izame ukuxhumeka futhi." + "Ukuze uxhume, i-%1$s idinga ukusebenzisa ikheli lakho ledivayisi ye-MAC, inkomba ehlukile. Okwamanje, izilungiselelo zemfihlo yakho ngale nethiwekhi zisebenzisa inkomba engahleliwe. \n\nLokhu kungavumela indawo yedivayisi yakho ukuthi ilandelelwe amadivayisi aseduze." "Shintsha isilungiselelo" "Isilungiselelo sibuyekeziwe. Zama ukuxhuma futhi." "Ayikwazi ukushintsha isilungiselelo sobumfihlo" -- GitLab From e09a79200291f39e23f7276b0ffc571f1ac33f93 Mon Sep 17 00:00:00 2001 From: Chris Tate Date: Fri, 20 Mar 2020 18:22:02 +0000 Subject: [PATCH 180/219] Revert "Revoke 'always' web handler status when not autoverifying" This reverts commit a8fb6dc1671c93b8063c9888339959d9cd9728e9. Reason for revert: Inadvertently broke link handling stickiness even for well behaved apps Bug: 146204120 Test: install app that handles web urls; set to 'always' in Settings; install same apk again. Verify that app is still in 'always' state via 'adb shell dumpsys package d' Merged-In: If9046cb420961b8ef0333e9f1115eb69fb92242e Merged-In: I36d9c352e741e88b9fc773b084bef3991b6d96ed Change-Id: Ifac4f0c044c2c575a29bdd5ce5d14d12373fbe70 --- .../server/pm/PackageManagerService.java | 44 +++++-------------- .../java/com/android/server/pm/Settings.java | 1 - 2 files changed, 11 insertions(+), 34 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 028c2ed11378..0a2951d147c9 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -18078,48 +18078,36 @@ public class PackageManagerService extends IPackageManager.Stub int count = 0; final String packageName = pkg.packageName; - boolean handlesWebUris = false; - final boolean alreadyVerified; synchronized (mPackages) { // If this is a new install and we see that we've already run verification for this // package, we have nothing to do: it means the state was restored from backup. - final IntentFilterVerificationInfo ivi = - mSettings.getIntentFilterVerificationLPr(packageName); - alreadyVerified = (ivi != null); - if (!replacing && alreadyVerified) { - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.i(TAG, "Package " + packageName + " already verified: status=" - + ivi.getStatusString()); + if (!replacing) { + IntentFilterVerificationInfo ivi = + mSettings.getIntentFilterVerificationLPr(packageName); + if (ivi != null) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Package " + packageName+ " already verified: status=" + + ivi.getStatusString()); + } + return; } - return; } - // If any filters need to be verified, then all need to be. In addition, we need to - // know whether an updating app has any web navigation intent filters, to re- - // examine handling policy even if not re-verifying. + // If any filters need to be verified, then all need to be. boolean needToVerify = false; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { - if (filter.handlesWebUris(true)) { - handlesWebUris = true; - } if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) { Slog.d(TAG, "Intent filter needs verification, so processing all filters"); } needToVerify = true; - // It's safe to break out here because filter.needsVerification() - // can only be true if filter.handlesWebUris(true) returns true, so - // we've already noted that. break; } } } - // Note whether this app publishes any web navigation handling support at all, - // and whether there are any web-nav filters that fit the profile for running - // a verification pass now. if (needToVerify) { final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { @@ -18137,23 +18125,13 @@ public class PackageManagerService extends IPackageManager.Stub } if (count > 0) { - // count > 0 means that we're running a full verification pass if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count + " IntentFilter verification" + (count > 1 ? "s" : "") + " for userId:" + userId); mIntentFilterVerifier.startVerifications(userId); - } else if (alreadyVerified && handlesWebUris) { - // App used autoVerify in the past, no longer does, but still handles web - // navigation starts. - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy"); - } - synchronized (mPackages) { - clearIntentFilterVerificationsLPw(packageName, userId); - } } else { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "No web filters or no prior verify policy for " + packageName); + Slog.d(TAG, "No filters or not all autoVerify for " + packageName); } } } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 46485b5550a6..11a8f4b895f5 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1252,7 +1252,6 @@ public final class Settings { return false; } ps.clearDomainVerificationStatusForUser(userId); - ps.setIntentFilterVerificationInfo(null); return true; } -- GitLab From e6b4c38f902ef2f93e1ac1418186cbd243f46b6b Mon Sep 17 00:00:00 2001 From: Jay Aliomer Date: Tue, 24 Mar 2020 21:12:51 -0400 Subject: [PATCH 181/219] Failed UiModeManagerServiceTest Added a mock and mockito helpers to remedy failed tests Fixes: 151984124 Test: UiModeManagerServiceTest Change-Id: Ic128ed9853f6f3b9f8641c1bec2a7c981e52865f Merged-In: I09af78fd16662185d01aea427188f79527d47a9e --- .../src/com/android/server/UiModeManagerServiceTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java index 3fce5ebc8432..ef5e479171f2 100644 --- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java @@ -24,7 +24,6 @@ import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; import android.os.PowerManager; -import android.os.PowerManagerInternal; import android.os.RemoteException; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -49,6 +48,7 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.atLeastOnce; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @@ -76,6 +76,7 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { mUiManagerService = new UiModeManagerService(mContext, mWindowManager, mWakeLock, mTwilightManager, mPowerManager, true); mScreenOffRecievers = new HashSet<>(); + when(mPowerManager.isInteractive()).thenReturn(true); mService = mUiManagerService.getService(); when(mContext.checkCallingOrSelfPermission(anyString())) .thenReturn(PackageManager.PERMISSION_GRANTED); @@ -93,7 +94,7 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { mService.setNightMode(MODE_NIGHT_NO); } catch (SecurityException e) { /* we should ignore this update config exception*/ } mService.setNightMode(MODE_NIGHT_AUTO); - verify(mContext).registerReceiver(any(BroadcastReceiver.class), any()); + verify(mContext, atLeastOnce()).registerReceiver(any(BroadcastReceiver.class), any()); } @Test @@ -105,7 +106,7 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { mService.setNightMode(MODE_NIGHT_NO); } catch (SecurityException e) { /*we should ignore this update config exception*/ } given(mContext.registerReceiver(any(), any())).willThrow(SecurityException.class); - verify(mContext).unregisterReceiver(any(BroadcastReceiver.class)); + verify(mContext, atLeastOnce()).unregisterReceiver(any(BroadcastReceiver.class)); } @Test -- GitLab From 23c04c6f62f26809488d6f1710689fc408e03160 Mon Sep 17 00:00:00 2001 From: Dichen Zhang Date: Thu, 12 Mar 2020 12:25:09 -0700 Subject: [PATCH 182/219] Fix command injection on screencap There is a potential injection by using screencap in case of user handled parameters. "dumpstate" command launches "screencap", when "-p" is argument is set. At that moment, content of "-o" parameter generates a path with ".png" extension to define "screencap" argument. "dumpstate" is often run as a service with "root" privileged such as defined in "dumpstate.rc". For instance "bugreportz" call "ctl.start" property with "dumpstatez". Launching "dumpstate" with "-p" option and a user input as "-o" would result in a root command execution. SE Linux might protect part of this attack. Cherry-pick from ag/10651695 with fix ag/10700515 Bug: 123230379 Test: please see commands #4 and #5 Change-Id: Icd88cdf4af153e07addb4449cdb117b1a3c881d3 --- cmds/screencap/screencap.cpp | 38 +++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp index 0bb1af13643c..4410f1c4570c 100644 --- a/cmds/screencap/screencap.cpp +++ b/cmds/screencap/screencap.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -99,11 +100,38 @@ static uint32_t dataSpaceToInt(ui::Dataspace d) } static status_t notifyMediaScanner(const char* fileName) { - String8 cmd("am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file://"); - cmd.append(fileName); - cmd.append(" > /dev/null"); - int result = system(cmd.string()); - if (result < 0) { + std::string filePath("file://"); + filePath.append(fileName); + char *cmd[] = { + (char*) "am", + (char*) "broadcast", + (char*) "am", + (char*) "android.intent.action.MEDIA_SCANNER_SCAN_FILE", + (char*) "-d", + &filePath[0], + nullptr + }; + + int status; + int pid = fork(); + if (pid < 0){ + fprintf(stderr, "Unable to fork in order to send intent for media scanner.\n"); + return UNKNOWN_ERROR; + } + if (pid == 0){ + int fd = open("/dev/null", O_WRONLY); + if (fd < 0){ + fprintf(stderr, "Unable to open /dev/null for media scanner stdout redirection.\n"); + exit(1); + } + dup2(fd, 1); + int result = execvp(cmd[0], cmd); + close(fd); + exit(result); + } + wait(&status); + + if (status < 0) { fprintf(stderr, "Unable to broadcast intent for media scanner.\n"); return UNKNOWN_ERROR; } -- GitLab From d16e86f466c2fc18448b654cbe71089c7fede991 Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Wed, 25 Mar 2020 10:46:44 -0700 Subject: [PATCH 183/219] Require a more specific intent Fixes: 147606347 Test: run poc, device didn't reboot Change-Id: I8f721ca659d58271880a7adbf386b270b331e55b Merged-In: I8f721ca659d58271880a7adbf386b270b331e55b (cherry picked from commit a9afc32ddc013424e2d17a091ef3fdfbe18c0d76) --- .../com/android/systemui/keyguard/KeyguardSliceProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java index 0687b7d8efce..8a0672ca4ffe 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java @@ -319,7 +319,8 @@ public class KeyguardSliceProvider extends SliceProvider implements mZenModeController = new ZenModeControllerImpl(getContext(), mHandler); mZenModeController.addCallback(this); mDatePattern = getContext().getString(R.string.system_ui_aod_date_pattern); - mPendingIntent = PendingIntent.getActivity(getContext(), 0, new Intent(), 0); + mPendingIntent = PendingIntent.getActivity(getContext(), 0, + new Intent(getContext(), KeyguardSliceProvider.class), 0); mMediaWakeLock = new SettableWakeLock(WakeLock.createPartial(getContext(), "media"), "media"); KeyguardSliceProvider.sInstance = this; -- GitLab From 678528ed42e98bb3e71d0efc6768ff881d04728c Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 26 Mar 2020 10:13:27 +0900 Subject: [PATCH 184/219] Check permissions in INetworkManagementService#setIPv6AddrGenMode This function was missing a permission check, and thus would allow any app to transitively call the netd setIPv6AddrGenMode IPC. Fortunately, due to a bug in that IPC, it can only set the mode to stable privacy and not to EUI-64. This code is unused. The only thing on the system that sets the IPv6 addrgen mode is the networkstack, but that does so by calling the netd IPC directly. Test: builds Bug: 141920289 Change-Id: Id54431e81dceaff09f785a280ceee0973543a30f --- .../core/java/com/android/server/NetworkManagementService.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index e5fb5062541e..ab0d2b7b62d5 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -55,6 +55,7 @@ import android.net.IpPrefix; import android.net.LinkAddress; import android.net.Network; import android.net.NetworkPolicyManager; +import android.net.NetworkStack; import android.net.NetworkStats; import android.net.NetworkUtils; import android.net.RouteInfo; @@ -874,6 +875,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub { @Override public void setIPv6AddrGenMode(String iface, int mode) throws ServiceSpecificException { + NetworkStack.checkNetworkStackPermission(mContext); try { mNetdService.setIPv6AddrGenMode(iface, mode); } catch (RemoteException e) { -- GitLab From 76f76cc0f6faa13d78fedccbb962a44be6ec83cd Mon Sep 17 00:00:00 2001 From: Ugo Yu Date: Thu, 19 Mar 2020 16:15:58 +0800 Subject: [PATCH 185/219] Sequentially handle enable and disable * Replace thread sleeps in MESSAGE_ENABLE and MESSAGE_DISABLE to delay messages. To make sure we do not block the state change process while waiting for a state change callback. * Prevent handling enable or disable at the same time by deferring the the request when we are enabling or disabling Bluetooth. Bug: 128569058 Test: Manual Change-Id: I2301ba22b6c10fcea71e3b66eea3ea0a0d7f0475 --- .../server/BluetoothManagerService.java | 133 +++++++++++++++--- 1 file changed, 116 insertions(+), 17 deletions(-) diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index b92f23573a01..15a59ced54c1 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -107,9 +107,13 @@ class BluetoothManagerService extends IBluetoothManager.Stub { private static final int USER_SWITCHED_TIME_MS = 200; // Delay for the addProxy function in msec private static final int ADD_PROXY_DELAY_MS = 100; + // Delay for retrying enable and disable in msec + private static final int ENABLE_DISABLE_DELAY_MS = 300; private static final int MESSAGE_ENABLE = 1; private static final int MESSAGE_DISABLE = 2; + private static final int MESSAGE_HANDLE_ENABLE_DELAYED = 3; + private static final int MESSAGE_HANDLE_DISABLE_DELAYED = 4; private static final int MESSAGE_REGISTER_ADAPTER = 20; private static final int MESSAGE_UNREGISTER_ADAPTER = 21; private static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30; @@ -131,6 +135,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { private static final int RESTORE_SETTING_TO_OFF = 0; private static final int MAX_ERROR_RESTART_RETRIES = 6; + private static final int MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES = 10; // Bluetooth persisted setting is off private static final int BLUETOOTH_OFF = 0; @@ -161,6 +166,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { private final ReentrantReadWriteLock mBluetoothLock = new ReentrantReadWriteLock(); private boolean mBinding; private boolean mUnbinding; + private int mWaitForEnableRetry; + private int mWaitForDisableRetry; private BluetoothAirplaneModeListener mBluetoothAirplaneModeListener; @@ -1638,8 +1645,18 @@ class BluetoothManagerService extends IBluetoothManager.Stub { break; case MESSAGE_ENABLE: + int quietEnable = msg.arg1; + if (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED) + || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED)) { + // We are handling enable or disable right now, wait for it. + mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_ENABLE, + quietEnable, 0), ENABLE_DISABLE_DELAY_MS); + break; + } + if (DBG) { - Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth); + Slog.d(TAG, "MESSAGE_ENABLE(" + quietEnable + "): mBluetooth = " + + mBluetooth); } mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); mEnable = true; @@ -1662,7 +1679,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { mBluetoothLock.readLock().unlock(); } - mQuietEnable = (msg.arg1 == 1); + mQuietEnable = (quietEnable == 1); if (mBluetooth == null) { handleEnable(mQuietEnable); } else { @@ -1671,8 +1688,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { // the previous Bluetooth process has exited. The // waiting period has three components: // (a) Wait until the local state is STATE_OFF. This - // is accomplished by - // "waitForState(Set.of(BluetoothAdapter.STATE_OFF))". + // is accomplished by sending delay a message + // MESSAGE_HANDLE_ENABLE_DELAYED // (b) Wait until the STATE_OFF state is updated to // all components. // (c) Wait until the Bluetooth process exits, and @@ -1682,33 +1699,108 @@ class BluetoothManagerService extends IBluetoothManager.Stub { // message. The delay time is backed off if Bluetooth // continuously failed to turn on itself. // - waitForState(Set.of(BluetoothAdapter.STATE_OFF)); - Message restartMsg = - mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE); - mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs()); + mWaitForEnableRetry = 0; + Message enableDelayedMsg = + mHandler.obtainMessage(MESSAGE_HANDLE_ENABLE_DELAYED); + mHandler.sendMessageDelayed(enableDelayedMsg, ENABLE_DISABLE_DELAY_MS); } break; case MESSAGE_DISABLE: + if (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED) || mBinding + || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED)) { + // We are handling enable or disable right now, wait for it. + mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_DISABLE), + ENABLE_DISABLE_DELAY_MS); + break; + } + if (DBG) { - Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth); + Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth + + ", mBinding = " + mBinding); } mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); + if (mEnable && mBluetooth != null) { - waitForState(Set.of(BluetoothAdapter.STATE_ON)); + mWaitForDisableRetry = 0; + Message disableDelayedMsg = + mHandler.obtainMessage(MESSAGE_HANDLE_DISABLE_DELAYED, 0, 0); + mHandler.sendMessageDelayed(disableDelayedMsg, ENABLE_DISABLE_DELAY_MS); + } else { mEnable = false; handleDisable(); - waitForState(Set.of(BluetoothAdapter.STATE_OFF, - BluetoothAdapter.STATE_TURNING_ON, - BluetoothAdapter.STATE_TURNING_OFF, - BluetoothAdapter.STATE_BLE_TURNING_ON, - BluetoothAdapter.STATE_BLE_ON, - BluetoothAdapter.STATE_BLE_TURNING_OFF)); - } else { + } + break; + + case MESSAGE_HANDLE_ENABLE_DELAYED: { + // The Bluetooth is turning off, wait for STATE_OFF + if (mState != BluetoothAdapter.STATE_OFF) { + if (mWaitForEnableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) { + mWaitForEnableRetry++; + Message enableDelayedMsg = + mHandler.obtainMessage(MESSAGE_HANDLE_ENABLE_DELAYED); + mHandler.sendMessageDelayed(enableDelayedMsg, ENABLE_DISABLE_DELAY_MS); + break; + } else { + Slog.e(TAG, "Wait for STATE_OFF timeout"); + } + } + // Either state is changed to STATE_OFF or reaches the maximum retry, we + // should move forward to the next step. + mWaitForEnableRetry = 0; + Message restartMsg = + mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE); + mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs()); + Slog.d(TAG, "Handle enable is finished"); + break; + } + + case MESSAGE_HANDLE_DISABLE_DELAYED: { + boolean disabling = (msg.arg1 == 1); + Slog.d(TAG, "MESSAGE_HANDLE_DISABLE_DELAYED: disabling:" + disabling); + if (!disabling) { + // The Bluetooth is turning on, wait for STATE_ON + if (mState != BluetoothAdapter.STATE_ON) { + if (mWaitForDisableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) { + mWaitForDisableRetry++; + Message disableDelayedMsg = mHandler.obtainMessage( + MESSAGE_HANDLE_DISABLE_DELAYED, 0, 0); + mHandler.sendMessageDelayed(disableDelayedMsg, + ENABLE_DISABLE_DELAY_MS); + break; + } else { + Slog.e(TAG, "Wait for STATE_ON timeout"); + } + } + // Either state is changed to STATE_ON or reaches the maximum retry, we + // should move forward to the next step. + mWaitForDisableRetry = 0; mEnable = false; handleDisable(); + // Wait for state exiting STATE_ON + Message disableDelayedMsg = + mHandler.obtainMessage(MESSAGE_HANDLE_DISABLE_DELAYED, 1, 0); + mHandler.sendMessageDelayed(disableDelayedMsg, ENABLE_DISABLE_DELAY_MS); + } else { + // The Bluetooth is turning off, wait for exiting STATE_ON + if (mState == BluetoothAdapter.STATE_ON) { + if (mWaitForDisableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) { + mWaitForDisableRetry++; + Message disableDelayedMsg = mHandler.obtainMessage( + MESSAGE_HANDLE_DISABLE_DELAYED, 1, 0); + mHandler.sendMessageDelayed(disableDelayedMsg, + ENABLE_DISABLE_DELAY_MS); + break; + } else { + Slog.e(TAG, "Wait for exiting STATE_ON timeout"); + } + } + // Either state is exited from STATE_ON or reaches the maximum retry, we + // should move forward to the next step. + Slog.d(TAG, "Handle disable is finished"); } break; + } case MESSAGE_RESTORE_USER_SETTING: if ((msg.arg1 == RESTORE_SETTING_TO_OFF) && mEnable) { @@ -2084,6 +2176,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { try { mBluetoothLock.writeLock().lock(); if ((mBluetooth == null) && (!mBinding)) { + Slog.d(TAG, "binding Bluetooth service"); //Start bind timeout and bind Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND); mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS); @@ -2452,6 +2545,12 @@ class BluetoothManagerService extends IBluetoothManager.Stub { writer.println(" " + app.getPackageName()); } + writer.println("\nBluetoothManagerService:"); + writer.println(" mEnable:" + mEnable); + writer.println(" mQuietEnable:" + mQuietEnable); + writer.println(" mEnableExternal:" + mEnableExternal); + writer.println(" mQuietEnableExternal:" + mQuietEnableExternal); + writer.println(""); writer.flush(); if (args.length == 0) { -- GitLab From cfad989c72d3f309ac56bd0db04bb748b09ddf03 Mon Sep 17 00:00:00 2001 From: Oli Lan Date: Fri, 1 Nov 2019 11:33:53 +0000 Subject: [PATCH 186/219] Check DUMP permission before dumping in RollbackManagerService. Bug: 143125031 Bug: 150949837 Test: atest CtsSecurityTestCases:android.security.cts.ServicePermissionsTest#testDumpProtected Change-Id: Icd813d30eabc6d52a34bd3440a73d2e0876a89ed Merged-In: Icd813d30eabc6d52a34bd3440a73d2e0876a89ed (cherry picked from commit 8753d8249e40f55e2a565e109561e6ba184c2e4a) --- .../android/server/rollback/RollbackManagerServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java index 08c1bb536211..1f75294de8e5 100644 --- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java @@ -58,6 +58,7 @@ import android.util.SparseLongArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ArrayUtils; +import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.server.LocalServices; import com.android.server.Watchdog; @@ -1479,6 +1480,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; + IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); synchronized (mLock) { for (RollbackData data : mRollbacks) { -- GitLab From a3d4c80e04eb95865d8f55e11e36e3ef0d6d6519 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 26 Mar 2020 19:06:00 -0700 Subject: [PATCH 187/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: Ib177970aca9cdefefed358524c8fe22ac8527102 --- core/res/res/values-af/strings.xml | 3 +-- core/res/res/values-am/strings.xml | 3 +-- core/res/res/values-ar/strings.xml | 3 +-- core/res/res/values-as/strings.xml | 8 +++----- core/res/res/values-az/strings.xml | 3 +-- core/res/res/values-b+sr+Latn/strings.xml | 3 +-- core/res/res/values-be/strings.xml | 3 +-- core/res/res/values-bg/strings.xml | 3 +-- core/res/res/values-bn/strings.xml | 2 +- core/res/res/values-bs/strings.xml | 3 +-- core/res/res/values-ca/strings.xml | 3 +-- core/res/res/values-cs/strings.xml | 3 +-- core/res/res/values-da/strings.xml | 3 +-- core/res/res/values-de/strings.xml | 3 +-- core/res/res/values-el/strings.xml | 3 +-- core/res/res/values-es-rUS/strings.xml | 4 ++-- core/res/res/values-es/strings.xml | 3 +-- core/res/res/values-et/strings.xml | 3 +-- core/res/res/values-eu/strings.xml | 6 ++---- core/res/res/values-fa/strings.xml | 3 +-- core/res/res/values-fi/strings.xml | 3 +-- core/res/res/values-fr-rCA/strings.xml | 3 +-- core/res/res/values-fr/strings.xml | 3 +-- core/res/res/values-gl/strings.xml | 3 +-- core/res/res/values-gu/strings.xml | 4 ++-- core/res/res/values-hi/strings.xml | 12 +++++------- core/res/res/values-hr/strings.xml | 3 +-- core/res/res/values-hu/strings.xml | 3 +-- core/res/res/values-hy/strings.xml | 3 +-- core/res/res/values-in/strings.xml | 3 +-- core/res/res/values-is/strings.xml | 3 +-- core/res/res/values-it/strings.xml | 3 +-- core/res/res/values-iw/strings.xml | 3 +-- core/res/res/values-ja/strings.xml | 3 +-- core/res/res/values-ka/strings.xml | 3 +-- core/res/res/values-kk/strings.xml | 3 +-- core/res/res/values-km/strings.xml | 3 +-- core/res/res/values-kn/strings.xml | 5 ++--- core/res/res/values-ko/strings.xml | 3 +-- core/res/res/values-ky/strings.xml | 3 +-- core/res/res/values-lo/strings.xml | 3 +-- core/res/res/values-lt/strings.xml | 3 +-- core/res/res/values-lv/strings.xml | 3 +-- core/res/res/values-mk/strings.xml | 3 +-- core/res/res/values-ml/strings.xml | 2 +- core/res/res/values-mr/strings.xml | 5 ++--- core/res/res/values-ms/strings.xml | 3 +-- core/res/res/values-nb/strings.xml | 3 +-- core/res/res/values-ne/strings.xml | 3 +-- core/res/res/values-nl/strings.xml | 3 +-- core/res/res/values-or/strings.xml | 7 +++---- core/res/res/values-pt-rPT/strings.xml | 3 +-- core/res/res/values-ro/strings.xml | 3 +-- core/res/res/values-ru/strings.xml | 3 +-- core/res/res/values-sl/strings.xml | 3 +-- core/res/res/values-sr/strings.xml | 3 +-- core/res/res/values-sv/strings.xml | 3 +-- core/res/res/values-sw/strings.xml | 3 +-- core/res/res/values-ta/strings.xml | 5 ++--- core/res/res/values-te/strings.xml | 2 +- core/res/res/values-th/strings.xml | 3 +-- core/res/res/values-tl/strings.xml | 6 ++---- core/res/res/values-tr/strings.xml | 3 +-- core/res/res/values-uk/strings.xml | 3 +-- core/res/res/values-vi/strings.xml | 3 +-- core/res/res/values-zh-rCN/strings.xml | 3 +-- core/res/res/values-zh-rHK/strings.xml | 3 +-- core/res/res/values-zh-rTW/strings.xml | 3 +-- core/res/res/values-zu/strings.xml | 3 +-- 69 files changed, 84 insertions(+), 152 deletions(-) diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index cbc76f4260e5..019b0d70009d 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -435,8 +435,7 @@ "neem foto\'s en video\'s" "Hierdie program kan enige tyd met die kamera foto\'s neem en video\'s opneem." "Laat \'n program of diens toe om terugbeloproepe te ontvang oor kameratoestelle wat oopgemaak of toegemaak word." - - + "Hierdie program kan terugbeloproepe ontvang wanneer enige kameratoestel oopgemaak (deur watter program) of toegemaak word." "beheer vibrasie" "Laat die program toe om die vibrator te beheer." "skakel foonnommers direk" diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index bbd2ca68d46e..8b650ebb7c8d 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -435,8 +435,7 @@ "ፎቶዎች እና ቪዲዮዎች ያንሱ" "ይህ መተግበሪያ በማናቸውም ጊዜ ካሜራውን በመጠቀም ፎቶ ሊያነሳ እና ቪዲዮዎችን ሊቀርጽ ይችላል።" "አንድ መተግበሪያ ወይም አገልግሎት እየተከፈቱ ወይም እየተዘጉ ስላሉ የካሜራ መሣሪያዎች መልሶ ጥሪዎችን እንዲቀበል ይፍቀዱ።" - - + "ማንኛውም የካሜራ መሣሪያ እየተከፈተ (በምን መተግበሪያ) ወይም እየተዘጋ ባለበት ጊዜ ይህ መተግበሪያ መልሶ ጥሪዎችን መቀበል ይችላል።" "ነዛሪ ተቆጣጠር" "ነዛሪውን ለመቆጣጠር ለመተግበሪያው ይፈቅዳሉ።" "በቀጥታ ስልክ ቁጥሮች ደውል" diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 5caaf1bfab7f..03706a7bd354 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -447,8 +447,7 @@ "التقاط صور وفيديوهات" "يمكن لهذا التطبيق التقاط صور وتسجيل فيديوهات باستخدام الكاميرا في أي وقت." "يسمح الإذن لتطبيق أو خدمة بتلقّي استدعاءات عما إذا كانت أجهزة الكاميرات مفتوحة أو مغلقة." - - + "يمكن أن يتلقّى هذا التطبيق استدعاءات عندما يكون جهاز أي كاميرا مفتوحًا (بتطبيق) أو مغلقًا." "التحكم في الاهتزاز" "للسماح للتطبيق بالتحكم في الهزّاز." "اتصال مباشر بأرقام الهواتف" diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index a25fd3dfdf44..480902c6d388 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -435,8 +435,7 @@ "ফট\' তোলা আৰু ভিডিঅ\' ৰেকৰ্ড কৰা" "এই এপে যিকোনো সময়তে কেমেৰা ব্যৱহাৰ কৰি ফট\' তুলিব আৰু ভিডিঅ\' ৰেকর্ড কৰিব পাৰে।" "কোনো এপ্লিকেশ্বন অথবা সেৱাক কেমেৰা ডিভাইচসমূহ খোলা অথবা বন্ধ কৰাৰ বিষয়ে কলবেকসমূহ গ্ৰহণ কৰিবলৈ অনুমতি দিয়ক।" - - + "যিকোনো কেমেৰা ডিভাইচ খুলি থকা অথবা বন্ধ কৰি থকাৰ সময়ত (কোনো এপ্লিকেশ্বনৰ দ্বাৰা) এই এপ্‌টোৱে কলবেক গ্ৰহণ কৰিব পাৰে।" "কম্পন নিয়ন্ত্ৰণ কৰক" "ভাইব্ৰেটৰ নিয়ন্ত্ৰণ কৰিবলৈ এপটোক অনুমতি দিয়ে।" "পোনপটীয়াকৈ ফ\'ন নম্বৰলৈ কল কৰক" @@ -784,7 +783,7 @@ "অন্যান্য" "নিজৰ উপযোগিতা অনুযায়ী" "নিজৰ উপযোগিতা অনুযায়ী" - "সহায়ক" + "Assistant" "ভাতৃ" "শিশু" "সংগী" @@ -1248,8 +1247,7 @@ "%1$sৰ সৈতে সংযোগ কৰিব নোৱাৰি" "গোপনীয়তাৰ ছেটিংসমূহ সলনি কৰিবলৈ আৰু পুনৰ চেষ্টা কৰিবলৈ টিপক" "গোপনীয়তাৰ ছেটিংটো সলনি কৰিবনে?" - - + "সংযোগ কৰিবলৈ %1$sএ আপোনাৰ ডিভাইচৰ MAC ঠিকনাটো, যিটো এটা অদ্বৈত চিনাক্তকাৰী, সেইটো ব্যৱহাৰ কৰিব লাগে। বৰ্তমানে, এই নেটৱৰ্কটোৰ বাবে আপোনাৰ গোপনীয়তাৰ ছেটিঙে এটা যাদৃচ্ছিক চিনাক্তকাৰী ব্যৱহাৰ কৰিছে। \n\nএই সালসলনিয়ে নিকটৱৰ্তী ডিভাইচসমূহক আপোনাৰ ডিভাইচটোৰ অৱস্থান ট্ৰেক কৰাৰ অনুমতি দিব পাৰে।" "ছেটিংটো সলনি কৰক" "ছেটিংটো আপডে’ট হ’ল। পুনৰ সংযোগ কৰিবলৈ চেষ্টা কৰক।" "গোপনীয়তাৰ ছেটিংটো সলনি কৰিব নোৱাৰি" diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 1d76a814ab6b..6c0fd3131db8 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -435,8 +435,7 @@ "şəkil və video çəkmək" "Bu tətbiq istədiyiniz zaman kameranı istifadə edərək şəkil çəkə və video qeydə ala bilər." "Tətbiqə və ya xidmətə kamera cihazlarının açılması və ya bağlanması haqqında geri zənglər qəbul etməyə icazə verin." - - + "Hansısa kamera cihazı açıldıqda və ya bağlandıqda (hansısa tətbiq tərəfindən) bu tətbiq geri çağırışlar qəbul edə bilər." "vibrasiyaya nəzarət edir" "Tətbiqə vibratoru idarə etmə icazəsi verir." "telefon nömrələrinə birbaşa zəng edir" diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index f8e352a0112f..a397c07be911 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -438,8 +438,7 @@ "snimanje fotografija i video snimaka" "Ova aplikacija može da snima fotografije i video snimke pomoću kamere u bilo kom trenutku." "Dozvolite aplikaciji ili usluzi da dobija povratne pozive o otvaranju ili zatvaranju uređaja sa kamerom." - - + "Ova aplikacija može da dobija povratne pozive kada se bilo koji uređaj sa kamerom otvara ili zatvara (pomoću neke aplikacije)." "kontrola vibracije" "Dozvoljava aplikaciji da kontroliše vibraciju." "direktno pozivanje brojeva telefona" diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 202dc3887d2e..b40d5e5100b1 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -441,8 +441,7 @@ "рабіць фатаграфіі і відэа" "Гэта праграма можа рабіць фота і запісваць відэа з дапамогай камеры ў любы час." "Дазволіць праграме ці сэрвісу атрымліваць зваротныя выклікі наконт адкрыцця ці закрыцця прылад камеры." - - + "Гэта праграма можа атрымліваць зваротныя выклікі, калі адкрываецца (праграмай) або закрываецца прылада камеры." "кіраванне вібрацыяй" "Дазваляе прыкладанням кіраваць вібрацыяй." "непасрэдна набіраць тэлефонныя нумары" diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 1f54ef57e7dd..60db24aa4846 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -435,8 +435,7 @@ "правене на снимки и видеоклипове" "Това приложение може по всяко време да прави снимки и да записва видеоклипове посредством камерата." "Разрешаване на приложение или услуга да получават обратни повиквания за отварянето или затварянето на снимачни устройства." - - + "Това приложение може да получава обратни повиквания, когато снимачно устройство бъде отворено (от кое приложение) или затворено." "контролиране на вибрирането" "Разрешава на приложението да контролира устройството за вибрация." "директно обаждане до телефонни номера" diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 01fbd7ad0663..bd29fa020036 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -783,7 +783,7 @@ "অন্যান্য" "কাস্টম" "কাস্টম" - "সহায়ক" + "Assistant" "ভাই" "সন্তান" "জীবনসাথি" diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 2e0cd444feae..5d2761e3c73c 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -438,8 +438,7 @@ "snimanje slika i videozapisa" "Ova aplikacija može slikati fotografije i snimati videozapise koristeći kameru bilo kada." "Dozvoliti aplikaciji ili usluzi da prima povratne pozive o otvaranju ili zatvaranju kamera." - - + "Ova aplikacija može primati povratne pozive kada se otvara ili zatvara bilo koja kamera (kojom aplikacijom)." "kontrola vibracije" "Dozvoljava aplikaciji upravljanje vibracijom." "izravno zvanje telefonskih brojeva" diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 063dddb59717..57967c828891 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -435,8 +435,7 @@ "fer fotos i vídeos" "Aquesta aplicació pot fer fotos i gravar vídeos amb la càmera en qualsevol moment." "Permet que una aplicació o un servei pugui rebre crides de retorn sobre els dispositius de càmera que s\'obren o es tanquen." - - + "Aquesta aplicació pot rebre crides de retorn quan s\'obre o es tanca un dispositiu de càmera (segons l\'aplicació)." "controlar la vibració" "Permet que l\'aplicació controli el vibrador." "trucar directament a números de telèfon" diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index c64631dfa3f3..aafe6a5d74e7 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -441,8 +441,7 @@ "pořizování fotografií a videí" "Tato aplikace může pomocí fotoaparátu kdykoli pořídit snímek nebo nahrát video." "Povolte aplikaci nebo službě přijímat zpětná volání o otevření nebo zavření zařízení s fotoaparátem." - - + "Tato aplikace může přijímat zpětná volání při otevírání nebo zavírání libovolného fotoaparátu (s informacemi o tom, která aplikace tuto akci provádí)." "ovládání vibrací" "Umožňuje aplikaci ovládat vibrace." "přímé volání na telefonní čísla" diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 3516d5360b6f..c5d1f4fee236 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -435,8 +435,7 @@ "tage billeder og optage video" "Med denne app kan du tage billeder og optage video med kameraet når som helst." "Tillad, at en app eller tjeneste modtager tilbagekald om kameraenheder, der åbnes eller lukkes." - - + "Denne app kan modtage tilbagekald, når en kameraenhed åbnes (via appen) eller lukkes." "administrere vibration" "Tillader, at appen kan administrere vibratoren." "ringe direkte op til telefonnumre" diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 4f88e8458577..01311b6595e2 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -435,8 +435,7 @@ "Bilder und Videos aufnehmen" "Diese App kann mit der Kamera jederzeit Bilder und Videos aufnehmen." "Einer App oder einem Dienst den Empfang von Callbacks erlauben, wenn eine Kamera geöffnet oder geschlossen wird." - - + "Diese App kann Callbacks empfangen, wenn eine Kamera von einer Anwendung geöffnet oder geschlossen wird." "Vibrationsalarm steuern" "Ermöglicht der App, den Vibrationsalarm zu steuern" "Telefonnummern direkt anrufen" diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 47e00504383e..52be0640f397 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -435,8 +435,7 @@ "κάνει λήψη φωτογραφιών και βίντεο" "Αυτή η εφαρμογή μπορεί να τραβήξει φωτογραφίες και βίντεο χρησιμοποιώντας την κάμερα, ανά πάσα στιγμή." "Επιτρέψτε σε μια εφαρμογή ή μια υπηρεσία να λαμβάνει επανάκλησεις σχετικά με το άνοιγμα ή το κλείσιμο συσκευών κάμερας." - - + "Αυτή η εφαρμογή μπορεί να λαμβάνει επανακλήσεις κατά το άνοιγμα οποιασδήποτε συσκευής κάμερας (από οποιαδήποτε εφαρμογή) ή κατά το κλείσιμο." "ελέγχει τη δόνηση" "Επιτρέπει στην εφαρμογή τον έλεγχο της δόνησης." "πραγματοποιεί απευθείας κλήση τηλεφωνικών αριθμών" diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index ce977b1d4d24..9b60b914ea8e 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -1260,7 +1260,7 @@ Abrir redes de Wi-Fi disponibles Abrir red de Wi-Fi disponible - "Conectarse a una red Wi-Fi abierta" + "Conéctate a una red Wi-Fi abierta" "Conectarse a la red Wi-Fi del proveedor" "Estableciendo conexión con la red Wi-Fi" "Se conectó a la red Wi-Fi" @@ -1489,7 +1489,7 @@ "Enviar" "Se está ejecutando la app de conducción" "Presiona para salir de la app de conducción." - "Anclaje a red o zona activa conectados" + "Conexión a red o hotspot conectados" "Presiona para configurar." "Se inhabilitó la conexión mediante dispositivo móvil" "Para obtener más información, comunícate con el administrador" diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index f9150e9bb25a..59d173c9df13 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -435,8 +435,7 @@ "realizar fotografías y vídeos" "Esta aplicación puede hacer fotografías y grabar vídeos con la cámara en cualquier momento." "Permitir que una aplicación o servicio reciba retrollamadas cada vez que se abra o cierre una cámara." - - + "Esta aplicación puede recibir retrollamadas cuando se abre o se cierra la cámara con cualquier aplicación." "controlar la vibración" "Permite que la aplicación controle la función de vibración." "llamar directamente a números de teléfono" diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 0a194596ed2c..1ad795fdc8bf 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -435,8 +435,7 @@ "piltide ja videote tegemine" "See rakendus saab mis tahes ajal kaameraga pildistada ja videoid salvestada." "Lubab rakendusel või teenusel kaameraseadmete avamise või sulgemise kohta tagasikutseid vastu võtta." - - + "See rakendus saab mis tahes kaameraseadme avamisel (vastava rakendusega) või sulgemisel tagasikutseid vastu võtta." "juhtige vibreerimist" "Võimaldab rakendusel juhtida vibreerimist." "helista otse telefoninumbritele" diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 53fb56e4986f..1a827e798a0c 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -435,8 +435,7 @@ "atera argazkiak eta grabatu bideoak" "Aplikazioak edonoiz erabil dezake kamera argazkiak ateratzeko eta bideoak grabatzeko." "eman jakinarazpenak jasotzeko baimena aplikazioari edo zerbitzuari kamerak ireki edo ixten direnean." - - + "Kamera ireki edo itxi dela (eta zer aplikaziorekin) dioten jakinarazpenak jaso ditzake aplikazio honek." "kontrolatu dardara" "Bibragailua kontrolatzeko aukera ematen die aplikazioei." "deitu zuzenean telefono-zenbakietara" @@ -1248,8 +1247,7 @@ "Ezin da konektatu %1$s sarera" "Sakatu hau pribatutasun-ezarpenak aldatzeko, eta saiatu berriro" "Pribatutasun-ezarpena aldatu nahi duzu?" - - + "Konektatzeko, %1$s sareak gailuaren MAC helbidea (identifikatzaile esklusiboa) behar du. Sarearen uneko pribatutasun-ezarpenen arabera, ausazko identifikatzaile bat erabiltzen da. \n\nAldaketa horrekin, baliteke inguruko gailuek zure gailuaren kokapenaren jarraipena egin ahal izatea." "Aldatu ezarpena" "Eguneratu da ezarpena. Saiatu berriro konektatzen." "Ezin da aldatu pribatutasun-ezarpena" diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index fed10e271d55..79a7783384b3 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -435,8 +435,7 @@ "عکسبرداری و فیلمبرداری" "این برنامه می‌تواند در هرزمانی با استفاده از دوربین عکس و فیلم بگیرد." "مجاز کردن برنامه یا سرویس برای دریافت پاسخ تماس درباره دستگاه‌های دوربینی که باز یا بسته می‌شوند." - - + "این برنامه می‌تواند هروقت دستگاه دوربین باز (براساس برنامه) یا بسته می‌شود، پاسخ تماس دریافت کند." "کنترل لرزش" "‏به برنامه اجازه می‎دهد تا لرزاننده را کنترل کند." "تماس مستقیم با شماره تلفن‌ها" diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 14ff6d4eff8b..8772da663599 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -435,8 +435,7 @@ "ota kuvia ja videoita" "Tämä sovellus voi ottaa kameralla kuvia ja videoita koska tahansa." "Salli sovelluksen tai palvelun vastaanottaa vastakutsuja kameralaitteiden avaamisesta tai sulkemisesta." - - + "Tämä sovellus voi saada vastakutsuja, kun jokin kameralaite avataan tai suljetaan (jollakin sovelluksella)." "hallita värinää" "Antaa sovelluksen hallita värinää." "soittaa puhelinnumeroihin suoraan" diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 3d4a4bd80e6a..358bfb66c492 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -435,8 +435,7 @@ "prendre des photos et filmer des vidéos" "Cette application peut prendre des photos et enregistrer des vidéos à l\'aide de l\'appareil photo en tout temps." "Autoriser une application ou un service de recevoir des rappels relatifs à l\'ouverture ou à la fermeture des appareils photos." - - + "Cette application peut recevoir des rappels lorsque l\'appareil photo est ouvert ou fermé (par l\'application) en question." "gérer le vibreur" "Permet à l\'application de gérer le vibreur de l\'appareil." "appeler directement des numéros de téléphone" diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 739068cd351b..aca7493c873d 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -435,8 +435,7 @@ "prendre des photos et enregistrer des vidéos" "Cette application peut utiliser l\'appareil photo pour prendre des photos et enregistrer des vidéos à tout moment." "Autoriser une application ou un service à recevoir des rappels liés à l\'ouverture ou à la fermeture de caméras" - - + "Cette application peut recevoir des rappels lors de la fermeture ou de l\'ouverture d\'une caméra (par une application)." "contrôler le vibreur" "Permet à l\'application de contrôler le vibreur." "appeler directement les numéros de téléphone" diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 290db459793a..e6fe41b4113e 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -435,8 +435,7 @@ "facer fotos e vídeos" "Esta aplicación pode utilizar a cámara en calquera momento para sacar fotos e gravar vídeos." "Permitir que unha aplicación ou servizo reciba retrochamadas cando se abran ou se pechen dispositivos con cámara." - - + "Esta aplicación pode recibir retrochamadas cando outra aplicación abra ou peche un dispositivo con cámara." "controlar a vibración" "Permite á aplicación controlar o vibrador." "chamar directamente aos números de teléfono" diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 5ab36e631ad0..01c05133bec2 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -435,7 +435,7 @@ "ચિત્રો અને વિડિઓઝ લો" "આ ઍપ્લિકેશન, કૅમેરાનો ઉપયોગ કરીને કોઈપણ સમયે ચિત્રો લઈ અને વિડિઓઝ રેકોર્ડ કરી શકે છે." "કૅમેરા ડિવાઇસ ચાલુ કે બંધ થવા વિશે કૉલબૅક પ્રાપ્ત કરવાની ઍપ્લિકેશન કે સેવાને મંજૂરી આપો." - "જ્યારે કોઈ કૅમેરા ડિવાઇસ (કયા ઍપ્લિકેશન વડે) ખોલવા કે બંધ કરવામાં આવે, ત્યારે આ વિશેષ ઍપ કૉલબૅક પ્રાપ્ત કરી શકે છે." + "જ્યારે કોઈ કૅમેરા ડિવાઇસ (કયા ઍપ્લિકેશન વડે) ખોલવા કે બંધ કરવામાં આવે, ત્યારે આ ઍપ કૉલબૅક પ્રાપ્ત કરી શકે છે." "વાઇબ્રેશન નિયંત્રિત કરો" "એપ્લિકેશનને વાઇબ્રેટરને નિયંત્રિત કરવાની મંજૂરી આપે છે." "સીધા જ ફોન નંબર્સ પર કૉલ કરો" @@ -783,7 +783,7 @@ "અન્ય" "કસ્ટમ" "કસ્ટમ" - "સહાયક" + "Assistant" "ભાઈ" "બાળક" "ઘરેલું ભાગીદાર" diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 4fe032718cce..09f2b4569182 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -218,7 +218,7 @@ "आपका फ़ोन शट डाउन हो जाएगा." "क्‍या आप शट डाउन करना चाहते हैं?" "सुरक्षित मोड में रीबूट करें" - "क्या आप सुरक्षित मोड में रीबूट करना चाहते हैं? इससे आपके इंस्टॉल किए हुए सभी तृतीय पक्ष ऐप्स अक्षम हो जाएंगे. जब आप फिर से रीबूट करेंगे तो वे पुनर्स्थापित हो जाएंगे." + "क्या आप सुरक्षित मोड में रीबूट करना चाहते हैं? इससे तीसरे पक्ष के सभी ऐप्लिकेशन बंद हो जाएंगे जो आपने इंस्टॉल किए थे. जब आप फिर से रीबूट करेंगे, तब वे वापस आ जाएंगे." "हाल के" "कोई हाल ही के ऐप्स नहीं." "टैबलेट विकल्‍प" @@ -434,10 +434,8 @@ "यह ऐप्लिकेशन आपके शरीर की गतिविधि को पहचान सकता है." "चित्र और वीडियो लें" "यह ऐप्लिकेशन किसी भी समय कैमरे का उपयोग करके चित्र ले सकता है और वीडियो रिकॉर्ड कर सकता है." - - - - + "डिवाइस का कैमरे चालू या बंद होने पर, किसी ऐप्लिकेशन या सेवा को कॉलबैक पाने की मंज़ूरी दें." + "यह ऐप्लिकेशन, किसी भी कैमरा डिवाइस को खोलते या बंद करते समय (किसी ऐप्लिकेशन से) कॉलबैक पा सकता है." "कंपन (वाइब्रेशन) को नियंत्रित करें" "ऐप्स को कंपनकर्ता नियंत्रित करने देता है." "फ़ोन नंबर पर सीधे कॉल करें" @@ -785,7 +783,7 @@ "अन्य" "कस्टम" "कस्टम" - "सहायक" + "असिस्टेंट" "भाई" "बच्चा" "हमसफ़र" @@ -1611,7 +1609,7 @@ "डॉक स्‍पीकर" "HDMI" "हेडफ़ोन" - "USB" + "यूएसबी" "सिस्‍टम" "ब्लूटूथ ऑडियो" "वायरलेस डिसप्ले" diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index f4f27bd7aaec..095fb461457b 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -438,8 +438,7 @@ "snimi fotografije i videozapise" "Aplikacija u svakom trenutku može snimati fotografije i videozapise fotoaparatom." "Dopustite aplikaciji ili usluzi da prima povratne pozive o otvaranju ili zatvaranju fotoaparata." - - + "Ta aplikacija može primati povratne pozive prilikom otvaranja (putem neke aplikacije) ili zatvaranja fotoaparata." "upravljanje vibracijom" "Aplikaciji omogućuje nadzor nad vibratorom." "izravno pozivanje telefonskog broja" diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index a2e982db1e60..2dc6b114122d 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -435,8 +435,7 @@ "fotók és videók készítése" "Az alkalmazás a kamera használatával bármikor készíthet fényképeket és rögzíthet videókat." "Visszahívás fogadásának engedélyezése alkalmazás vagy szolgáltatás számára, ha a kamerákat megnyitják vagy bezárják." - - + "Ez az alkalmazás fogadhat visszahívásokat bármelyik kamera (adott alkalmazás általi) megnyitásakor vagy bezárásakor." "rezgés szabályozása" "Lehetővé teszi az alkalmazás számára a rezgés vezérlését." "telefonszámok közvetlen hívása" diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index d3a9289ca520..78d9c89efe80 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -435,8 +435,7 @@ "լուսանկարել և տեսանկարել" "Այս հավելվածը կարող է ցանկացած պահի լուսանկարել և տեսագրել՝ օգտագործելով տեսախցիկը:" "Թույլատրել հավելվածին կամ ծառայությանը հետզանգեր ստանալ՝ տեսախցիկների բացվելու և փակվելու դեպքում։" - - + "Այս հավելվածը կարող է հետզանգեր ստանալ՝ ցանկացած տեսախցիկի բացվելու (կնշվի բացող հավելվածը) և փակվելու դեպքում։" "կառավարել թրթռումը" "Թույլ է տալիս հավելվածին կառավարել թրթռոցը:" "ուղղակիորեն զանգել հեռախոսահամարներին" diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index afb77bcdb983..c7a21d615541 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -435,8 +435,7 @@ "ambil gambar dan video" "Aplikasi ini dapat mengambil foto dan merekam video menggunakan kamera kapan saja." "Izinkan aplikasi atau layanan untuk menerima callback tentang perangkat kamera yang sedang dibuka atau ditutup." - - + "Aplikasi ini dapat menerima callback saat perangkat kamera dibuka (oleh aplikasi) atau ditutup." "kontrol getaran" "Mengizinkan aplikasi untuk mengendalikan vibrator." "panggil nomor telepon secara langsung" diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index a6793f47238c..77b7a9869cc3 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -435,8 +435,7 @@ "taka myndir og myndskeið" "Þetta forrit getur tekið myndir og tekið upp myndskeið með myndavélinni hvenær sem er." "Leyfa forriti eða þjónustu að taka við svörum um myndavélar sem verið er að opna eða loka." - - + "Þetta forrit getur tekið við svörum þegar verið er að opna eða loka myndavél í hvaða forriti sem er." "stjórna titringi" "Leyfir forriti að stjórna titraranum." "hringja beint í símanúmer" diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index b0b206173cb6..797da5d8ff9b 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -435,8 +435,7 @@ "acquisizione di foto e video" "Questa app può scattare foto e registrare video tramite la fotocamera in qualsiasi momento." "Consenti a un\'applicazione o a un servizio di ricevere callback relativi all\'apertura o alla chiusura di videocamere." - - + "Questa app può ricevere callback quando viene aperta (da quale applicazione) o chiusa qualsiasi videocamera." "controllo vibrazione" "Consente all\'applicazione di controllare la vibrazione." "chiamata diretta n. telefono" diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 7a954911600b..809dc01901a7 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -441,8 +441,7 @@ "צלם תמונות וסרטונים" "אפליקציה זו יכולה להשתמש במצלמה כדי לצלם תמונות ולהקליט סרטונים בכל עת." "‏אפליקציה או שירות יוכלו לקבל קריאות חוזרות (callback) כשמכשירי מצלמה ייפתחו או ייסגרו." - - + "‏האפליקציה הזו יכולה לקבל קריאות חוזרות (callback) כשמכשיר מצלמה כלשהו נפתח (באמצעות אפליקציה) או נסגר." "שליטה ברטט" "מאפשר לאפליקציה לשלוט ברטט." "התקשר ישירות למספרי טלפון" diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 16da3ac4b1a3..36234fbbcaac 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -435,8 +435,7 @@ "写真と動画の撮影" "このアプリは、いつでもカメラを使用して写真や動画を撮影できます。" "カメラデバイスが起動または終了したときにコールバックを受け取ることを、アプリまたはサービスに許可してください。" - - + "このアプリは、カメラデバイスが(なんらかのアプリによって)起動するとき、または終了するときにコールバックを受け取ることができます。" "バイブレーションの制御" "バイブレーションの制御をアプリに許可します。" "電話番号発信" diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 467718cafb24..a98f9055c157 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -435,8 +435,7 @@ "სურათებისა და ვიდეოების გადაღება" "ამ აპს ნებისმიერ დროს შეუძლია კამერით სურათების გადაღება და ვიდეოების ჩაწერა." "ნება დაერთოს აპლიკაციას ან სერვისს, მიიღოს გადმორეკვები კამერის მოწყობილობის გახსნის ან დახურვისას." - - + "ამ აპს შეუძლია მიიღოს გადმორეკვები, როდესაც რომელიმე კამერის მოწყობილობა იხსნება (რომელიმე აპლიკაციით) ან იხურება." "ვიბრაციის კონტროლი" "აპს შეეძლება, მართოს ვიბრირება." "პირდაპირი დარეკვა ტელეფონის ნომრებზე" diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 8d9d3ec0ebdd..3fbc25977082 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -435,8 +435,7 @@ "фотосурет жасау және бейне жазу" "Бұл қолданба кез келген уақытта камерамен суретке түсіруі және бейнелерді жазуы мүмкін." "Қолданбаға не қызметке ашылып не жабылып жатқан камера құрылғылары туралы кері шақыру алуға рұқсат ету" - - + "Кез келген камера ашылып (көрсетілген қолданба арқылы) не жабылып жатқанда, бұл қолданба кері шақыру алады." "тербелісті басқару" "Қолданбаға вибраторды басқаруға рұқсат береді." "нөмірлерге тікелей телефон шалу" diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index dbcdeb14d47b..b504958fc891 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -435,8 +435,7 @@ "ថត​រូប និងវីដេអូ" "កម្មវិធី​នេះ​អាច​ថត​រូប​ និង​ថត​វីដេអូ​ ដោយ​ប្រើ​កាមេរ៉ា​បាន​គ្រប់​ពេល​។" "អនុញ្ញាតឱ្យកម្មវិធី ឬសេវាកម្ម​ទទួលការហៅត្រឡប់វិញអំពី​កាមេរ៉ាដែលកំពុងបិទ ឬបើក។" - - + "កម្មវិធី​នេះ​អាច​ទទួល​ការហៅត្រឡប់វិញ​បាន នៅពេល​កំពុងបិទ ឬ​បើក​កាមេរ៉ា (ដោយ​កម្មវិធី)​។" "ពិនិត្យ​ការ​ញ័រ" "ឲ្យ​កម្មវិធី​គ្រប់គ្រង​កម្មវិធី​ញ័រ។" "ហៅ​លេខ​ទូរស័ព្ទ​ដោយ​ផ្ទាល់" diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 2038719b1c22..f211742b3c01 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -435,8 +435,7 @@ "ಚಿತ್ರಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳನ್ನು ಸೆರೆಹಿಡಿಯಿರಿ" "ಈ ಅಪ್ಲಿಕೇಶನ್ ಯಾವ ಸಮಯದಲ್ಲಾದರೂ ಕ್ಯಾಮರಾ ಬಳಸಿಕೊಂಡು ಚಿತ್ರಗಳು ಮತ್ತು ವಿಡಿಯೋಗಳನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಬಹುದು." "ಕ್ಯಾಮರಾ ಸಾಧನಗಳನ್ನು ತೆರೆಯುತ್ತಿರುವ ಅಥವಾ ಮುಚ್ಚುತ್ತಿರುವ ಕುರಿತು ಕಾಲ್‌ಬ್ಯಾಕ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಆ್ಯಪ್‌ ಅಥವಾ ಸೇವೆಗೆ ಅನುಮತಿಸಿ." - - + "ಯಾವುದೇ ಕ್ಯಾಮರಾ ಸಾಧನವನ್ನು ತೆರೆಯುತ್ತಿರುವಾಗ ಅಥವಾ ಮುಚ್ಚುತ್ತಿರುವಾಗ (ಯಾವ ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ ಎಂಬ ಮಾಹಿತಿಯ ಮೂಲಕ) ಈ ಆ್ಯಪ್, ಕಾಲ್‌ಬ್ಯಾಕ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಬಹುದು." "ವೈಬ್ರೇಷನ್‌‌ ನಿಯಂತ್ರಿಸಿ" "ವೈಬ್ರೇಟರ್‌ ನಿಯಂತ್ರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ." "ಫೋನ್ ಸಂಖ್ಯೆಗಳಿಗೆ ನೇರವಾಗಿ ಕರೆ ಮಾಡಿ" @@ -784,7 +783,7 @@ "ಇತರೆ" "ಕಸ್ಟಮ್" "ಕಸ್ಟಮ್" - "ಸಹಾಯಕ" + "Assistant" "ಸಹೋದರ" "ಮಗು" "ಸ್ಥಳೀಯ ಪಾಲುದಾರ" diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index de28f99bcd9d..09d3bb9973f3 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -435,8 +435,7 @@ "사진과 동영상 찍기" "이 앱은 언제든지 카메라를 사용하여 사진을 촬영하고 동영상을 녹화할 수 있습니다." "애플리케이션 또는 서비스에서 카메라 기기 열림 또는 닫힘에 대한 콜백을 수신하도록 허용" - - + "이 앱은 어떤 애플리케이션이든지 카메라 기기를 열 때나 닫을 때 콜백을 수신할 수 있습니다." "진동 제어" "앱이 진동을 제어할 수 있도록 허용합니다." "전화번호 자동 연결" diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index b6cff08122d4..f7fadfb9fe1f 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -435,8 +435,7 @@ "сүрөт жана видео тартуу" "Бул колдонмо каалаган убакта камера менен сүрөт же видеолорду тарта алат." "Колдонмого же кызматка камера ачылып же жабылып жатканда чалууларды кабыл алууга уруксат берүү." - - + "Бул колдонмо камера ачылып (аны ачып жаткан колдонмо көрсөтүлгөндө) же жабылып жатканда чалууларды кабыл алат." "титирөөнү башкаруу" "Колдонмого дирилдегичти көзөмөлдөө мүмкүнчүлүгүн берет." "телефон номерлерине түз чалуу" diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 9396d3eafc2f..4acfb04932c7 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -435,8 +435,7 @@ "ຖ່າຍຮູບ ແລະວິດີໂອ" "This app can take pictures and record videos using the camera at any time." "ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ຫຼື ບໍລິການຮັບການເອີ້ນກັບກ່ຽວກັບອຸປະກອນກ້ອງຖືກເປີດ ຫຼື ປິດໄດ້." - - + "ແອັບນີ້ສາມາດຮັບການເອີ້ນກັບໄດ້ເມື່ອມີອຸປະກອນກ້ອງໃດຖືກເປີດ (ໂດຍແພັກເກດແອັບພລິເຄຊັນຫຍັງ) ຫຼື ຖືກປິດ." "ຄວບຄຸມການສັ່ນ" "ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມໂຕສັ່ນ." "ໂທຫາເບີໂທລະສັບໂດຍກົງ" diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 0ce61bad2f57..dda67a00289b 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -441,8 +441,7 @@ "fotografuoti ir filmuoti" "Ši programa gali bet kada fotografuoti ir įrašyti vaizdo įrašų naudodama fotoaparatą." "Leisti programai ar paslaugai sulaukti atgalinio skambinimo, kai atidaromas ar uždaromas fotoaparatas." - - + "Ši programa gali sulaukti atgalinio skambinimo, kai atidaromas ar uždaromas (kurios nors programos) koks nors fotoaparatas." "valdyti vibraciją" "Leidžiama programai valdyti vibravimą." "skambinti tiesiogiai telefono numeriais" diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 671be2600580..3bb1c8099d70 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -438,8 +438,7 @@ "uzņemt attēlus un videoklipus" "Šī lietotne jebkurā brīdī var uzņemt attēlus un ierakstīt videoklipus, izmantojot kameru." "Atļaut lietojumprogrammai vai pakalpojumam saņemt atzvanus par kameras ierīču atvēršanu vai aizvēršanu" - - + "Šajā lietotnē var saņemt atzvanus, ja tiek atvērta vai aizvērta jebkāda kameras ierīce (atkarībā no lietojumprogrammas)." "kontrolēt vibrosignālu" "Ļauj lietotnei kontrolēt vibrosignālu." "tieši zvanīt uz tālruņa numuriem" diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 1d1d4bbdb124..14ec75349b6a 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -435,8 +435,7 @@ "снимај слики и видеа" "Апликацијава може да фотографира и да снима видеа со камерата во секое време." "Дозволете апликацијатa или услугата да прима повратни повици за отворањето или затворањето на уредите со камера." - - + "Оваа апликација може да прима повратни повици кога кој било уред со камера се отвора (од некоја апликација) или затвора." "контролирај вибрации" "Дозволува апликацијата да ги контролира вибрациите." "директно избирај телефонски броеви" diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index d9c97afb841f..95854436fb7c 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -783,7 +783,7 @@ "മറ്റുള്ളവ" "ഇഷ്‌ടാനുസൃതം" "ഇഷ്‌ടാനുസൃതം" - "സഹായി" + "Assistant" "സഹോദരന്‍‌" "കുട്ടി" "ഗാര്‍‌ഹിക പങ്കാളി" diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 0b930054a498..299abcf5ad5e 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -435,8 +435,7 @@ "चित्रे आणि व्हिडिओ घ्या" "हा अ‍ॅप कोणत्याही वेळी कॅमेरा वापरून चित्रेे घेऊ आणि व्ह‍िडिओ रेकॉर्ड करू शकतो." "एखाद्या अ‍ॅप्लिकेशन किंवा सेवेला कॅमेरा डिव्हाइस सुरू किंवा बंद केल्याची कॉलबॅक मिळवण्याची अनुमती द्या." - - + "कोणतेही कॅमेरा डिव्हाइस (कोणत्या अ‍ॅप्लिकेशनने) सुरू किंवा बंद केले जाते तेव्हा हे ॲप कॉलबॅक मिळवू शकते." "व्हायब्रेट नियंत्रित करा" "अ‍ॅप ला व्हायब्रेटर नियंत्रित करण्यासाठी अनुमती देते." "फोन नंबरवर प्रत्यक्ष कॉल करा" @@ -784,7 +783,7 @@ "अन्य" "कस्टम" "कस्टम" - "असिस्टंट" + "Assistant" "भाऊ" "मूल" "घरातील जोडीदार" diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index f6e9d8a57e46..f34e1fb2e82e 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -435,8 +435,7 @@ "ambil gambar dan video" "Apl ini boleh mengambil gambar dan merakam video menggunakan kamera pada bila-bila masa." "Benarkan aplikasi atau perkhidmatan menerima panggilan balik tentang peranti kamera yang dibuka atau ditutup." - - + "Apl ini boleh menerima panggilan balik apabila mana-mana peranti kamera dibuka (oleh aplikasi) atau ditutup." "kawal getaran" "Membenarkan apl mengawal penggetar." "panggil terus nombor telefon" diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 8d4b8e5e2aeb..72339c501be0 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -435,8 +435,7 @@ "ta bilder og videoer" "Denne appen kan når som helst ta bilder og spille inn videoer ved hjelp av kameraet." "Tillat at en app eller tjeneste mottar tilbakekallinger om kameraenheter som åpnes eller lukkes." - - + "Denne appen kan motta tilbakekallinger når en kameraenhet blir åpnet (av hvilken app) eller lukket." "kontrollere vibreringen" "Lar appen kontrollere vibreringsfunksjonen." "ringe telefonnummer direkte" diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 17f091fb148e..4d8db52dc686 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -435,8 +435,7 @@ "तस्बिरहरू र भिडियोहरू लिनुहोस्।" "यस अनुप्रयोगले जुनसुकै समय क्यामेराको प्रयोग गरी तस्बिर खिच्न र भिडियो रेकर्ड गर्न सक्छ।" "कुनै अनुप्रयोग वा सेवालाई खोलिँदै वा बन्द गरिँदै गरेका क्यामेरा यन्त्रहरूका बारेमा कलब्याक प्राप्त गर्ने अनुमति दिनुहोस्।" - - + "कुनै क्यामेरा यन्त्र खोलिँदा (कुन अनुप्रयोगले खोलेको भन्ने बारेमा) वा बन्द गरिँदा यो अनुप्रयोगले कलब्याक प्राप्त गर्न सक्छ।" "कम्पन नियन्त्रण गर्नुहोस्" "अनुप्रयोगलाई भाइब्रेटर नियन्त्रण गर्न अनुमति दिन्छ।" "फोन नम्बरहरूमा सीधै कल गर्नुहोस्" diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 611fd9ef71a2..e252ead48b58 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -435,8 +435,7 @@ "foto\'s en video\'s maken" "Deze app kan op elk moment foto\'s maken en video\'s opnemen met de camera." "Een app of service toestaan callbacks te ontvangen over camera-apparaten die worden geopend of gesloten." - - + "Deze app kan callbacks ontvangen als een camera-apparaat wordt geopend (en door welke app) of gesloten." "trilling beheren" "Hiermee kan de app de trilstand beheren." "telefoonnummers rechtstreeks bellen" diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index c5311bd9520c..9fb0e1953246 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -435,8 +435,7 @@ "ଫଟୋ ଓ ଭିଡିଓଗୁଡ଼ିକୁ ନିଅନ୍ତୁ" "ଏହି ଆପ୍‍ ଯେକୌଣସି ସମୟରେ କ୍ୟାମେରା ବ୍ୟବହାର କରି ଫଟୋ ଉଠାଇପାରେ ଏବଂ ଭିଡିଓ ରେକର୍ଡ କରିପାରେ।" "କ୍ୟାମେରା ଡିଭାଇସଗୁଡ଼ିକ ଖୋଲିବା କିମ୍ବା ବନ୍ଦ କରିବା ବିଷୟରେ କଲବ୍ୟାକଗୁଡ଼ିକ ପାଇବାକୁ ଏକ ଆପ୍ଲିକେସନ୍ କିମ୍ବା ସେବାକୁ ଅନୁମତି ଦିଅନ୍ତୁ।" - - + "ଯେ କୌଣସି କ୍ୟାମେରା ଡିଭାଇସ୍ ଖୋଲାଗଲେ (କେଉଁ ଆପ୍ଲିକେସନ୍ ଦ୍ୱାରା) କିମ୍ବା ବନ୍ଦ କରାଗଲେ ଏହି ଆପ୍ କଲବ୍ୟାକ୍ ପାଇପାରିବ।" "କମ୍ପନ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ" "ଆପ୍‍କୁ, ଭାଇବ୍ରେଟର୍‍ ନିୟନ୍ତ୍ରଣ କରିବାକୁ ଦେଇଥାଏ।" "ସିଧାସଳଖ ଫୋନ୍ ନମ୍ବରଗୁଡ଼ିକୁ କଲ୍ କରନ୍ତୁ" @@ -751,7 +750,7 @@ "TTY TDD" "ୱାର୍କ ମୋବାଇଲ୍" "ୱାର୍କ ପେଜର୍" - "ସହାୟକ" + "Assistant" "MMS" "କଷ୍ଟମ୍‌" "ଜନ୍ମଦିନ" @@ -784,7 +783,7 @@ "ଅନ୍ୟାନ୍ୟ" "କଷ୍ଟମ୍‌" "କଷ୍ଟମ୍‌" - "ସହାୟକ" + "Assistant" "ଭାଇ" "ଶିଶୁ" "ଡୋମେଷ୍ଟିକ୍‌ ପାର୍ଟନର୍‌" diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 7d56530aeeb7..411af630dff2 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -435,8 +435,7 @@ "tirar fotos e vídeos" "Esta aplicação pode tirar fotos e gravar vídeos através da câmara em qualquer altura." "Permitir que uma app ou um serviço receba chamadas de retorno sobre dispositivos de câmara que estão a ser abertos ou fechados" - - + "Esta app pode receber chamadas de retorno quando qualquer dispositivo de câmara está a ser aberto (e por que aplicação) ou fechado." "controlar vibração" "Permite à aplicação controlar o vibrador." "marcar números de telefone diretamente" diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 9364376bc66d..46ed52089c61 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -438,8 +438,7 @@ "realizarea de fotografii și videoclipuri" "Această aplicație poate să facă fotografii și să înregistreze videoclipuri folosind camera foto în orice moment." "Permiteți unei aplicații sau unui serviciu să primească apeluri inverse atunci când sunt deschise sau închise dispozitive cu cameră." - - + "Această aplicație poate primi apeluri inverse atunci când este deschis (de aplicație) sau închis orice dispozitiv cu cameră." "controlează vibrarea" "Permite aplicației să controleze mecanismul de vibrare." "apelare directă numere de telefon" diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 9c58276fff81..758852962779 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -441,8 +441,7 @@ "Фото- и видеосъемка" "Приложение может в любое время делать фотографии и снимать видео с помощью камеры." "Разрешить приложению или сервису получать обратные вызовы при открытии и закрытии камер" - - + "Это приложение сможет получать обратные вызовы при открытии (с указанием открывающего приложения) и закрытии любых камер." "Управление функцией вибросигнала" "Приложение сможет контролировать вибросигналы." "Осуществление телефонных вызовов" diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index c20f71f2a26e..cd777ee453cc 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -441,8 +441,7 @@ "fotografiranje in snemanje videoposnetkov" "Ta aplikacija lahko poljubno uporablja fotoaparat za snemanje fotografij ali videoposnetkov." "Aplikaciji ali storitvi dovoli prejemanje povratnih klicev o odpiranju ali zapiranju naprav s fotoaparati." - - + "Ta aplikacija lahko prejema povratne klice, ko se odpira (s katero aplikacijo) ali zapira katera koli naprava s fotoaparatom." "nadzor vibriranja" "Aplikaciji omogoča nadzor vibriranja." "neposredno klicanje telefonskih številk" diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index afcb671869c1..6631cf8f1040 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -438,8 +438,7 @@ "снимање фотографија и видео снимака" "Ова апликација може да снима фотографије и видео снимке помоћу камере у било ком тренутку." "Дозволите апликацији или услузи да добија повратне позиве о отварању или затварању уређаја са камером." - - + "Ова апликација може да добија повратне позиве када се било који уређај са камером отвара или затвара (помоћу неке апликације)." "контрола вибрације" "Дозвољава апликацији да контролише вибрацију." "директно позивање бројева телефона" diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 692550e56e63..eb1da6447ddf 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -435,8 +435,7 @@ "ta bilder och spela in videoklipp" "Appen kan ta kort och spela in video med kameran när som helst." "Tillåt att en app eller tjänst får återanrop när en kameraenhet öppnas eller stängs." - - + "Den här appen kan få återanrop när en kameraenhet öppnas (efter app) eller stängs." "styra vibration" "Tillåter att appen styr vibrationen." "ringa telefonnummer direkt" diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index b1b29c394361..c21dec380dce 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -435,8 +435,7 @@ "Kupiga picha na kurekodi video" "Programu hii inaweza kupiga picha na kurekodi video kwa kutumia kamera wakati wowote." "Ruhusu programu au huduma ipokee simu zinazopigwa tena kuhusu vifaa vya kamera kufunguliwa au kufungwa." - - + "Programu hii inaweza kupokea simu zinazopigwa tena wakati kifaa chochote cha kamera kinafunguliwa (kulingana na programu) au kufungwa." "Kudhibiti mtetemo" "Inaruhusu programu kudhibiti kitingishi." "piga simu moja kwa moja kwa nambari za simu" diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 97212ffd54e0..2a1b066e2d20 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -434,8 +434,7 @@ "உங்கள் உடல் செயல்பாட்டை இந்த ஆப்ஸால் கண்டறிய முடியும்." "படங்கள் மற்றும் வீடியோக்களை எடுத்தல்" "இந்த ஆப்ஸ் எப்போது வேண்டுமானாலும் கேமராவைப் பயன்படுத்தி படங்களை எடுக்கலாம், வீடியோக்களை ரெக்கார்டு செய்யலாம்." - - + "கேமரா சாதனங்கள் திறக்கப்படும்போதோ மூடப்படும்போதோ அது குறித்த கால்பேக்குகளைப் பெற ஒரு ஆப்ஸையோ சேவையையோ அனுமதிக்கவும்." "அதிர்வைக் கட்டுப்படுத்துதல்" @@ -785,7 +784,7 @@ "மற்றவை" "பிரத்தியேகம்" "பிரத்தியேகம்" - "உதவியாளர்" + "Assistant" "சகோதரர்" "குழந்தை" "வாழ்வுத் துணை" diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index bd0ccf9db55c..5c16fa31485f 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -784,7 +784,7 @@ "ఇతరం" "అనుకూలం" "అనుకూలం" - "అసిస్టెంట్" + "Assistant" "సోదరుడు" "బిడ్డ" "జీవిత భాగస్వామి" diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index cbd083af83d7..5af675b400f5 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -435,8 +435,7 @@ "ถ่ายภาพและวิดีโอ" "แอปนี้สามารถถ่ายภาพและวิดีโอด้วยกล้องได้ทุกเมื่อ" "อนุญาตให้แอปพลิเคชันหรือบริการได้รับโค้ดเรียกกลับเมื่อมีการเปิดหรือปิดอุปกรณ์กล้อง" - - + "แอปนี้จะได้รับโค้ดเรียกกลับเมื่อมีการปิดหรือเปิดอุปกรณ์กล้อง (แอปพลิเคชันที่เปิด)" "ควบคุมการสั่นเตือน" "อนุญาตให้แอปพลิเคชันควบคุมการสั่นเตือน" "โทรติดต่อหมายเลขโทรศัพท์โดยตรง" diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index f40404fc3059..ca5f29ae789d 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -435,8 +435,7 @@ "kumuha ng mga larawan at video" "Makakakuha ng mga larawan at makakapag-record ng mga video ang app na ito gamit ang camera anumang oras." "Payagan ang isang application o serbisyo na makatanggap ng mga callback tungkol sa pagbubukas o pagsasara ng mga camera device." - - + "Puwedeng makatanggap ang app na ito ng mga callback kapag binubuksan (kung anong application) o isinasara ang anumang camera device." "kontrolin ang pag-vibrate" "Pinapayagan ang app na kontrolin ang vibrator." "direktang tawagan ang mga numero ng telepono" @@ -1248,8 +1247,7 @@ "Hindi makakonekta sa %1$s" "I-tap para baguhin ang mga setting ng privacy at subukan ulit" "Baguhin ang setting ng privacy?" - - + "Para kumonekta, kailangan ng %1$s ang MAC address ng iyong device, na isang natatanging identifier. Sa kasalukuyan, gumagamit ng naka-randomize na identifier ang mga setting mo sa privacy para sa network na ito. \n\nDahil sa pagbabagong ito, baka mapahintulutan ang mga kalapit na device na subaybayan ang lokasyon ng iyong device." "Baguhin ang setting" "Na-update ang setting. Subukang kumonekta ulit." "Hindi puwedeng baguhin ang setting ng privacy" diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 91129f6b4507..f46c157f1006 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -435,8 +435,7 @@ "resim çekme ve görüntü kaydetme" "Bu uygulama, herhangi bir zamanda kamerayı kullanarak fotoğraf ve video çekebilir." "Bir uygulama veya hizmetin açılıp kapatılan kamera cihazları hakkında geri çağırmalar almasına izin verin." - - + "Bu uygulama, herhangi bir kamera cihazı açıldığında (herhangi bir uygulama tarafından) veya kapatıldığında geri çağırmalar alabilir." "titreşimi denetleme" "Uygulamaya, titreşimi denetleme izni verir." "telefon numaralarına doğrudan çağrı yap" diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 0cdb607fbf03..32e520f0ae25 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -441,8 +441,7 @@ "фотограф. та знімати відео" "Цей додаток може будь-коли робити фотографії та записувати відео за допомогою камери." "Дозволити додатку або сервісу отримувати зворотні виклики щодо відкриття чи закриття камер." - - + "Цей додаток може отримувати зворотні виклики, коли будь-яка камера відкривається (з указанням додатка) чи закривається." "контролювати вібросигнал" "Дозволяє програмі контролювати вібросигнал." "прямо набирати номери тел." diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 3dea941ce4df..70b1df5261dc 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -435,8 +435,7 @@ "chụp ảnh và quay video" "Ứng dụng này có thể chụp ảnh và quay video bằng máy ảnh bất cứ lúc nào." "Cho phép một ứng dụng hoặc dịch vụ nhận lệnh gọi lại khi các thiết bị máy ảnh đang được mở/đóng." - - + "Ứng dụng này có thể nhận các lệnh gọi lại khi có bất kỳ thiết bị camera nào đang được mở (bằng ứng dụng) hoặc đóng." "kiểm soát rung" "Cho phép ứng dụng kiểm soát bộ rung." "gọi trực tiếp số điện thoại" diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 85e5b358d856..7ee5c8b5dcd7 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -435,8 +435,7 @@ "拍摄照片和视频" "此应用可随时使用相机拍摄照片和录制视频。" "允许应用或服务接收与打开或关闭摄像头设备有关的回调。" - - + "此应用可在任何摄像头设备(被某些应用)打开或关闭时接收相应回调。" "控制振动" "允许应用控制振动器。" "拨打电话" diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 8f34ca3125cd..56bff4bf05a9 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -435,8 +435,7 @@ "拍照和拍攝影片" "此應用程式可以隨時使用相機拍照和攝錄。" "允許應用程式或服務接收相機裝置開啟或關閉的相關回電。" - - + "當任何相機裝置在開啟 (由應用程式) 或關閉時,此應用程式就能接收回電。" "控制震動" "允許應用程式控制震動。" "直接撥打電話號碼" diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 543cf893276d..1b483488e4d0 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -435,8 +435,7 @@ "拍攝相片和影片" "這個應用程式隨時可使用相機拍照及錄影。" "允許應用程式或服務接收相機裝置開啟或關閉的相關回呼。" - - + "當任何相機裝置在開啟 (由應用程式) 或關閉時,這個應用程式就能接收回呼。" "控制震動" "允許應用程式控制震動。" "直接撥打電話號碼" diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 61a9b76667e7..b329f27b2e65 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -435,8 +435,7 @@ "thatha izithombe namavidiyo" "Lolu hlelo lokusebenza lungathatha izithombe futhi lirekhode amavidiyo lusebenzisa ikhamera noma kunini." "Vumela uhlelo lokusebenza noma isevisi ukwamukela ukuphinda ufonelwe mayelana namadivayisi wekhamera avuliwe noma avaliwe." - - + "Lolu hlelo lokusebenza lungakwazi ukuthola ukuphinda ufonelwe uma noma iyiphi idivayisi yekhamera ivulwa (ngephakheji yohlelo lokusebenza) noma ivalwa." "lawula ukudlidliza" "Ivumela uhlelo lokusebenza ukulawula isidlidlizi." "ngokuqondile shayela izinombolo zocingo" -- GitLab From 8ef5d5e438957e39fc4fa9423b5420326ff04b92 Mon Sep 17 00:00:00 2001 From: Raff Tsai Date: Wed, 4 Sep 2019 15:08:57 +0800 Subject: [PATCH 188/219] Fix Battery optimization takes long time isDefaultActiveApp is called on every package. We can cache default dialer and default sms package in a list, and check if the list contains target package name. Fixes: 140279638 Bug: 151233929 Test: manual, make RunSettingsLibRoboTests Change-Id: I81f5ccb7aed1ebec797a21af6094971e05f456a7 (cherry picked from commit 19c2bbccfd34af8cd305b7416f4a64632f461b8b) --- .../fuelgauge/PowerWhitelistBackend.java | 29 ++++++++++++------- .../fuelgauge/PowerWhitelistBackendTest.java | 4 +++ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java index eeb6cb015ae6..ea8a62f84164 100644 --- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java +++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java @@ -49,6 +49,7 @@ public class PowerWhitelistBackend { private final ArraySet mWhitelistedApps = new ArraySet<>(); private final ArraySet mSysWhitelistedApps = new ArraySet<>(); private final ArraySet mSysWhitelistedAppsExceptIdle = new ArraySet<>(); + private final ArraySet mDefaultActiveApps = new ArraySet<>(); public PowerWhitelistBackend(Context context) { this(context, IDeviceIdleController.Stub.asInterface( @@ -90,17 +91,7 @@ public class PowerWhitelistBackend { // should be automatically whitelisted (otherwise user may be able to set restriction on // them, leading to bad device behavior.) - final boolean hasTelephony = mAppContext.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_TELEPHONY); - final ComponentName defaultSms = SmsApplication.getDefaultSmsApplication(mAppContext, - true /* updateIfNeeded */); - if (hasTelephony && defaultSms != null && TextUtils.equals(pkg, - defaultSms.getPackageName())) { - return true; - } - - final String defaultDialer = DefaultDialerManager.getDefaultDialerApplication(mAppContext); - if (hasTelephony && TextUtils.equals(pkg, defaultDialer)) { + if (mDefaultActiveApps.contains(pkg)) { return true; } @@ -166,6 +157,7 @@ public class PowerWhitelistBackend { mSysWhitelistedApps.clear(); mSysWhitelistedAppsExceptIdle.clear(); mWhitelistedApps.clear(); + mDefaultActiveApps.clear(); if (mDeviceIdleService == null) { return; } @@ -183,6 +175,21 @@ public class PowerWhitelistBackend { for (String app : sysWhitelistedAppsExceptIdle) { mSysWhitelistedAppsExceptIdle.add(app); } + final boolean hasTelephony = mAppContext.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_TELEPHONY); + final ComponentName defaultSms = SmsApplication.getDefaultSmsApplication(mAppContext, + true /* updateIfNeeded */); + final String defaultDialer = DefaultDialerManager.getDefaultDialerApplication( + mAppContext); + + if (hasTelephony) { + if (defaultSms != null) { + mDefaultActiveApps.add(defaultSms.getPackageName()); + } + if (!TextUtils.isEmpty(defaultDialer)) { + mDefaultActiveApps.add(defaultDialer); + } + } } catch (RemoteException e) { Log.w(TAG, "Unable to reach IDeviceIdleController", e); } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java index 44ee423785c2..3a571f9c24cf 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java @@ -117,6 +117,8 @@ public class PowerWhitelistBackendTest { final String testSms = "com.android.test.defaultsms"; ShadowSmsApplication.setDefaultSmsApplication(new ComponentName(testSms, "receiver")); + mPowerWhitelistBackend.refreshList(); + assertThat(mPowerWhitelistBackend.isWhitelisted(testSms)).isTrue(); assertThat(mPowerWhitelistBackend.isDefaultActiveApp(testSms)).isTrue(); } @@ -126,6 +128,8 @@ public class PowerWhitelistBackendTest { final String testDialer = "com.android.test.defaultdialer"; ShadowDefaultDialerManager.setDefaultDialerApplication(testDialer); + mPowerWhitelistBackend.refreshList(); + assertThat(mPowerWhitelistBackend.isWhitelisted(testDialer)).isTrue(); assertThat(mPowerWhitelistBackend.isDefaultActiveApp(testDialer)).isTrue(); } -- GitLab From 63b6cfd96485c11b906ca4ecc83245335d531364 Mon Sep 17 00:00:00 2001 From: Chris Tate Date: Fri, 20 Mar 2020 18:30:24 +0000 Subject: [PATCH 189/219] Revert "Revoke 'always' web handler status when not autoverifying" This reverts commit ce22265eeda3a96613b9a7bb7dd898c69d295964. Reason for revert: Inadvertently broke link handling stickiness even for well behaved apps Bug: 146204120 Test: install app that handles web urls; set to 'always' in Settings; install same apk again. Verify that app is still in 'always' state via 'adb shell dumpsys package d' Merged-In: Ifac4f0c044c2c575a29bdd5ce5d14d12373fbe70 Merged-In: If9046cb420961b8ef0333e9f1115eb69fb92242e Change-Id: Ife6cd66e0bae5738c08962a8fa9397973e33f28e --- .../server/pm/PackageManagerService.java | 44 +++++-------------- .../java/com/android/server/pm/Settings.java | 1 - 2 files changed, 11 insertions(+), 34 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 5a6168596369..033c62bf0fc2 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -17725,48 +17725,36 @@ public class PackageManagerService extends IPackageManager.Stub int count = 0; final String packageName = pkg.packageName; - boolean handlesWebUris = false; - final boolean alreadyVerified; synchronized (mPackages) { // If this is a new install and we see that we've already run verification for this // package, we have nothing to do: it means the state was restored from backup. - final IntentFilterVerificationInfo ivi = - mSettings.getIntentFilterVerificationLPr(packageName); - alreadyVerified = (ivi != null); - if (!replacing && alreadyVerified) { - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.i(TAG, "Package " + packageName + " already verified: status=" - + ivi.getStatusString()); + if (!replacing) { + IntentFilterVerificationInfo ivi = + mSettings.getIntentFilterVerificationLPr(packageName); + if (ivi != null) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Package " + packageName+ " already verified: status=" + + ivi.getStatusString()); + } + return; } - return; } - // If any filters need to be verified, then all need to be. In addition, we need to - // know whether an updating app has any web navigation intent filters, to re- - // examine handling policy even if not re-verifying. + // If any filters need to be verified, then all need to be. boolean needToVerify = false; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { - if (filter.handlesWebUris(true)) { - handlesWebUris = true; - } if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) { Slog.d(TAG, "Intent filter needs verification, so processing all filters"); } needToVerify = true; - // It's safe to break out here because filter.needsVerification() - // can only be true if filter.handlesWebUris(true) returns true, so - // we've already noted that. break; } } } - // Note whether this app publishes any web navigation handling support at all, - // and whether there are any web-nav filters that fit the profile for running - // a verification pass now. if (needToVerify) { final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { @@ -17784,23 +17772,13 @@ public class PackageManagerService extends IPackageManager.Stub } if (count > 0) { - // count > 0 means that we're running a full verification pass if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count + " IntentFilter verification" + (count > 1 ? "s" : "") + " for userId:" + userId); mIntentFilterVerifier.startVerifications(userId); - } else if (alreadyVerified && handlesWebUris) { - // App used autoVerify in the past, no longer does, but still handles web - // navigation starts. - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy"); - } - synchronized (mPackages) { - clearIntentFilterVerificationsLPw(packageName, userId); - } } else { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "No web filters or no prior verify policy for " + packageName); + Slog.d(TAG, "No filters or not all autoVerify for " + packageName); } } } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 6036e7d75433..a7e38301bb40 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1319,7 +1319,6 @@ public final class Settings { return false; } ps.clearDomainVerificationStatusForUser(userId); - ps.setIntentFilterVerificationInfo(null); return true; } -- GitLab From 8cd8797876e5e6feae4bc6b5d407e594db2d2eec Mon Sep 17 00:00:00 2001 From: Chris Tate Date: Fri, 20 Mar 2020 18:33:28 +0000 Subject: [PATCH 190/219] Revert "Revoke 'always' web handler status when not autoverifying" This reverts commit ef5220e5b2a4b90d4260eb058475fdcdf30d861d. Reason for revert: Inadvertently broke link handling stickiness even for well behaved apps Bug: 146204120 Test: install app that handles web urls; set to 'always' in Settings; install same apk again. Verify that app is still in 'always' state via 'adb shell dumpsys package d' Merged-In: Ife6cd66e0bae5738c08962a8fa9397973e33f28e Merged-In: If9046cb420961b8ef0333e9f1115eb69fb92242e Change-Id: I2b108064794b961904811c5d9f54c37dd2c7f482 --- .../server/pm/PackageManagerService.java | 44 +++++-------------- .../java/com/android/server/pm/Settings.java | 1 - 2 files changed, 11 insertions(+), 34 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 599753b024ce..bf1da5625857 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -19061,47 +19061,35 @@ public class PackageManagerService extends IPackageManager.Stub int count = 0; final String packageName = pkg.packageName; - boolean handlesWebUris = false; - final boolean alreadyVerified; synchronized (mPackages) { // If this is a new install and we see that we've already run verification for this // package, we have nothing to do: it means the state was restored from backup. - final IntentFilterVerificationInfo ivi = - mSettings.getIntentFilterVerificationLPr(packageName); - alreadyVerified = (ivi != null); - if (!replacing && alreadyVerified) { - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.i(TAG, "Package " + packageName + " already verified: status=" - + ivi.getStatusString()); + if (!replacing) { + IntentFilterVerificationInfo ivi = + mSettings.getIntentFilterVerificationLPr(packageName); + if (ivi != null) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Package " + packageName+ " already verified: status=" + + ivi.getStatusString()); + } + return; } - return; } - // If any filters need to be verified, then all need to be. In addition, we need to - // know whether an updating app has any web navigation intent filters, to re- - // examine handling policy even if not re-verifying. + // If any filters need to be verified, then all need to be. boolean needToVerify = false; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { - if (filter.handlesWebUris(true)) { - handlesWebUris = true; - } if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) { Slog.d(TAG, "Intent filter needs verification, so processing all filters"); } needToVerify = true; - // It's safe to break out here because filter.needsVerification() - // can only be true if filter.handlesWebUris(true) returns true, so - // we've already noted that. break; } } } - // Note whether this app publishes any web navigation handling support at all, - // and whether there are any web-nav filters that fit the profile for running - // a verification pass now. if (needToVerify) { final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { @@ -19119,23 +19107,13 @@ public class PackageManagerService extends IPackageManager.Stub } if (count > 0) { - // count > 0 means that we're running a full verification pass if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count + " IntentFilter verification" + (count > 1 ? "s" : "") + " for userId:" + userId); mIntentFilterVerifier.startVerifications(userId); - } else if (alreadyVerified && handlesWebUris) { - // App used autoVerify in the past, no longer does, but still handles web - // navigation starts. - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy"); - } - synchronized (mPackages) { - clearIntentFilterVerificationsLPw(packageName, userId); - } } else { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "No web filters or no prior verify policy for " + packageName); + Slog.d(TAG, "No filters or not all autoVerify for " + packageName); } } } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 0e1f3c295784..56835f69a3c7 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1380,7 +1380,6 @@ final class Settings { return false; } ps.clearDomainVerificationStatusForUser(userId); - ps.setIntentFilterVerificationInfo(null); return true; } -- GitLab From 92561d210d2382880fd6b2fd5a4dfa2d0cc00920 Mon Sep 17 00:00:00 2001 From: Chris Tate Date: Fri, 20 Mar 2020 18:40:14 +0000 Subject: [PATCH 191/219] Revert "Revoke 'always' web handler status when not autoverifying" This reverts commit 6cf5f92825df545bd011b7163418f2ea0b337af3. Reason for revert: Inadvertently broke link handling stickiness even for well behaved apps Bug: 146204120 Test: install app that handles web urls; set to 'always' in Settings; install same apk again. Verify that app is still in 'always' state via 'adb shell dumpsys package d' Merged-In: I2b108064794b961904811c5d9f54c37dd2c7f482 Merged-In: If9046cb420961b8ef0333e9f1115eb69fb92242e Change-Id: I03a121c0c1284c965bb87ee426eb0376681cf7d8 --- .../server/pm/PackageManagerService.java | 44 +++++-------------- .../java/com/android/server/pm/Settings.java | 1 - 2 files changed, 11 insertions(+), 34 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index efc7fabc0a85..ab6c956c6924 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -18437,47 +18437,35 @@ public class PackageManagerService extends IPackageManager.Stub int count = 0; final String packageName = pkg.packageName; - boolean handlesWebUris = false; - final boolean alreadyVerified; synchronized (mPackages) { // If this is a new install and we see that we've already run verification for this // package, we have nothing to do: it means the state was restored from backup. - final IntentFilterVerificationInfo ivi = - mSettings.getIntentFilterVerificationLPr(packageName); - alreadyVerified = (ivi != null); - if (!replacing && alreadyVerified) { - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.i(TAG, "Package " + packageName + " already verified: status=" - + ivi.getStatusString()); + if (!replacing) { + IntentFilterVerificationInfo ivi = + mSettings.getIntentFilterVerificationLPr(packageName); + if (ivi != null) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Package " + packageName+ " already verified: status=" + + ivi.getStatusString()); + } + return; } - return; } - // If any filters need to be verified, then all need to be. In addition, we need to - // know whether an updating app has any web navigation intent filters, to re- - // examine handling policy even if not re-verifying. + // If any filters need to be verified, then all need to be. boolean needToVerify = false; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { - if (filter.handlesWebUris(true)) { - handlesWebUris = true; - } if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) { Slog.d(TAG, "Intent filter needs verification, so processing all filters"); } needToVerify = true; - // It's safe to break out here because filter.needsVerification() - // can only be true if filter.handlesWebUris(true) returns true, so - // we've already noted that. break; } } } - // Note whether this app publishes any web navigation handling support at all, - // and whether there are any web-nav filters that fit the profile for running - // a verification pass now. if (needToVerify) { final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { @@ -18495,23 +18483,13 @@ public class PackageManagerService extends IPackageManager.Stub } if (count > 0) { - // count > 0 means that we're running a full verification pass if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count + " IntentFilter verification" + (count > 1 ? "s" : "") + " for userId:" + userId); mIntentFilterVerifier.startVerifications(userId); - } else if (alreadyVerified && handlesWebUris) { - // App used autoVerify in the past, no longer does, but still handles web - // navigation starts. - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy"); - } - synchronized (mPackages) { - clearIntentFilterVerificationsLPw(packageName, userId); - } } else { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "No web filters or no prior verify policy for " + packageName); + Slog.d(TAG, "No filters or not all autoVerify for " + packageName); } } } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 5ab97a4e9f35..45d0c585627b 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1377,7 +1377,6 @@ final class Settings { return false; } ps.clearDomainVerificationStatusForUser(userId); - ps.setIntentFilterVerificationInfo(null); return true; } -- GitLab From b235ee861774278e5fab1a4917216cd2e5f7bacb Mon Sep 17 00:00:00 2001 From: Linus Tufvesson Date: Tue, 31 Mar 2020 17:27:41 +0000 Subject: [PATCH 192/219] RESTRICT AUTOMERGE Revert submission 10446362-type-presentation-p Reason for revert: Breaks apps using Presentation in combination with private virtual displays Reverted Changes: Ib5a24f8be:RESTRICT AUTOMERGE Add test for Presentation I2aaab1903:RESTRICT AUTOMERGE Block TYPE_PRESENTATION windows... Bug: 141745510 Change-Id: I9e8a02d5162cd5f8fb0f1860c4d4f099c718a946 --- core/java/android/app/Presentation.java | 16 +++++++--------- .../android/server/wm/WindowManagerService.java | 8 -------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java index bc2b250328a6..af55788e617f 100644 --- a/core/java/android/app/Presentation.java +++ b/core/java/android/app/Presentation.java @@ -25,18 +25,18 @@ import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.os.Binder; -import android.os.Handler; import android.os.IBinder; -import android.os.Message; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.Gravity; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; +import android.os.Handler; +import android.os.Message; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; /** * Base class for presentations. @@ -115,9 +115,7 @@ import android.view.WindowManagerImpl; * The display manager keeps track of all displays in the system. However, not all * displays are appropriate for showing presentations. For example, if an activity * attempted to show a presentation on the main display it might obscure its own content - * (it's like opening a dialog on top of your activity). Creating a presentation on the main - * display will result in {@link android.view.WindowManager.InvalidDisplayException} being thrown - * when invoking {@link #show()}. + * (it's like opening a dialog on top of your activity). *

* Here's how to identify suitable displays for showing presentations using * {@link DisplayManager#getDisplays(String)} and the @@ -244,7 +242,7 @@ public class Presentation extends Dialog { /** * Inherited from {@link Dialog#show}. Will throw * {@link android.view.WindowManager.InvalidDisplayException} if the specified secondary - * {@link Display} can't be found or if it does not have {@link Display#FLAG_PRESENTATION} set. + * {@link Display} can't be found. */ @Override public void show() { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index b438d044d102..8b4a2dd36e6c 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -55,7 +55,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_DREAM; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; -import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; @@ -1183,13 +1182,6 @@ public class WindowManagerService extends IWindowManager.Stub return WindowManagerGlobal.ADD_PERMISSION_DENIED; } - if (type == TYPE_PRESENTATION && !displayContent.getDisplay().isPublicPresentation()) { - Slog.w(TAG_WM, - "Attempted to add presentation window to a non-suitable display. " - + "Aborting."); - return WindowManagerGlobal.ADD_INVALID_DISPLAY; - } - AppWindowToken atoken = null; final boolean hasParent = parentWindow != null; // Use existing parent window token for child windows since they go in the same token -- GitLab From a9211d687df742350916103f50ace9953c1abf48 Mon Sep 17 00:00:00 2001 From: Linus Tufvesson Date: Tue, 31 Mar 2020 15:18:14 +0000 Subject: [PATCH 193/219] RESTRICT AUTOMERGE Revert submission 10383599-type-presentation-q Reason for revert: Breaks apps using Presentation in combination with private virtual displays Reverted Changes: I2aaab1903:RESTRICT AUTOMERGE Block TYPE_PRESENTATION windows... Ib5a24f8be:RESTRICT AUTOMERGE Add test for Presentation Bug: 141745510 Change-Id: I0b3a332c286900952b65ece12435f981e324cb5b --- core/java/android/app/Presentation.java | 16 +++++++--------- .../android/server/wm/WindowManagerService.java | 8 -------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java index b3a39f5025c7..cb72d4d5dc2c 100644 --- a/core/java/android/app/Presentation.java +++ b/core/java/android/app/Presentation.java @@ -26,18 +26,18 @@ import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.os.Binder; -import android.os.Handler; import android.os.IBinder; -import android.os.Message; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.Gravity; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; +import android.os.Handler; +import android.os.Message; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; /** * Base class for presentations. @@ -116,9 +116,7 @@ import android.view.WindowManagerImpl; * The display manager keeps track of all displays in the system. However, not all * displays are appropriate for showing presentations. For example, if an activity * attempted to show a presentation on the main display it might obscure its own content - * (it's like opening a dialog on top of your activity). Creating a presentation on the main - * display will result in {@link android.view.WindowManager.InvalidDisplayException} being thrown - * when invoking {@link #show()}. + * (it's like opening a dialog on top of your activity). *

* Here's how to identify suitable displays for showing presentations using * {@link DisplayManager#getDisplays(String)} and the @@ -245,7 +243,7 @@ public class Presentation extends Dialog { /** * Inherited from {@link Dialog#show}. Will throw * {@link android.view.WindowManager.InvalidDisplayException} if the specified secondary - * {@link Display} can't be found or if it does not have {@link Display#FLAG_PRESENTATION} set. + * {@link Display} can't be found. */ @Override public void show() { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 2de8ae155f81..436a5c729b86 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -60,7 +60,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_DREAM; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; -import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; @@ -1277,13 +1276,6 @@ public class WindowManagerService extends IWindowManager.Stub return WindowManagerGlobal.ADD_PERMISSION_DENIED; } - if (type == TYPE_PRESENTATION && !displayContent.getDisplay().isPublicPresentation()) { - Slog.w(TAG_WM, - "Attempted to add presentation window to a non-suitable display. " - + "Aborting."); - return WindowManagerGlobal.ADD_INVALID_DISPLAY; - } - AppWindowToken atoken = null; final boolean hasParent = parentWindow != null; // Use existing parent window token for child windows since they go in the same token -- GitLab From 18e46e36eba07a83a204cb3d16aa2b2cf4c5164d Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 25 Feb 2020 17:48:49 -0800 Subject: [PATCH 194/219] Verify all possible hosts that match web nav Even if an matches non-web schemes in addition to http or https, make sure to include its cited hosts in the autoVerify evaluation. Bug: 150038428 Test: atest OsHostTests#testIntentFilterHostValidation Change-Id: If9ef0fc53d96e6581c56d86f89fe63bc9a5fb89a Merged-In: If9ef0fc53d96e6581c56d86f89fe63bc9a5fb89a (cherry picked from commit 1fba0f897f276d5d47962534867e764da8061105) --- .../java/com/android/server/pm/PackageManagerService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index a3f3cedf1e2c..3888c3130c15 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -18470,7 +18470,9 @@ public class PackageManagerService extends IPackageManager.Stub final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { - if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { + // Run verification against hosts mentioned in any web-nav intent filter, + // even if the filter matches non-web schemes as well + if (filter.handlesWebUris(false) && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString()); mIntentFilterVerifier.addOneIntentFilterVerification( -- GitLab From a481c86cd3742c7792f8607c004e0eeb4016b894 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 25 Feb 2020 17:48:49 -0800 Subject: [PATCH 195/219] Verify all possible hosts that match web nav Even if an matches non-web schemes in addition to http or https, make sure to include its cited hosts in the autoVerify evaluation. Bug: 150038428 Test: atest OsHostTests#testIntentFilterHostValidation Change-Id: If9ef0fc53d96e6581c56d86f89fe63bc9a5fb89a Merged-In: If9ef0fc53d96e6581c56d86f89fe63bc9a5fb89a (cherry picked from commit 1fba0f897f276d5d47962534867e764da8061105) --- .../java/com/android/server/pm/PackageManagerService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index db3b7677f426..c8175befe179 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -19094,7 +19094,9 @@ public class PackageManagerService extends IPackageManager.Stub final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { - if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { + // Run verification against hosts mentioned in any web-nav intent filter, + // even if the filter matches non-web schemes as well + if (filter.handlesWebUris(false) && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString()); mIntentFilterVerifier.addOneIntentFilterVerification( -- GitLab From bfa779601082d9021ea4e7d4cca571575bd0b13b Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 25 Feb 2020 17:48:49 -0800 Subject: [PATCH 196/219] Verify all possible hosts that match web nav Even if an matches non-web schemes in addition to http or https, make sure to include its cited hosts in the autoVerify evaluation. Bug: 150038428 Test: atest OsHostTests#testIntentFilterHostValidation Change-Id: If9ef0fc53d96e6581c56d86f89fe63bc9a5fb89a Merged-In: If9ef0fc53d96e6581c56d86f89fe63bc9a5fb89a (cherry picked from commit 1fba0f897f276d5d47962534867e764da8061105) --- .../java/com/android/server/pm/PackageManagerService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 1a08668b1fa3..8d43959fb2c2 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -17759,7 +17759,9 @@ public class PackageManagerService extends IPackageManager.Stub final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { - if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { + // Run verification against hosts mentioned in any web-nav intent filter, + // even if the filter matches non-web schemes as well + if (filter.handlesWebUris(false) && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString()); mIntentFilterVerifier.addOneIntentFilterVerification( -- GitLab From 24e0f76afc3a23c4c5ab7326986ccf65eaec93e2 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 25 Feb 2020 17:48:49 -0800 Subject: [PATCH 197/219] Verify all possible hosts that match web nav Even if an matches non-web schemes in addition to http or https, make sure to include its cited hosts in the autoVerify evaluation. Bug: 150038428 Test: atest OsHostTests#testIntentFilterHostValidation Change-Id: If9ef0fc53d96e6581c56d86f89fe63bc9a5fb89a Merged-In: If9ef0fc53d96e6581c56d86f89fe63bc9a5fb89a (cherry picked from commit 1fba0f897f276d5d47962534867e764da8061105) --- .../java/com/android/server/pm/PackageManagerService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 26677dc52909..522e08842459 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -18114,7 +18114,9 @@ public class PackageManagerService extends IPackageManager.Stub final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { - if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { + // Run verification against hosts mentioned in any web-nav intent filter, + // even if the filter matches non-web schemes as well + if (filter.handlesWebUris(false) && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString()); mIntentFilterVerifier.addOneIntentFilterVerification( -- GitLab From f4976307cec95e213cf0ad656dd3d34a311e55c5 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 25 Feb 2020 17:48:49 -0800 Subject: [PATCH 198/219] Verify all possible hosts that match web nav Even if an matches non-web schemes in addition to http or https, make sure to include its cited hosts in the autoVerify evaluation. Bug: 150038428 Test: atest OsHostTests#testIntentFilterHostValidation Change-Id: If9ef0fc53d96e6581c56d86f89fe63bc9a5fb89a Merged-In: If9ef0fc53d96e6581c56d86f89fe63bc9a5fb89a (cherry picked from commit 1fba0f897f276d5d47962534867e764da8061105) --- .../java/com/android/server/pm/PackageManagerService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 093382a632c6..6bed7f381a6c 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -18156,7 +18156,9 @@ public class PackageManagerService extends IPackageManager.Stub final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { - if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { + // Run verification against hosts mentioned in any web-nav intent filter, + // even if the filter matches non-web schemes as well + if (filter.handlesWebUris(false) && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString()); mIntentFilterVerifier.addOneIntentFilterVerification( -- GitLab From 41215b67a334203fb1a7c3f1542598ce4881b6d0 Mon Sep 17 00:00:00 2001 From: Linus Tufvesson Date: Wed, 1 Apr 2020 13:31:34 +0000 Subject: [PATCH 199/219] RESTRICT AUTOMERGE This reverts commit 7d4adf4d46caa7695c395e3e994e1d57a94ae92c. Reason for revert: Breaks apps using Presentation in combination with private virtual displays Bug: 141745510 Change-Id: I15ded4f1a7cf152e331c853c128c91db173f3cd7 --- core/java/android/app/Presentation.java | 16 +++++++--------- .../android/server/wm/WindowManagerService.java | 8 -------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java index bc2b250328a6..af55788e617f 100644 --- a/core/java/android/app/Presentation.java +++ b/core/java/android/app/Presentation.java @@ -25,18 +25,18 @@ import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.os.Binder; -import android.os.Handler; import android.os.IBinder; -import android.os.Message; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.Gravity; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; +import android.os.Handler; +import android.os.Message; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; /** * Base class for presentations. @@ -115,9 +115,7 @@ import android.view.WindowManagerImpl; * The display manager keeps track of all displays in the system. However, not all * displays are appropriate for showing presentations. For example, if an activity * attempted to show a presentation on the main display it might obscure its own content - * (it's like opening a dialog on top of your activity). Creating a presentation on the main - * display will result in {@link android.view.WindowManager.InvalidDisplayException} being thrown - * when invoking {@link #show()}. + * (it's like opening a dialog on top of your activity). *

* Here's how to identify suitable displays for showing presentations using * {@link DisplayManager#getDisplays(String)} and the @@ -244,7 +242,7 @@ public class Presentation extends Dialog { /** * Inherited from {@link Dialog#show}. Will throw * {@link android.view.WindowManager.InvalidDisplayException} if the specified secondary - * {@link Display} can't be found or if it does not have {@link Display#FLAG_PRESENTATION} set. + * {@link Display} can't be found. */ @Override public void show() { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index d35ad413ccef..5f4c99437af9 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -58,7 +58,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_DREAM; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; -import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; @@ -1256,13 +1255,6 @@ public class WindowManagerService extends IWindowManager.Stub return WindowManagerGlobal.ADD_PERMISSION_DENIED; } - if (type == TYPE_PRESENTATION && !displayContent.getDisplay().isPublicPresentation()) { - Slog.w(TAG_WM, - "Attempted to add presentation window to a non-suitable display. " - + "Aborting."); - return WindowManagerGlobal.ADD_INVALID_DISPLAY; - } - AppWindowToken atoken = null; final boolean hasParent = parentWindow != null; // Use existing parent window token for child windows since they go in the same token -- GitLab From 59ba1518541c405302077f657c092d0c1fad2d82 Mon Sep 17 00:00:00 2001 From: Linus Tufvesson Date: Wed, 1 Apr 2020 13:31:51 +0000 Subject: [PATCH 200/219] RESTRICT AUTOMERGE This reverts commit 0bb93d4b1c05d717ed4cbf5772a6a766b5281f1e. Reason for revert: Breaks apps using Presentation in combination with private virtual displays Bug: 141745510 Change-Id: I6673946137d6b12fa725e6df1c936068dedc3787 --- core/java/android/app/Presentation.java | 16 +++++++--------- .../android/server/wm/WindowManagerService.java | 8 -------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java index bc2b250328a6..af55788e617f 100644 --- a/core/java/android/app/Presentation.java +++ b/core/java/android/app/Presentation.java @@ -25,18 +25,18 @@ import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.os.Binder; -import android.os.Handler; import android.os.IBinder; -import android.os.Message; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.Gravity; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; +import android.os.Handler; +import android.os.Message; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; /** * Base class for presentations. @@ -115,9 +115,7 @@ import android.view.WindowManagerImpl; * The display manager keeps track of all displays in the system. However, not all * displays are appropriate for showing presentations. For example, if an activity * attempted to show a presentation on the main display it might obscure its own content - * (it's like opening a dialog on top of your activity). Creating a presentation on the main - * display will result in {@link android.view.WindowManager.InvalidDisplayException} being thrown - * when invoking {@link #show()}. + * (it's like opening a dialog on top of your activity). *

* Here's how to identify suitable displays for showing presentations using * {@link DisplayManager#getDisplays(String)} and the @@ -244,7 +242,7 @@ public class Presentation extends Dialog { /** * Inherited from {@link Dialog#show}. Will throw * {@link android.view.WindowManager.InvalidDisplayException} if the specified secondary - * {@link Display} can't be found or if it does not have {@link Display#FLAG_PRESENTATION} set. + * {@link Display} can't be found. */ @Override public void show() { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 361c116b67f6..8439669a2147 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -56,7 +56,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_DREAM; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; -import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; @@ -1228,13 +1227,6 @@ public class WindowManagerService extends IWindowManager.Stub return WindowManagerGlobal.ADD_PERMISSION_DENIED; } - if (type == TYPE_PRESENTATION && !displayContent.getDisplay().isPublicPresentation()) { - Slog.w(TAG_WM, - "Attempted to add presentation window to a non-suitable display. " - + "Aborting."); - return WindowManagerGlobal.ADD_INVALID_DISPLAY; - } - AppWindowToken atoken = null; final boolean hasParent = parentWindow != null; // Use existing parent window token for child windows since they go in the same token -- GitLab From 4bf1986a323ed8bdff7934a0f9df60e06c8745f6 Mon Sep 17 00:00:00 2001 From: Hall Liu Date: Wed, 1 Apr 2020 18:00:09 -0700 Subject: [PATCH 201/219] Fix order of uid/pid in LocationAccessPolicy Fix the order in which uid and pid are passed into the permission check. Test: atest LocationAccessPolicyTest Fixes: 151330809 Change-Id: I479c8fc123d5a994e8cbe6489aa00bea4abca1c7 Merged-In: I479c8fc123d5a994e8cbe6489aa00bea4abca1c7 --- telephony/java/android/telephony/LocationAccessPolicy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telephony/java/android/telephony/LocationAccessPolicy.java b/telephony/java/android/telephony/LocationAccessPolicy.java index eb744f619f2e..2d7c561cd180 100644 --- a/telephony/java/android/telephony/LocationAccessPolicy.java +++ b/telephony/java/android/telephony/LocationAccessPolicy.java @@ -286,7 +286,7 @@ public final class LocationAccessPolicy { } // If the user or profile is current, permission is granted. // Otherwise, uid must have INTERACT_ACROSS_USERS_FULL permission. - return isCurrentProfile(context, uid) || checkInteractAcrossUsersFull(context, uid, pid); + return isCurrentProfile(context, uid) || checkInteractAcrossUsersFull(context, pid, uid); } private static boolean isLocationModeEnabled(@NonNull Context context, @UserIdInt int userId) { -- GitLab From 61f45818582d8a0a7f3030cf065ad73cd616b870 Mon Sep 17 00:00:00 2001 From: Linus Tufvesson Date: Tue, 31 Mar 2020 15:18:14 +0000 Subject: [PATCH 202/219] RESTRICT AUTOMERGE Revert submission 10383599-type-presentation-q Reason for revert: Breaks apps using Presentation in combination with private virtual displays Reverted Changes: I2aaab1903:RESTRICT AUTOMERGE Block TYPE_PRESENTATION windows... Ib5a24f8be:RESTRICT AUTOMERGE Add test for Presentation Bug: 141745510 Bug: 152342138 Merged-In: I0b3a332c286900952b65ece12435f981e324cb5b Change-Id: I0b3a332c286900952b65ece12435f981e324cb5b (cherry picked from commit a9211d687df742350916103f50ace9953c1abf48) --- core/java/android/app/Presentation.java | 16 +++++++--------- .../android/server/wm/WindowManagerService.java | 8 -------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java index eaee0602f4b7..138578ef6654 100644 --- a/core/java/android/app/Presentation.java +++ b/core/java/android/app/Presentation.java @@ -26,18 +26,18 @@ import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.os.Binder; -import android.os.Handler; import android.os.IBinder; -import android.os.Message; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.Gravity; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; +import android.os.Handler; +import android.os.Message; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; /** * Base class for presentations. @@ -116,9 +116,7 @@ import android.view.WindowManagerImpl; * The display manager keeps track of all displays in the system. However, not all * displays are appropriate for showing presentations. For example, if an activity * attempted to show a presentation on the main display it might obscure its own content - * (it's like opening a dialog on top of your activity). Creating a presentation on the main - * display will result in {@link android.view.WindowManager.InvalidDisplayException} being thrown - * when invoking {@link #show()}. + * (it's like opening a dialog on top of your activity). *

* Here's how to identify suitable displays for showing presentations using * {@link DisplayManager#getDisplays(String)} and the @@ -245,7 +243,7 @@ public class Presentation extends Dialog { /** * Inherited from {@link Dialog#show}. Will throw * {@link android.view.WindowManager.InvalidDisplayException} if the specified secondary - * {@link Display} can't be found or if it does not have {@link Display#FLAG_PRESENTATION} set. + * {@link Display} can't be found. */ @Override public void show() { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index adbfb8587e47..1b6daf400e26 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -61,7 +61,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_DREAM; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; -import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; @@ -1298,13 +1297,6 @@ public class WindowManagerService extends IWindowManager.Stub return WindowManagerGlobal.ADD_PERMISSION_DENIED; } - if (type == TYPE_PRESENTATION && !displayContent.getDisplay().isPublicPresentation()) { - Slog.w(TAG_WM, - "Attempted to add presentation window to a non-suitable display. " - + "Aborting."); - return WindowManagerGlobal.ADD_INVALID_DISPLAY; - } - AppWindowToken atoken = null; final boolean hasParent = parentWindow != null; // Use existing parent window token for child windows since they go in the same token -- GitLab From 71f012c4cdac7f25565c1b0e1292cadb86504a69 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 2 Apr 2020 20:39:08 -0700 Subject: [PATCH 203/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: I80b216aec67e5fabf72ab1bc4952327c3c710ae6 --- core/res/res/values-ar/strings.xml | 10 +++++----- core/res/res/values-as/strings.xml | 2 +- core/res/res/values-be/strings.xml | 2 +- core/res/res/values-bg/strings.xml | 2 +- core/res/res/values-bn/strings.xml | 4 ++-- core/res/res/values-bs/strings.xml | 2 +- core/res/res/values-ca/strings.xml | 2 +- core/res/res/values-de/strings.xml | 2 +- core/res/res/values-fr-rCA/strings.xml | 2 +- core/res/res/values-gu/strings.xml | 4 ++-- core/res/res/values-hi/strings.xml | 4 ++-- core/res/res/values-it/strings.xml | 2 +- core/res/res/values-ka/strings.xml | 2 +- core/res/res/values-kn/strings.xml | 4 ++-- core/res/res/values-ko/strings.xml | 2 +- core/res/res/values-ky/strings.xml | 2 +- core/res/res/values-lt/strings.xml | 2 +- core/res/res/values-lv/strings.xml | 2 +- core/res/res/values-ml/strings.xml | 6 +++--- core/res/res/values-mr/strings.xml | 2 +- core/res/res/values-my/strings.xml | 6 +++--- core/res/res/values-pa/strings.xml | 2 +- core/res/res/values-pl/strings.xml | 2 +- core/res/res/values-sk/strings.xml | 2 +- core/res/res/values-sq/strings.xml | 2 +- core/res/res/values-sw/strings.xml | 2 +- core/res/res/values-ta/strings.xml | 10 ++++------ core/res/res/values-te/strings.xml | 7 +++---- core/res/res/values-th/strings.xml | 2 +- core/res/res/values-tr/strings.xml | 2 +- core/res/res/values-uk/strings.xml | 2 +- core/res/res/values-uz/strings.xml | 2 +- core/res/res/values-vi/strings.xml | 2 +- core/res/res/values-zh-rCN/strings.xml | 2 +- 34 files changed, 51 insertions(+), 54 deletions(-) diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 03706a7bd354..87d1c57699a4 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -207,7 +207,7 @@ "خيارات الهاتف" "وضع صامت" "تفعيل اللاسلكي" - "إيقاف تفعيل الشبكة اللاسلكية" + "إيقاف الشبكة اللاسلكية" "قفل الشاشة" "إيقاف التشغيل" "إيقاف الرنين" @@ -220,10 +220,10 @@ "إعادة الضبط على الإعدادات الأصلية" "جارٍ إعادة التشغيل…" "جارٍ إيقاف التشغيل..." - "سيتم إيقاف تفعيل الجهاز اللوحي." + "سيتم إيقاف الجهاز اللوحي." "سيتم إيقاف التلفزيون." "سيتم إيقاف المشاهدة." - "سيتم إيقاف تفعيل هاتفك." + "سيتم إيقاف هاتفك." "هل تريد إيقاف التشغيل؟" "إعادة تشغيل في الوضع الآمن" "هل تريد إعادة تشغيل الكمبيوتر في الوضع الآمن؟ سيؤدي ذلك إلى إيقاف جميع تطبيقات الجهات الخارجية التي تم تثبيتها. ستتم استعادتها عند إعادة التشغيل مرة أخرى." @@ -447,7 +447,7 @@ "التقاط صور وفيديوهات" "يمكن لهذا التطبيق التقاط صور وتسجيل فيديوهات باستخدام الكاميرا في أي وقت." "يسمح الإذن لتطبيق أو خدمة بتلقّي استدعاءات عما إذا كانت أجهزة الكاميرات مفتوحة أو مغلقة." - "يمكن أن يتلقّى هذا التطبيق استدعاءات عندما يكون جهاز أي كاميرا مفتوحًا (بتطبيق) أو مغلقًا." + "يمكن أن يتلقّى هذا التطبيق استدعاءات عندما تكون هناك كاميرا مفتوحة (بواسطة هذا التطبيق) أو مغلقة." "التحكم في الاهتزاز" "للسماح للتطبيق بالتحكم في الهزّاز." "اتصال مباشر بأرقام الهواتف" @@ -616,7 +616,7 @@ "التبديل بين تفعيل المزامنة وإيقافها" "للسماح للتطبيق بتعديل إعدادات المزامنة لحساب ما. على سبيل المثال، يمكن استخدام ذلك لتفعيل مزامنة تطبيق \"الأشخاص\" مع حساب ما." "قراءة إحصاءات المزامنة" - "للسماح للتطبيق بقراءة إحصائيات المزامنة لحساب ما، بما في ذلك سجل الأحداث المتزامنة ومقدار البيانات التي تمت مزامنتها." + "للسماح للتطبيق بقراءة إحصاءات المزامنة لحساب ما، بما في ذلك سجل الأحداث المتزامنة ومقدار البيانات التي تمت مزامنتها." "قراءة محتوى مساحة التخزين المشتركة" "للسماح للتطبيق بقراءة محتوى مساحة التخزين المشتركة." "تعديل محتوى مساحة التخزين المشتركة أو حذفه" diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 480902c6d388..6400f37a73d7 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -750,7 +750,7 @@ "TTY TDD" "কৰ্মস্থানৰ ম’বাইল নম্বৰ" "কৰ্মস্থানৰ পেজাৰৰ নম্বৰ" - "সহায়ক" + "Assistant" "এমএমএছ" "নিজৰ উপযোগিতা অনুযায়ী" "জন্মদিন" diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index b40d5e5100b1..e9aa8a064f95 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -1125,7 +1125,7 @@ "Уставіць як звычайны тэкст" "Замяніць..." "Выдаліць" - "Скапіяваць URL" + "Скапіраваць URL-адрас" "Выбраць тэкст" "Адрабіць" "Узнавіць" diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 60db24aa4846..e5d69e394f34 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -227,7 +227,7 @@ "Заключване на екрана" "Изключване" "Спешно обаждане" - "Сигнал за програмна грешка" + "Сигнал за грешка" "Прекратяване на сесията" "Екранна снимка" "Сигнал за грешка" diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index bd29fa020036..3ce28e19753b 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -286,7 +286,7 @@ "আপনি এই অ্যাপ ব্যবহার করার সময়েই শুধু সেটি আপনার লোকেশন অ্যাক্সেস করতে পারবে" "<b>%1$s</b> অ্যাপকে এই ডিভাইসের লোকেশন <b>সব সময়</b> অ্যাক্সেস করার অনুমতি দিতে চান?" "আপনি যখন অ্যাপটি ব্যবহার করবেন শুধুমাত্র তখনই অ্যাপটি বর্তমান লোকেশন অ্যাক্সেস করতে পারবে।" - "ক্যালেন্ডার" + "Calendar" "আপনার ক্যালেন্ডারে অ্যাক্সেস" "<b>%1$s</b>-কে আপনার ক্যালেন্ডারে অ্যাক্সেস দেবেন?" "SMS" @@ -750,7 +750,7 @@ "TTY TDD" "অফিসের মোবাইল" "কার্যক্ষেত্রের পেজার" - "সহায়ক" + "Assistant" "MMS" "কাস্টম" "জন্মদিন" diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 5d2761e3c73c..033da2e4e29f 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -438,7 +438,7 @@ "snimanje slika i videozapisa" "Ova aplikacija može slikati fotografije i snimati videozapise koristeći kameru bilo kada." "Dozvoliti aplikaciji ili usluzi da prima povratne pozive o otvaranju ili zatvaranju kamera." - "Ova aplikacija može primati povratne pozive kada se otvara ili zatvara bilo koja kamera (kojom aplikacijom)." + "Ova aplikacija može primati povratne pozive kada se otvara ili zatvara bilo koji uređaj s kamerom (putem neke aplikacije)." "kontrola vibracije" "Dozvoljava aplikaciji upravljanje vibracijom." "izravno zvanje telefonskih brojeva" diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 57967c828891..2052de4f38a3 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -435,7 +435,7 @@ "fer fotos i vídeos" "Aquesta aplicació pot fer fotos i gravar vídeos amb la càmera en qualsevol moment." "Permet que una aplicació o un servei pugui rebre crides de retorn sobre els dispositius de càmera que s\'obren o es tanquen." - "Aquesta aplicació pot rebre crides de retorn quan s\'obre o es tanca un dispositiu de càmera (segons l\'aplicació)." + "Aquesta aplicació pot rebre crides de retorn quan s\'obre o es tanca un dispositiu de càmera mitjançant l\'aplicació en qüestió." "controlar la vibració" "Permet que l\'aplicació controli el vibrador." "trucar directament a números de telèfon" diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 01311b6595e2..5b7858586c40 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -435,7 +435,7 @@ "Bilder und Videos aufnehmen" "Diese App kann mit der Kamera jederzeit Bilder und Videos aufnehmen." "Einer App oder einem Dienst den Empfang von Callbacks erlauben, wenn eine Kamera geöffnet oder geschlossen wird." - "Diese App kann Callbacks empfangen, wenn eine Kamera von einer Anwendung geöffnet oder geschlossen wird." + "Diese App kann Callbacks empfangen, wenn eine der Kameras des Geräts von einer Anwendung geöffnet oder geschlossen wird." "Vibrationsalarm steuern" "Ermöglicht der App, den Vibrationsalarm zu steuern" "Telefonnummern direkt anrufen" diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 358bfb66c492..c0a570300480 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -435,7 +435,7 @@ "prendre des photos et filmer des vidéos" "Cette application peut prendre des photos et enregistrer des vidéos à l\'aide de l\'appareil photo en tout temps." "Autoriser une application ou un service de recevoir des rappels relatifs à l\'ouverture ou à la fermeture des appareils photos." - "Cette application peut recevoir des rappels lorsque l\'appareil photo est ouvert ou fermé (par l\'application) en question." + "Cette application peut recevoir des rappels lorsque l\'appareil photo est ouvert ou fermé (par l\'application en question)." "gérer le vibreur" "Permet à l\'application de gérer le vibreur de l\'appareil." "appeler directement des numéros de téléphone" diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 01c05133bec2..decb2fbe9331 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -286,7 +286,7 @@ "જ્યારે તમે ઍપનો ઉપયોગ કરી રહ્યા હશો માત્ર ત્યારે જ ઍપ સ્થાનને ઍક્સેસ કરી શકશે" "<b>%1$s</b>ને આ ડિવાઇસનું સ્થાન <b>હંમેશાં</b> ઍક્સેસ કરવાની મંજૂરી આપીએ?" "હાલમાં માત્ર જ્યારે તમે ઍપનો ઉપયોગ કરી રહ્યા હશો હોય ત્યારે જ ઍપ સ્થાનને ઍક્સેસ કરી શકશે" - "કૅલેન્ડર" + "Calendar" "તમારા કેલેન્ડરને ઍક્સેસ કરવાની" "<b>%1$s</b>ને તમારા કૅલેન્ડરને ઍક્સેસ કરવાની મંજૂરી આપીએ?" "SMS" @@ -750,7 +750,7 @@ "TTY TDD" "કાર્યાલય મોબાઇલ" "કાર્ય પેજર" - "સહાયક" + "Assistant" "MMS" "કસ્ટમ" "જન્મદિવસ" diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 09f2b4569182..57c6f324690e 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -435,7 +435,7 @@ "चित्र और वीडियो लें" "यह ऐप्लिकेशन किसी भी समय कैमरे का उपयोग करके चित्र ले सकता है और वीडियो रिकॉर्ड कर सकता है." "डिवाइस का कैमरे चालू या बंद होने पर, किसी ऐप्लिकेशन या सेवा को कॉलबैक पाने की मंज़ूरी दें." - "यह ऐप्लिकेशन, किसी भी कैमरा डिवाइस को खोलते या बंद करते समय (किसी ऐप्लिकेशन से) कॉलबैक पा सकता है." + "यह ऐप्लिकेशन, डिवाइस के कैमरे को चालू या बंद करते समय (किसी ऐप्लिकेशन से) कॉलबैक पा सकता है." "कंपन (वाइब्रेशन) को नियंत्रित करें" "ऐप्स को कंपनकर्ता नियंत्रित करने देता है." "फ़ोन नंबर पर सीधे कॉल करें" @@ -750,7 +750,7 @@ "टेलीटाइपराइटर (TTY) टीडीडी (TDD)" "कार्यालय का मोबाइल" "कार्यालय का पेजर" - "सहायक" + "Assistant" "मल्टीमीडिया मैसेज (एमएमएस)" "कस्टम" "जन्‍मदिन" diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 797da5d8ff9b..6e14c5977692 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -435,7 +435,7 @@ "acquisizione di foto e video" "Questa app può scattare foto e registrare video tramite la fotocamera in qualsiasi momento." "Consenti a un\'applicazione o a un servizio di ricevere callback relativi all\'apertura o alla chiusura di videocamere." - "Questa app può ricevere callback quando viene aperta (da quale applicazione) o chiusa qualsiasi videocamera." + "Questa app può ricevere callback quando una videocamera viene aperta (da una specifica applicazione) o chiusa." "controllo vibrazione" "Consente all\'applicazione di controllare la vibrazione." "chiamata diretta n. telefono" diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index a98f9055c157..7ee505d2e41f 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -227,7 +227,7 @@ "ეკრანის დაბლოკვა" "გამორთვ." "საგანგებო სამსახურები" - "ხარვეზის შესახებ ანგარიში" + "ხარვეზის ანგარიში" "სესიის დასრულება" "ეკრანის ანაბეჭდი" "ხარვეზის ანგარიში" diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index f211742b3c01..cd2ebfb9df03 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -286,7 +286,7 @@ "ನೀವು ಆ್ಯಪ್ ಅನ್ನು ಬಳಸುವಾಗ, ಆ್ಯಪ್ ಮಾತ್ರ ಸ್ಥಳಕ್ಕೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತದೆ" "<b>ಎಲ್ಲಾ ಸಮಯದಲ್ಲೂ</b> ಈ ಸಾಧನದ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಲು <b>%1$s</b> ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುವುದೇ?" "ನೀವು ಆ್ಯಪ್ ಅನ್ನು ಬಳಸುವಾಗ ಮಾತ್ರ, ಅದು ಪ್ರಸ್ತುತವಾಗಿ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು" - "ಕ್ಯಾಲೆಂಡರ್" + "Calendar" "ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಪ್ರವೇಶಿಸಲು" "ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಪ್ರವೇಶಿಸಲು <b>%1$s</b> ಗೆ ಅನುಮತಿಸಬೇಕೇ?" "SMS" @@ -750,7 +750,7 @@ "TTY TDD" "ಕಚೇರಿ ಮೊಬೈಲ್" "ಕಚೇರಿ ಪೇಜರ್" - "ಸಹಾಯಕ" + "Assistant" "MMS" "ಕಸ್ಟಮ್" "ಜನ್ಮದಿನ" diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 09d3bb9973f3..3d7314732caa 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -435,7 +435,7 @@ "사진과 동영상 찍기" "이 앱은 언제든지 카메라를 사용하여 사진을 촬영하고 동영상을 녹화할 수 있습니다." "애플리케이션 또는 서비스에서 카메라 기기 열림 또는 닫힘에 대한 콜백을 수신하도록 허용" - "이 앱은 어떤 애플리케이션이든지 카메라 기기를 열 때나 닫을 때 콜백을 수신할 수 있습니다." + "이 앱은 애플리케이션이 카메라 기기를 열거나 닫을 때 콜백을 수신할 수 있습니다." "진동 제어" "앱이 진동을 제어할 수 있도록 허용합니다." "전화번호 자동 연결" diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index f7fadfb9fe1f..5a93e527b1ef 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -812,7 +812,7 @@ "PIN-код туура эмес." "Кулпусун ачуу үчүн, Менюна андан соң 0 баскычын басыңыз." "Өзгөчө кырдаалдар кызматы" - "Байланыш жок" + "Интернет жок" "Экран кулпуланды." "Кулпусун ачып же Шашылыш чалуу аткаруу үчүн менюну басыңыз." "Бөгөттөн чыгаруу үчүн Менюну басыңыз." diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index dda67a00289b..2a0caa9c12c9 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -230,7 +230,7 @@ "Telefono parinktys" "Ekrano užraktas" "Išjungiamas maitinimas" - "Skambutis pagalbos numeriu" + "Skubus atvejis" "Pranešimas apie riktą" "Baigti seansą" "Ekrano kopija" diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 3bb1c8099d70..d412022182b0 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -227,7 +227,7 @@ "TV opcijas" "Tālruņa opcijas" "Ekrāna bloķētājs" - "Strāvas padeve ir izslēgta." + "Strāvas padeve izslēgta." "Ārkārtas situācija" "Kļūdu ziņojums" "Beigt sesiju" diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 95854436fb7c..16fceb5187fe 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -286,7 +286,7 @@ "നിങ്ങൾ ആപ്പ് ഉപയോഗിക്കുമ്പോൾ മാത്രമേ അതിന് ലൊക്കേഷൻ ആക്‌സസ് ലഭിക്കൂ." "%1$s എന്നതിനെ ഈ ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ആക്‌സസ് ചെയ്യാൻ എപ്പോഴും അനുവദിക്കണോ?" "നിലവിൽ, ഉപയോഗിക്കുമ്പോൾ മാത്രം ആപ്പിന് ലൊക്കേഷൻ ആക്‌സസ് ചെയ്യാം" - "കലണ്ടർ" + "Calendar" "നിങ്ങളുടെ കലണ്ടർ ആക്‌സസ്സ് ചെയ്യുക" "നിങ്ങളുടെ കലണ്ടർ ആക്‌സസ് ചെയ്യാൻ <b>%1$s</b> ആപ്പിനെ അനുവദിക്കണോ?" "SMS" @@ -435,7 +435,7 @@ "ചിത്രങ്ങളും വീഡിയോകളും എടുക്കുക" "ഏതുസമയത്തും ക്യാമറ ഉപയോഗിച്ചുകൊണ്ട് ചിത്രങ്ങൾ എടുക്കാനും വീഡിയോകൾ റെക്കോർഡുചെയ്യാനും ഈ ആപ്പിന് കഴിയും." "ക്യാമറയുള്ള ഉപകരണങ്ങൾ ഓണാക്കുന്നതിനെയോ അടയ്ക്കുന്നതിനെയോ കുറിച്ചുള്ള കോൾബാക്കുകൾ സ്വീകരിക്കാൻ ആപ്പിനെയോ സേവനത്തെയോ അനുവദിക്കുക." - "ക്യാമറയുള്ള ഏതെങ്കിലും ഉപകരണം ഓണാക്കുമ്പോഴോ (ആപ്പ് മുഖേന) അടയ്ക്കുമ്പോഴോ ഈ ആപ്പിന് കോൾബാക്കുകൾ സ്വീകരിക്കാനാവും." + "ഏതെങ്കിലും ക്യാമറ ഉപകരണം തുറക്കുമ്പോഴോ (ഏത് ആപ്പ് ഉപയോഗിച്ചും) അടയ്ക്കുമ്പോഴോ ഈ ആപ്പിന് കോൾബാക്കുകൾ സ്വീകരിക്കാനാവും." "വൈബ്രേറ്റുചെയ്യൽ നിയന്ത്രിക്കുക" "വൈബ്രേറ്റർ നിയന്ത്രിക്കുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു." "ഫോൺ നമ്പറുകളിലേക്ക് നേരിട്ട് വിളിക്കുക" @@ -750,7 +750,7 @@ "TTY TDD" "ഓഫീസ് മൊബൈല്‍" "ഔദ്യോഗിക പേജര്‍‌" - "അസിസ്റ്റന്‍റ്" + "Assistant" "MMS" "ഇഷ്‌ടാനുസൃതം" "ജന്മദിനം" diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 299abcf5ad5e..71e038acb20f 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -286,7 +286,7 @@ "तुम्ही अ‍ॅप वापरत असताना अ‍ॅपला फक्त स्थानाचा अ‍ॅक्सेस असेल" "<b>%1$s</b> ला <b>प्रत्येक वेळी</b> या डिव्हाइसच्या स्थानाचा अ‍ॅक्सेस द्यायचा?" "अ‍ॅप सध्या फक्त तुम्ही अ‍ॅप वापरत असतानाच स्थान अ‍ॅक्सेस करू शकते" - "कॅलेंडर" + "Calendar" "आपल्या कॅलेंडरवर प्रवेश" "<b>%1$s</b> ला तुमचे कॅलेंडर अ‍ॅक्सेस करू द्यायचे?" "SMS" diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 4882eb311c5b..7bb85c63a31d 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -224,11 +224,11 @@ "Tabletဆိုင်ရာရွေးချယ်မှုများ" "တီဗွီ ရွေးချယ်စရာများ" "ဖုန်းဆိုင်ရာရွေးချယ်မှုများ" - "ဖန်သားပြင် လော့ခ်ချခြင်း" + "ဖန်သားပြင် လော့ခ်ချရန်" "ပါဝါပိတ်ရန်" "အရေးပေါ်" - "အမှားရှာဖွေပြင်ဆင်မှုမှတ်တမ်း" - "သတ်မှတ်ပေးထားသည့်အချိန် ပြီးဆုံးပြီ" + "အမှားရှာပြင် မှတ်တမ်း" + "စက်ရှင် ပြီးဆုံးပြီ" "ဖန်သားပြင်ဓာတ်ပုံ" "အမှားပြင် အစီရင်ခံစာ" "သင့်ရဲ့ လက်ရှိ စက်အခြေအနေ အချက်အလက်များကို အီးမေးလ် အနေဖြင့် ပေးပို့ရန် စုဆောင်းပါမည်။ အမှားရှာဖွေပြင်ဆင်မှုမှတ်တမ်းမှ ပေးပို့ရန် အသင့်ဖြစ်သည်အထိ အချိန် အနည်းငယ်ကြာမြင့်မှာ ဖြစ်သဖြင့် သည်းခံပြီး စောင့်ပါရန်" diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 639c9bae3b0c..57807f742429 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -286,7 +286,7 @@ "ਤੁਹਾਡੇ ਵੱਲੋਂ ਐਪ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਹੀ ਐਪ ਕੋਲ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਹੋਵੇਗੀ" "ਕੀ <b>%1$s</b> ਨੂੰ ਹਰ ਵੇਲੇ <b>ਇਸ ਡੀਵਾਈਸ ਦੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ</b>?" "ਤੁਹਾਡੇ ਵੱਲੋਂ ਐਪ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਹੀ ਐਪ ਹੁਣ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕੇਗੀ" - "ਕੈਲੰਡਰ" + "Calendar" "ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨ" "ਕੀ <b>%1$s</b> ਨੂੰ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨੀ ਦੇਣੀ ਹੈ?" "SMS" diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index a60192851940..8ad26872adb3 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -441,7 +441,7 @@ "wykonywanie zdjęć i filmów wideo" "Ta aplikacja może w dowolnym momencie robić zdjęcia i nagrywać filmy przy użyciu aparatu." "Zezwól na dostęp aplikacji lub usługi na otrzymywanie wywoływania zwrotnego o urządzeniach z aparatem, kiedy są one uruchamiane lub zamykane." - "Ta aplikacja może korzystać z wywoływania zwrotnego, kiedy urządzenie z aparatem jest uruchamiane (przez jaką aplikację) albo zamykane." + "Ta aplikacja może otrzymywać wywołania zwrotne, kiedy urządzenie z aparatem jest uruchamiane (przez jaką aplikację) albo zamykane." "sterowanie wibracjami" "Pozwala aplikacji na sterowanie wibracjami." "bezpośrednie wybieranie numerów telefonów" diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 2969ece60a16..b50d33fdda28 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -441,7 +441,7 @@ "fotiť a nakrúcať videá" "Táto aplikácia môže kedykoľvek fotografovať a zaznamenávať videá pomocou fotoaparátu." "Povoliť aplikácii alebo službe prijímať spätné volanie, keď sú zariadenia s kamerou otvorené alebo zatvorené." - "Táto aplikácia môže prijímať spätné volanie, keď je ľubovoľné zariadenie s kamerou otvorené (aplikáciou, ktorú určíte) alebo zatvorené." + "Táto aplikácia môže prijímať spätné volania pri otváraní alebo zatváraní ľubovoľného fotoaparátu (s infomáciou o aplikácii, ktorá to robí)." "ovládať vibrovanie" "Umožňuje aplikácii ovládať vibrácie." "priamo volať na telefónne čísla" diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 9e05a605b2e8..b2e78362d7ad 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -227,7 +227,7 @@ "Kyçja e ekranit" "Fik" "Urgjenca" - "Raporti i defekteve në kod" + "Raport i defektit në kod" "Jepi fund sesionit" "Pamja e ekranit" "Raporti i defekteve në kod" diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index c21dec380dce..3a91a357437f 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -435,7 +435,7 @@ "Kupiga picha na kurekodi video" "Programu hii inaweza kupiga picha na kurekodi video kwa kutumia kamera wakati wowote." "Ruhusu programu au huduma ipokee simu zinazopigwa tena kuhusu vifaa vya kamera kufunguliwa au kufungwa." - "Programu hii inaweza kupokea simu zinazopigwa tena wakati kifaa chochote cha kamera kinafunguliwa (kulingana na programu) au kufungwa." + "Programu hii inaweza kupokea misimbo ya kutekeleza wakati kifaa chochote cha kamera kinafunguliwa (na programu) au kufungwa." "Kudhibiti mtetemo" "Inaruhusu programu kudhibiti kitingishi." "piga simu moja kwa moja kwa nambari za simu" diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 2a1b066e2d20..1e0c02d33132 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -286,7 +286,7 @@ "இந்த ஆப்ஸை நீங்கள் உபயோகிக்கும்போது மட்டுமே இருப்பிடத்தை அணுகும்" "<b>%1$s</b> ஆப்ஸிற்கு <b>எப்போதும்</b> இந்தச் சாதனத்தின் இருப்பிட அணுகலை அனுமதிக்கவா?" "நீங்கள் ஆப்ஸை உபயோகிக்கும்போது மட்டுமே அது இருப்பிடத்தை அணுக முடியும்" - "கேலெண்டர்" + "Calendar" "கேலெண்டரை அணுகலாம்" "கேலெண்டரை அணுகுவதற்கு <b>%1$s</b> ஆப்ஸை அனுமதிக்கவா?" "SMS" @@ -435,8 +435,7 @@ "படங்கள் மற்றும் வீடியோக்களை எடுத்தல்" "இந்த ஆப்ஸ் எப்போது வேண்டுமானாலும் கேமராவைப் பயன்படுத்தி படங்களை எடுக்கலாம், வீடியோக்களை ரெக்கார்டு செய்யலாம்." "கேமரா சாதனங்கள் திறக்கப்படும்போதோ மூடப்படும்போதோ அது குறித்த கால்பேக்குகளைப் பெற ஒரு ஆப்ஸையோ சேவையையோ அனுமதிக்கவும்." - - + "எந்தக் கேமரா சாதனமும் (எந்த ஆப்ஸாலும்) திறக்கப்படும்போதோ மூடப்படும்போதோ இந்த ஆப்ஸால் கால்பேக்குகளைப் பெற முடியும்." "அதிர்வைக் கட்டுப்படுத்துதல்" "அதிர்வைக் கட்டுப்படுத்தப் ஆப்ஸை அனுமதிக்கிறது." "தொலைபேசி எண்களை நேரடியாக அழைத்தல்" @@ -751,7 +750,7 @@ "TTY TDD" "பணியிட மொபைல்" "பணியிட பேஜர்" - "உதவியாளர்" + "Assistant" "MMS" "பிரத்தியேகம்" "பிறந்தநாள்" @@ -1248,8 +1247,7 @@ "%1$s உடன் இணைக்க முடியவில்லை" "தனியுரிமை அமைப்புகளை மாற்ற தட்டி மீண்டும் முயலவும்" "தனியுரிமை அமைப்பை மாற்றவா?" - - + "இணைப்பதற்கு, பிரத்தியேக அடையாளங்காட்டியான உங்கள் சாதன MAC முகவரியை %1$s பயன்படுத்த வேண்டும். தற்போது ரேண்டம் ஆக்கப்பட்ட அடையாளங்காட்டியை இந்த நெட்வொர்க்கிற்கான உங்கள் தனியுரிமை அமைப்பு பயன்படுத்துகிறது. \n\nஇதனால் அருகில் இருக்கும் சாதனங்கள் உங்கள் சாதனத்தின் இருப்பிடத்தை டிராக் செய்ய அனுமதிக்கப்படக்கூடும்." "அமைப்பை மாற்று" "அமைப்பு புதுப்பிக்கப்பட்டது. மீண்டும் இணைக்கவும்." "தனியுரிமை அமைப்பை மாற்ற இயலவில்லை" diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 5c16fa31485f..7ec7574a9a33 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -286,7 +286,7 @@ "మీరు యాప్‌ను ఉపయోగిస్తున్నప్పుడు మాత్రమే స్థానానికి యాప్ యాక్సెస్ కలిగి ఉంటుంది" "ఈ పరికరం యొక్క లొకేషన్‌ను <b>అన్ని సమయాలలో</b> యాక్సెస్ చేయడానికి <b>%1$s</b>ను అనుమతించాలా?" "యాప్ ప్రస్తుతం మీరు ఆ యాప్‌ను ఉపయోగిస్తున్నప్పుడు మాత్రమే స్థానాన్ని యాక్సెస్ చేయగలుగుతుంది" - "క్యాలెండర్" + "Calendar" "మీ క్యాలెండర్‌ను యాక్సెస్ చేయడానికి" "మీ క్యాలెండర్‌ని యాక్సెస్ చేయడానికి <b>%1$s</b>ని అనుమతించాలా?" "SMS" @@ -435,8 +435,7 @@ "చిత్రాలు మరియు వీడియోలు తీయడం" "ఈ యాప్‌ కెమెరాను ఉపయోగించి ఎప్పుడైనా చిత్రాలను తీయగలదు మరియు వీడియోలను రికార్డ్ చేయగలదు." "కెమెరా పరికరాలు తెరుచుకుంటున్నప్పుడు లేదా మూసుకుంటున్నప్పుడు కాల్‌బ్యాక్‌లను స్వీకరించడానికి యాప్‌ను లేదా సర్వీస్‌ను అనుమతించండి." - - + "ఏదైనా కెమెరా పరికరం తెరుచుకుంటున్నప్పుడు (ఏదైనా యాప్ ద్వారా) లేదా మూసుకుంటున్నప్పుడు ఈ యాప్ కాల్‌బ్యాక్‌లను అందుకోగలదు." "వైబ్రేషన్‌ను నియంత్రించడం" "వైబ్రేటర్‌ను నియంత్రించడానికి యాప్‌ను అనుమతిస్తుంది." "నేరుగా కాల్ చేసే ఫోన్ నంబర్‌లు" @@ -751,7 +750,7 @@ "TTY TDD" "కార్యాలయ మొబైల్" "కార్యాలయ పేజర్" - "అసిస్టెంట్" + "Assistant" "MMS" "అనుకూలం" "పుట్టినరోజు" diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 5af675b400f5..4fdb7599639d 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -435,7 +435,7 @@ "ถ่ายภาพและวิดีโอ" "แอปนี้สามารถถ่ายภาพและวิดีโอด้วยกล้องได้ทุกเมื่อ" "อนุญาตให้แอปพลิเคชันหรือบริการได้รับโค้ดเรียกกลับเมื่อมีการเปิดหรือปิดอุปกรณ์กล้อง" - "แอปนี้จะได้รับโค้ดเรียกกลับเมื่อมีการปิดหรือเปิดอุปกรณ์กล้อง (แอปพลิเคชันที่เปิด)" + "แอปนี้จะได้รับโค้ดเรียกกลับเมื่อมีการปิดหรือเปิดอุปกรณ์กล้อง (โดยแอปพลิเคชันที่เปิด)" "ควบคุมการสั่นเตือน" "อนุญาตให้แอปพลิเคชันควบคุมการสั่นเตือน" "โทรติดต่อหมายเลขโทรศัพท์โดยตรง" diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index f46c157f1006..45f2dde9b376 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -435,7 +435,7 @@ "resim çekme ve görüntü kaydetme" "Bu uygulama, herhangi bir zamanda kamerayı kullanarak fotoğraf ve video çekebilir." "Bir uygulama veya hizmetin açılıp kapatılan kamera cihazları hakkında geri çağırmalar almasına izin verin." - "Bu uygulama, herhangi bir kamera cihazı açıldığında (herhangi bir uygulama tarafından) veya kapatıldığında geri çağırmalar alabilir." + "Bu uygulama, herhangi bir kamera cihazı açıldığında (kamerayı açan uygulama tarafından) veya kapatıldığında geri çağırmalar alabilir." "titreşimi denetleme" "Uygulamaya, titreşimi denetleme izni verir." "telefon numaralarına doğrudan çağrı yap" diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 32e520f0ae25..f70098ad1257 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -441,7 +441,7 @@ "фотограф. та знімати відео" "Цей додаток може будь-коли робити фотографії та записувати відео за допомогою камери." "Дозволити додатку або сервісу отримувати зворотні виклики щодо відкриття чи закриття камер." - "Цей додаток може отримувати зворотні виклики, коли будь-яка камера відкривається (з указанням додатка) чи закривається." + "Цей додаток може отримувати зворотні виклики, коли одна з камер вмикається (певним додатком) чи вимикається." "контролювати вібросигнал" "Дозволяє програмі контролювати вібросигнал." "прямо набирати номери тел." diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index 6e27035a5c56..a0f075f76716 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -227,7 +227,7 @@ "Ekran qulfi" "O‘chirish" "Favqulodda chaqiruv" - "Nosozlik haqida ma’lumot berish" + "Xatoliklar hisoboti" "Seansni yakunlash" "Skrinshot" "Xatoliklar hisoboti" diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 70b1df5261dc..fb78367ca1da 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -224,7 +224,7 @@ "Tùy chọn máy tính bảng" "Tùy chọn TV" "Tùy chọn điện thoại" - "Phương thức khoá màn hình" + "Cách khóa màn hình" "Tắt nguồn" "Khẩn cấp" "Báo cáo lỗi" diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 7ee5c8b5dcd7..aae5771e8b00 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -435,7 +435,7 @@ "拍摄照片和视频" "此应用可随时使用相机拍摄照片和录制视频。" "允许应用或服务接收与打开或关闭摄像头设备有关的回调。" - "此应用可在任何摄像头设备(被某些应用)打开或关闭时接收相应回调。" + "此应用可在任何摄像头设备(被某些应用)打开或关闭时收到相应回调。" "控制振动" "允许应用控制振动器。" "拨打电话" -- GitLab From 839f0944aa8e3114ffd86335547a966b586106d0 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 2 Apr 2020 20:57:45 -0700 Subject: [PATCH 204/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: I1ec2cd67b57dcc978ab42b69689a835ad0c619d4 --- packages/CarrierDefaultApp/res/values-fa/strings.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/CarrierDefaultApp/res/values-fa/strings.xml b/packages/CarrierDefaultApp/res/values-fa/strings.xml index 37a3de87ba01..5328a03d9646 100644 --- a/packages/CarrierDefaultApp/res/values-fa/strings.xml +++ b/packages/CarrierDefaultApp/res/values-fa/strings.xml @@ -6,9 +6,7 @@ "داده تلفن همراه تمام شده است" "داده شبکه تلفن همراه شما غیرفعال شده است" "‏برای رفتن به وب‌سایت %s، ضربه بزنید" - - - + "‏لطفاً با ارائه‌دهنده خدمات %s خود تماس بگیرید" "بدون اتصال داده دستگاه همراه" "‏افزودن طرح داده یا فراگردی ازطریق %s" "وضعیت داده تلفن همراه" -- GitLab From 8ddcc41d71c578bba41fb6ae3f511fb45361cd51 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 3 Apr 2020 10:01:03 -0700 Subject: [PATCH 205/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: I2b498e617088e6a5c8a9c2bbea197897b9b3e863 --- packages/Shell/res/values-it/strings.xml | 2 +- packages/Shell/res/values-or/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/Shell/res/values-it/strings.xml b/packages/Shell/res/values-it/strings.xml index 7d04eeb9165f..18ab908945ac 100644 --- a/packages/Shell/res/values-it/strings.xml +++ b/packages/Shell/res/values-it/strings.xml @@ -30,7 +30,7 @@ "Tocca per inviare la segnalazione del bug senza screenshot o attendi che lo screenshot sia completo" "Le segnalazioni di bug contengono dati recuperati da vari file di log del sistema e potrebbero includere dati considerati riservati (ad esempio dati relativi alla posizione e all\'utilizzo delle app). Condividi le segnalazioni di bug solo con persone e app attendibili." "Non mostrare più" - "Rapporti sui bug" + "Segnalazioni di bug" "Impossibile leggere il file relativo alla segnalazione di bug" "Impossibile aggiungere i dettagli della segnalazione di bug al file zip" "senza nome" diff --git a/packages/Shell/res/values-or/strings.xml b/packages/Shell/res/values-or/strings.xml index bd2b6cd6a740..517183972e4d 100644 --- a/packages/Shell/res/values-or/strings.xml +++ b/packages/Shell/res/values-or/strings.xml @@ -35,7 +35,7 @@ "ଜିପ୍‍ ଫାଇଲରେ ବଗ୍‍ ରିପୋର୍ଟ ବିବରଣୀ ଯୋଡ଼ାଯାଇପାରିଲା ନାହିଁ" "ବେନାମୀ" "ବିବରଣୀ" - "ସ୍କ୍ରୀନ୍‌ଶଟ୍‌" + "ସ୍କ୍ରିନ୍‌ସଟ୍‌" "ସଫଳତାପୂର୍ବକ ସ୍କ୍ରୀନଶଟ୍‍ ନିଆଗଲା" "ସ୍କ୍ରୀନ୍‍ଶଟ୍‍ ନିଆଯାଇପାରିଲା ନାହିଁ।" "ବଗ୍‍ ରିପୋର୍ଟ #%dର ବିବରଣୀ" -- GitLab From 19930103d8653ddcd0c28eead5b852218b6f9ee3 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 3 Apr 2020 10:18:47 -0700 Subject: [PATCH 206/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: I79ce54a0bef07969a91a96ed8451d73085e76fa6 --- packages/SystemUI/legacy/recents/res/values-es/strings.xml | 2 +- packages/SystemUI/legacy/recents/res/values-ta/strings.xml | 2 +- packages/SystemUI/legacy/recents/res/values-te/strings.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/legacy/recents/res/values-es/strings.xml b/packages/SystemUI/legacy/recents/res/values-es/strings.xml index 3f4a65cda27d..fc4efaf46442 100644 --- a/packages/SystemUI/legacy/recents/res/values-es/strings.xml +++ b/packages/SystemUI/legacy/recents/res/values-es/strings.xml @@ -25,7 +25,7 @@ "Se han ignorado todas las aplicaciones recientes." "Abre la información de la aplicación %s." "Iniciando la aplicación %s." - "No hay elementos recientes" + "No hay nada reciente" "Has borrado todo" "Información de la aplicación" "fijar pantalla" diff --git a/packages/SystemUI/legacy/recents/res/values-ta/strings.xml b/packages/SystemUI/legacy/recents/res/values-ta/strings.xml index dd1ceed72362..bc93a5564478 100644 --- a/packages/SystemUI/legacy/recents/res/values-ta/strings.xml +++ b/packages/SystemUI/legacy/recents/res/values-ta/strings.xml @@ -36,7 +36,7 @@ "\'திரைப் பிரிப்பைப்\' பயன்படுத்த இங்கே இழுக்கவும்" "கிடைமட்டமாகப் பிரி" "செங்குத்தாகப் பிரி" - "தனிப்பயன் விருப்பத்தில் பிரி" + "பிரத்தியேக விருப்பத்தில் பிரி" "திரையை மேற்புறமாகப் பிரிக்கும்" "திரையை இடப்புறமாகப் பிரிக்கும்" "திரையை வலப்புறமாகப் பிரிக்கும்" diff --git a/packages/SystemUI/legacy/recents/res/values-te/strings.xml b/packages/SystemUI/legacy/recents/res/values-te/strings.xml index 9f953acccd94..1928afe9289c 100644 --- a/packages/SystemUI/legacy/recents/res/values-te/strings.xml +++ b/packages/SystemUI/legacy/recents/res/values-te/strings.xml @@ -19,7 +19,7 @@ - "అవలోకనం." + "ఓవర్‌వ్యూ." "%sని తీసివేయండి." "%s తీసివేయబడింది." "అన్ని ఇటీవలి యాప్‌లు తీసివేయబడ్డాయి." -- GitLab From 1cb36d018b3c2e84297828d41f1a2445a9facf8e Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 3 Apr 2020 10:37:35 -0700 Subject: [PATCH 207/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: I21548478d4d9df10bb278663862b8cbd9ca15326 --- packages/SystemUI/res/values-af/strings.xml | 2 +- packages/SystemUI/res/values-ar/strings.xml | 58 +++++++++---------- packages/SystemUI/res/values-as/strings.xml | 4 +- .../SystemUI/res/values-b+sr+Latn/strings.xml | 2 +- packages/SystemUI/res/values-be/strings.xml | 6 +- packages/SystemUI/res/values-bg/strings.xml | 2 +- packages/SystemUI/res/values-bn/strings.xml | 4 +- packages/SystemUI/res/values-ca/strings.xml | 26 ++++----- packages/SystemUI/res/values-de/strings.xml | 8 +-- packages/SystemUI/res/values-el/strings.xml | 2 +- .../SystemUI/res/values-es-rUS/strings.xml | 4 +- packages/SystemUI/res/values-es/strings.xml | 2 +- packages/SystemUI/res/values-eu/strings.xml | 8 +-- packages/SystemUI/res/values-fa/strings.xml | 2 +- .../SystemUI/res/values-fr-rCA/strings.xml | 4 +- packages/SystemUI/res/values-gl/strings.xml | 2 +- packages/SystemUI/res/values-gu/strings.xml | 2 +- packages/SystemUI/res/values-hi/strings.xml | 4 +- packages/SystemUI/res/values-hu/strings.xml | 2 +- packages/SystemUI/res/values-iw/strings.xml | 2 +- packages/SystemUI/res/values-ja/strings.xml | 2 +- packages/SystemUI/res/values-ka/strings.xml | 2 +- packages/SystemUI/res/values-kn/strings.xml | 2 +- packages/SystemUI/res/values-ky/strings.xml | 40 ++++++------- packages/SystemUI/res/values-mk/strings.xml | 6 +- packages/SystemUI/res/values-ml/strings.xml | 4 +- packages/SystemUI/res/values-mr/strings.xml | 2 +- packages/SystemUI/res/values-my/strings.xml | 2 +- packages/SystemUI/res/values-ne/strings.xml | 2 +- packages/SystemUI/res/values-or/strings.xml | 2 +- packages/SystemUI/res/values-pa/strings.xml | 4 +- packages/SystemUI/res/values-pl/strings.xml | 8 +-- .../SystemUI/res/values-pt-rPT/strings.xml | 2 +- packages/SystemUI/res/values-ro/strings.xml | 2 +- packages/SystemUI/res/values-sl/strings.xml | 2 +- packages/SystemUI/res/values-sq/strings.xml | 2 +- packages/SystemUI/res/values-sr/strings.xml | 2 +- packages/SystemUI/res/values-sw/strings.xml | 8 +-- packages/SystemUI/res/values-ta/strings.xml | 26 ++++----- packages/SystemUI/res/values-te/strings.xml | 12 ++-- packages/SystemUI/res/values-uk/strings.xml | 4 +- packages/SystemUI/res/values-ur/strings.xml | 2 +- packages/SystemUI/res/values-uz/strings.xml | 6 +- packages/SystemUI/res/values-vi/strings.xml | 4 +- packages/SystemUI/res/values-zu/strings.xml | 2 +- 45 files changed, 145 insertions(+), 151 deletions(-) diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 2b9b169dec0c..7390b3e575ed 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -528,7 +528,7 @@ "Toestel sal gesluit bly totdat jy dit handmatig ontsluit" "Kry kennisgewings vinniger" "Sien hulle voordat jy ontsluit" - "Nee dankie" + "Nee, dankie" "Stel op" "%1$s. %2$s" "Skakel nou af" diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 9548551d6ba6..16ed86cede9a 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -35,7 +35,7 @@ "الإعدادات" "هل تريد تفعيل ميزة توفير شحن البطارية؟" "لمحة حول ميزة \"توفير شحن البطارية\"" - "تشغيل" + "تفعيل" "هل تريد تفعيل ميزة توفير شحن البطارية؟" "الإعدادات" "Wi-Fi" @@ -60,7 +60,7 @@ "السماح دائمًا من هذا الكمبيوتر" "سماح" "‏لا يُسمح بتصحيح أخطاء USB" - "‏لا يمكن للمستخدم الذي يسجّل دخوله حاليًا إلى هذا الجهاز تشغيل تصحيح أخطاء USB. لاستخدام هذه الميزة، يمكنك التبديل إلى المستخدم الأساسي." + "‏لا يمكن للمستخدم الذي يسجّل دخوله حاليًا إلى هذا الجهاز تفعيل تصحيح الأخطاء USB. لاستخدام هذه الميزة، يمكنك التبديل إلى المستخدم الأساسي." "‏تمّ إيقاف منفذ USB" "‏لحماية جهازك من السوائل أو الشوائب، سيتمّ إيقاف منفذ USB ولن يتم رصد أيّ ملحقات.\n\nوسيتمّ إعلامك عندما يُسمح باستخدام منفذ USB مرة أخرى." "‏تم تفعيل منفذ USB لاكتشاف أجهزة الشحن والملحقات." @@ -187,13 +187,13 @@ "Wi-Fi" "‏ليست هناك شريحة SIM." "بيانات الجوّال" - "تشغيل بيانات الجوال" + "تفعيل بيانات الجوال" "تم إيقاف بيانات الجوال" "لم يتم الضبط على استخدام البيانات" "إيقاف" "التوصيل عبر البلوتوث" "وضع الطائرة." - "‏الشبكة الافتراضية الخاصة (VPN) قيد التشغيل." + "‏الشبكة الافتراضية الخاصة (VPN) قيد التفعيل." "‏ليس هناك شريحة SIM." "جارٍ تغيير شبكة مشغِّل شبكة الجوّال." "فتح تفاصيل البطارية" @@ -223,13 +223,13 @@ "إغلاق" "%1$s." "‏تم إيقاف Wifi." - "‏تم تشغيل Wifi." + "‏تم تفعيل Wifi." "الجوّال %1$s. %2$s. %3$s." "البطارية %s." "إيقاف وضع الطائرة." - "تشغيل وضع الطائرة." + "تفعيل وضع الطائرة." "تم إيقاف وضع الطائرة." - "تم تشغيل وضع الطائرة." + "تم تفعيل وضع الطائرة." "كتم الصوت تمامًا" "المنبِّهات فقط" "عدم الإزعاج" @@ -237,35 +237,35 @@ "تم تفعيل \"عدم الإزعاج\"." "البلوتوث." "إيقاف البلوتوث." - "تشغيل البلوتوث." + "تفعيل البلوتوث." "جارٍ توصيل البلوتوث." "تم توصيل البلوتوث." "تم إيقاف البلوتوث." - "تم تشغيل البلوتوث." + "تم تفعيل البلوتوث." "إيقاف الإبلاغ عن الموقع." - "تشغيل الإبلاغ عن الموقع." + "تفعيل ميزة الإبلاغ عن الموقع الجغرافي." "تم إيقاف الإبلاغ عن الموقع." - "تم تشغيل الإبلاغ عن الموقع." + "تم تفعيل ميزة الإبلاغ عن الموقع الجغرافي." "تم ضبط المنبّه على %s." "إغلاق اللوحة." "وقت أكثر." "وقت أقل." "إيقاف الفلاش." "تطبيق المصباح اليدوي غير متاح." - "تشغيل الفلاش." + "تفعيل الفلاش." "تم إيقاف الفلاش." - "تم تشغيل الفلاش." + "تم تفعيل الفلاش." "تم إيقاف انعكاس اللون." - "تم تشغيل انعكاس اللون." + "تم تفعيل انعكاس اللون." "تم إيقاف نقطة اتصال الجوّال." - "تم تشغيل نقطة اتصال الجوّال." + "تم تفعيل نقطة اتصال الجوّال." "توقف إرسال الشاشة." "وضع العمل معطَّل." "وضع العمل قيد التشغيل." "تم إيقاف وضع العمل." - "تم تشغيل وضع العمل." + "تم تفعيل وضع العمل." "تم إيقاف توفير البيانات." - "تم تشغيل توفير البيانات." + "تم تفعيل توفير البيانات." "تم إيقاف \"خصوصية أجهزة الاستشعار\"." "تم تفعيل \"خصوصية أجهزة الاستشعار\"." "سطوع الشاشة" @@ -339,7 +339,7 @@ "ليست متصلة" "لا تتوفر شبكة" "‏إيقاف Wi-Fi" - "‏تم تشغيل Wi-Fi" + "‏تم تفعيل Wi-Fi" "‏لا تتوفر أي شبكة Wi-Fi" "جارٍ التفعيل…" "بث الشاشة" @@ -543,7 +543,7 @@ "لا، شكرًا" "إعداد" "%1$s. %2$s" - "إيقاف التشغيل الآن" + "إيقاف التفعيل الآن" "إعدادات الصوت" "توسيع" "تصغير" @@ -636,9 +636,9 @@ "إعادة ترتيب الإعدادات السريعة" "عرض السطوع في الإعدادات السريعة" "إعدادات تجريبية" - "تشغيل البلوتوث؟" - "لتوصيل لوحة المفاتيح بالجهاز اللوحي، يلزمك تشغيل بلوتوث أولاً." - "تشغيل" + "تفعيل البلوتوث؟" + "لتوصيل لوحة المفاتيح بالجهاز اللوحي، يلزمك تفعيل بلوتوث أولاً." + "تفعيل" "عرض الإشعارات بدون تنبيه صوتي" "حظر كل الإشعارات" "عدم كتم التنبيه الصوتي" @@ -734,7 +734,7 @@ "إيقاف" "التالي" "السابق" - "إرجاع" + "ترجيع" "تقديم سريع" "Page Up" "Page Down" @@ -771,7 +771,7 @@ "تم توصيل سماعات رأس" "تم توصيل سماعات رأس" "توفير البيانات" - "تم تشغيل توفير البيانات" + "تم تفعيل توفير البيانات" "تم إيقاف توفير البيانات" "مفعّل" "إيقاف" @@ -862,12 +862,12 @@ "اسحب لأسفل للإلغاء" "القائمة" "%s يظهر في صورة داخل صورة" - "إذا كنت لا تريد أن يستخدم %s هذه الميزة، فانقر لفتح الإعدادات، ثم أوقِف تشغيل هذه الميزة." + "إذا كنت لا تريد أن يستخدم %s هذه الميزة، فانقر لفتح الإعدادات، ثم أوقِف تفعيل هذه الميزة." "تشغيل" "إيقاف مؤقت" "التخطي إلى التالي" "التخطي إلى السابق" - "تم إيقاف تشغيل الهاتف بسبب الحرارة" + "تم إيقاف الهاتف بسبب الحرارة" "يعمل هاتفك الآن بشكل طبيعي" "ارتفعت درجة حرارة هاتفك بشدة، لذا تم إيقاف تشغيله لخفض درجة حرارته. يعمل هاتفك الآن بشكل طبيعي.\n\nقد ترتفع بشدة درجة حرارة هاتفك إذا:\n • استخدمت تطبيقات كثيفة الاستخدام لموارد الجهاز (مثل الألعاب أو الفيديو أو تطبيقات التنقل)\n • نزَّلت أو حمَّلت ملفات كبيرة الحجم\n • استخدمت هاتفك وسط أجواء مرتفعة الحرارة" "تزداد درجة حرارة الهاتف" @@ -908,9 +908,9 @@ "‏تم إيقاف شبكة Wi-Fi" "تم إيقاف البلوتوث." "تم إيقاف وضع \"عدم الإزعاج\"" - "تم تشغيل وضع \"عدم الإزعاج\" بواسطة قاعدة تلقائية (%s)." - "تم تشغيل وضع \"عدم الإزعاج\" بواسطة تطبيق (%s)." - "تم تشغيل وضع \"عدم الإزعاج\" بواسطة قاعدة تلقائية أو تطبيق." + "تم تفعيل وضع \"عدم الإزعاج\" بواسطة قاعدة تلقائية (%s)." + "تم تفعيل وضع \"عدم الإزعاج\" بواسطة تطبيق (%s)." + "تم تفعيل وضع \"عدم الإزعاج\" بواسطة قاعدة تلقائية أو تطبيق." "حتى %s" "الإبقاء على الإعدادات" "استبدال" diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 24511313913e..3f3627b0fea0 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -199,7 +199,7 @@ "বেটাৰিৰ বিৱৰণসমূহ খোলক" "%d শতাংশ বেটাৰি।" "আপোনাৰ ব্যৱহাৰৰ ওপৰত ভিত্তি কৰি বেটাৰী %1$s শতাংশ, প্ৰায় %2$s বাকী আছে" - "বেটাৰি চ্চাৰ্জ কৰি থকা হৈছে, %d শতাংশ।" + "বেটাৰি চাৰ্জ হৈ আছে, %d শতাংশ।" "ছিষ্টেমৰ ছেটিংসমূহ৷" "জাননীসমূহ।" "সকলো জাননীবোৰ চাওক" @@ -739,7 +739,7 @@ "এছএমএছ" "সংগীত" "YouTube" - "কেলেণ্ডাৰ" + "Calendar" "ভলিউম নিয়ন্ত্ৰণৰ সৈতে দেখুৱাওক" "অসুবিধা নিদিব" "ভলিউম বুটামসমূহৰ শ্বৰ্টকাট" diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 8f45be38b269..7710fa9162af 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -199,7 +199,7 @@ "Otvori detalje o bateriji" "Baterija je na %d posto." "Baterija je na %1$s posto, preostalo vreme na osnovu korišćenja je %2$s" - "Baterija se puni, %d%%." + "Baterija se puni, %d posto." "Sistemska podešavanja." "Obaveštenja." "Pogledajte sva obaveštenja" diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index f5c5cdf37ef3..51f44cf74501 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -197,11 +197,9 @@ "Няма SIM-карты." "Змяненне аператара сеткі" "Паказаць падрабязную інфармацыю пра акумулятар" - - - + "Працэнт зараду акумулятара: %d." "Зарад акумулятара ў працэнтах: %1$s. Пры такім выкарыстанні яго хопіць прыблізна на %2$s" - "Зарадка акумулятара: %d%%." + "Акумулятар зараджаецца. Бягучы зарад: %d%%." "Сістэмныя налады." "Апавяшчэнні." "Паказаць усе апавяшчэнні" diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 027c8df45c01..75516e5583f8 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -199,7 +199,7 @@ "Отваряне на подробностите за батерията" "%d процента батерия." "Батерията е на %1$s процента. Още около %2$s въз основа на използването" - "Батерията се зарежда – %d%%." + "Батерията се зарежда, %d%%." "Системни настройки." "Известия." "Вижте всички известия" diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 62d0007b6410..1e75343890f4 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -199,7 +199,7 @@ "ব্যাটারির বিশদ বিবরণ খুলুন" "%d শতাংশ ব্যাটারি রয়েছে৷" "ব্যাটারি %1$s শতাংশ, বর্তমান ব্যবহারের উপর ভিত্তি করে আর %2$s চলবে" - "ব্যাটারি চার্জ হচ্ছে, %d শতাংশ৷" + "ব্যাটারি চার্জ হচ্ছে, এখন %d শতাংশ চার্জ আছে৷" "সিস্টেম সেটিংস৷" "বিজ্ঞপ্তি৷" "সমস্ত বিজ্ঞপ্তি দেখুন" @@ -739,7 +739,7 @@ "SMS" "সংগীত" "YouTube" - "ক্যালেন্ডার" + "Calendar" "ভলিউম নিয়ন্ত্রণ সহ দেখান" "বিরক্ত করবে না" "ভলিউম বোতামের শর্টকাট" diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 797fa23639a9..924af81e1fd1 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -199,7 +199,7 @@ "Obre els detalls de la bateria" "%d per cent de bateria." "%1$s per cent de bateria amb aproximadament %2$s de temps restant segons l\'ús que en fas" - "La bateria s\'està carregant, %d%%." + "La bateria s\'està carregant (%d%%)." "Configuració del sistema." "Notificacions." "Mostra totes les notificacions" @@ -370,7 +370,7 @@ "Dades utilitzades: %s" "Límit: %s" "Advertiment: %s" - "Perfil professional" + "Perfil de treball" "Llum nocturna" "Al vespre" "Fins a l\'alba" @@ -479,12 +479,12 @@ "%1$s gestiona el dispositiu" "Dispositiu gestionat per la teva organització i connectat a xarxes VPN" "%1$s gestiona el dispositiu, que està connectat a xarxes VPN" - "És possible que la teva organització supervisi el trànsit de xarxa al teu perfil professional" - "És possible que %1$s supervisi el trànsit de xarxa del teu perfil professional" + "És possible que la teva organització supervisi el trànsit de xarxa al teu perfil de treball" + "És possible que %1$s supervisi el trànsit de xarxa del teu perfil de treball" "És possible que la xarxa estigui supervisada" "El dispositiu està connectat a xarxes VPN" - "El perfil professional està connectat a %1$s" - "El perfil professional està connectat a %1$s" + "El perfil de treball està connectat a %1$s" + "El perfil de treball està connectat a %1$s" "El dispositiu està connectat a %1$s" "Gestió del dispositiu" "Supervisió del perfil" @@ -498,12 +498,12 @@ "%1$s gestiona el dispositiu.\n\nL\'administrador pot supervisar i gestionar la configuració, l\'accés corporatiu, les aplicacions, les dades associades al dispositiu, inclosa la informació d\'ubicació.\n\nPer obtenir més informació, contacta amb l\'administrador." "La teva organització gestiona el dispositiu.\n\nL\'administrador pot supervisar i gestionar la configuració, l\'accés corporatiu, les aplicacions, les dades associades al dispositiu, inclosa la informació d\'ubicació.\n\nPer obtenir més informació, contacta amb l\'administrador." "La teva organització ha instal·lat una autoritat de certificació en aquest dispositiu. És possible que el trànsit a la xarxa segura se supervisi o es modifiqui." - "La teva organització ha instal·lat una autoritat de certificació al teu perfil professional. És possible que el trànsit de xarxa segura se supervisi o es modifiqui." + "La teva organització ha instal·lat una autoritat de certificació al teu perfil de treball. És possible que el trànsit de xarxa segura se supervisi o es modifiqui." "S\'ha instal·lat una autoritat de certificació en aquest dispositiu. És possible que el trànsit de xarxa segura se supervisi o es modifiqui." "L\'administrador ha activat el registre de xarxa, que supervisa el trànsit del teu dispositiu." "Estàs connectat a %1$s, que pot supervisar la teva activitat a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web." "Estàs connectat a %1$s i %2$s, que poden supervisar la teva activitat a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web." - "El teu perfil professional està connectat a %1$s, que pot supervisar la teva activitat a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web." + "El teu perfil de treball està connectat a %1$s, que pot supervisar la teva activitat a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web." "El teu perfil personal està connectat a %1$s,que pot supervisar la teva activitat a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web." "El teu dispositiu està gestionat per %1$s." "%1$s utilitza %2$s per gestionar el teu dispositiu." @@ -517,13 +517,13 @@ "Obre les credencials de confiança" "L\'administrador ha activat el registre de xarxa, que supervisa el trànsit del teu dispositiu.\n\nPer obtenir més informació, contacta amb l\'administrador." "Has donat permís a una aplicació per configurar una connexió VPN.\n\nAquesta aplicació pot supervisar el dispositiu i l\'activitat a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web." - "%1$s gestiona el teu perfil professional.\n\nL\'administrador pot supervisar la teva activitat a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web.\n\nPer obtenir més informació, contacta amb l\'administrador.\n\nA més, estàs connectat a una VPN, que també pot supervisar la teva activitat a la xarxa." + "%1$s gestiona el teu perfil de treball.\n\nL\'administrador pot supervisar la teva activitat a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web.\n\nPer obtenir més informació, contacta amb l\'administrador.\n\nA més, estàs connectat a una VPN, que també pot supervisar la teva activitat a la xarxa." "VPN" "Estàs connectat a %1$s, que pot supervisar la teva activitat a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web." "Estàs connectat a %1$s, que pot supervisar la teva activitat personal a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web." "Estàs connectat a %1$s, que pot supervisar la teva activitat personal a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web." - "%1$s gestiona el teu perfil professional. El perfil està connectat a %2$s, que pot supervisar la teva activitat a la xarxa de treball, com ara els correus electrònics, les aplicacions i els llocs web.\n\nPer obtenir més informació, contacta amb l\'administrador." - "%1$s gestiona el teu perfil professional. El perfil està connectat a %2$s, que pot supervisar la teva activitat a la xarxa de treball, com ara els correus electrònics, les aplicacions i els llocs web.\n\nTambé estàs connectat a %3$s, que pot supervisar la teva activitat personal a la xarxa." + "%1$s gestiona el teu perfil de treball. El perfil està connectat a %2$s, que pot supervisar la teva activitat a la xarxa de treball, com ara els correus electrònics, les aplicacions i els llocs web.\n\nPer obtenir més informació, contacta amb l\'administrador." + "%1$s gestiona el teu perfil de treball. El perfil està connectat a %2$s, que pot supervisar la teva activitat a la xarxa de treball, com ara els correus electrònics, les aplicacions i els llocs web.\n\nTambé estàs connectat a %3$s, que pot supervisar la teva activitat personal a la xarxa." "Desbloquejat per TrustAgent" "El dispositiu continuarà bloquejat fins que no el desbloquegis manualment." "Rep notificacions més ràpidament" @@ -600,7 +600,7 @@ "Mostra el mode de demostració" "Ethernet" "Alarma" - "Perfil professional" + "Perfil de treball" "Mode d\'avió" "Afegeix un mosaic" "Mosaic d\'emissió" @@ -610,7 +610,7 @@ "Dia: %1$s" "Configuració ràpida, %s." "Punt d\'accés Wi-Fi" - "Perfil professional" + "Perfil de treball" "Diversió per a uns quants, però no per a tothom" "El Personalitzador d\'interfície d\'usuari presenta opcions addicionals per canviar i personalitzar la interfície d\'usuari d\'Android. És possible que aquestes funcions experimentals canviïn, deixin de funcionar o desapareguin en versions futures. Continua amb precaució." "És possible que aquestes funcions experimentals canviïn, deixin de funcionar o desapareguin en versions futures. Continua amb precaució." diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 08fa095b8e44..531f1f7b2912 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -197,13 +197,9 @@ "Keine SIM-Karte" "Mobilfunknetzwerk wird gewechselt" "Akkudetails öffnen" - - - + "Akku bei %d Prozent." "Akku bei %1$s Prozent. Bei deinem Nutzungsmuster hast du noch Strom für etwa %2$s" - - - + "Akku wird aufgeladen, %d Prozent." "Systemeinstellungen" "Benachrichtigungen" "Alle Benachrichtigungen ansehen" diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index b3bf4e428515..f0221b661643 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -199,7 +199,7 @@ "Άνοιγμα λεπτομερειών μπαταρίας" "Μπαταρία %d τοις εκατό." "Μπαταρία στο %1$s τοις εκατό. Περίπου %2$s ακόμη, βάσει της χρήσης σας" - "Φόρτιση μπαταρίας, %d%% τοις εκατό." + "Φόρτιση μπαταρίας: %d%%." "Ρυθμίσεις συστήματος." "Ειδοποιήσεις." "Δείτε όλες τις ειδοποιήσεις" diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 015d62f8e2c3..3f6d40544808 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -199,7 +199,7 @@ "Abrir detalles de la batería" "Batería %d por ciento" "Batería: %1$s por ciento; tiempo restante: aproximadamente %2$s en función del uso" - "Cargando batería: %d%%" + "Batería cargando: %d%%" "Configuración del sistema" "Notificaciones" "Ver todas las notificaciones" @@ -401,7 +401,7 @@ "Esta acción bloquea TODOS los sonidos y las vibraciones, incluso los que provienen de alarmas, música, videos y juegos." "+%d" "Notificaciones menos urgentes abajo" - "Presionar de nuevo para abrir" + "Presiona de nuevo para abrir" "Desliza el dedo hacia arriba para abrir" "Desliza el dedo hacia arriba para volver a intentarlo" "Vuelve a alinear el teléfono para cargarlo más rápido" diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 01200b782b21..c0762ce4caa1 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -199,7 +199,7 @@ "Abrir detalles de la batería" "%d por ciento de batería" "Queda un %1$s por ciento de batería (%2$s aproximadamente según tu uso)" - "Batería cargando (%d %%)." + "Batería cargándose (%d %%)." "Ajustes del sistema" "Notificaciones" "Ver todas las notificaciones" diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 4362e8d5b56d..39ed82097696 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -199,7 +199,7 @@ "Ireki bateriaren xehetasunak" "Bateriaren karga: %d." "Bateriak ehuneko %1$s dauka kargatuta. Zure erabilera kontuan izanda, %2$s inguru gelditzen zaizkio." - "Kargatzen ari da bateria. %% %d arte kargatu da oraingoz." + "Kargatzen ari da bateria. Ehuneko %d arte kargatu da oraingoz." "Sistemaren ezarpenak." "Jakinarazpenak." "Ikusi jakinarazpen guztiak" @@ -343,7 +343,7 @@ "Izenik gabeko gailua" "Igortzeko prest" "Ez dago gailurik erabilgarri" - "Ez zaude konektatuta Wi-Fi sarera" + "Ez zaude konektatuta wifi-sarera" "Distira" "AUTOMATIKOA" "Alderantzikatu koloreak" @@ -748,7 +748,7 @@ "Erlojua" "Mikrofonodun entzungailua" "Ireki ezarpenak" - "Aurikularrak konektatu dira" + "Entzungailuak konektatu dira" "Mikrofonodun entzungailua konektatu da" "Datu-aurrezlea" "Aktibatuta dago datu-aurrezlea" @@ -903,7 +903,7 @@ "%2$s aplikazioaren zatiak erakusteko baimena eman nahi diozu %1$s aplikazioari?" "- %1$s aplikazioaren informazioa irakur dezake." "- %1$s aplikazioan ekintzak gauza ditzake." - "Baimendu %1$s aplikazioari edozein aplikazioren zatiak erakustea" + "Eman aplikazio guztien zatiak erakusteko baimena %1$s aplikazioari" "Baimendu" "Ukatu" "Sakatu bateria-aurrezlea noiz aktibatu antolatzeko" diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 5207cfda2202..354e7190af12 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -466,7 +466,7 @@ "اعلان‌های بی‌صدا" "پاک کردن همه اعلان‌های بی‌صدا" "اعلان‌ها توسط «مزاحم نشوید» موقتاً متوقف شدند" - "اکنون شروع شود" + "اکنون شروع کنید" "اعلانی موجود نیست" "شاید نمایه کنترل شود" "ممکن است شبکه کنترل شود" diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index afc11f3de77a..70f41b840328 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -199,7 +199,7 @@ "Ouvrir les détails de la pile" "Pile : %d pour cent" "Pile chargée à %1$s pour cent (environ %2$s d\'autonomie en fonction de votre usage)" - "La pile est en cours de charge : %d %%." + "Pile en charge : %d %%." "Paramètres système" "Notifications" "Afficher toutes les notifications" @@ -782,7 +782,7 @@ "Code de touche droit" "Icône à gauche" "Icône droite" - "Maint. doigt sur écran, puis glissez-le pour ajouter tuiles" + "Sélectionnez et faites glisser les tuiles pour les ajouter" "Maint. doigt sur l\'écran, puis glissez-le pour réorg. tuiles" "Faites glisser les tuiles ici pour les supprimer" "Vous avez besoin d\'au moins %1$d tuiles" diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 66f31bcc34d7..c2609a5baf87 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -199,7 +199,7 @@ "Abrir os detalles da batería" "Carga da batería: %d por cento." "Batería: %1$s por cento, durará %2$s co uso que adoitas darlle" - "A batería está cargando. Nivel: %d %%." + "Batería cargando. Nivel: %d por cento." "Configuración do sistema" "Notificacións" "Ver todas as notificacións" diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index d4fdfb19e3a3..20f2a9ae63b1 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -739,7 +739,7 @@ "SMS" "સંગીત" "YouTube" - "કૅલેન્ડર" + "Calendar" "વૉલ્યૂમ નિયંત્રણ સાથે બતાવો" "ખલેલ પાડશો નહીં" "વૉલ્યૂમ બટન્સ શૉર્ટકટ" diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 9e35f99dbc50..c16da74bc11e 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -199,7 +199,9 @@ "बैटरी का विवरण खोलें" "%d प्रति‍शत बैटरी." "%1$s प्रतिशत बैटरी बची है और आपके इस्तेमाल के हिसाब से यह %2$s में खत्म हो जाएगी" - "बैटरी चार्ज हो रही है, %d%%." + + + "सिस्टम सेटिंग." "सूचनाएं." "पूरी सूचनाएं देखें" diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 574b4bb04e68..e20a326d57ed 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -199,7 +199,7 @@ "Az akkumulátorral kapcsolatos részletek megnyitása" "Akkumulátor %d százalék." "Az akkumulátor %1$s százalékon áll, a használati adatok alapján körülbelül %2$s múlva merül le" - "Akkumulátor töltése folyamatban, %d százalék." + "Tölt az akkumulátor, %d százalék." "Rendszerbeállítások" "Értesítések" "Összes értesítés megtekintése" diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 9ef82f5fe6e0..fc531e74dd78 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -199,7 +199,7 @@ "פתיחת פרטי סוללה" "%d אחוזים של סוללה." "רמת הטעינה בסוללה: %1$s אחוזים, הזמן הנותר המשוער על סמך השימוש שלך:%2$s" - "טעינת סוללה, %d%%." + "הסוללה בטעינה, %d%%." "הגדרות מערכת" "התראות" "הצגת כל ההתראות" diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 7e3ee3660819..76fec33828eb 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -199,7 +199,7 @@ "電池の詳細情報を開きます" "電池残量: %dパーセント" "電池残量: %1$s、およそ %2$s に電池切れ(使用状況に基づく)" - "電池充電中: %d%%" + "電池充電中: %dパーセント" "システム設定。" "通知。" "通知をすべて表示" diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index e13218641396..22baf2f9ba8d 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -199,7 +199,7 @@ "ბატარეის დეტალების გახსნა" "ბატარეა: %d პროცენტი." "ბატარეა %1$s პროცენტზეა, მოხმარების გათვალისწინებით დარჩა დაახლოებით %2$s" - "ბატარეა იტენება, %d %%." + "ბატარეა იტენება. ამჟამად არის %d პროცენტი." "სისტემის პარამეტრები." "შეტყობინებები" "ყველა შეტყობინების ნახვა" diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 712dca2748c5..5d9e7082656b 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -739,7 +739,7 @@ "ಎಸ್ಎಂಎಸ್" "ಸಂಗೀತ" "YouTube" - "ಕ್ಯಾಲೆಂಡರ್" + "Calendar" "ವಾಲ್ಯೂಮ್ ನಿಯಂತ್ರಣಗಳ ಜೊತೆಗೆ ತೋರಿಸು" "ಅಡಚಣೆ ಮಾಡಬೇಡ" "ವಾಲ್ಯೂಮ್ ಬಟನ್‌ಗಳ ಶಾರ್ಟ್‌ಕಟ್‌" diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 47b280a9effc..ee9ccc57cc4a 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -75,7 +75,7 @@ "Скриншотуңузду көрүү үчүн таптап коюңуз" "Скриншот сакталган жок" "Скриншотту кайра тартып көрүңүз" - "Сактагычта бош орун аз болгондуктан скриншот сакталбай жатат" + "Сактагычта бош орун аз болгондуктан, скриншот сакталбай жатат" "Скриншот тартууга колдонмо же ишканаңыз тыюу салган." "Экранды жаздыруу" "Экранды жаздыруу сеансы боюнча учурдагы билдирме" @@ -120,7 +120,7 @@ "Ырастоо" "Кайталоо" "Бош жер калып калды, аутентификацияны жокко чыгаруу үчүн таптап коюңуз" - "Кайра аракет кылыңыз" + "Кайталап көрүңүз" "Жүзүңүз изделүүдө" "Жүздүн аныктыгы текшерилди" "Ырасталды" @@ -159,7 +159,7 @@ "Ethernet ажырады." "Ethernet туташты." "Сигнал жок." - "Байланыш жок." + "Интернет жок." "Таякча жок." "Бир таякча." "Эки таякча." @@ -202,7 +202,7 @@ "Батарея кубатталууда, %d%%." "Система тууралоолору." "Билдирмелер" - "Бардык эскертмелерди көрүү" + "Бардык билдирмелерди көрүү" "Эскертмелерди тазалоо." "GPS жандырылган." "GPS байланышууда." @@ -213,7 +213,7 @@ - "Эскертме жок кылынды." + "Эскертме өчүрүлдү." "Билдирмелер тактасы." "Тез тууралоолор." "Кулпуланган экран." @@ -280,7 +280,7 @@ "GPS боюнча аныкталган жайгашуу" "Жайгаштыруу талаптары иштелүүдө" "\"Сенсорлорду өчүрүүнү\" активдештирүү" - "Бардык эскертмелерди тазалоо." + "Бардык билдирмелерди өчүрүү." "+ %s" Дагы %s эскертме бар. @@ -332,7 +332,7 @@ "Колдонуучу" "Жаңы колдонуучу" "Wi-Fi" - "Байланыш жок" + "Интернет жок" "Желе жок" "Wi-Fi өчүк" "Wi-Fi күйүк" @@ -400,7 +400,7 @@ "Ушуну менен эскертүүлөрдүн, музыканын, видеолордун жана оюндардын үндөрү жана дирилдөөлөрү өчүрүлөт. Бирок телефон менен сүйлөшө бересиз." "Ушуну менен эскертүүлөрдүн, музыканын, видеолордун жана оюндардын үндөрү жана дирилдөөлөрү өчүрүлөт." "+%d" - "Анчейин шашылыш эмес эскертмелер төмөндө" + "Анчейин шашылыш эмес билдирмелер төмөндө" "Ачуу үчүн кайра таптап коюңуз" "Ачуу үчүн өйдө сүрүңүз" "Кайталоо үчүн экранды өйдө сүрүңүз" @@ -432,7 +432,7 @@ "Конок кошуу" "Конокту алып салуу" "Конокту алып саласызбы?" - "Бул сеанстагы бардык колдонмолор жана дайындар жок кылынат." + "Бул сеанстагы бардык колдонмолор жана дайындар өчүрүлөт." "Алып салуу" "Кайтып келишиңиз менен, конок!" "Сеансыңызды улантасызбы?" @@ -452,7 +452,7 @@ Бир колдонуучуну гана кошууга болот. "Колдонуучу алынып салынсынбы?" - "Бул колдонуучунун бардык колдонмолору жана дайындары жок кылынат." + "Бул колдонуучунун бардык колдонмолору жана дайындары өчүрүлөт." "Алып салуу" "Батареяны үнөмдөгүч режими күйүк" "Иштин майнаптуулугун начарлатып, фондук дайындарды чектейт" @@ -617,7 +617,7 @@ "Түшүндүм" "Куттуктайбыз! Жөндөөлөргө System UI Tuner кошулду" "Жөндөөлөрдөн алып салуу" - "System UI Tuner Жөндөөлөрдөн алынып салынып, анын бардык функциялары токтотулсунбу?" + "System UI Tuner Жөндөөлөрдөн өчүрүлүп, анын бардык функциялары токтотулсунбу?" "Колдонмо сиздин түзмөгүңүздө орнотулган эмес" "Сааттын секунддары көрсөтүлсүн" "Абал тилкесинен сааттын секунддары көрсөтүлсүн. Батареянын кубаты көбүрөөк сарпталышы мүмкүн." @@ -628,22 +628,22 @@ "Баскычтобуңузду планшетиңизге туташтыруу үчүн, адегенде Bluetooth\'ту күйгүзүшүңүз керек." "Күйгүзүү" "Үнсүз көрүнөт" - "Бардык эскертмелерди бөгөттөө" + "Бардык билдирмелерди бөгөттөө" "Үнү менен көрсөтүлсүн" "Үнү менен көрсөтүлүп бөгөттөлбөсүн" "Эскертмелерди башкаруу каражаттары" "Күйүк" "Өчүк" - "Бул функциянын жардамы менен ар бир колдонмо үчүн билдирменин маанилүүлүгүн 0дон 5ке чейин бааласаңыз болот. \n\n""5-деңгээл"" \n- Билдирмелер тизмесинин өйдө жагында көрсөтүлөт \n- Билдирмелер толук экранда көрсөтүлөт \n- Калкып чыгуучу билдирмелерге уруксат берилет \n\n""4-деңгээл"" \n- Билдирмелер толук экранда көрсөтүлбөйт \n- Калкып чыгуучу билдирмелерге уруксат берилет \n\n""3-деңгээл"" \n- Билдирмелер толук экранда көрсөтүлбөйт \n- Калкып чыгуучу билдирмелерге тыюу салынат \n\n""2-деңгээл"" \n- Билдирмелер толук экранда көрсөтүлбөйт \n- Калкып чыгуучу билдирмелерге тыюу салынат \n- Эч качан үн чыкпайт же дирилдебейт \n\n""1-деңгээл"" \n- Билдирмелер толук экранда көрсөтүлбөйт \n- Калкып чыгуучу билдирмелерге тыюу салынат \n- Эч качан үн чыкпайт же дирилдебейт \n- Кулпуланган экрандан жана абал тилкесинен жашырылат \n- Билдирмелер тизмесинин ылдый жагында көрсөтүлөт \n\n""0-деңгээл"" \n- Колдонмодон алынган бардык билдирмелер бөгөттөлөт" + "Бул функциянын жардамы менен, ар бир колдонмо үчүн билдирменин маанилүүлүгүн 0дон 5ке чейин бааласаңыз болот. \n\n""5-деңгээл"" \n- Билдирмелер тизмесинин өйдө жагында көрсөтүлөт \n- Билдирмелер толук экранда көрсөтүлөт \n- Калкып чыгуучу билдирмелерге уруксат берилет \n\n""4-деңгээл"" \n- Билдирмелер толук экранда көрүнбөйт \n- Калкып чыгуучу билдирмелерге уруксат берилет \n\n""3-деңгээл"" \n- Билдирмелер толук экранда көрүнбөйт \n- Калкып чыгуучу билдирмелерге тыюу салынат \n\n""2-деңгээл"" \n- Билдирмелер толук экранда көрүнбөйт \n- Калкып чыгуучу билдирмелерге тыюу салынат \n- Эч качан үн чыкпайт же дирилдебейт \n\n""1-деңгээл"" \n- Билдирмелер толук экранда көрүнбөйт \n- Калкып чыгуучу билдирмелерге тыюу салынат \n- Эч качан үн чыкпайт же дирилдебейт \n- Кулпуланган экрандан жана абал тилкесинен жашырылат \n- Билдирмелер тизмесинин ылдый жагында көрсөтүлөт \n\n""0-деңгээл"" \n- Колдонмодон алынган бардык билдирмелер бөгөттөлөт" "Билдирмелер" - "Мындан ары бул эскертмелер сизге көрсөтүлбөйт" - "Бул эскертмелер кичирейтилет" + "Мындан ары бул билдирмелер сизге көрүнбөйт" + "Бул билдирмелер кичирейтилет" "Бул билдирмелер үнсүз көрсөтүлөт" "Бул билдирмелер тууралуу кабарлап турабыз" - "Адатта мындай эскертмелерди өткөрүп жибересиз. \nАлар көрсөтүлө берсинби?" + "Адатта мындай билдирмелерди өткөрүп жибересиз. \nАлар көрсөтүлө берсинби?" "Бүттү" "Колдонуу" - "Бул эскертмелер көрсөтүлө берсинби?" + "Бул билдирмелер көрсөтүлө берсинби?" "Эскертмелерди токтотуу" "Үнсүз жеткирүү" "Бөгөттөө" @@ -654,7 +654,7 @@ "Билдирүү" "Кабар бериле берсин" "Билдирмелерди өчүрүү" - "Бул колдонмонун эскертмелери көрсөтүлө берсинби?" + "Бул колдонмонун билдирмелери көрсөтүлө берсинби?" "Үнсүз" "Шашылыш билдирүү" "Үн же дирилдөөсүз ой топтоого жардам берет." @@ -681,7 +681,7 @@ "Бүттү" "Кайтаруу" "%1$s %2$s" - "эскертмелерди башкаруу каражаттары" + "билдирмелерди башкаруу каражаттары" "эскертмени тындыруу опциялары" "Тындыруу" "КАЙТАРУУ" @@ -940,6 +940,6 @@ "Төмөнкү сол жакка жылдыруу" "Төмөнкү оң жакка жылдырыңыз" "Жабуу" - "Тутум чабыттоосу жаңыртылды. Өзгөртүү үчүн, Жөндөөлөргө өтүңүз." + "Тутум чабыттоосу жаңырды. Өзгөртүү үчүн, Жөндөөлөргө өтүңүз." "Тутум чабыттоосун жаңыртуу үчүн Жөндөөлөргө өтүңүз" diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 4ecb7ed4d546..40a65f7f5335 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -199,7 +199,7 @@ "Отвори ги деталите за батеријата" "Батерија %d проценти." "Батерија %1$s отсто, уште околу %2$s според вашето користење" - "Полнење на батеријата, %d %%." + "Полнење на батеријата, %d отсто." "Поставки на систем." "Известувања" "Видете ги сите известувања" @@ -280,7 +280,7 @@ "Локацијата е поставена со GPS" "Активни барања за локација" "Исклучувањето на сензорите е активно" - "Исчисти ги сите известувања." + "Избриши ги сите известувања." "+ %s" Уште %s известување внатре. @@ -464,7 +464,7 @@ "Избриши сѐ" "Управувајте" "Тивки известувања" - "Исчисти ги сите тивки известувања" + "Избриши ги сите тивки известувања" "Известувањата се паузирани од „Не вознемирувај“" "Започни сега" "Нема известувања" diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index b82cfff5fc58..c1ba0151af9d 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -199,7 +199,7 @@ "ബാറ്ററി വിശദാംശങ്ങൾ തുറക്കുക" "ബാറ്ററി %d ശതമാനം." "ബാറ്ററി %1$s ശതമാനം, നിങ്ങളുടെ ഉപയോഗത്തിൻ്റെ അടിസ്ഥാനത്തിൽ ഏകദേശം %2$s സമയം കൂടി ശേഷിക്കുന്നു" - "ബാറ്ററി ചാർജുചെയ്യുന്നു, %d%%." + "ബാറ്ററി ചാർജ് ചെയ്യുന്നു, %d%%." "സിസ്‌റ്റം ക്രമീകരണങ്ങൾ." "അറിയിപ്പുകൾ." "എല്ലാ അറിയിപ്പുകളും കാണുക" @@ -739,7 +739,7 @@ "SMS:" "സംഗീതം" "YouTube" - "കലണ്ടർ" + "Calendar" "വോളിയം നിയന്ത്രണങ്ങളോടൊപ്പം കാണിക്കുക" "ശല്യപ്പെടുത്തരുത്" "വോളിയം ബട്ടൺ കുറുക്കുവഴി" diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index a251fb25279b..b5027755db5f 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -739,7 +739,7 @@ "SMS" "संगीत" "YouTube" - "कॅलेंडर" + "Calendar" "आवाज नियंत्रणांसह दर्शवा" "व्यत्यय आणू नका" "आवाजाच्या बटणांचा शार्टकट" diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 616b6ff6171e..e993f5ddb6f3 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -197,7 +197,7 @@ "SIM ကတ် မရှိပါ" "ဝန်ဆောင်မှုပေးသူ ကွန်ရက် ပြောင်းလဲနေသည်။" "ဘက်ထရီ အသေးစိတ် အချက်အလက်များကို ဖွင့်ပါ" - "ဘတ္တရီ %d ရာခိုင်နှုန်း။" + "ဘက်ထရီ %d ရာခိုင်နှုန်း။" "ဘက်ထရီ %1$s ရာခိုင်နှုန်း၊ သင်၏ အသုံးပြုမှုအပေါ် မူတည်၍ %2$s ခန့်ကျန်သည်" "ဘက်ထရီအားသွင်းနေသည်၊ %d %%။" "စနစ်အပြင်အဆင်များ" diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 70b77efa2f8c..d5db5519b436 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -199,7 +199,7 @@ "ब्याट्री सम्बन्धी विवरणहरूलाई खोल्नुहोस्" "ब्याट्री %d प्रतिशत" "ब्याट्रीको चार्ज %1$s प्रतिशत छ, तपाईंको प्रयोगका आधारमा %2$s बाँकी छ" - "ब्याट्री चार्ज हुँदैछ, %d प्रतिशत।" + "ब्याट्री चार्ज हुँदैछ, %d प्रतिशत भयो।" "प्रणाली सेटिङहरू" "सूचनाहरू।" "सबै सूचनाहरू हेर्नुहोस्" diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index f4bcc0edd626..269ba7ca0e29 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -197,7 +197,7 @@ "କୌଣସି SIM କାର୍ଡ ନାହିଁ।" "କେରିଅର୍‍ ନେଟ୍‌ୱର୍କ ବଦଳୁଛି" "ବ୍ୟାଟେରୀ ବିବରଣୀ ଖୋଲନ୍ତୁ" - "ବ୍ୟାଟେରୀ %d ଶତକଡ଼ା ଅଛି।" + "ବ୍ୟାଟେରୀ %d ଶତକଡ଼ା।" "ବ୍ୟାଟେରୀ %1$s ଶତକଡା, ଆପଣଙ୍କର ବ୍ୟବହାରକୁ ଆଧାର କରି ପାଖାପାଖି %2$s ବାକି ଅଛି" "ବ୍ୟାଟେରୀ ଚାର୍ଜ ହେଉଛି, %d ଶତକଡ଼ା।" "ସିଷ୍ଟମ୍‍ ସେଟିଙ୍ଗ।" diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index d3fa31e76f3f..fc4648e71344 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -199,7 +199,7 @@ "ਬੈਟਰੀ ਵੇਰਵੇ ਖੋਲ੍ਹੋ" "ਬੈਟਰੀ %d ਪ੍ਰਤੀਸ਼ਤ ਹੈ।" "ਬੈਟਰੀ %1$s ਫ਼ੀਸਦ, ਤੁਹਾਡੀ ਵਰਤੋਂ ਦੇ ਆਧਾਰ \'ਤੇ ਲਗਭਗ %2$s ਬਾਕੀ" - "ਬੈਟਰੀ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ, %d ਪ੍ਰਤੀਸ਼ਤ।" + "ਬੈਟਰੀ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ, %d ਪ੍ਰਤੀਸ਼ਤ ਹੋ ਗਈ।" "ਸਿਸਟਮ ਸੈਟਿੰਗਾਂ।" "ਸੂਚਨਾਵਾਂ।" "ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਦੇਖੋ" @@ -739,7 +739,7 @@ "SMS" "ਸੰਗੀਤ" "YouTube" - "ਕੈਲੰਡਰ" + "Calendar" "ਵੌਲਿਊਮ ਕੰਟਰੋਲਾਂ ਨਾਲ ਦਿਖਾਓ" "ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ" "ਵੌਲਿਊਮ ਬਟਨ ਸ਼ਾਰਟਕੱਟ" diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index bae0fd4e663b..37efd33ae6ef 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -112,7 +112,7 @@ "Odblokuj bez używania odcisku palca" "Skanowanie twarzy" "Wyślij" - "Zarządzanie powiadomieniami" + "Zarządzaj powiadomieniami" "otwórz telefon" "otwórz pomoc głosową" "otwórz aparat" @@ -178,9 +178,7 @@ "4G+" "LTE" "LTE+" - - - + "5Ge" "5G" "5G+" "1X" @@ -886,7 +884,7 @@ "Bateria" "Zrzuty ekranu" "Wiadomości" - "Pamięć" + "Pamięć wewnętrzna" "Wskazówki" "Aplikacje błyskawiczne" "Aplikacja %1$s działa" diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 0acd0e56f1c9..2d3d78e39a7b 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -199,7 +199,7 @@ "Abrir detalhes da bateria" "Bateria a %d por cento." "Bateria a %1$s por cento, resta(m) cerca de %2$s com base na sua utilização." - "A bateria está a carregar, %d por cento." + "Bateria a carregar (%d %%)." "Definições do sistema" "Notificações." "Ver todas as notificações" diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 2a0452d55ea0..c34eade3cf03 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -199,7 +199,7 @@ "Deschideți detaliile privind bateria" "Baterie: %d la sută." "Procentul rămas din baterie este %1$s. În baza utilizării, timpul rămas este de aproximativ %2$s" - "Se încarcă bateria, %d%%." + "Bateria se încarcă, %d la sută." "Setări de sistem." "Notificări." "Vedeți toate notificările" diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 7bbc1465856f..292d03f372ea 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -199,7 +199,7 @@ "Odpiranje podrobnosti o akumulatorju" "Baterija %d odstotkov." "Napolnjenost akumulatorja je %1$s, glede na način uporabe imate na voljo še približno %2$s" - "Polnjenje akumulatorja, %d %%." + "Baterija se polni, %d odstotkov." "Sistemske nastavitve." "Obvestila." "Prikaži vsa obvestila" diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 5165533b4326..c4fee659890f 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -349,7 +349,7 @@ "Shkëmbe ngjyrat" "Modaliteti i korrigjimit të ngjyrës" "Cilësime të tjera" - "U krye!" + "U krye" "I lidhur" "E lidhur, bateria %1$s" "Po lidhet..." diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 9795adfe5347..aa797905f474 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -199,7 +199,7 @@ "Отвори детаље о батерији" "Батерија је на %d посто." "Батерија је на %1$s посто, преостало време на основу коришћења је %2$s" - "Батерија се пуни, %d%%." + "Батерија се пуни, %d посто." "Системска подешавања." "Обавештења." "Погледајте сва обавештења" diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 804096d21eb0..1e036fa3ef83 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -528,7 +528,7 @@ "Kifaa kitaendelea kuwa katika hali ya kufungwa hadi utakapokifungua mwenyewe" "Pata arifa kwa haraka" "Zitazame kabla hujafungua" - "Hapana, asante" + "Hapana" "Sanidi" "%1$s. %2$s" "Izime sasa" @@ -551,7 +551,7 @@ "Ili ubandue skrini hii, gusa na ushikilie vitufe vya Nyuma na Mwanzo" "Ili ubandue skrini hii, telezesha kidole juu na ushikilie" "Nimeelewa" - "Hapana, asante" + "Hapana" "Skrini imebandikwa" "Skrini imebanduliwa" "Ungependa kuficha %1$s?" @@ -908,7 +908,7 @@ "Kataa" "Gusa ili uratibu wakati wa kuwasha Kiokoa Betri" "Washa wakati betri inakaribia kuisha" - "Hapana, asante" + "Hapana" "Ratiba ya Kiokoa Betri imewashwa" "Kiokoa Betri kitawaka kiotomatiki baada ya chaji ya betri kufika chini ya %d%%." "Mipangilio" @@ -940,6 +940,6 @@ "Sogeza chini kushoto" "Sogeza chini kulia" "Ondoa" - "Umesasisha usogezaji kwenye mfumo. Ili ufanye mabadiliko, nenda kwenye Mipangilio." + "Umesasisha usogezaji kwenye mfumo. Ili ubadilishe, nenda kwenye Mipangilio." "Nenda kwenye mipangilio ili usasishe usogezaji kwenye mfumo" diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index d0c272457673..92a6c19c34f8 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -199,7 +199,7 @@ "பேட்டரி விவரங்களைத் திறக்கும்" "பேட்டரி சக்தி %d சதவிகிதம் உள்ளது." "பேட்டரி: %1$s சதவீதம், உபயோகத்தின் அடிப்படையில் %2$s மீதமுள்ளது" - "பேட்டரி சார்ஜ் செய்யப்படுகிறது, %d சதவீதம்." + "பேட்டரி சார்ஜ் ஆகிறது, %d சதவீதம் உள்ளது." "கணினி அமைப்பு." "அறிவிப்புகள்." "எல்லா அறிவிப்புகளையும் காட்டும்" @@ -396,7 +396,7 @@ "%s க்கு இடதுபக்கமாக இழுக்கவும்." "அலாரங்கள், நினைவூட்டல்கள், நிகழ்வுகள் மற்றும் குறிப்பிட்ட அழைப்பாளர்களைத் தவிர்த்து, பிற ஒலிகள் மற்றும் அதிர்வுகளின் தொந்தரவு இருக்காது. எனினும், நீங்கள் எதையேனும் (இசை, வீடியோக்கள், கேம்ஸ் போன்றவை) ஒலிக்கும்படி தேர்ந்தெடுத்திருந்தால், அவை வழக்கம் போல் ஒலிக்கும்." "அலாரங்களைத் தவிர்த்து, பிற ஒலிகள் மற்றும் அதிர்வுகளின் தொந்தரவு இருக்காது. எனினும், நீங்கள் எதையேனும் (இசை, வீடியோக்கள், கேம்ஸ் போன்றவை) ஒலிக்கும்படி தேர்ந்தெடுத்திருந்தால், அவை வழக்கம் போல் ஒலிக்கும்." - "தனிப்பயனாக்கு" + "பிரத்தியேகமாக்கு" "இது அலாரங்கள், இசை, வீடியோக்கள் மற்றும் கேம்ஸ் உட்பட எல்லா ஒலிகளையும் அதிர்வுகளையும் தடுக்கும். எனினும், உங்களால் ஃபோன் அழைப்புகளைச் செய்ய முடியும்." "இது அலாரங்கள், இசை, வீடியோக்கள் மற்றும் கேம்ஸ் உட்பட எல்லா ஒலிகளையும் அதிர்வுகளையும் தடுக்கும்." "+%d" @@ -428,19 +428,19 @@ "சுயவிவரத்தைக் காட்டு" "பயனரைச் சேர்" "புதியவர்" - "வேறொருவர்" - "வேறொருவரைச் சேர்" - "அழைக்கப்பட்டவரை அகற்று" - "அழைக்கப்பட்டவரை அகற்றவா?" + "கெஸ்ட்" + "கெஸ்ட்டைச் சேர்" + "கெஸ்ட்டை அகற்று" + "கெஸ்ட்டை அகற்றவா?" "இந்த அமர்வின் எல்லா பயன்பாடுகளும், தரவும் நீக்கப்படும்." "அகற்று" "நல்வரவு!" "உங்கள் அமர்வைத் தொடர விருப்பமா?" "மீண்டும் தொடங்கு" "தொடரவும்" - "வேறொருவர்" - "பயன்பாடுகளையும் தரவையும் நீக்க, விருந்தினர் பயனரை அகற்றவும்" - "அழைக்கப்பட்டவரை அகற்றவா?" + "கெஸ்ட்" + "பயன்பாடுகளையும் தரவையும் நீக்க, கெஸ்ட் பயனரை அகற்றவும்" + "கெஸ்ட்டை அகற்றவா?" "பயனரை வெளியேற்று" "தற்போதைய பயனரிலிருந்து வெளியேறு" "பயனரை வெளியேற்று" @@ -623,7 +623,7 @@ "நிலைப் பட்டியில் கடிகார வினாடிகளைக் காட்டும். பேட்டரியின் ஆயுளைக் குறைக்கலாம்." "விரைவு அமைப்புகளை மறுவரிசைப்படுத்து" "விரைவு அமைப்புகளில் ஒளிர்வுப் பட்டியைக் காட்டு" - "சோதனை முயற்சி" + "பரிசோதனை முயற்சி" "புளூடூத்தை இயக்கவா?" "உங்கள் டேப்லெட்டுடன் விசைப்பலகையை இணைக்க, முதலில் புளூடூத்தை இயக்க வேண்டும்." "இயக்கு" @@ -677,7 +677,7 @@ "%1$sக்கான அறிவிப்புக் கட்டுப்பாடுகள் மூடப்பட்டன" "இந்தச் சேனலிலிருந்து அறிவிப்புகளைப் பெறுவதை அனுமதிக்கும்" "மேலும் அமைப்புகள்" - "தனிப்பயனாக்கு" + "பிரத்தியேகமாக்கு" "முடிந்தது" "செயல்தவிர்" "%1$s %2$s" @@ -739,7 +739,7 @@ "SMS" "மியூசிக்" "YouTube" - "கேலெண்டர்" + "Calendar" "ஒலிக் கட்டுப்பாடுகளுடன் காட்டு" "தொந்தரவு செய்ய வேண்டாம்" "ஒலியளவுப் பொத்தான்களுக்கான ஷார்ட்கட்" @@ -777,7 +777,7 @@ "மீட்டமை" "பட்டனின் அகலத்தை மாற்று" "கிளிப்போர்டு" - "தனிப்பயன் வழிசெலுத்தல் பட்டன்" + "பிரத்தியேக வழிசெலுத்தல் பட்டன்" "இடப்புற விசைக்குறியீடு" "வலப்புற விசைக்குறியீடு" "இடப்புற ஐகான்" diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 0f58d56f11ec..10ce592b8c34 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -102,7 +102,7 @@ "మెను" "యాక్సెస్ సామర్థ్యం" "స్క్రీన్‌ను తిప్పండి" - "అవలోకనం" + "ఓవర్‌వ్యూ" "వెతుకు" "కెమెరా" "ఫోన్" @@ -199,7 +199,7 @@ "బ్యాటరీ వివరాలను తెరుస్తుంది" "బ్యాటరీ %d శాతం." "బ్యాటరీ %1$s శాతం ఉంది, మీ వినియోగాన్ని బట్టి %2$s పని చేస్తుంది" - "బ్యాటరీ ఛార్జ్ అవుతోంది, %d %%." + "బ్యాటరీ ఛార్జ్ అవుతోంది, %d శాతం వద్ద ఉంది." "సిస్టమ్ సెట్టింగ్‌లు." "నోటిఫికేషన్‌లు." "అన్ని నోటిఫికేషన్‌లను చూడండి" @@ -218,7 +218,7 @@ "శీఘ్ర సెట్టింగ్‌లు." "లాక్ స్క్రీన్." "సెట్టింగ్‌లు" - "అవలోకనం." + "ఓవర్‌వ్యూ." "కార్యాలయ లాక్ స్క్రీన్" "మూసివేస్తుంది" "%1$s." @@ -594,7 +594,7 @@ "ఛార్జింగ్‌లో లేనప్పుడు స్థితి పట్టీ చిహ్నం లోపల బ్యాటరీ స్థాయి శాతం చూపుతుంది" "శీఘ్ర సెట్టింగ్‌లు" "స్థితి పట్టీ" - "స్థూలదృష్టి" + "ఓవర్‌వ్యూ" "సిస్టమ్ UI డెమో మోడ్" "డెమో మోడ్ ప్రారంభించండి" "డెమో మోడ్ చూపు" @@ -642,7 +642,7 @@ "ఈ నోటిఫికేషన్‌లు మిమ్మల్ని హెచ్చరిస్తాయి" "మీరు సాధారణంగా ఈ నోటిఫికేషన్‌లను విస్మరిస్తారు. \nవాటి ప్రదర్శనను కొనసాగించాలా?" "పూర్తయింది" - "వర్తింపజేయి" + "అప్లై చేయి" "ఈ నోటిఫికేషన్‌లను చూపిస్తూ ఉండాలా?" "నోటిఫికేషన్‌లను ఆపివేయి" "నిశ్శబ్దంగా బట్వాడా చేయండి" @@ -739,7 +739,7 @@ "SMS" "సంగీతం" "YouTube" - "క్యాలెండర్" + "Calendar" "వాల్యూమ్ నియంత్రణలతో చూపు" "అంతరాయం కలిగించవద్దు" "వాల్యూమ్ బటన్‌ల షార్ట్‌కట్" diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 7afe4d10c22a..05ffb1d9c0f5 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -199,7 +199,7 @@ "Відкрити деталі акумулятора" "Заряд акумулятора у відсотках: %d." "Згідно з даними про використання залишилося %1$s заряду акумулятора – близько %2$s" - "Акумулятор заряджається: %d%%." + "Акумулятор заряджається, поточний заряд %d відсотків." "Налаштування системи." "Сповіщення." "Переглянути всі сповіщення" @@ -915,7 +915,7 @@ "- Може виконувати дії в додатку %1$s" "Дозволити додатку %1$s показувати фрагменти будь-якого додатка" "Дозволити" - "Відмовити" + "Заборонити" "Торкніться, щоб увімкнути автоматичний режим економії заряду акумулятора" "Вмикати, коли заряд акумулятора закінчується" "Ні, дякую" diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 0b37bcf3e2a7..2954ca00eac9 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -199,7 +199,7 @@ "بیٹری کی تفصیلات کھولیں" "بیٹری %d فیصد۔" "آپ کے استعمال کی بنیاد پر بیٹری %1$s فیصد، تقریباً %2$s باقی ہے" - "بیٹری چارج ہو رہی ہے، %d%%" + "بیٹری چارج ہو رہی ہے، اس وقت %d فیصد ہے۔" "سسٹم کی ترتیبات۔" "اطلاعات۔" "تمام اطلاعات دیکھیں" diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 3596baac36d3..99f2b83e1eee 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -199,7 +199,7 @@ "Quvvat sarfi tafsilotlari" "Batareya %d foiz." "Batareya quvvati %1$s foiz, joriy holatda yana %2$s qoldi" - "Batareya quvvat olmoqda (%d%%)." + "Batareya quvvat olmoqda, %d foiz." "Tizim sozlamalari." "Eslatmalar." "Barcha bildirishnomalarni ko‘rish" @@ -463,8 +463,8 @@ "Boshqa ko‘rsatilmasin" "Hammasini tozalash" "Boshqarish" - "Tovushsiz bildirishnomalar" - "Barcha tovushsiz bildirishnomalarni tozalash" + "Sokin bildirishnomalar" + "Barcha sokin bildirishnomalarni tozalash" "Bezovta qilinmasin rejimida bildirishnomalar pauza qilingan" "Boshlash" "Bildirishnomalar yo‘q" diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index eb4185190e04..654e708ae909 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -926,8 +926,8 @@ "Không có tiêu đề" "Nhấn để khởi động lại ứng dụng này và xem ở chế độ toàn màn hình." "Mở %1$s" - "Tùy chọn cài đặt cho bong bóng %1$s" - "Bạn muốn cho phép bong bóng của %1$s?" + "Tùy chọn cài đặt cho bong bóng trò chuyện %1$s" + "Bạn muốn cho phép bong bóng trò chuyện của %1$s?" "Quản lý" "Từ chối" "Cho phép" diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index aae9b199758a..f800bcc98dfc 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -199,7 +199,7 @@ "Vula imininingwane yebhethri" "Iphesenti %d lebhethri" "Amaphesenti ebhethri ngu-%1$s, cishe kusele okungu-%2$s kusukela ekusetshenzisweni kwakho" - "Ibhethri liyashaja, %d iphesenti." + "Ibhethri liyashaja, %d %%" "Izilungiselelo zesistimu" "Izaziso" "Bona zonke izaziso" -- GitLab From 767f71aab9952f30738aa721c04a7192ab522b73 Mon Sep 17 00:00:00 2001 From: Raman Tenneti Date: Thu, 2 Apr 2020 15:19:36 -0700 Subject: [PATCH 208/219] Disable the failing setAutoMode_screenOff* tests in stage-aosp-master. BUG: 152719290 Forrest run: https://android-build.googleplex.com/builds/forrest/run/L28100000517212766 Test: manual. Change-Id: I2a9ec6e37584e55f8419d993ee73c3987ac80439 Merged-In: I0dca5268fb5fed46b898ec3c90e6d9f7ff42312f --- .../src/com/android/server/UiModeManagerServiceTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java index 3fce5ebc8432..05dbaf94ad54 100644 --- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java @@ -31,6 +31,7 @@ import android.testing.TestableLooper; import com.android.server.twilight.TwilightManager; import com.android.server.wm.WindowManagerInternal; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -87,6 +88,7 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { }); } + @Ignore // b/152719290 - Fails on stage-aosp-master @Test public void setAutoMode_screenOffRegistered() throws RemoteException { try { @@ -96,6 +98,7 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { verify(mContext).registerReceiver(any(BroadcastReceiver.class), any()); } + @Ignore // b/152719290 - Fails on stage-aosp-master @Test public void setAutoMode_screenOffUnRegistered() throws RemoteException { try { -- GitLab From 23c71c07116328130e0c4e02e52b4fa1f203688e Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 3 Apr 2020 11:49:41 -0700 Subject: [PATCH 209/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: I61a6b3cee34371950b7ec398c8448aae590c8fea --- packages/SystemUI/res-keyguard/values-ar/strings.xml | 8 ++++---- packages/SystemUI/res-keyguard/values-ca/strings.xml | 8 ++++---- packages/SystemUI/res-keyguard/values-ky/strings.xml | 2 +- packages/SystemUI/res-keyguard/values-pl/strings.xml | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml index 414317ff7b52..f20ec01812ea 100644 --- a/packages/SystemUI/res-keyguard/values-ar/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml @@ -92,10 +92,10 @@ "لقد كتبت رقم التعريف الشخصي بشكل غير صحيح %1$d مرة. \n\nأعد المحاولة خلال %2$d ثانية." "لقد كتبت كلمة المرور بشكل غير صحيح %1$d مرة. \n\nأعد المحاولة خلال %2$d ثانية." "لقد رسمت نقش فتح القفل بطريقة غير صحيحة %1$d مرة. \n\nأعد المحاولة خلال %2$d ثانية." - "أخطأت في محاولة فتح قفل الجهاز اللوحي %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إعادة تعيين هذا الجهاز، ومن ثم يتم حذف جميع بياناته." - "أخطأت في محاولة فتح قفل الهاتف %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إعادة تعيين هذا الهاتف، ومن ثم يتم حذف جميع بياناته." - "أخطأت في محاولة فتح قفل الجهاز اللوحي %d مرة. ستتم إعادة تعيين هذا الجهاز، ومن ثم يتم حذف جميع بياناته." - "أخطأت في محاولة فتح قفل الهاتف %d مرة. ستتم إعادة تعيين هذا الهاتف، ومن ثم يتم حذف جميع بياناته." + "أخطأت في محاولة فتح قفل الجهاز اللوحي %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إعادة ضبط هذا الجهاز، ومن ثم يتم حذف جميع بياناته." + "أخطأت في محاولة فتح قفل الهاتف %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إعادة ضبط هذا الهاتف، ومن ثم يتم حذف جميع بياناته." + "أخطأت في محاولة فتح قفل الجهاز اللوحي %d مرة. ستتم إعادة ضبط هذا الجهاز، ومن ثم يتم حذف جميع بياناته." + "أخطأت في محاولة فتح قفل الهاتف %d مرة. ستتم إعادة ضبط هذا الهاتف، ومن ثم يتم حذف جميع بياناته." "أخطأت في محاولة فتح قفل الجهاز اللوحي %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إزالة هذا المستخدم، ومن ثم يتم حذف جميع بيانات المستخدم." "أخطأت في محاولة فتح قفل الهاتف %1$d مرة. بعد %2$d محاولة غير ناجحة أخرى، ستتم إزالة هذا المستخدم، ومن ثم يتم حذف جميع بيانات المستخدم." "أخطأت في محاولة فتح قفل الجهاز اللوحي %d مرة. ستتم إزالة المستخدم، ومن ثم يتم حذف جميع بياناته." diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml index 6ea9697a208c..ddb991edab96 100644 --- a/packages/SystemUI/res-keyguard/values-ca/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml @@ -96,10 +96,10 @@ "Has provat de desbloquejar el telèfon %1$d vegades de manera incorrecta. Si falles %2$d vegades més, l\'usuari se suprimirà, juntament amb totes les seves dades." "Has provat de desbloquejar la tauleta %d vegades de manera incorrecta. L\'usuari se suprimirà, juntament amb totes les seves dades." "Has provat de desbloquejar el telèfon %d vegades de manera incorrecta. L\'usuari se suprimirà, juntament amb totes les seves dades." - "Has provat de desbloquejar la tauleta %1$d vegades de manera incorrecta. Si falles %2$d vegades més, el perfil professional se suprimirà, juntament amb totes les dades que contingui." - "Has provat de desbloquejar el telèfon %1$d vegades de manera incorrecta. Si falles %2$d vegades més, el perfil professional se suprimirà, juntament amb totes les dades que contingui." - "Has provat de desbloquejar la tauleta %d vegades de manera incorrecta. El perfil professional se suprimirà, juntament amb totes les dades que contingui." - "Has provat de desbloquejar el telèfon %d vegades de manera incorrecta. El perfil professional se suprimirà, juntament amb totes les dades que contingui." + "Has provat de desbloquejar la tauleta %1$d vegades de manera incorrecta. Si falles %2$d vegades més, el perfil de treball se suprimirà, juntament amb totes les dades que contingui." + "Has provat de desbloquejar el telèfon %1$d vegades de manera incorrecta. Si falles %2$d vegades més, el perfil de treball se suprimirà, juntament amb totes les dades que contingui." + "Has provat de desbloquejar la tauleta %d vegades de manera incorrecta. El perfil de treball se suprimirà, juntament amb totes les dades que contingui." + "Has provat de desbloquejar el telèfon %d vegades de manera incorrecta. El perfil de treball se suprimirà, juntament amb totes les dades que contingui." "Has dibuixat el patró de desbloqueig %1$d vegades de manera incorrecta. Si falles %2$d vegades més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a %3$d segons." "Has dibuixat el patró de desbloqueig %1$d vegades de manera incorrecta. Si falles %2$d vegades més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a %3$d segons." "El codi PIN de la SIM no és correcte. Contacta amb l\'operador de telefonia mòbil per desbloquejar el dispositiu." diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml index bb5e776525ed..f6c2150c5c91 100644 --- a/packages/SystemUI/res-keyguard/values-ky/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml @@ -115,7 +115,7 @@ "SIM-картанын PIN-кодун ачуу кыйрады!" "SIM-картанын PUK-кодун ачуу кыйрады!" "Код кабыл алынды!" - "Байланыш жок." + "Интернет жок." "Киргизүү ыкмасын өзгөртүү" "Учак режими" "Түзмөк кайра күйгүзүлгөндөн кийин графикалык ачкычты тартуу талап кылынат" diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml index f6d1e900edb8..0f0d8a199f78 100644 --- a/packages/SystemUI/res-keyguard/values-pl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml @@ -56,7 +56,7 @@ "Miejsce na kod PIN karty SIM" "Miejsce na kod PUK karty SIM" "Następny alarm ustawiony na: %1$s" - "Usuwanie" + "Usuń" "Wyłącz eSIM" "Nie można wyłączyć karty eSIM" "Nie można wyłączyć karty eSIM z powodu błędu." -- GitLab From 31839ba1537f438c106c45073fe650e8e6bd17f4 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 3 Apr 2020 12:08:23 -0700 Subject: [PATCH 210/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: I6f38253f0e74f1cf2a0dc8b17d494d7d90c1318b --- packages/VpnDialogs/res/values-ky/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/VpnDialogs/res/values-ky/strings.xml b/packages/VpnDialogs/res/values-ky/strings.xml index 4e2f698bb1e5..23c9be8819a8 100644 --- a/packages/VpnDialogs/res/values-ky/strings.xml +++ b/packages/VpnDialogs/res/values-ky/strings.xml @@ -26,7 +26,7 @@ "%1$s байт / %2$s пакет" "Ар дайым күйүк VPN\'ге туташа албай жатат" "%1$s тармагына ар дайым туташып турсун деп жөндөлгөн, бирок учурда телефонуңуз ага туташа албай жатат. %1$s тармагына кайра туташканга чейин телефонуңуз жалпыга ачык тармакты пайдаланып турат." - "%1$s тармагына ар дайым туташып турсун деп жөндөлгөн, бирок учурда телефонуңуз ага туташа албай жатат. VPN тармагына кайра туташмайынча, Интернет байланышыңыз жок болот." + "%1$s тармагына ар дайым туташып турсун деп жөндөлгөн, бирок учурда телефонуңуз ага туташа албай жатат. VPN тармагына кайра туташмайынча, Интернет жок болот." " " "VPN жөндөөлөрүн өзгөртүү" "Конфигурациялоо" -- GitLab From c0e4c56696b88d3c87db25d0323cecfa40f362bd Mon Sep 17 00:00:00 2001 From: Ned Burns Date: Thu, 2 Apr 2020 17:22:40 -0400 Subject: [PATCH 211/219] Don't crash if NSSL gets incomplete gesture In *theory*, a View should always receive an ACTION_DOWN before receiving any other touch events, but this isn't always the case in practice. Whenever we see one of these "partial" gestures, we should ignore it until a real one starts. Test: manual Bug: 146323887 Merged-In: I22182d90b0057df67fbd6d20785da23d6c17dcf3 Change-Id: I22182d90b0057df67fbd6d20785da23d6c17dcf3 (cherry picked from commit c8048daed2e1b15fca1e281499d426920fc245c0) --- .../stack/NotificationStackScrollLayout.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 7c49c3f961c9..073e474fed19 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -3773,9 +3773,16 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd initVelocityTrackerIfNotExists(); mVelocityTracker.addMovement(ev); - final int action = ev.getAction(); + final int action = ev.getActionMasked(); + if (ev.findPointerIndex(mActivePointerId) == -1 && action != MotionEvent.ACTION_DOWN) { + // Incomplete gesture, possibly due to window swap mid-gesture. Ignore until a new + // one starts. + Log.e(TAG, "Invalid pointerId=" + mActivePointerId + " in onTouchEvent " + + MotionEvent.actionToString(ev.getActionMasked())); + return true; + } - switch (action & MotionEvent.ACTION_MASK) { + switch (action) { case MotionEvent.ACTION_DOWN: { if (getChildCount() == 0 || !isInContentBounds(ev)) { return false; -- GitLab From 33df27420ff132631ee7c5802157807d77a63b12 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 3 Apr 2020 18:53:57 -0700 Subject: [PATCH 212/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: Ie681fba26516cd915d05a130602139804b13e893 --- packages/SettingsLib/res/values-ca/strings.xml | 4 ++-- packages/SettingsLib/res/values-eu/strings.xml | 2 +- packages/SettingsLib/res/values-in/strings.xml | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index d734a1daf89f..61fc7672140b 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -167,11 +167,11 @@ "Instal·la dades de veu" "Instal·la les dades de veu necessàries per a la síntesi de veu" "Pot ser que aquest motor de síntesi de parla pugui recopilar tot el text que s\'enunciarà, incloses les dades personals, com ara les contrasenyes i els números de les targetes de crèdit. Ve del motor %s. Vols activar l\'ús d\'aquest motor de síntesi de parla?" - "Aquest idioma requereix una connexió de xarxa activa per a la sortida de text a parla." + "Aquest idioma requereix una connexió a la xarxa activa per a la sortida de text a parla." "Això és un exemple de síntesi de veu" "Estat de l\'idioma predeterminat" "%1$s és totalment compatible" - "Es necessita una connexió de xarxa per a %1$s" + "Es necessita una connexió a la xarxa per a %1$s" "%1$s no és compatible" "S\'està comprovant…" "Configuració de: %s" diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index f1bb45fdfea6..010a532d765f 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -205,7 +205,7 @@ "Gaitu arazketa modua USBa konektatzean" "Baliogabetu USB bidezko arazketarako baimenak" "Akatsen txostenerako lasterbidea" - "Bateriaren menuan, erakutsi akatsen txostena sortzeko botoia" + "Pizteko menuan, erakutsi akatsen txostena sortzeko botoia" "Mantendu aktibo" "Pantaila ez da ezarriko inoiz inaktibo kargatu bitartean" "Gaitu Bluetooth HCI miatze-erregistroa" diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index 0b634fcab2c3..f14c96def1f6 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -86,7 +86,7 @@ "Akses Internet" "Berbagi kontak" "Gunakan untuk berbagi kontak" - "Berbagi sambungan internet" + "Berbagi koneksi internet" "SMS" "Akses SIM" "Audio HD: %1$s" @@ -101,7 +101,7 @@ "Tidak tersambung kepada server transfer file" "Terhubung ke perangkat masukan" "Terhubung ke perangkat untuk akses internet" - "Berbagi sambungan internet lokal dengan perangkat" + "Berbagi koneksi internet lokal dengan perangkat" "Digunakan untuk akses internet" "Gunakan untuk peta" "Gunakan untuk akses SIM" @@ -167,11 +167,11 @@ "Instal data suara" "Instal data suara yang dibutuhkan untuk sintesis suara" "Mesin sintesis suara ini mungkin dapat mengumpulkan semua teks yang akan diucapkan, termasuk di antaranya data pribadi seperti sandi dan nomor kartu kredit. Berasal dari %s aplikasi. Gunakan metode masukan ini?" - "Bahasa ini perlu sambungan jaringan yang bekerja untuk keluaran text-to-speech." + "Bahasa ini perlu koneksi jaringan yang bekerja untuk keluaran text-to-speech." "Ini adalah contoh sintesis suara" "Status bahasa default" "%1$s didukung sepenuhnya" - "%1$s membutuhkan sambungan jaringan" + "%1$s membutuhkan koneksi jaringan" "%1$s tidak didukung" "Memeriksa…" "Setelan untuk %s" -- GitLab From ff31536aca1ba4fcb088ae19b6afda04a8d27adc Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 3 Apr 2020 19:23:26 -0700 Subject: [PATCH 213/219] Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: I033c4759b70bbf29777d4267e2dc728ab9b58e6f --- packages/SettingsLib/SearchWidget/res/values-es-rUS/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SettingsLib/SearchWidget/res/values-es-rUS/strings.xml b/packages/SettingsLib/SearchWidget/res/values-es-rUS/strings.xml index ed549db3c113..9b735fece386 100644 --- a/packages/SettingsLib/SearchWidget/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/SearchWidget/res/values-es-rUS/strings.xml @@ -17,5 +17,5 @@ - "Buscar en la configuración" + "Buscar configuraciones" -- GitLab From a1b4489ffa8a24f9530065eb5d9611c28593b8ee Mon Sep 17 00:00:00 2001 From: Ahan Wu Date: Fri, 21 Feb 2020 15:18:15 +0800 Subject: [PATCH 214/219] DO NOT MERGE Fix ImageWallpaper memory regression Scale bitmap to fit display size leads to memory regression, this cl removes the sacling logic and also disable wallpaper transitions when the bitmap size is smaller than display size to avoid broken visual. We backport the solution to Q. Bug: 147379974 Bug: 145897588 Bug: 124838911 Test: Manually Test: atest com.android.systemui Test: adb shell dumpsys SurfaceFlinger, then check layer size of ImageWallpaper Merged-In: I243274af54538fc89268c448aa2c5a95f63c7ae3 Change-Id: If348748ec453f2b35b25576181c8a144496e258c --- .../com/android/systemui/ImageWallpaper.java | 57 ++++++++++++++----- .../glwallpaper/ImageWallpaperRenderer.java | 11 +--- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java index 319d1177622d..fa3405fab8df 100644 --- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java @@ -18,12 +18,14 @@ package com.android.systemui; import android.app.ActivityManager; import android.content.Context; +import android.content.res.Configuration; import android.graphics.Rect; import android.os.HandlerThread; import android.os.Trace; import android.service.wallpaper.WallpaperService; import android.util.Log; import android.util.Size; +import android.view.DisplayInfo; import android.view.SurfaceHolder; import com.android.internal.annotations.VisibleForTesting; @@ -84,14 +86,19 @@ public class ImageWallpaper extends WallpaperService { private StatusBarStateController mController; private final Runnable mFinishRenderingTask = this::finishRendering; private final boolean mNeedTransition; + private boolean mShouldStopTransition; + private final boolean mIsHighEndGfx; + private final boolean mDisplayNeedsBlanking; + private final DisplayInfo mDisplayInfo = new DisplayInfo(); private final Object mMonitor = new Object(); private boolean mNeedRedraw; // This variable can only be accessed in synchronized block. private boolean mWaitingForRendering; GLEngine(Context context) { - mNeedTransition = ActivityManager.isHighEndGfx() - && !DozeParameters.getInstance(context).getDisplayNeedsBlanking(); + mIsHighEndGfx = ActivityManager.isHighEndGfx(); + mDisplayNeedsBlanking = DozeParameters.getInstance(context).getDisplayNeedsBlanking(); + mNeedTransition = mIsHighEndGfx && !mDisplayNeedsBlanking; // We will preserve EGL context when we are in lock screen or aod // to avoid janking in following transition, we need to release when back to home. @@ -99,12 +106,14 @@ public class ImageWallpaper extends WallpaperService { if (mController != null) { mController.addCallback(this /* StateListener */); } - mEglHelper = new EglHelper(); - mRenderer = new ImageWallpaperRenderer(context, this /* SurfaceProxy */); } @Override public void onCreate(SurfaceHolder surfaceHolder) { + mEglHelper = new EglHelper(); + // Deferred init renderer because we need to get wallpaper by display context. + mRenderer = new ImageWallpaperRenderer(getDisplayContext(), this /* SurfaceProxy */); + getDisplayContext().getDisplay().getDisplayInfo(mDisplayInfo); setFixedSizeAllowed(true); setOffsetNotificationsEnabled(true); updateSurfaceSize(); @@ -118,6 +127,26 @@ public class ImageWallpaper extends WallpaperService { holder.setFixedSize(width, height); } + /** + * Check if necessary to stop transition with current wallpaper on this device.
+ * This should only be invoked after {@link #onSurfaceCreated(SurfaceHolder)}} + * is invoked since it needs display context and surface frame size. + * + * @return true if need to stop transition + */ + @VisibleForTesting + boolean checkIfShouldStopTransition() { + int orientation = getDisplayContext().getResources().getConfiguration().orientation; + boolean portrait = orientation == Configuration.ORIENTATION_PORTRAIT; + Rect frame = getSurfaceHolder().getSurfaceFrame(); + int frameWidth = frame.width(); + int frameHeight = frame.height(); + int displayWidth = portrait ? mDisplayInfo.logicalWidth : mDisplayInfo.logicalHeight; + int displayHeight = portrait ? mDisplayInfo.logicalHeight : mDisplayInfo.logicalWidth; + return mNeedTransition + && (frameWidth < displayWidth || frameHeight < displayHeight); + } + @Override public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) { @@ -128,12 +157,14 @@ public class ImageWallpaper extends WallpaperService { @Override public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) { if (mWorker == null || !mNeedTransition) return; + final long duration = mShouldStopTransition ? 0 : animationDuration; if (DEBUG) { Log.d(TAG, "onAmbientModeChanged: inAmbient=" + inAmbientMode - + ", duration=" + animationDuration); + + ", duration=" + duration + + ", mShouldStopTransition=" + mShouldStopTransition); } mWorker.getThreadHandler().post( - () -> mRenderer.updateAmbientMode(inAmbientMode, animationDuration)); + () -> mRenderer.updateAmbientMode(inAmbientMode, duration)); if (inAmbientMode && animationDuration == 0) { // This means that we are transiting from home to aod, to avoid // race condition between window visibility and transition, @@ -169,13 +200,13 @@ public class ImageWallpaper extends WallpaperService { mRenderer = null; mEglHelper.finish(); mEglHelper = null; - getSurfaceHolder().getSurface().hwuiDestroy(); }); } @Override public void onSurfaceCreated(SurfaceHolder holder) { if (mWorker == null) return; + mShouldStopTransition = checkIfShouldStopTransition(); mWorker.getThreadHandler().post(() -> { mEglHelper.init(holder); mRenderer.onSurfaceCreated(); @@ -365,15 +396,13 @@ public class ImageWallpaper extends WallpaperService { protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) { super.dump(prefix, fd, out, args); out.print(prefix); out.print("Engine="); out.println(this); - - boolean isHighEndGfx = ActivityManager.isHighEndGfx(); - out.print(prefix); out.print("isHighEndGfx="); out.println(isHighEndGfx); - - DozeParameters dozeParameters = DozeParameters.getInstance(getApplicationContext()); + out.print(prefix); out.print("isHighEndGfx="); out.println(mIsHighEndGfx); out.print(prefix); out.print("displayNeedsBlanking="); - out.println(dozeParameters != null ? dozeParameters.getDisplayNeedsBlanking() : "null"); - + out.println(mDisplayNeedsBlanking); + out.print(prefix); out.print("displayInfo="); out.print(mDisplayInfo); out.print(prefix); out.print("mNeedTransition="); out.println(mNeedTransition); + out.print(prefix); out.print("mShouldStopTransition="); + out.println(mShouldStopTransition); out.print(prefix); out.print("StatusBarState="); out.println(mController != null ? mController.getState() : "null"); diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java index be6f7bfe2587..5f6588f9fca8 100644 --- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java +++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java @@ -31,7 +31,6 @@ import android.util.Log; import android.util.MathUtils; import android.util.Size; import android.view.DisplayInfo; -import android.view.WindowManager; import com.android.systemui.R; @@ -70,8 +69,7 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer, } DisplayInfo displayInfo = new DisplayInfo(); - WindowManager wm = context.getSystemService(WindowManager.class); - wm.getDefaultDisplay().getDisplayInfo(displayInfo); + context.getDisplay().getDisplayInfo(displayInfo); // We only do transition in portrait currently, b/137962047. int orientation = context.getResources().getConfiguration().orientation; @@ -115,12 +113,7 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer, mBitmap = mWallpaperManager.getBitmap(); mWallpaperManager.forgetLoadedWallpaper(); if (mBitmap != null) { - float scale = (float) mScissor.height() / mBitmap.getHeight(); - int surfaceHeight = Math.max(mScissor.height(), mBitmap.getHeight()); - int surfaceWidth = scale > 1f - ? Math.round(mBitmap.getWidth() * scale) - : mBitmap.getWidth(); - mSurfaceSize.set(0, 0, surfaceWidth, surfaceHeight); + mSurfaceSize.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight()); } } if (DEBUG) { -- GitLab From df8396f2c386eb28557660e6c843db5ab83d670c Mon Sep 17 00:00:00 2001 From: Andrew Sapperstein Date: Tue, 5 May 2020 16:55:22 -0700 Subject: [PATCH 215/219] Fix last broken @see links in aosp. Seems that the doc-comment-check-docs wasn't in presubmit. Bug: 6963924 Bug: 155825675 Test: make doc-comment-check-docs Change-Id: I018a50cd76b0fd5f8c3642efa1374e53f1b746a6 Merged-In: Ib2e4360493275b79c72487ee1cb173bb5e0fd35f --- core/java/android/app/job/JobScheduler.java | 4 +- .../android/telephony/euicc/EuiccManager.java | 68 +++++++++---------- wifi/java/android/net/wifi/WifiManager.java | 2 +- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/core/java/android/app/job/JobScheduler.java b/core/java/android/app/job/JobScheduler.java index 08b1c2b9f548..ec9c57466310 100644 --- a/core/java/android/app/job/JobScheduler.java +++ b/core/java/android/app/job/JobScheduler.java @@ -41,7 +41,7 @@ import java.util.List; * system will execute this job on your application's {@link android.app.job.JobService}. * You identify the service component that implements the logic for your job when you * construct the JobInfo using - * {@link android.app.job.JobInfo.Builder#JobInfo.Builder(int,android.content.ComponentName)}. + * {@link android.app.job.JobInfo.Builder#Builder(int,android.content.ComponentName)}. *

*

* The framework will be intelligent about when it executes jobs, and attempt to batch @@ -147,7 +147,7 @@ public abstract class JobScheduler { * method is ignored. * * @param jobId unique identifier for the job to be canceled, as supplied to - * {@link JobInfo.Builder#JobInfo.Builder(int, android.content.ComponentName) + * {@link JobInfo.Builder#Builder(int, android.content.ComponentName) * JobInfo.Builder(int, android.content.ComponentName)}. */ public abstract void cancel(int jobId); diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java index 44b0968eaa90..5500d635d2ff 100644 --- a/telephony/java/android/telephony/euicc/EuiccManager.java +++ b/telephony/java/android/telephony/euicc/EuiccManager.java @@ -269,10 +269,10 @@ public class EuiccManager { * only contains {@link #OPERATION_DOWNLOAD} and ErrorCode is 0 implies this is an unknown * Download error. * - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE} - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE} - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE} - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE} + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE */ public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE"; @@ -552,7 +552,7 @@ public class EuiccManager { /** * List of OperationCode corresponding to {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}'s - * value, an integer. @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * value, an integer. @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE * * @hide */ @@ -575,44 +575,44 @@ public class EuiccManager { /** * Internal system error. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int OPERATION_SYSTEM = 1; /** * SIM slot error. Failed to switch slot, failed to access the physical slot etc. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int OPERATION_SIM_SLOT = 2; /** * eUICC card error. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int OPERATION_EUICC_CARD = 3; /** * Generic switching profile error - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int OPERATION_SWITCH = 4; /** * Download profile error. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int OPERATION_DOWNLOAD = 5; /** * Subscription's metadata error - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int OPERATION_METADATA = 6; /** * eUICC returned an error defined in GSMA (SGP.22 v2.2) while running one of the ES10x * functions. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int OPERATION_EUICC_GSMA = 7; @@ -620,13 +620,13 @@ public class EuiccManager { * The exception of failing to execute an APDU command. It can be caused by an error * happening on opening the basic or logical channel, or the response of the APDU command is * not success (0x9000). - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int OPERATION_APDU = 8; /** * SMDX(SMDP/SMDS) error - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int OPERATION_SMDX = 9; @@ -655,19 +655,19 @@ public class EuiccManager { * Thus the integer stored in {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} is * 0xA8B1051(176885841) * - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int OPERATION_SMDX_SUBJECT_REASON_CODE = 10; /** * HTTP error - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int OPERATION_HTTP = 11; /** * List of ErrorCode corresponding to {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE * @hide */ @Retention(RetentionPolicy.SOURCE) @@ -695,56 +695,56 @@ public class EuiccManager { /** * Operation such as downloading/switching to another profile failed due to device being * carrier locked. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_CARRIER_LOCKED = 10000; /** * The activation code(SGP.22 v2.2 section[4.1]) is invalid. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_INVALID_ACTIVATION_CODE = 10001; /** * The confirmation code(SGP.22 v2.2 section[4.7]) is invalid. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_INVALID_CONFIRMATION_CODE = 10002; /** * The profile's carrier is incompatible with the LPA. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_INCOMPATIBLE_CARRIER = 10003; /** * There is no more space available on the eUICC for new profiles. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_EUICC_INSUFFICIENT_MEMORY = 10004; /** * Timed out while waiting for an operation to complete. i.e restart, disable, * switch reset etc. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_TIME_OUT = 10005; /** * eUICC is missing or defective on the device. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_EUICC_MISSING = 10006; /** * The eUICC card(hardware) version is incompatible with the software - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_UNSUPPORTED_VERSION = 10007; /** * No SIM card is available in the device. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_SIM_MISSING = 10008; @@ -754,52 +754,52 @@ public class EuiccManager { * 2. GSMA(.22 v2.2) Profile Install Result - installFailedDueToDataMismatch * 3. operation was interrupted * 4. SIMalliance error in PEStatus(SGP.22 v2.2 section 2.5.6.1) - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_INSTALL_PROFILE = 10009; /** * Failed to load profile onto eUICC due to Profile Poicly Rules. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_DISALLOWED_BY_PPR = 10010; /** * Address is missing e.g SMDS/SMDP address is missing. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_ADDRESS_MISSING = 10011; /** * Certificate needed for authentication is not valid or missing. E.g SMDP/SMDS authentication * failed. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_CERTIFICATE_ERROR = 10012; /** * No profiles available. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_NO_PROFILES_AVAILABLE = 10013; /** * Failure to create a connection. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_CONNECTION_ERROR = 10014; /** * Response format is invalid. e.g SMDP/SMDS response contains invalid json, header or/and ASN1. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_INVALID_RESPONSE = 10015; /** * The operation is currently busy, try again later. - * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE */ public static final int ERROR_OPERATION_BUSY = 10016; diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 47d8f13bf9ef..29e09a11590b 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -892,7 +892,7 @@ public class WifiManager { * The RSSI (signal strength) has changed. * * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE - * @see {@link #EXTRA_NEW_RSSI} + * @see #EXTRA_NEW_RSSI */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED"; -- GitLab From 72dbe56d760765cb307044a342db286eeec981d4 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Mon, 19 Aug 2019 16:16:20 -0700 Subject: [PATCH 216/219] DO NOT MERGE - Kill apps outright for API contract violations ...rather than relying on in-app code to perform the shutdown. Bug: 128649910 Bug: 140108616 Test: manual Test: atest OsHostTests#testForegroundServiceBadNotification Change-Id: I94d9de50bb03c33666471e3dbd9c721e9278f7cb Merged-In: I94d9de50bb03c33666471e3dbd9c721e9278f7cb (cherry picked from commit 45a53e6cb8d3276126cfe0e717ad7ed486d39b24) (cherry picked from commit e737c1bc6295286a1a44979d2281c3eb637fe8b1) --- core/java/android/app/IActivityManager.aidl | 3 ++- .../com/android/server/am/ActiveServices.java | 11 +++++++- .../server/am/ActivityManagerService.java | 5 ++-- .../am/ActivityManagerShellCommand.java | 2 +- .../java/com/android/server/am/AppErrors.java | 26 ++++++++++++++----- .../com/android/server/am/ServiceRecord.java | 7 +++-- .../NotificationManagerService.java | 2 +- 7 files changed, 39 insertions(+), 17 deletions(-) diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 7a560c07a365..0feed7383020 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -299,7 +299,8 @@ interface IActivityManager { void handleApplicationStrictModeViolation(in IBinder app, int penaltyMask, in StrictMode.ViolationInfo crashInfo); boolean isTopActivityImmersive(); - void crashApplication(int uid, int initialPid, in String packageName, int userId, in String message); + void crashApplication(int uid, int initialPid, in String packageName, int userId, + in String message, boolean force); @UnsupportedAppUsage String getProviderMimeType(in Uri uri, int userId); // Cause the specified process to dump the specified heap. diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 87a8d8c282c4..ead2da660de5 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -842,6 +842,15 @@ public final class ActiveServices { } } + void killMisbehavingService(ServiceRecord r, + int appUid, int appPid, String localPackageName) { + synchronized (mAm) { + stopServiceLocked(r); + mAm.crashApplication(appUid, appPid, localPackageName, -1, + "Bad notification for startForeground", true /*force*/); + } + } + IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) { ServiceLookupResult r = retrieveServiceLocked(service, null, resolvedType, callingPackage, Binder.getCallingPid(), Binder.getCallingUid(), @@ -3949,7 +3958,7 @@ public final class ActiveServices { void serviceForegroundCrash(ProcessRecord app, CharSequence serviceRecord) { mAm.crashApplication(app.uid, app.pid, app.info.packageName, app.userId, "Context.startForegroundService() did not then call Service.startForeground(): " - + serviceRecord); + + serviceRecord, false /*force*/); } void scheduleServiceTimeoutLocked(ProcessRecord proc) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index e2c3d9730305..04941676abe3 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -3596,7 +3596,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void crashApplication(int uid, int initialPid, String packageName, int userId, - String message) { + String message, boolean force) { if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: crashApplication() from pid=" @@ -3608,7 +3608,8 @@ public class ActivityManagerService extends IActivityManager.Stub } synchronized(this) { - mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message); + mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, + message, force); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 5078b8a14eb2..5ab18d95b84d 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -1058,7 +1058,7 @@ final class ActivityManagerShellCommand extends ShellCommand { } catch (NumberFormatException e) { packageName = arg; } - mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash"); + mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash", false); return 0; } diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index a4c695067139..bbd2d34e92a6 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -314,20 +314,24 @@ class AppErrors { } void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) { - app.setCrashing(false); - app.crashingReport = null; - app.setNotResponding(false); - app.notRespondingReport = null; if (app.anrDialog == fromDialog) { app.anrDialog = null; } if (app.waitDialog == fromDialog) { app.waitDialog = null; } + killAppImmediateLocked(app, "user-terminated", "user request after error"); + } + + private void killAppImmediateLocked(ProcessRecord app, String reason, String killReason) { + app.setCrashing(false); + app.crashingReport = null; + app.setNotResponding(false); + app.notRespondingReport = null; if (app.pid > 0 && app.pid != MY_PID) { - handleAppCrashLocked(app, "user-terminated" /*reason*/, + handleAppCrashLocked(app, reason, null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/); - app.kill("user request after error", true); + app.kill(killReason, true); } } @@ -341,7 +345,7 @@ class AppErrors { * @param message */ void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId, - String message) { + String message, boolean force) { ProcessRecord proc = null; // Figure out which process to kill. We don't trust that initialPid @@ -374,6 +378,14 @@ class AppErrors { } proc.scheduleCrash(message); + if (force) { + // If the app is responsive, the scheduled crash will happen as expected + // and then the delayed summary kill will be a no-op. + final ProcessRecord p = proc; + mService.mHandler.postDelayed( + () -> killAppImmediateLocked(p, "forced", "killed for invalid state"), + 5000L); + } } /** diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index dee8e3b285a7..c408695bcb66 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -798,6 +798,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN final String localPackageName = packageName; final int localForegroundId = foregroundId; final Notification _foregroundNoti = foregroundNoti; + final ServiceRecord record = this; ams.mHandler.post(new Runnable() { public void run() { NotificationManagerInternal nm = LocalServices.getService( @@ -896,10 +897,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN Slog.w(TAG, "Error showing notification for service", e); // If it gave us a garbage notification, it doesn't // get to be foreground. - ams.setServiceForeground(instanceName, ServiceRecord.this, - 0, null, 0, 0); - ams.crashApplication(appUid, appPid, localPackageName, -1, - "Bad notification for startForeground: " + e); + ams.mServices.killMisbehavingService(record, + appUid, appPid, localPackageName); } } }); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index a2f191444b63..2d39e9169245 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -920,7 +920,7 @@ public class NotificationManagerService extends SystemService { () -> mAm.crashApplication(uid, initialPid, pkg, -1, "Bad notification(tag=" + tag + ", id=" + id + ") posted from package " + pkg + ", crashing app(uid=" + uid + ", pid=" + initialPid + "): " - + message)); + + message, true /* force */)); } } -- GitLab From 63d9e496f3b9bc140a8b2843f3db18daec0c4ae6 Mon Sep 17 00:00:00 2001 From: Susheel Nyamala Date: Tue, 14 May 2019 16:46:09 +0530 Subject: [PATCH 217/219] Add support for pdp reject retry feature 1. Define config values for retry interval 2. Define config values to operator mcc-mnc config file Bug: 152277258 Test: Compile build for pixel variant Device bootup and camps Change-Id: I0c897589852acecab41bdbf20c8abda7f53c20ab Merged-in: I0c897589852acecab41bdbf20c8abda7f53c20ab (cherry picked from commit b5005dbca893aff869c491033b96287a6ca5ba07) --- core/res/res/values-mcc334-mnc020/config.xml | 5 +++- core/res/res/values-mcc334-mnc020/strings.xml | 25 +++++++++++++++++++ core/res/res/values/config.xml | 5 ++++ core/res/res/values/strings.xml | 6 +++++ core/res/res/values/symbols.xml | 8 ++++++ 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 core/res/res/values-mcc334-mnc020/strings.xml diff --git a/core/res/res/values-mcc334-mnc020/config.xml b/core/res/res/values-mcc334-mnc020/config.xml index 0970517835b6..4aad53460038 100644 --- a/core/res/res/values-mcc334-mnc020/config.xml +++ b/core/res/res/values-mcc334-mnc020/config.xml @@ -18,4 +18,7 @@ --> false - \ No newline at end of file + + true + 45000 + diff --git a/core/res/res/values-mcc334-mnc020/strings.xml b/core/res/res/values-mcc334-mnc020/strings.xml new file mode 100644 index 000000000000..91b560aeef7e --- /dev/null +++ b/core/res/res/values-mcc334-mnc020/strings.xml @@ -0,0 +1,25 @@ + + + + + AUTHENTICATION FAILURE -29-. + NOT SUBSCRIBED TO SERVICE -33-. + Multiple PDN connections for a given APN not allowed -55-. + diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index b945cef17543..7bd34728e28f 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4377,4 +4377,9 @@ com.android.server.location.ComprehensiveCountryDetector + + + false + + -1 diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 738d16ba991c..753ebeae99fe 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -5662,4 +5662,10 @@ ul. IMPI unlock successful. Network subset service provider unlock successful. + + + + + + diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 9ebe9aaf4f39..fc091635ed92 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3877,4 +3877,12 @@ + + + + + + + + -- GitLab From 76df99e11c0ea59a31083d914b5b5e9bcdee0008 Mon Sep 17 00:00:00 2001 From: Greg Kaiser Date: Fri, 8 May 2020 16:31:51 -0700 Subject: [PATCH 218/219] [DO NOT MERGE] Revert "Make libstatssocket shared" This reverts commit 3944f2d9075fc0c01ea8f486eacf7fc843ba0712. Specifically, we're reverting https://googleplex-android-review.git.corp.google.com/c/platform/frameworks/base/+/11419426/1 Test: Local 'm -j71 out/soong/.intermediates/frameworks/base/tools/stats_log_api_gen/libstatslog/android_arm64_armv8-a_shared_com.android.bluetooth.updatable/unstripped/libstatslog.so' Bug: 156091657 Change-Id: I076a3b57123c329ecc68ae36f081f642ac2c48fb --- tools/stats_log_api_gen/Android.bp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp index 964583d0a424..d3958a65c704 100644 --- a/tools/stats_log_api_gen/Android.bp +++ b/tools/stats_log_api_gen/Android.bp @@ -122,13 +122,6 @@ cc_library { "liblog", "libcutils", ], - target: { - android: { - shared_libs: ["libstatssocket"], - }, - host: { - static_libs: ["libstatssocket"], - }, - }, + static_libs: ["libstatssocket"], } -- GitLab From 74148323554faa584d11e6d78372763b154eeeac Mon Sep 17 00:00:00 2001 From: Amit Mahajan Date: Mon, 11 May 2020 16:51:25 -0700 Subject: [PATCH 219/219] Correct a typo in config name. Test: TH Bug: 152277258 Change-Id: I8c4f7a1c84489b8cd3c93dd3c3ca12644ee94ea1 Merged-in: I8c4f7a1c84489b8cd3c93dd3c3ca12644ee94ea1 --- core/res/res/values-mcc334-mnc020/config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/res/res/values-mcc334-mnc020/config.xml b/core/res/res/values-mcc334-mnc020/config.xml index 4aad53460038..82b3ee6448e3 100644 --- a/core/res/res/values-mcc334-mnc020/config.xml +++ b/core/res/res/values-mcc334-mnc020/config.xml @@ -19,6 +19,6 @@ false - true + true 45000 -- GitLab