diff options
101 files changed, 2856 insertions, 649 deletions
diff --git a/Android.mk b/Android.mk index 81154726694c..bd88877b5841 100644 --- a/Android.mk +++ b/Android.mk @@ -126,6 +126,7 @@ LOCAL_SRC_FILES += \ core/java/android/hardware/input/IInputDevicesChangedListener.aidl \ core/java/android/hardware/location/IGeofenceHardware.aidl \ core/java/android/hardware/location/IGeofenceHardwareCallback.aidl \ + core/java/android/hardware/location/IGeofenceHardwareMonitorCallback.aidl \ core/java/android/hardware/usb/IUsbManager.aidl \ core/java/android/net/IConnectivityManager.aidl \ core/java/android/net/INetworkManagementEventObserver.aidl \ diff --git a/api/current.txt b/api/current.txt index 67190661575f..803bb0253475 100644 --- a/api/current.txt +++ b/api/current.txt @@ -4628,13 +4628,11 @@ package android.bluetooth { method public boolean isEnabled(); method public android.bluetooth.BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(java.lang.String, java.util.UUID) throws java.io.IOException; method public android.bluetooth.BluetoothServerSocket listenUsingRfcommWithServiceRecord(java.lang.String, java.util.UUID) throws java.io.IOException; - method public boolean registerCallback(android.bluetooth.BluetoothAdapterCallback); method public boolean setName(java.lang.String); method public boolean startDiscovery(); - method public boolean startLeScan(); - method public boolean startLeScan(java.util.UUID[]); - method public void stopLeScan(); - method public boolean unRegisterCallback(android.bluetooth.BluetoothAdapterCallback); + method public boolean startLeScan(android.bluetooth.BluetoothAdapter.LeScanCallback); + method public boolean startLeScan(java.util.UUID[], android.bluetooth.BluetoothAdapter.LeScanCallback); + method public void stopLeScan(android.bluetooth.BluetoothAdapter.LeScanCallback); field public static final java.lang.String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED"; field public static final java.lang.String ACTION_DISCOVERY_FINISHED = "android.bluetooth.adapter.action.DISCOVERY_FINISHED"; field public static final java.lang.String ACTION_DISCOVERY_STARTED = "android.bluetooth.adapter.action.DISCOVERY_STARTED"; @@ -4665,12 +4663,8 @@ package android.bluetooth { field public static final int STATE_TURNING_ON = 11; // 0xb } - public abstract class BluetoothAdapterCallback { - ctor public BluetoothAdapterCallback(); - method public void onCallbackRegistration(int); - method public void onLeScan(android.bluetooth.BluetoothDevice, int, byte[]); - field public static final int CALLBACK_REGISTERED = 0; // 0x0 - field public static final int CALLBACK_REGISTRATION_FAILURE = 1; // 0x1 + public static abstract interface BluetoothAdapter.LeScanCallback { + method public abstract void onLeScan(android.bluetooth.BluetoothDevice, int, byte[]); } public class BluetoothAssignedNumbers { @@ -10471,13 +10465,14 @@ package android.hardware.input { package android.hardware.location { public final class GeofenceHardware { - method public boolean addCircularFence(int, double, double, double, int, int, int, int, int, android.hardware.location.GeofenceHardwareCallback); - method public int[] getMonitoringTypesAndStatus(); + method public boolean addGeofence(int, int, android.hardware.location.GeofenceHardwareRequest, android.hardware.location.GeofenceHardwareCallback); + method public int[] getMonitoringTypes(); + method public int getStatusOfMonitoringType(int); method public boolean pauseGeofence(int, int); - method public boolean registerForMonitorStateChangeCallback(int, android.hardware.location.GeofenceHardwareCallback); + method public boolean registerForMonitorStateChangeCallback(int, android.hardware.location.GeofenceHardwareMonitorCallback); method public boolean removeGeofence(int, int); method public boolean resumeGeofence(int, int, int); - method public boolean unregisterForMonitorStateChangeCallback(int, android.hardware.location.GeofenceHardwareCallback); + method public boolean unregisterForMonitorStateChangeCallback(int, android.hardware.location.GeofenceHardwareMonitorCallback); field public static final int GEOFENCE_ENTERED = 1; // 0x1 field public static final int GEOFENCE_ERROR_ID_EXISTS = 2; // 0x2 field public static final int GEOFENCE_ERROR_ID_UNKNOWN = 3; // 0x3 @@ -10496,13 +10491,33 @@ package android.hardware.location { public abstract class GeofenceHardwareCallback { ctor public GeofenceHardwareCallback(); method public void onGeofenceAdd(int, int); - method public void onGeofenceChange(int, int, android.location.Location, long, int); method public void onGeofencePause(int, int); method public void onGeofenceRemove(int, int); method public void onGeofenceResume(int, int); + method public void onGeofenceTransition(int, int, android.location.Location, long, int); + } + + public abstract class GeofenceHardwareMonitorCallback { + ctor public GeofenceHardwareMonitorCallback(); method public void onMonitoringSystemChange(int, boolean, android.location.Location); } + public final class GeofenceHardwareRequest { + ctor public GeofenceHardwareRequest(); + method public static android.hardware.location.GeofenceHardwareRequest createCircularGeofence(double, double, double); + method public int getLastTransition(); + method public double getLatitude(); + method public double getLongitude(); + method public int getMonitorTransitions(); + method public int getNotificationResponsiveness(); + method public double getRadius(); + method public int getUnknownTimer(); + method public void setLastTransition(int); + method public void setMonitorTransitions(int); + method public void setNotificationResponsiveness(int); + method public void setUnknownTimer(int); + } + } package android.hardware.usb { @@ -11796,6 +11811,66 @@ package android.media { ctor public MediaCryptoException(java.lang.String); } + public final class MediaDrm { + ctor public MediaDrm(java.util.UUID) throws android.media.MediaDrmException; + method public void closeSession(byte[]); + method public android.media.MediaDrm.CryptoSession getCryptoSession(byte[], java.lang.String, java.lang.String); + method public android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>); + method public byte[] getPropertyByteArray(java.lang.String); + method public java.lang.String getPropertyString(java.lang.String); + method public android.media.MediaDrm.ProvisionRequest getProvisionRequest(); + method public java.util.List<byte[]> getSecureStops(); + method public static final boolean isCryptoSchemeSupported(java.util.UUID); + method public byte[] openSession(); + method public byte[] provideKeyResponse(byte[], byte[]); + method public void provideProvisionResponse(byte[]); + method public java.util.HashMap<java.lang.String, java.lang.String> queryKeyStatus(byte[]); + method public final void release(); + method public void releaseSecureStops(byte[]); + method public void removeKeys(byte[]); + method public void restoreKeys(byte[], byte[]); + method public void setOnEventListener(android.media.MediaDrm.OnEventListener); + method public void setPropertyByteArray(java.lang.String, byte[]); + method public void setPropertyString(java.lang.String, java.lang.String); + field public static final int EVENT_KEY_EXPIRED = 3; // 0x3 + field public static final int EVENT_KEY_REQUIRED = 2; // 0x2 + field public static final int EVENT_PROVISION_REQUIRED = 1; // 0x1 + field public static final int EVENT_VENDOR_DEFINED = 4; // 0x4 + field public static final int KEY_TYPE_OFFLINE = 2; // 0x2 + field public static final int KEY_TYPE_RELEASE = 3; // 0x3 + field public static final int KEY_TYPE_STREAMING = 1; // 0x1 + field public static final java.lang.String PROPERTY_ALGORITHM = "algorithm"; + field public static final java.lang.String PROPERTY_DESCRIPTION = "description"; + field public static final java.lang.String PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId"; + field public static final java.lang.String PROPERTY_VENDOR = "vendor"; + field public static final java.lang.String PROPERTY_VERSION = "version"; + } + + public final class MediaDrm.CryptoSession { + method public byte[] decrypt(byte[], byte[], byte[]); + method public byte[] encrypt(byte[], byte[], byte[]); + method public byte[] sign(byte[], byte[]); + method public boolean verify(byte[], byte[], byte[]); + } + + public static final class MediaDrm.KeyRequest { + method public byte[] getData(); + method public java.lang.String getDefaultUrl(); + } + + public static abstract interface MediaDrm.OnEventListener { + method public abstract void onEvent(android.media.MediaDrm, byte[], int, int, byte[]); + } + + public static final class MediaDrm.ProvisionRequest { + method public byte[] getData(); + method public java.lang.String getDefaultUrl(); + } + + public final class MediaDrmException extends java.lang.Exception { + ctor public MediaDrmException(java.lang.String); + } + public final class MediaExtractor { ctor public MediaExtractor(); method public boolean advance(); @@ -21490,7 +21565,7 @@ package android.telephony { method public int getLac(); method public int getMcc(); method public int getMnc(); - method public int getPsc(); + method public deprecated int getPsc(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; } @@ -21506,6 +21581,17 @@ package android.telephony { field public static final android.os.Parcelable.Creator CREATOR; } + public final class CellIdentityWcdma implements android.os.Parcelable { + method public int describeContents(); + method public int getCid(); + method public int getLac(); + method public int getMcc(); + method public int getMnc(); + method public int getPsc(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator CREATOR; + } + public abstract class CellInfo implements android.os.Parcelable { method public int describeContents(); method public long getTimeStamp(); @@ -21535,6 +21621,13 @@ package android.telephony { field public static final android.os.Parcelable.Creator CREATOR; } + public final class CellInfoWcdma extends android.telephony.CellInfo implements android.os.Parcelable { + method public android.telephony.CellIdentityWcdma getCellIdentity(); + method public android.telephony.CellSignalStrengthWcdma getCellSignalStrength(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator CREATOR; + } + public abstract class CellLocation { ctor public CellLocation(); method public static android.telephony.CellLocation getEmpty(); @@ -21590,6 +21683,17 @@ package android.telephony { field public static final android.os.Parcelable.Creator CREATOR; } + public final class CellSignalStrengthWcdma extends android.telephony.CellSignalStrength implements android.os.Parcelable { + method public int describeContents(); + method public boolean equals(java.lang.Object); + method public int getAsuLevel(); + method public int getDbm(); + method public int getLevel(); + method public int hashCode(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator CREATOR; + } + public class NeighboringCellInfo implements android.os.Parcelable { ctor public deprecated NeighboringCellInfo(); ctor public deprecated NeighboringCellInfo(int, int); diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 2e9c9e334d68..3498bb8e47be 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -20,7 +20,6 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.content.Context; import android.os.Binder; -import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.ParcelUuid; @@ -30,11 +29,14 @@ import android.util.Log; import android.util.Pair; import java.io.IOException; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import java.util.HashMap; import java.util.LinkedList; +import java.util.Map; import java.util.Random; import java.util.Set; import java.util.UUID; @@ -357,9 +359,7 @@ public final class BluetoothAdapter { private final IBluetoothManager mManagerService; private IBluetooth mService; - private Handler mServiceRecordHandler; - private BluetoothAdapterCallback mCallback; - private int mClientIf; + private final Map<LeScanCallback, GattCallbackWrapper> mLeScanClients; /** * Get a handle to the default local Bluetooth adapter. @@ -394,7 +394,7 @@ public final class BluetoothAdapter { mService = managerService.registerAdapter(mManagerCallback); } catch (RemoteException e) {Log.e(TAG, "", e);} mManagerService = managerService; - mServiceRecordHandler = null; + mLeScanClients = new HashMap<LeScanCallback, GattCallbackWrapper>(); } /** @@ -1409,72 +1409,38 @@ public final class BluetoothAdapter { } /** - * Register an callback to receive async results, such as LE scan result. + * Callback interface used to deliver LE scan results. * - * <p>This is an asynchronous call. The callback - * {@link BluetoothAdapterCallback#onCallbackRegistration} - * is used to notify success or failure if the function returns true. - * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param callback BluetootAdapter callback handler that will receive asynchronous callbacks. - * @return If true, the callback will be called to notify success or failure, - * false on immediate error - */ - public boolean registerCallback(BluetoothAdapterCallback callback) { - try { - IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt(); - mCallback = callback; - UUID uuid = UUID.randomUUID(); - if (DBG) Log.d(TAG, "registerCallback() - UUID=" + uuid); - - iGatt.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback); - return true; - } catch (RemoteException e) { - Log.e(TAG,"",e); - return false; - } - } - - /** - * Unregister the registered callback. - */ - public boolean unRegisterCallback(BluetoothAdapterCallback callback) { - if (callback != mCallback) return false; - try { - IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt(); - - iGatt.unregisterClient(mClientIf); - return true; - } catch (RemoteException e) { - Log.e(TAG,"",e); - return false; - } + * @see #startLeScan(LeScanCallback) + * @see #startLeScan(UUID[], LeScanCallback) + */ + public interface LeScanCallback { + /** + * Callback reporting an LE device found during a device scan initiated + * by the {@link BluetoothAdapter#startLeScan} function. + * + * @param device Identifies the remote device + * @param rssi The RSSI value for the remote device as reported by the + * Bluetooth hardware. 0 if no RSSI value is available. + * @param scanRecord The content of the advertisement record offered by + * the remote device. + */ + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord); } /** * Starts a scan for Bluetooth LE devices. * * <p>Results of the scan are reported using the - * {@link BluetoothAdapterCallback#onLeScan} callback. + * {@link LeScanCallback#onLeScan} callback. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * + * @param callback the callback LE scan results are delivered * @return true, if the scan was started successfully */ - public boolean startLeScan() { - if (DBG) Log.d(TAG, "startLeScan()"); - if (mClientIf == 0) return false; - - try { - IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt(); - iGatt.startScan(mClientIf, false); - } catch (RemoteException e) { - Log.e(TAG,"",e); - return false; - } - - return true; + public boolean startLeScan(LeScanCallback callback) { + return startLeScan(null, callback); } /** @@ -1482,155 +1448,281 @@ public final class BluetoothAdapter { * advertise given services. * * <p>Devices which advertise all specified services are reported using the - * {@link BluetoothAdapterCallback#onLeScan} callback. + * {@link LeScanCallback#onLeScan} callback. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @param serviceUuids Array of services to look for + * @param callback the callback LE scan results are delivered * @return true, if the scan was started successfully */ - public boolean startLeScan(UUID[] serviceUuids) { - if (DBG) Log.d(TAG, "startLeScan() - with UUIDs"); - if (mClientIf == 0) return false; + public boolean startLeScan(UUID[] serviceUuids, LeScanCallback callback) { + if (DBG) Log.d(TAG, "startLeScan(): " + serviceUuids); - try { - IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt(); - ParcelUuid[] uuids = new ParcelUuid[serviceUuids.length]; - for(int i = 0; i != uuids.length; ++i) { - uuids[i] = new ParcelUuid(serviceUuids[i]); - } - iGatt.startScanWithUuids(mClientIf, false, uuids); - } catch (RemoteException e) { - Log.e(TAG,"",e); + if (callback == null) { + if (DBG) Log.e(TAG, "startLeScan: null callback"); return false; } - return true; + synchronized(mLeScanClients) { + if (mLeScanClients.containsKey(callback)) { + if (DBG) Log.e(TAG, "LE Scan has already started"); + return false; + } + + try { + IBluetoothGatt iGatt = mManagerService.getBluetoothGatt(); + UUID uuid = UUID.randomUUID(); + GattCallbackWrapper wrapper = new GattCallbackWrapper(this, callback, serviceUuids); + + iGatt.registerClient(new ParcelUuid(uuid), wrapper); + if (wrapper.scanStarted()) { + mLeScanClients.put(callback, wrapper); + return true; + } + } catch (RemoteException e) { + Log.e(TAG,"",e); + } + } + return false; } /** * Stops an ongoing Bluetooth LE device scan. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. - */ - public void stopLeScan() { - if (DBG) Log.d(TAG, "stopScan()"); - if (mClientIf == 0) return; - - try { - IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt(); - iGatt.stopScan(mClientIf, false); - } catch (RemoteException e) { - Log.e(TAG,"",e); + * + * @param callback used to identify which scan to stop + * must be the same handle used to start the scan + */ + public void stopLeScan(LeScanCallback callback) { + if (DBG) Log.d(TAG, "stopLeScan()"); + GattCallbackWrapper wrapper; + synchronized(mLeScanClients) { + wrapper = mLeScanClients.remove(callback); + if (wrapper == null) return; } + wrapper.stopLeScan(); } /** * Bluetooth GATT interface callbacks */ - private final IBluetoothGattCallback mBluetoothGattCallback = - new IBluetoothGattCallback.Stub() { - /** - * Application interface registered - app is ready to go - */ - public void onClientRegistered(int status, int clientIf) { - if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status - + " clientIf=" + clientIf); - mClientIf = clientIf; - mCallback.onCallbackRegistration(status == BluetoothGatt.GATT_SUCCESS ? - BluetoothAdapterCallback.CALLBACK_REGISTERED : - BluetoothAdapterCallback.CALLBACK_REGISTRATION_FAILURE); - } + private static class GattCallbackWrapper extends IBluetoothGattCallback.Stub { + private static final int LE_CALLBACK_REG_TIMEOUT = 2000; + private static final int LE_CALLBACK_REG_WAIT_COUNT = 5; + + private final LeScanCallback mLeScanCb; + // mLeHandle 0: not registered + // -1: scan stopped + // >0: registered and scan started + private int mLeHandle; + private final UUID[] mScanFilter; + private WeakReference<BluetoothAdapter> mBluetoothAdapter; + + public GattCallbackWrapper(BluetoothAdapter bluetoothAdapter, + LeScanCallback leScanCb, UUID[] uuid) { + mBluetoothAdapter = new WeakReference<BluetoothAdapter>(bluetoothAdapter); + mLeScanCb = leScanCb; + mScanFilter = uuid; + mLeHandle = 0; + } - public void onClientConnectionState(int status, int clientIf, - boolean connected, String address) { - // no op + public boolean scanStarted() { + boolean started = false; + synchronized(this) { + if (mLeHandle == -1) return false; + + int count = 0; + // wait for callback registration and LE scan to start + while (mLeHandle == 0 && count < LE_CALLBACK_REG_WAIT_COUNT) { + try { + wait(LE_CALLBACK_REG_TIMEOUT); + } catch (InterruptedException e) { + Log.e(TAG, "Callback reg wait interrupted: " + e); + } + count++; + } + started = (mLeHandle > 0); } + return started; + } - /** - * Callback reporting an LE scan result. - * @hide - */ - public void onScanResult(String address, int rssi, byte[] advData) { - if (DBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi); - - try { - mCallback.onLeScan(getRemoteDevice(address), rssi, advData); - } catch (Exception ex) { - Log.w(TAG, "Unhandled exception: " + ex); + public void stopLeScan() { + synchronized(this) { + if (mLeHandle <= 0) { + Log.e(TAG, "Error state, mLeHandle: " + mLeHandle); + return; + } + BluetoothAdapter adapter = mBluetoothAdapter.get(); + if (adapter != null) { + try { + IBluetoothGatt iGatt = adapter.getBluetoothManager().getBluetoothGatt(); + iGatt.stopScan(mLeHandle, false); + iGatt.unregisterClient(mLeHandle); + } catch (RemoteException e) { + Log.e(TAG, "Failed to stop scan and unregister" + e); + } + } else { + Log.e(TAG, "stopLeScan, BluetoothAdapter is null"); } + mLeHandle = -1; + notifyAll(); } + } - public void onGetService(String address, int srvcType, - int srvcInstId, ParcelUuid srvcUuid) { - // no op - } + /** + * Application interface registered - app is ready to go + */ + public void onClientRegistered(int status, int clientIf) { + if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status + + " clientIf=" + clientIf); + synchronized(this) { + if (mLeHandle == -1) { + if (DBG) Log.d(TAG, "onClientRegistered LE scan canceled"); + } - public void onGetIncludedService(String address, int srvcType, - int srvcInstId, ParcelUuid srvcUuid, - int inclSrvcType, int inclSrvcInstId, - ParcelUuid inclSrvcUuid) { - // no op + if (status == BluetoothGatt.GATT_SUCCESS) { + mLeHandle = clientIf; + IBluetoothGatt iGatt = null; + try { + BluetoothAdapter adapter = mBluetoothAdapter.get(); + if (adapter != null) { + iGatt = adapter.getBluetoothManager().getBluetoothGatt(); + if (mScanFilter == null) { + iGatt.startScan(mLeHandle, false); + } else { + ParcelUuid[] uuids = new ParcelUuid[mScanFilter.length]; + for(int i = 0; i != uuids.length; ++i) { + uuids[i] = new ParcelUuid(mScanFilter[i]); + } + iGatt.startScanWithUuids(mLeHandle, false, uuids); + } + } else { + Log.e(TAG, "onClientRegistered, BluetoothAdapter null"); + mLeHandle = -1; + } + } catch (RemoteException e) { + Log.e(TAG, "fail to start le scan: " + e); + mLeHandle = -1; + } + if (mLeHandle == -1) { + // registration succeeded but start scan failed + if (iGatt != null) { + try { + iGatt.unregisterClient(mLeHandle); + } catch (RemoteException e) { + Log.e(TAG, "fail to unregister callback: " + mLeHandle + + " error: " + e); + } + } + } + } else { + // registration failed + mLeHandle = -1; + } + notifyAll(); } + } - public void onGetCharacteristic(String address, int srvcType, - int srvcInstId, ParcelUuid srvcUuid, - int charInstId, ParcelUuid charUuid, - int charProps) { - // no op - } + public void onClientConnectionState(int status, int clientIf, + boolean connected, String address) { + // no op + } - public void onGetDescriptor(String address, int srvcType, - int srvcInstId, ParcelUuid srvcUuid, - int charInstId, ParcelUuid charUuid, - ParcelUuid descUuid) { - // no op - } + /** + * Callback reporting an LE scan result. + * @hide + */ + public void onScanResult(String address, int rssi, byte[] advData) { + if (DBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi); - public void onSearchComplete(String address, int status) { - // no op + // Check null in case the scan has been stopped + synchronized(this) { + if (mLeHandle <= 0) return; } - - public void onCharacteristicRead(String address, int status, int srvcType, - int srvcInstId, ParcelUuid srvcUuid, - int charInstId, ParcelUuid charUuid, byte[] value) { - // no op + try { + BluetoothAdapter adapter = mBluetoothAdapter.get(); + if (adapter == null) { + Log.d(TAG, "onScanResult, BluetoothAdapter null"); + return; + } + mLeScanCb.onLeScan(adapter.getRemoteDevice(address), rssi, advData); + } catch (Exception ex) { + Log.w(TAG, "Unhandled exception: " + ex); } + } - public void onCharacteristicWrite(String address, int status, int srvcType, - int srvcInstId, ParcelUuid srvcUuid, - int charInstId, ParcelUuid charUuid) { - // no op - } + public void onGetService(String address, int srvcType, + int srvcInstId, ParcelUuid srvcUuid) { + // no op + } + + public void onGetIncludedService(String address, int srvcType, + int srvcInstId, ParcelUuid srvcUuid, + int inclSrvcType, int inclSrvcInstId, + ParcelUuid inclSrvcUuid) { + // no op + } - public void onNotify(String address, int srvcType, + public void onGetCharacteristic(String address, int srvcType, + int srvcInstId, ParcelUuid srvcUuid, + int charInstId, ParcelUuid charUuid, + int charProps) { + // no op + } + + public void onGetDescriptor(String address, int srvcType, + int srvcInstId, ParcelUuid srvcUuid, + int charInstId, ParcelUuid charUuid, + ParcelUuid descUuid) { + // no op + } + + public void onSearchComplete(String address, int status) { + // no op + } + + public void onCharacteristicRead(String address, int status, int srvcType, + int srvcInstId, ParcelUuid srvcUuid, + int charInstId, ParcelUuid charUuid, byte[] value) { + // no op + } + + public void onCharacteristicWrite(String address, int status, int srvcType, + int srvcInstId, ParcelUuid srvcUuid, + int charInstId, ParcelUuid charUuid) { + // no op + } + + public void onNotify(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, byte[] value) { - // no op - } + // no op + } - public void onDescriptorRead(String address, int status, int srvcType, - int srvcInstId, ParcelUuid srvcUuid, - int charInstId, ParcelUuid charUuid, - ParcelUuid descrUuid, byte[] value) { - // no op - } + public void onDescriptorRead(String address, int status, int srvcType, + int srvcInstId, ParcelUuid srvcUuid, + int charInstId, ParcelUuid charUuid, + ParcelUuid descrUuid, byte[] value) { + // no op + } - public void onDescriptorWrite(String address, int status, int srvcType, - int srvcInstId, ParcelUuid srvcUuid, - int charInstId, ParcelUuid charUuid, - ParcelUuid descrUuid) { - // no op - } + public void onDescriptorWrite(String address, int status, int srvcType, + int srvcInstId, ParcelUuid srvcUuid, + int charInstId, ParcelUuid charUuid, + ParcelUuid descrUuid) { + // no op + } - public void onExecuteWrite(String address, int status) { - // no op - } + public void onExecuteWrite(String address, int status) { + // no op + } - public void onReadRemoteRssi(String address, int rssi, int status) { - // no op - } - }; + public void onReadRemoteRssi(String address, int rssi, int status) { + // no op + } + } } diff --git a/core/java/android/bluetooth/BluetoothAdapterCallback.java b/core/java/android/bluetooth/BluetoothAdapterCallback.java deleted file mode 100644 index a726bc91895b..000000000000 --- a/core/java/android/bluetooth/BluetoothAdapterCallback.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth; - -import android.bluetooth.BluetoothDevice; - -/** - * This abstract class is used to implement {@link BluetoothAdapter} callbacks. - */ -public abstract class BluetoothAdapterCallback { - - /** - * Indicates the callback has been registered successfully - */ - public static final int CALLBACK_REGISTERED = 0; - - /** - * Indicates the callback registration has failed - */ - public static final int CALLBACK_REGISTRATION_FAILURE = 1; - - /** - * Callback to inform change in registration state of the application. - * - * @param status Returns {@link #CALLBACK_REGISTERED} if the application - * was successfully registered. - */ - public void onCallbackRegistration(int status) { - } - - /** - * Callback reporting an LE device found during a device scan initiated - * by the {@link BluetoothAdapter#startLeScan} function. - * - * @param device Identifies the remote device - * @param rssi The RSSI value for the remote device as reported by the - * Bluetooth hardware. 0 if no RSSI value is available. - * @param scanRecord The content of the advertisement record offered by - * the remote device. - */ - public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { - } -} diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java index 19083b55dac2..172f3bcdefed 100644 --- a/core/java/android/bluetooth/BluetoothManager.java +++ b/core/java/android/bluetooth/BluetoothManager.java @@ -127,7 +127,7 @@ public final class BluetoothManager { try { IBluetoothManager managerService = mAdapter.getBluetoothManager(); - IBluetoothGatt iGatt = (IBluetoothGatt) managerService.getBluetoothGatt(); + IBluetoothGatt iGatt = managerService.getBluetoothGatt(); if (iGatt == null) return connectedDevices; connectedDevices = iGatt.getDevicesMatchingConnectionStates( @@ -172,7 +172,7 @@ public final class BluetoothManager { try { IBluetoothManager managerService = mAdapter.getBluetoothManager(); - IBluetoothGatt iGatt = (IBluetoothGatt) managerService.getBluetoothGatt(); + IBluetoothGatt iGatt = managerService.getBluetoothGatt(); if (iGatt == null) return devices; devices = iGatt.getDevicesMatchingConnectionStates(states); } catch (RemoteException e) { @@ -203,7 +203,7 @@ public final class BluetoothManager { try { IBluetoothManager managerService = mAdapter.getBluetoothManager(); - IBluetoothGatt iGatt = (IBluetoothGatt) managerService.getBluetoothGatt(); + IBluetoothGatt iGatt = managerService.getBluetoothGatt(); if (iGatt == null) { Log.e(TAG, "Fail to get GATT Server connection"); return null; diff --git a/core/java/android/hardware/location/GeofenceHardware.java b/core/java/android/hardware/location/GeofenceHardware.java index 35bbb9c1bf8b..e67d0d7fd974 100644 --- a/core/java/android/hardware/location/GeofenceHardware.java +++ b/core/java/android/hardware/location/GeofenceHardware.java @@ -129,6 +129,9 @@ public final class GeofenceHardware { private HashMap<GeofenceHardwareCallback, GeofenceHardwareCallbackWrapper> mCallbacks = new HashMap<GeofenceHardwareCallback, GeofenceHardwareCallbackWrapper>(); + private HashMap<GeofenceHardwareMonitorCallback, GeofenceHardwareMonitorCallbackWrapper> + mMonitorCallbacks = new HashMap<GeofenceHardwareMonitorCallback, + GeofenceHardwareMonitorCallbackWrapper>(); /** * @hide */ @@ -137,8 +140,29 @@ public final class GeofenceHardware { } /** - * Returns all the hardware geofence monitoring systems and their status. - * Status can be one of {@link #MONITOR_CURRENTLY_AVAILABLE}, + * Returns all the hardware geofence monitoring systems which are supported + * + * <p> Call {@link #getStatusOfMonitoringType(int)} to know the current state + * of a monitoring system. + * + * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access + * geofencing in hardware. + * + * @return An array of all the monitoring types. + * An array of length 0 is returned in case of errors. + */ + public int[] getMonitoringTypes() { + try { + return mService.getMonitoringTypes(); + } catch (RemoteException e) { + } + return new int[0]; + } + + /** + * Returns current status of a hardware geofence monitoring system. + * + * <p>Status can be one of {@link #MONITOR_CURRENTLY_AVAILABLE}, * {@link #MONITOR_CURRENTLY_UNAVAILABLE} or {@link #MONITOR_UNSUPPORTED} * * <p> Some supported hardware monitoring systems might not be available @@ -147,18 +171,15 @@ public final class GeofenceHardware { * geofences and will change from {@link #MONITOR_CURRENTLY_AVAILABLE} to * {@link #MONITOR_CURRENTLY_UNAVAILABLE}. * - * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access - * geofencing in hardware. - * - * @return An array indexed by the various monitoring types and their status. - * An array of length 0 is returned in case of errors. + * @param monitoringType + * @return Current status of the monitoring type. */ - public int[] getMonitoringTypesAndStatus() { + public int getStatusOfMonitoringType(int monitoringType) { try { - return mService.getMonitoringTypesAndStatus(); + return mService.getStatusOfMonitoringType(monitoringType); } catch (RemoteException e) { + return MONITOR_UNSUPPORTED; } - return new int[0]; } /** @@ -167,8 +188,10 @@ public final class GeofenceHardware { * <p> When the device detects that is has entered, exited or is uncertain * about the area specified by the geofence, the given callback will be called. * - * <p> The {@link GeofenceHardwareCallback#onGeofenceChange} callback will be called, - * with the following parameters + * <p> If this call returns true, it means that the geofence has been sent to the hardware. + * {@link GeofenceHardwareCallback#onGeofenceAdd} will be called with the result of the + * add call from the hardware. The {@link GeofenceHardwareCallback#onGeofenceAdd} will be + * called with the following parameters when a transition event occurs. * <ul> * <li> The geofence Id * <li> The location object indicating the last known location. @@ -195,43 +218,46 @@ public final class GeofenceHardware { * which abstracts the hardware should be used instead. All the checks are done by the higher * level public API. Any needed locking should be handled by the higher level API. * - * @param latitude Latitude of the area to be monitored. - * @param longitude Longitude of the area to be monitored. - * @param radius Radius (in meters) of the area to be monitored. - * @param lastTransition The current state of the geofence. Can be one of - * {@link #GEOFENCE_ENTERED}, {@link #GEOFENCE_EXITED}, - * {@link #GEOFENCE_UNCERTAIN}. - * @param monitorTransitions Bitwise OR of {@link #GEOFENCE_ENTERED}, - * {@link #GEOFENCE_EXITED}, {@link #GEOFENCE_UNCERTAIN} - * @param notificationResponsivenes Defines the best-effort description - * of how soon should the callback be called when the transition - * associated with the Geofence is triggered. For instance, if - * set to 1000 millseconds with {@link #GEOFENCE_ENTERED}, - * the callback will be called 1000 milliseconds within entering - * the geofence. This parameter is defined in milliseconds. - * @param unknownTimer The time limit after which the - * {@link #GEOFENCE_UNCERTAIN} transition - * should be triggered. This paramter is defined in milliseconds. + * <p> Create a geofence request object using the methods in {@link GeofenceHardwareRequest} to + * set all the characteristics of the geofence. Use the created GeofenceHardwareRequest object + * in this call. + * + * @param geofenceId The id associated with the geofence. * @param monitoringType The type of the hardware subsystem that should be used * to monitor the geofence. + * @param geofenceRequest The {@link GeofenceHardwareRequest} object associated with the + * geofence. * @param callback {@link GeofenceHardwareCallback} that will be use to notify the * transition. - * @return true on success. + * @return true when the geofence is successfully sent to the hardware for addition. + * @throws IllegalArgumentException when the geofence request type is not supported. */ - public boolean addCircularFence(int geofenceId, double latitude, double longitude, - double radius, int lastTransition,int monitorTransitions, int notificationResponsivenes, - int unknownTimer, int monitoringType, GeofenceHardwareCallback callback) { + public boolean addGeofence(int geofenceId, int monitoringType, GeofenceHardwareRequest + geofenceRequest, GeofenceHardwareCallback callback) { try { - return mService.addCircularFence(geofenceId, latitude, longitude, radius, - lastTransition, monitorTransitions, notificationResponsivenes, unknownTimer, - monitoringType, getCallbackWrapper(callback)); + if (geofenceRequest.getType() == GeofenceHardwareRequest.GEOFENCE_TYPE_CIRCLE) { + return mService.addCircularFence(geofenceId, monitoringType, + geofenceRequest.getLatitude(), + geofenceRequest.getLongitude(), geofenceRequest.getRadius(), + geofenceRequest.getLastTransition(), + geofenceRequest.getMonitorTransitions(), + geofenceRequest.getNotificationResponsiveness(), + geofenceRequest.getUnknownTimer(), + getCallbackWrapper(callback)); + } else { + throw new IllegalArgumentException("Geofence Request type not supported"); + } } catch (RemoteException e) { } return false; } /** - * Removes a geofence added by {@link #addCircularFence} call. + * Removes a geofence added by {@link #addGeofence} call. + * + * <p> If this call returns true, it means that the geofence has been sent to the hardware. + * {@link GeofenceHardwareCallback#onGeofenceRemove} will be called with the result of the + * remove call from the hardware. * * <p> Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission when * {@link #MONITORING_TYPE_GPS_HARDWARE} is used. @@ -246,7 +272,7 @@ public final class GeofenceHardware { * @param geofenceId The id of the geofence. * @param monitoringType The type of the hardware subsystem that should be used * to monitor the geofence. - * @return true on success. + * @return true when the geofence is successfully sent to the hardware for removal. . */ public boolean removeGeofence(int geofenceId, int monitoringType) { try { @@ -257,7 +283,11 @@ public final class GeofenceHardware { } /** - * Pauses the monitoring of a geofence added by {@link #addCircularFence} call. + * Pauses the monitoring of a geofence added by {@link #addGeofence} call. + * + * <p> If this call returns true, it means that the geofence has been sent to the hardware. + * {@link GeofenceHardwareCallback#onGeofencePause} will be called with the result of the + * pause call from the hardware. * * <p> Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission when * {@link #MONITORING_TYPE_GPS_HARDWARE} is used. @@ -272,7 +302,7 @@ public final class GeofenceHardware { * @param geofenceId The id of the geofence. * @param monitoringType The type of the hardware subsystem that should be used * to monitor the geofence. - * @return true on success. + * @return true when the geofence is successfully sent to the hardware for pausing. */ public boolean pauseGeofence(int geofenceId, int monitoringType) { try { @@ -285,6 +315,10 @@ public final class GeofenceHardware { /** * Resumes the monitoring of a geofence added by {@link #pauseGeofence} call. * + * <p> If this call returns true, it means that the geofence has been sent to the hardware. + * {@link GeofenceHardwareCallback#onGeofenceResume} will be called with the result of the + * resume call from the hardware. + * * <p> Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission when * {@link #MONITORING_TYPE_GPS_HARDWARE} is used. * @@ -296,15 +330,15 @@ public final class GeofenceHardware { * level public API. Any needed locking should be handled by the higher level API. * * @param geofenceId The id of the geofence. - * @param monitorTransition Bitwise OR of {@link #GEOFENCE_ENTERED}, - * {@link #GEOFENCE_EXITED}, {@link #GEOFENCE_UNCERTAIN} * @param monitoringType The type of the hardware subsystem that should be used * to monitor the geofence. - * @return true on success. + * @param monitorTransition Bitwise OR of {@link #GEOFENCE_ENTERED}, + * {@link #GEOFENCE_EXITED}, {@link #GEOFENCE_UNCERTAIN} + * @return true when the geofence is successfully sent to the hardware for resumption. */ - public boolean resumeGeofence(int geofenceId, int monitorTransition, int monitoringType) { + public boolean resumeGeofence(int geofenceId, int monitoringType, int monitorTransition) { try { - return mService.resumeGeofence(geofenceId, monitorTransition, monitoringType); + return mService.resumeGeofence(geofenceId, monitoringType, monitorTransition); } catch (RemoteException e) { } return false; @@ -333,10 +367,10 @@ public final class GeofenceHardware { * @return true on success */ public boolean registerForMonitorStateChangeCallback(int monitoringType, - GeofenceHardwareCallback callback) { + GeofenceHardwareMonitorCallback callback) { try { return mService.registerForMonitorStateChangeCallback(monitoringType, - getCallbackWrapper(callback)); + getMonitorCallbackWrapper(callback)); } catch (RemoteException e) { } return false; @@ -361,12 +395,12 @@ public final class GeofenceHardware { * @return true on success */ public boolean unregisterForMonitorStateChangeCallback(int monitoringType, - GeofenceHardwareCallback callback) { + GeofenceHardwareMonitorCallback callback) { boolean result = false; try { result = mService.unregisterForMonitorStateChangeCallback(monitoringType, - getCallbackWrapper(callback)); - if (result) removeCallback(callback); + getMonitorCallbackWrapper(callback)); + if (result) removeMonitorCallback(callback); } catch (RemoteException e) { } @@ -391,24 +425,50 @@ public final class GeofenceHardware { } } - class GeofenceHardwareCallbackWrapper extends IGeofenceHardwareCallback.Stub { - private WeakReference<GeofenceHardwareCallback> mCallback; + private void removeMonitorCallback(GeofenceHardwareMonitorCallback callback) { + synchronized (mMonitorCallbacks) { + mMonitorCallbacks.remove(callback); + } + } - GeofenceHardwareCallbackWrapper(GeofenceHardwareCallback c) { - mCallback = new WeakReference<GeofenceHardwareCallback>(c); + private GeofenceHardwareMonitorCallbackWrapper getMonitorCallbackWrapper( + GeofenceHardwareMonitorCallback callback) { + synchronized (mMonitorCallbacks) { + GeofenceHardwareMonitorCallbackWrapper wrapper = mMonitorCallbacks.get(callback); + if (wrapper == null) { + wrapper = new GeofenceHardwareMonitorCallbackWrapper(callback); + mMonitorCallbacks.put(callback, wrapper); + } + return wrapper; + } + } + + class GeofenceHardwareMonitorCallbackWrapper extends IGeofenceHardwareMonitorCallback.Stub { + private WeakReference<GeofenceHardwareMonitorCallback> mCallback; + + GeofenceHardwareMonitorCallbackWrapper(GeofenceHardwareMonitorCallback c) { + mCallback = new WeakReference<GeofenceHardwareMonitorCallback>(c); } public void onMonitoringSystemChange(int monitoringType, boolean available, Location location) { - GeofenceHardwareCallback c = mCallback.get(); + GeofenceHardwareMonitorCallback c = mCallback.get(); if (c != null) c.onMonitoringSystemChange(monitoringType, available, location); } + } + + class GeofenceHardwareCallbackWrapper extends IGeofenceHardwareCallback.Stub { + private WeakReference<GeofenceHardwareCallback> mCallback; - public void onGeofenceChange(int geofenceId, int transition, Location location, + GeofenceHardwareCallbackWrapper(GeofenceHardwareCallback c) { + mCallback = new WeakReference<GeofenceHardwareCallback>(c); + } + + public void onGeofenceTransition(int geofenceId, int transition, Location location, long timestamp, int monitoringType) { GeofenceHardwareCallback c = mCallback.get(); if (c != null) { - c.onGeofenceChange(geofenceId, transition, location, timestamp, + c.onGeofenceTransition(geofenceId, transition, location, timestamp, monitoringType); } } @@ -428,7 +488,9 @@ public final class GeofenceHardware { public void onGeofencePause(int geofenceId, int status) { GeofenceHardwareCallback c = mCallback.get(); - if (c != null) c.onGeofencePause(geofenceId, status); + if (c != null) { + c.onGeofencePause(geofenceId, status); + } } public void onGeofenceResume(int geofenceId, int status) { diff --git a/core/java/android/hardware/location/GeofenceHardwareCallback.java b/core/java/android/hardware/location/GeofenceHardwareCallback.java index 8ab582aa24c4..6cad3dac54e4 100644 --- a/core/java/android/hardware/location/GeofenceHardwareCallback.java +++ b/core/java/android/hardware/location/GeofenceHardwareCallback.java @@ -22,19 +22,6 @@ import android.location.Location; * The callback class associated with the APIs in {@link GeofenceHardware} */ public abstract class GeofenceHardwareCallback { - - /** - * The callback called when the state of a monitoring system changes. - * {@link GeofenceHardware#MONITORING_TYPE_GPS_HARDWARE} is an example of a - * monitoring system. - * - * @param monitoringType The type of the monitoring system. - * @param available Indicates whether the system is currently available or not. - * @param location The last known location according to the monitoring system. - */ - public void onMonitoringSystemChange(int monitoringType, boolean available, Location location) { - } - /** * The callback called when there is a transition to report for the specific * geofence. @@ -47,7 +34,7 @@ public abstract class GeofenceHardwareCallback { * detected * @param monitoringType Type of the monitoring system. */ - public void onGeofenceChange(int geofenceId, int transition, Location location, + public void onGeofenceTransition(int geofenceId, int transition, Location location, long timestamp, int monitoringType) { } diff --git a/core/java/android/hardware/location/GeofenceHardwareImpl.java b/core/java/android/hardware/location/GeofenceHardwareImpl.java index 21f1ea61031e..a62b6606abe2 100644 --- a/core/java/android/hardware/location/GeofenceHardwareImpl.java +++ b/core/java/android/hardware/location/GeofenceHardwareImpl.java @@ -21,8 +21,10 @@ import android.content.pm.PackageManager; import android.location.IGpsGeofenceHardware; import android.location.Location; import android.location.LocationManager; +import android.os.Binder; import android.os.Bundle; import android.os.Handler; +import android.os.IBinder; import android.os.Message; import android.os.PowerManager; import android.os.RemoteException; @@ -48,8 +50,9 @@ public final class GeofenceHardwareImpl { private PowerManager.WakeLock mWakeLock; private SparseArray<IGeofenceHardwareCallback> mGeofences = new SparseArray<IGeofenceHardwareCallback>(); - private ArrayList<IGeofenceHardwareCallback>[] mCallbacks = + private ArrayList<IGeofenceHardwareMonitorCallback>[] mCallbacks = new ArrayList[GeofenceHardware.NUM_MONITORS]; + private ArrayList<Reaper> mReapers = new ArrayList<Reaper>(); private IGpsGeofenceHardware mGpsService; @@ -63,11 +66,18 @@ public final class GeofenceHardwareImpl { private static final int RESUME_GEOFENCE_CALLBACK = 5; private static final int ADD_GEOFENCE = 6; private static final int REMOVE_GEOFENCE = 7; + private static final int GEOFENCE_CALLBACK_BINDER_DIED = 8; // mCallbacksHandler message types private static final int GPS_GEOFENCE_STATUS = 1; private static final int CALLBACK_ADD = 2; private static final int CALLBACK_REMOVE = 3; + private static final int MONITOR_CALLBACK_BINDER_DIED = 4; + + // mReaperHandler message types + private static final int REAPER_GEOFENCE_ADDED = 1; + private static final int REAPER_MONITOR_CALLBACK_ADDED = 2; + private static final int REAPER_REMOVED = 3; // The following constants need to match GpsLocationFlags enum in gps.h private static final int LOCATION_INVALID = 0; @@ -151,15 +161,28 @@ public final class GeofenceHardwareImpl { } } - public int[] getMonitoringTypesAndStatus() { + public int[] getMonitoringTypes() { synchronized (mSupportedMonitorTypes) { - return mSupportedMonitorTypes; + if (mSupportedMonitorTypes[GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE] != + GeofenceHardware.MONITOR_UNSUPPORTED) { + return new int[] {GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE}; + } + return new int[0]; + } + } + + public int getStatusOfMonitoringType(int monitoringType) { + synchronized (mSupportedMonitorTypes) { + if (monitoringType >= mSupportedMonitorTypes.length || monitoringType < 0) { + throw new IllegalArgumentException("Unknown monitoring type"); + } + return mSupportedMonitorTypes[monitoringType]; } } - public boolean addCircularFence(int geofenceId, double latitude, double longitude, - double radius, int lastTransition,int monitorTransitions, int notificationResponsivenes, - int unknownTimer, int monitoringType, IGeofenceHardwareCallback callback) { + public boolean addCircularFence(int geofenceId, int monitoringType, double latitude, + double longitude, double radius, int lastTransition,int monitorTransitions, + int notificationResponsivenes, int unknownTimer, IGeofenceHardwareCallback callback) { // This API is not thread safe. Operations on the same geofence need to be serialized // by upper layers if (DEBUG) { @@ -190,7 +213,11 @@ public final class GeofenceHardwareImpl { default: result = false; } - if (!result) { + if (result) { + m = mReaperHandler.obtainMessage(REAPER_GEOFENCE_ADDED, callback); + m.arg1 = monitoringType; + mReaperHandler.sendMessage(m); + } else { m = mGeofenceHandler.obtainMessage(REMOVE_GEOFENCE); m.arg1 = geofenceId; mGeofenceHandler.sendMessage(m); @@ -245,7 +272,7 @@ public final class GeofenceHardwareImpl { } - public boolean resumeGeofence(int geofenceId, int monitorTransition, int monitoringType) { + public boolean resumeGeofence(int geofenceId, int monitoringType, int monitorTransition) { // This API is not thread safe. Operations on the same geofence need to be serialized // by upper layers if (DEBUG) Log.d(TAG, "Resume Geofence: GeofenceId: " + geofenceId); @@ -268,7 +295,12 @@ public final class GeofenceHardwareImpl { } public boolean registerForMonitorStateChangeCallback(int monitoringType, - IGeofenceHardwareCallback callback) { + IGeofenceHardwareMonitorCallback callback) { + Message reaperMessage = + mReaperHandler.obtainMessage(REAPER_MONITOR_CALLBACK_ADDED, callback); + reaperMessage.arg1 = monitoringType; + mReaperHandler.sendMessage(reaperMessage); + Message m = mCallbacksHandler.obtainMessage(CALLBACK_ADD, callback); m.arg1 = monitoringType; mCallbacksHandler.sendMessage(m); @@ -276,7 +308,7 @@ public final class GeofenceHardwareImpl { } public boolean unregisterForMonitorStateChangeCallback(int monitoringType, - IGeofenceHardwareCallback callback) { + IGeofenceHardwareMonitorCallback callback) { Message m = mCallbacksHandler.obtainMessage(CALLBACK_REMOVE, callback); m.arg1 = monitoringType; mCallbacksHandler.sendMessage(m); @@ -477,13 +509,25 @@ public final class GeofenceHardwareImpl { "Location: " + geofenceTransition.mLocation + ":" + mGeofences); try { - callback.onGeofenceChange( + callback.onGeofenceTransition( geofenceTransition.mGeofenceId, geofenceTransition.mTransition, geofenceTransition.mLocation, geofenceTransition.mTimestamp, GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE); } catch (RemoteException e) {} releaseWakeLock(); break; + case GEOFENCE_CALLBACK_BINDER_DIED: + // Find all geofences associated with this callback and remove them. + callback = (IGeofenceHardwareCallback) (msg.obj); + if (DEBUG) Log.d(TAG, "Geofence callback reaped:" + callback); + int monitoringType = msg.arg1; + for (int i = 0; i < mGeofences.size(); i++) { + if (mGeofences.valueAt(i).equals(callback)) { + geofenceId = mGeofences.keyAt(i); + removeGeofence(mGeofences.keyAt(i), monitoringType); + mGeofences.remove(geofenceId); + } + } } } }; @@ -493,8 +537,8 @@ public final class GeofenceHardwareImpl { @Override public void handleMessage(Message msg) { int monitoringType; - ArrayList<IGeofenceHardwareCallback> callbackList; - IGeofenceHardwareCallback callback; + ArrayList<IGeofenceHardwareMonitorCallback> callbackList; + IGeofenceHardwareMonitorCallback callback; switch (msg.what) { case GPS_GEOFENCE_STATUS: @@ -508,7 +552,7 @@ public final class GeofenceHardwareImpl { if (DEBUG) Log.d(TAG, "MonitoringSystemChangeCallback: GPS : " + available); - for (IGeofenceHardwareCallback c: callbackList) { + for (IGeofenceHardwareMonitorCallback c: callbackList) { try { c.onMonitoringSystemChange( GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, available, @@ -519,22 +563,71 @@ public final class GeofenceHardwareImpl { break; case CALLBACK_ADD: monitoringType = msg.arg1; - callback = (IGeofenceHardwareCallback) msg.obj; + callback = (IGeofenceHardwareMonitorCallback) msg.obj; callbackList = mCallbacks[monitoringType]; if (callbackList == null) { - callbackList = new ArrayList<IGeofenceHardwareCallback>(); + callbackList = new ArrayList<IGeofenceHardwareMonitorCallback>(); mCallbacks[monitoringType] = callbackList; } if (!callbackList.contains(callback)) callbackList.add(callback); break; case CALLBACK_REMOVE: monitoringType = msg.arg1; - callback = (IGeofenceHardwareCallback) msg.obj; + callback = (IGeofenceHardwareMonitorCallback) msg.obj; callbackList = mCallbacks[monitoringType]; if (callbackList != null) { callbackList.remove(callback); } break; + case MONITOR_CALLBACK_BINDER_DIED: + callback = (IGeofenceHardwareMonitorCallback) msg.obj; + if (DEBUG) Log.d(TAG, "Monitor callback reaped:" + callback); + callbackList = mCallbacks[msg.arg1]; + if (callbackList != null && callbackList.contains(callback)) { + callbackList.remove(callback); + } + } + } + }; + + // All operations on mReaper + private Handler mReaperHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + Reaper r; + IGeofenceHardwareCallback callback; + IGeofenceHardwareMonitorCallback monitorCallback; + int monitoringType; + + switch (msg.what) { + case REAPER_GEOFENCE_ADDED: + callback = (IGeofenceHardwareCallback) msg.obj; + monitoringType = msg.arg1; + r = new Reaper(callback, monitoringType); + if (!mReapers.contains(r)) { + mReapers.add(r); + IBinder b = callback.asBinder(); + try { + b.linkToDeath(r, 0); + } catch (RemoteException e) {} + } + break; + case REAPER_MONITOR_CALLBACK_ADDED: + monitorCallback = (IGeofenceHardwareMonitorCallback) msg.obj; + monitoringType = msg.arg1; + + r = new Reaper(monitorCallback, monitoringType); + if (!mReapers.contains(r)) { + mReapers.add(r); + IBinder b = monitorCallback.asBinder(); + try { + b.linkToDeath(r, 0); + } catch (RemoteException e) {} + } + break; + case REAPER_REMOVED: + r = (Reaper) msg.obj; + mReapers.remove(r); } } }; @@ -567,6 +660,57 @@ public final class GeofenceHardwareImpl { return RESOLUTION_LEVEL_NONE; } + class Reaper implements IBinder.DeathRecipient { + private IGeofenceHardwareMonitorCallback mMonitorCallback; + private IGeofenceHardwareCallback mCallback; + private int mMonitoringType; + + Reaper(IGeofenceHardwareCallback c, int monitoringType) { + mCallback = c; + mMonitoringType = monitoringType; + } + + Reaper(IGeofenceHardwareMonitorCallback c, int monitoringType) { + mMonitorCallback = c; + mMonitoringType = monitoringType; + } + + @Override + public void binderDied() { + Message m; + if (mCallback != null) { + m = mGeofenceHandler.obtainMessage(GEOFENCE_CALLBACK_BINDER_DIED, mCallback); + m.arg1 = mMonitoringType; + mGeofenceHandler.sendMessage(m); + } else if (mMonitorCallback != null) { + m = mCallbacksHandler.obtainMessage(MONITOR_CALLBACK_BINDER_DIED, mMonitorCallback); + m.arg1 = mMonitoringType; + mCallbacksHandler.sendMessage(m); + } + Message reaperMessage = mReaperHandler.obtainMessage(REAPER_REMOVED, this); + mReaperHandler.sendMessage(reaperMessage); + } + + @Override + public int hashCode() { + int result = 17; + result = 31 * result + (mCallback != null ? mCallback.hashCode() : 0); + result = 31 * result + (mMonitorCallback != null ? mMonitorCallback.hashCode() : 0); + result = 31 * result + mMonitoringType; + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) return false; + if (obj == this) return true; + + Reaper rhs = (Reaper) obj; + return rhs.mCallback == mCallback && rhs.mMonitorCallback == mMonitorCallback && + rhs.mMonitoringType == mMonitoringType; + } + } + int getAllowedResolutionLevel(int pid, int uid) { if (mContext.checkPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, pid, uid) == PackageManager.PERMISSION_GRANTED) { diff --git a/core/java/android/hardware/location/GeofenceHardwareMonitorCallback.java b/core/java/android/hardware/location/GeofenceHardwareMonitorCallback.java new file mode 100644 index 000000000000..b8e927e2fefe --- /dev/null +++ b/core/java/android/hardware/location/GeofenceHardwareMonitorCallback.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.location; + +import android.location.Location; + +/** + * The callback class associated with the status change of hardware montiors + * in {@link GeofenceHardware} + */ +public abstract class GeofenceHardwareMonitorCallback { + /** + * The callback called when the state of a monitoring system changes. + * {@link GeofenceHardware#MONITORING_TYPE_GPS_HARDWARE} is an example of a + * monitoring system + * + * @param monitoringType The type of the monitoring system. + * @param available Indicates whether the system is currenty available or not. + * @param location The last known location according to the monitoring system. + */ + public void onMonitoringSystemChange(int monitoringType, boolean available, Location location) { + } +} diff --git a/core/java/android/hardware/location/GeofenceHardwareRequest.java b/core/java/android/hardware/location/GeofenceHardwareRequest.java new file mode 100644 index 000000000000..6e7b592eaa10 --- /dev/null +++ b/core/java/android/hardware/location/GeofenceHardwareRequest.java @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.location; + +import android.location.Location; + +/** + * This class represents the characteristics of the geofence. + * + * <p> Use this in conjunction with {@link GeofenceHardware} APIs. + */ + +public final class GeofenceHardwareRequest { + static final int GEOFENCE_TYPE_CIRCLE = 0; + private int mType; + private double mLatitude; + private double mLongitude; + private double mRadius; + private int mLastTransition = GeofenceHardware.GEOFENCE_UNCERTAIN; + private int mUnknownTimer = 30000; // 30 secs + private int mMonitorTransitions = GeofenceHardware.GEOFENCE_UNCERTAIN | + GeofenceHardware.GEOFENCE_ENTERED | GeofenceHardware.GEOFENCE_EXITED; + private int mNotificationResponsiveness = 5000; // 5 secs + + private void setCircularGeofence(double latitude, double longitude, double radius) { + mLatitude = latitude; + mLongitude = longitude; + mRadius = radius; + mType = GEOFENCE_TYPE_CIRCLE; + } + + /** + * Create a circular geofence. + * + * @param latitude Latitude of the geofence + * @param longitude Longitude of the geofence + * @param radius Radius of the geofence (in meters) + */ + public static GeofenceHardwareRequest createCircularGeofence(double latitude, + double longitude, double radius) { + GeofenceHardwareRequest geofenceRequest = new GeofenceHardwareRequest(); + geofenceRequest.setCircularGeofence(latitude, longitude, radius); + return geofenceRequest; + } + + /** + * Set the last known transition of the geofence. + * + * @param lastTransition The current state of the geofence. Can be one of + * {@link GeofenceHardware#GEOFENCE_ENTERED}, {@link GeofenceHardware#GEOFENCE_EXITED}, + * {@link GeofenceHardware#GEOFENCE_UNCERTAIN}. + */ + public void setLastTransition(int lastTransition) { + mLastTransition = lastTransition; + } + + /** + * Set the unknown timer for this geofence. + * + * @param unknownTimer The time limit after which the + * {@link GeofenceHardware#GEOFENCE_UNCERTAIN} transition + * should be triggered. This paramter is defined in milliseconds. + */ + public void setUnknownTimer(int unknownTimer) { + mUnknownTimer = unknownTimer; + } + + /** + * Set the transitions to be monitored. + * + * @param monitorTransitions Bitwise OR of {@link GeofenceHardware#GEOFENCE_ENTERED}, + * {@link GeofenceHardware#GEOFENCE_EXITED}, {@link GeofenceHardware#GEOFENCE_UNCERTAIN} + */ + public void setMonitorTransitions(int monitorTransitions) { + mMonitorTransitions = monitorTransitions; + } + + /** + * Set the notification responsiveness of the geofence. + * + * @param notificationResponsiveness (milliseconds) Defines the best-effort description + * of how soon should the callback be called when the transition + * associated with the Geofence is triggered. For instance, if + * set to 1000 millseconds with {@link GeofenceHardware#GEOFENCE_ENTERED}, + * the callback will be called 1000 milliseconds within entering + * the geofence. + */ + public void setNotificationResponsiveness(int notificationResponsiveness) { + mNotificationResponsiveness = notificationResponsiveness; + } + + /** + * Returns the latitude of this geofence. + */ + public double getLatitude() { + return mLatitude; + } + + /** + * Returns the longitude of this geofence. + */ + public double getLongitude() { + return mLongitude; + } + + /** + * Returns the radius of this geofence. + */ + public double getRadius() { + return mRadius; + } + + /** + * Returns transitions monitored for this geofence. + */ + public int getMonitorTransitions() { + return mMonitorTransitions; + } + + /** + * Returns the unknownTimer of this geofence. + */ + public int getUnknownTimer() { + return mUnknownTimer; + } + + /** + * Returns the notification responsiveness of this geofence. + */ + public int getNotificationResponsiveness() { + return mNotificationResponsiveness; + } + + /** + * Returns the last transition of this geofence. + */ + public int getLastTransition() { + return mLastTransition; + } + + int getType() { + return mType; + } +} diff --git a/core/java/android/hardware/location/GeofenceHardwareService.java b/core/java/android/hardware/location/GeofenceHardwareService.java index 0eccee6a785a..3bc70eed749f 100644 --- a/core/java/android/hardware/location/GeofenceHardwareService.java +++ b/core/java/android/hardware/location/GeofenceHardwareService.java @@ -68,23 +68,28 @@ public class GeofenceHardwareService extends Service { mGeofenceHardwareImpl.setGpsHardwareGeofence(service); } - public int[] getMonitoringTypesAndStatus() { + public int[] getMonitoringTypes() { mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, "Location Hardware permission not granted to access hardware geofence"); - return mGeofenceHardwareImpl.getMonitoringTypesAndStatus(); + return mGeofenceHardwareImpl.getMonitoringTypes(); } - public boolean addCircularFence(int id, double lat, double longitude, double radius, - int lastTransition, int monitorTransitions, int - notificationResponsiveness, int unknownTimer, int monitoringType, - IGeofenceHardwareCallback callback) { + public int getStatusOfMonitoringType(int monitoringType) { + mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, + "Location Hardware permission not granted to access hardware geofence"); + + return mGeofenceHardwareImpl.getStatusOfMonitoringType(monitoringType); + } + public boolean addCircularFence(int id, int monitoringType, double lat, double longitude, + double radius, int lastTransition, int monitorTransitions, int + notificationResponsiveness, int unknownTimer, IGeofenceHardwareCallback callback) { mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, "Location Hardware permission not granted to access hardware geofence"); checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType); - return mGeofenceHardwareImpl.addCircularFence(id, lat, longitude, radius, - lastTransition, monitorTransitions, notificationResponsiveness, unknownTimer, - monitoringType, callback); + return mGeofenceHardwareImpl.addCircularFence(id, monitoringType, lat, longitude, + radius, lastTransition, monitorTransitions, notificationResponsiveness, + unknownTimer, callback); } public boolean removeGeofence(int id, int monitoringType) { @@ -103,16 +108,16 @@ public class GeofenceHardwareService extends Service { return mGeofenceHardwareImpl.pauseGeofence(id, monitoringType); } - public boolean resumeGeofence(int id, int monitorTransitions, int monitoringType) { + public boolean resumeGeofence(int id, int monitoringType, int monitorTransitions) { mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, "Location Hardware permission not granted to access hardware geofence"); checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType); - return mGeofenceHardwareImpl.resumeGeofence(id, monitorTransitions, monitoringType); + return mGeofenceHardwareImpl.resumeGeofence(id, monitoringType, monitorTransitions); } public boolean registerForMonitorStateChangeCallback(int monitoringType, - IGeofenceHardwareCallback callback) { + IGeofenceHardwareMonitorCallback callback) { mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, "Location Hardware permission not granted to access hardware geofence"); @@ -122,7 +127,7 @@ public class GeofenceHardwareService extends Service { } public boolean unregisterForMonitorStateChangeCallback(int monitoringType, - IGeofenceHardwareCallback callback) { + IGeofenceHardwareMonitorCallback callback) { mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, "Location Hardware permission not granted to access hardware geofence"); diff --git a/core/java/android/hardware/location/IGeofenceHardware.aidl b/core/java/android/hardware/location/IGeofenceHardware.aidl index 4ba02b830616..6900070caf93 100644 --- a/core/java/android/hardware/location/IGeofenceHardware.aidl +++ b/core/java/android/hardware/location/IGeofenceHardware.aidl @@ -18,19 +18,21 @@ package android.hardware.location; import android.location.IGpsGeofenceHardware; import android.hardware.location.IGeofenceHardwareCallback; +import android.hardware.location.IGeofenceHardwareMonitorCallback; /** @hide */ interface IGeofenceHardware { void setGpsGeofenceHardware(in IGpsGeofenceHardware service); - int[] getMonitoringTypesAndStatus(); - boolean addCircularFence(int id, double lat, double longitude, double radius, - int lastTransition, int monitorTransitions, int notificationResponsiveness, - int unknownTimer, int monitoringType, in IGeofenceHardwareCallback callback); + int[] getMonitoringTypes(); + int getStatusOfMonitoringType(int monitoringType); + boolean addCircularFence(int id, int monitoringType, double lat, double longitude, + double radius, int lastTransition, int monitorTransitions, + int notificationResponsiveness, int unknownTimer,in IGeofenceHardwareCallback callback); boolean removeGeofence(int id, int monitoringType); boolean pauseGeofence(int id, int monitoringType); - boolean resumeGeofence(int id, int monitorTransitions, int monitoringType); + boolean resumeGeofence(int id, int monitoringType, int monitorTransitions); boolean registerForMonitorStateChangeCallback(int monitoringType, - IGeofenceHardwareCallback callback); + IGeofenceHardwareMonitorCallback callback); boolean unregisterForMonitorStateChangeCallback(int monitoringType, - IGeofenceHardwareCallback callback); + IGeofenceHardwareMonitorCallback callback); } diff --git a/core/java/android/hardware/location/IGeofenceHardwareCallback.aidl b/core/java/android/hardware/location/IGeofenceHardwareCallback.aidl index 678fc492156e..3a8f430db422 100644 --- a/core/java/android/hardware/location/IGeofenceHardwareCallback.aidl +++ b/core/java/android/hardware/location/IGeofenceHardwareCallback.aidl @@ -20,8 +20,7 @@ import android.location.Location; /** @hide */ oneway interface IGeofenceHardwareCallback { - void onMonitoringSystemChange(int monitoringType, boolean available, in Location location); - void onGeofenceChange(int geofenceId, int transition, in Location location, + void onGeofenceTransition(int geofenceId, int transition, in Location location, long timestamp, int monitoringType); void onGeofenceAdd(int geofenceId, int status); void onGeofenceRemove(int geofenceId, int status); diff --git a/core/java/android/hardware/location/IGeofenceHardwareMonitorCallback.aidl b/core/java/android/hardware/location/IGeofenceHardwareMonitorCallback.aidl new file mode 100644 index 000000000000..0b6e04ba1da2 --- /dev/null +++ b/core/java/android/hardware/location/IGeofenceHardwareMonitorCallback.aidl @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.location; + +import android.location.Location; + +/** @hide */ +oneway interface IGeofenceHardwareMonitorCallback { + void onMonitoringSystemChange(int monitoringType, boolean available, in Location location); +} diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 3df4e99f66b4..4de5933585a3 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -714,6 +714,17 @@ public final class Settings { */ public static final String EXTRA_AUTHORITIES = "authorities"; + /** + * Activity Extra: Limit available options in launched activity based on the given account + * types. + * <p> + * This can be passed as an extra field in an Activity Intent with one or more account types + * as a String[]. This field is used by some intents to alter the behavior of the called + * activity. + * <p> + * Example: The {@link #ACTION_ADD_ACCOUNT} intent restricts the account types to the specified + * list. + */ public static final String EXTRA_ACCOUNT_TYPES = "account_types"; public static final String EXTRA_INPUT_METHOD_ID = "input_method_id"; diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java index 59ff597ac6bb..d69bc31e15d9 100644 --- a/core/java/com/android/internal/widget/ActionBarView.java +++ b/core/java/com/android/internal/widget/ActionBarView.java @@ -1354,7 +1354,7 @@ public class ActionBarView extends AbsActionBarView { public void setHomeActionContentDescription(int resId) { mHomeDescriptionRes = resId; - mHomeDescription = getResources().getText(resId); + mHomeDescription = resId != 0 ? getResources().getText(resId) : null; } static class SavedState extends BaseSavedState { diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 514178dd2fa8..104cc91cdac7 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -134,6 +134,7 @@ <protected-broadcast android:name="android.net.conn.CONNECTIVITY_CHANGE" /> <protected-broadcast android:name="android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE" /> <protected-broadcast android:name="android.net.conn.DATA_ACTIVITY_CHANGE" /> + <protected-broadcast android:name="android.net.conn.BACKGROUND_DATA_SETTING_CHANGED" /> <protected-broadcast android:name="android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED" /> <protected-broadcast android:name="android.nfc.action.LLCP_LINK_STATE_CHANGED" /> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index ea194fc867e8..f1119e284c8c 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Herlaai"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Die bladsy by \"<xliff:g id="TITLE">%s</xliff:g>\" sê:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Navigeer weg van hierdie bladsy?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Raak OK om voort te gaan, of Kanselleer om op die huidige bladsy te bly."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Bevestig"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Wenk: Dubbeltik om in en uit te zoem."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Outovul"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 84eba57615e8..d689022c9109 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -387,7 +387,7 @@ <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"በሌሎች መተግበሪያዎች የመሸጎጫ ማውጫዎች ውስጥ ያሉትን ፋይሎች በመሰረዝ መተግበሪያው የጡባዊ ማከማቻ ቦታ ነጻ እንዲያስለቅቅ ያስችለዋል። ይሄ ሌሎች መተግበሪያዎች ውሂባቸውን ዳግም ማምጣት ስላለባቸው ይበልጥ ዘግየት ብለው እንዲጀምሩ ሊያደርጋቸው ይችላል።"</string> <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"በሌሎች መተግበሪያዎች የመሸጎጫ ማውጫዎች ውስጥ ያሉትን ፋይሎች በመሰረዝ መተግበሪያው የስልክ ማከማቻ ቦታ ነጻ እንዲያስለቅቅ ያስችለዋል። ይሄ ሌሎች መተግበሪያዎች ውሂባቸውን ዳግም ማምጣት ስላለባቸው ይበልጥ ዘግየት ብለው እንዲጀምሩ ሊያደርጋቸው ይችላል።"</string> <string name="permlab_movePackage" msgid="3289890271645921411">"የመተግበሪያ ሃብቶችን አንቀሳቅስ"</string> - <string name="permdesc_movePackage" msgid="319562217778244524">"ከውስጣዊ ወደ ውጫዊ ሚዲያ እና በተገላቢጦሽ የመተግበሪያ ሃብቶችን ለማንቀሳቀስ ለመተግበሪያው ይፈቅዳሉ፡፡"</string> + <string name="permdesc_movePackage" msgid="319562217778244524">"ከውስጣዊ ወደ ውጫዊ ማህደረ መረጃ እና በተገላቢጦሽ የመተግበሪያ ሃብቶችን ለማንቀሳቀስ ለመተግበሪያው ይፈቅዳሉ፡፡"</string> <string name="permlab_readLogs" msgid="6615778543198967614">"ወሳኝ የማስታወሻ ውሂብ አንብብ"</string> <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">" ከስርዓቱ የተለያዩ የማስታወሻ ፋይሎች ውስጥ ለማንበብ ለመተግበሪያ ይፈቅዳሉ። ይህ ስለ ጡባዊ ተኮህ ምን እያደረክበት እንደሆነ የግላዊ ወይም የግል መረጃን ጨምሮ ጠቅላላ መረጃ ለማግኘት ይፈቅዳል።"</string> <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">" ከስርዓቱ የተለያዩ የማስታወሻ ፋይሎች ውስጥ ለማንበብ ለመተግበሪያይፈቅዳሉ። ይህ ስለ ስልክህ ምን እያደረክበት እንደሆነ የግላዊ ወይም የግል መረጃን ጨምሮ ጠቅላላ መረጃ ለማግኘት ይፈቅዳል።"</string> @@ -403,9 +403,9 @@ <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ተመራጭ መተግበሪያዎች አዘጋጅ"</string> <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"ተመራጭ መተግበሪያዎችህን ለመቀየር ለመተግበሪያው ይፈቅዳሉ፡፡ ከአንተ የግል ውሂብ ለመሰብሰብ ያሉትን መተግበሪያዎች በመላክ፤ በመሄድ ላይ ያሉ መተግበሪያዎችን ተንኮል አዘል መተግበሪያዎች በዝምታ ሊለውጡ ይችላሉ፡፡"</string> <string name="permlab_writeSettings" msgid="2226195290955224730">"የስርዓት ቅንብሮችን አስተካክል"</string> - <string name="permdesc_writeSettings" msgid="7775723441558907181">"የስርዓት ቅንጅቶችን ውሂብ ለመቀየር ለመተግበሪያው ይፈቅዳሉ፡፡ ተንኮል አዘል መተግበሪያዎች የስርዓትህን አወቃቀር ብልሹ ሊያደርጉት ይችላሉ፡፡"</string> + <string name="permdesc_writeSettings" msgid="7775723441558907181">"የስርዓት ቅንብሮችን ውሂብ ለመቀየር ለመተግበሪያው ይፈቅዳሉ። ተንኮል አዘል መተግበሪያዎች የስርዓትዎን አወቃቀር ብልሹ ሊያደርጉት ይችላሉ።"</string> <string name="permlab_writeSecureSettings" msgid="204676251876718288">"የስርዓት ቅንብሮችንደህንነት ቀይር"</string> - <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"የስርዓቱን ደህንነቱ የተጠበቀ ቅንጅቶችን ውሂብ ለመቀየር ለመተግበሪያው ይፈቅዳሉ፡፡ለመደበኛ ትግበራዎች አያስፈልግም።"</string> + <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"የስርዓቱን ደህንነቱ የተጠበቀ ቅንብሮችን ውሂብ ለመቀየር ለመተግበሪያው ይፈቅዳሉ። ለመደበኛ ትግበራዎች አያስፈልግም።"</string> <string name="permlab_writeGservices" msgid="2149426664226152185">"የGoogle አገልግሎቶች ካርታን ቀይር"</string> <string name="permdesc_writeGservices" msgid="1287309437638380229">"ትግበራ የGoogle ካርታ አገልግሎቶችን ለመቀየር ይፈቅዳል።ለመደበኛ ትግበራዎች ጥቅም አይደለም።"</string> <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"መነሻ ላይ አሂድ"</string> @@ -541,8 +541,8 @@ <string name="permlab_accountManagerService" msgid="4829262349691386986">"እንደ አውርድአዸራጅአገልግሎት"</string> <string name="permdesc_accountManagerService" msgid="1948455552333615954">" ወደ መለያ አረጋጋጮች ጥሪ ለማድረግ ለመተግበሪያ ይፈቅዳሉ።"</string> <string name="permlab_getAccounts" msgid="1086795467760122114">"መሣሪያው ላይ ያሉ መለያዎችን አግኝ"</string> - <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"መተግበሪያው በጡባዊ ተኮው የሚታወቁትን መለያዎች ዝርዝር እንዲያገኝ ይፈቅድለታል። ይህ በጫንካቸው ማናቸውም መተግበሪያዎች የተፈጠሩ መለያዎችን ሊያጠቃልል ይችላል።"</string> - <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"መተግበሪያው በስልኩ የሚታወቁትን መለያዎች ዝርዝር እንዲያገኝ ይፈቅድለታል። ይህ በጫንካቸው ማናቸውም መተግበሪያዎች የተፈጠሩ መለያዎችን ሊያጠቃልል ይችላል።"</string> + <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"መተግበሪያው በጡባዊ ተኮው የሚታወቁትን መለያዎች ዝርዝር እንዲያገኝ ይፈቅድለታል። ይህ በጫንዋቸው ማናቸውም መተግበሪያዎች የተፈጠሩ መለያዎችን ሊያጠቃልል ይችላል።"</string> + <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"መተግበሪያው በስልኩ የሚታወቁትን መለያዎች ዝርዝር እንዲያገኝ ይፈቅድለታል። ይህ በጫንዋቸው ማናቸውም መተግበሪያዎች የተፈጠሩ መለያዎችን ሊያጠቃልል ይችላል።"</string> <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"መለያዎችን ፍጠርና የይለፍ ቃላትን አስቀምጥ"</string> <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"የመለያ አረጋጋጭ መለያ መናጅ ችሎታን ለመጠቀም፣ መለያ መፍጠር እና የይለፍ ቃሎችን ለማግኘት እና ለማቀናጀት አክሎ ለመተግበሪያው ይፈቅዳሉ ።"</string> <string name="permlab_manageAccounts" msgid="4983126304757177305">"መለያዎችን አክል ወይም አስወግድ"</string> @@ -554,7 +554,7 @@ <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"ሙሉ የአውታረ መረብ መዳረሻ"</string> <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"መተግበሪያው የአውታረ መረብ መሰኪያዎችን እንዲፈጥር እና ብጁ የአውታረ መረብ ፕሮቶኮሎችን እንዲጠቀም ይፈቅድለታል። አሳሹ እና ሌሎች መተግበሪያዎች ውሂብ ወደ በይነመረብ የመላኪያ መንገዶችን ስለሚያቀርቡውሂብ ወደ በይነመረብ ለመላክ ይህ ፍቃድ አያስፈልግም።"</string> <string name="permlab_writeApnSettings" msgid="505660159675751896">"የአውታረ መረብ ቅንብሮች እና ትራፊክ ለውጥ/ አቋርጥ"</string> - <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"የአውታረ መረብ ቅንጅቶችን ለመለወጥ እና ለማቋረጥ እና ሁሉንም የአውታረ መረብ ትራፊክ ለመመርመር፤ለምሳሌ ወኪል እና የማንኛውም APN ወደብ ለመለወጥ ለመተግበሪያው ይፈቅዳሉ፡፡ ተንኮል አዘል መተግበሪያዎች ሊቆጣጠሩ፣ አቅጣጫ ሊያስቀይሩ ፣ ወይም ያለአንተ እውቅና የአውታረ መረብ ፓኬቶችን ሊቀይሩ ይችላሉ፡፡"</string> + <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"የአውታረ መረብ ቅንብሮችን ለመለወጥ እና ለማቋረጥ እና ሁሉንም የአውታረ መረብ ትራፊክ ለመመርመር፤ለምሳሌ ወኪል እና የማንኛውም APN ወደብ ለመለወጥ ለመተግበሪያው ይፈቅዳሉ። ተንኮል አዘል መተግበሪያዎች ሊቆጣጠሩ፣ አቅጣጫ ሊያስቀይሩ ፣ ወይም ያለእርስዎ እውቅና የአውታረ መረብ ፓኬቶችን ሊቀይሩ ይችላሉ።"</string> <string name="permlab_changeNetworkState" msgid="958884291454327309">"የአውታረ መረብ ተያያዥነትን ለውጥ"</string> <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"የእውታረ መረቡን ግንኙነት ሁኔታ ለመለወጥ ለመተግበሪያው ይፈቅዳሉ።"</string> <string name="permlab_changeTetherState" msgid="5952584964373017960">"የተያያዘ ግንኙነት ለውጥ"</string> @@ -601,7 +601,7 @@ <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"ጥበቃ ወደሚደረግለት ማከማቻ ያለ መዳረሻን ፈትሽ"</string> <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"መተግበሪያው በወደፊት መሳሪዎች ላይ ለሚኖር የUSB ማህደረ ትውስታ ፈቃድ እንዲሞክር ይፈቅድለታል።"</string> <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"መተግበሪያው በወደፊት መሳሪዎች ላይ ለሚኖረው SD ካርድ ፈቃድ እንዲሞክር ይፈቅድለታል።"</string> - <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"የUSB ማከማቻህን ይዘቶች ቀይር ወይም ሰርዝ"</string> + <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"የUSB ማከማቻዎን ይዘቶች ይቀይሩ ወይም ይሰርዙ"</string> <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"የSD ካርድህን ይዘቶች ቀይር ወይም ሰርዝ"</string> <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"ወደ USB ማህደረ ትውስታው ለመፃፍ ለመተግበሪያው ይፈቅዳሉ፡፡"</string> <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"መተግበሪያውን ወደ SD ካርድ ለመፃፍ ይፈቅዳል።"</string> @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"ድጋሚ አስነሳ"</string> <string name="js_dialog_title" msgid="1987483977834603872">"በ«<xliff:g id="TITLE">%s</xliff:g>» ያለው ገጽ ይህን ይላል፦"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"ጃቫስክሪፕት"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"ከዚህ ገፅ ወጣ ብሎ ይዳስ? "\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n" ለመቀጠል እሺ ፣ወይም የአሁኑ ገፅ ላይ ለመቆየት ይቅር ምረጥ።"</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"አረጋግጥ"</string> <string name="double_tap_toast" msgid="4595046515400268881">"ጠቃሚ ምክር፦ ለማጉላት እና ለማሳነስ ሁለቴ-መታ አድርግ።"</string> <string name="autofill_this_form" msgid="4616758841157816676">"ራስ ሙላ"</string> @@ -1174,20 +1181,20 @@ <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"አዲስ፦ "</font></string> <string name="perms_description_app" msgid="5139836143293299417">"በ<xliff:g id="APP_NAME">%1$s</xliff:g> የቀረበ።"</string> <string name="no_permissions" msgid="7283357728219338112">"ምንም ፍቃዶች አይጠየቁም"</string> - <string name="perm_costs_money" msgid="4902470324142151116">"ይህ ገንዘብ ሊያስወጣዎብዎት ይችላል"</string> + <string name="perm_costs_money" msgid="4902470324142151116">"ይህ ገንዘብ ሊያስወጣዎት ይችላል"</string> <string name="usb_storage_activity_title" msgid="4465055157209648641">"USB ብዙ ማከማቻ"</string> <string name="usb_storage_title" msgid="5901459041398751495">"USB ተያይዟል"</string> <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"ከኮምፒዩተርህ ጋር በUSB በኩል አገናኝተሃል። በኮምፒዩተርህ እና በAndroid SD ማከማቻህ መካከል ፋይሎች ለመቅዳት ከፈለግህ ከዚህ በታች ያለውን አዝራር ንካ።"</string> <string name="usb_storage_message" product="default" msgid="805351000446037811">"ከኮምፒዩተርህ ጋር በUSB በኩል አገናኝተሃል። በኮምፒዩተርህ እና በAndroid SD ማከማቻህ መካከል ፋይሎች ለመቅዳት ከፈለግህ ከዚህ በታች ያለውን አዝራር ንካ።"</string> <string name="usb_storage_button_mount" msgid="1052259930369508235">"የUSB ማከማቻ አብራ"</string> - <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"የUSB ማከማቻህን ለUSB ብዙማከማቻ መጠቀም ችግር አለ።"</string> + <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"የUSB ማከማቻዎን ለUSB ብዙ ማከማቻ መጠቀም ችግር አለ።"</string> <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"የ SD ካርድህን ለUSB ብዙማከማቻ መጠቀም ችግር አለ።"</string> <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB ተያይዟል"</string> <string name="usb_storage_notification_message" msgid="939822783828183763">"ፋይሎችን ከ/ወደ ኮምፒዩተርህ ለመቅዳት ንካ።"</string> <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"የUSB ማከማቻ አጥፋ"</string> <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"የUSB ማከማቻ ለማጥፋት ንካ።"</string> <string name="usb_storage_stop_title" msgid="660129851708775853">"USB ማከማቻ በጥቅም ላይ"</string> - <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB ማከማቻን ከማጥፋትህ በፊት፤ የAndroid USB ማከማቻህን ከኮምውተርህ ንቀል (\"አውጣ\")።"</string> + <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB ማከማቻን ከማጥፋትዎ በፊት፤ የAndroid USB ማከማቻዎን ከኮምውተርዎ ይንቀሉ (\"ያውጡ\")።"</string> <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"የUSB ማከማቻ ከማጥፋት በፊት የAndroid SD ካርድህን ከኮምፒዩተርህ ላይ ንቀል(“አውጣ”)።"</string> <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB ማከማቻ አጥፋ"</string> <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"የ USB ማከማቻ ለማጥፋት ችግር ነበር። USB አስተናጋጅ መንቀልህን አረጋግጥ፤ ከዛም እንደገና ሞክር።"</string> @@ -1380,7 +1387,7 @@ <string name="storage_usb" msgid="3017954059538517278">"የUSB ማከማቻ"</string> <string name="extract_edit_menu_button" msgid="8940478730496610137">"አርትዕ"</string> <string name="data_usage_warning_title" msgid="1955638862122232342">"የውሂብ አጠቃቀም ማስጠንቀቂየ"</string> - <string name="data_usage_warning_body" msgid="2814673551471969954">"ቅንጅቶችን እና አጠቃቀምን ለማየት ንካ።"</string> + <string name="data_usage_warning_body" msgid="2814673551471969954">"ቅንብሮችን እና አጠቃቀምን ለማየት ይንኩ።"</string> <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G ውሂብ ቦዝኗል"</string> <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G ውሂብ ቦዝኗል"</string> <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"የተንቀሳቃሽ ውሂብ ቦዝኗል"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index d134ca45bd81..0c611cdf2e72 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"إعادة تشغيل"</string> <string name="js_dialog_title" msgid="1987483977834603872">"تعرض الصفحة في \"<xliff:g id="TITLE">%s</xliff:g>\":"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"جافا سكريبت"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"هل تريد الانتقال بعيدًا عن هذه الصفحة؟"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"المس \"موافق\" للمتابعة، أو \"إلغاء\" للبقاء في الصفحة الحالية."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"تأكيد"</string> <string name="double_tap_toast" msgid="4595046515400268881">"نصيحة: اضغط مرتين للتكبير والتصغير."</string> <string name="autofill_this_form" msgid="4616758841157816676">"ملء تلقائي"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 9f3d3e671f51..eb2033c09dfe 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Перазагрузіць"</string> <string name="js_dialog_title" msgid="1987483977834603872">"На старонцы з адрасам <xliff:g id="TITLE">%s</xliff:g> вызначана:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Пакiнуць гэту старонку?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Націсніце \"OK\", каб працягнуць, або \"Адмена\", каб застацца на бягучай старонцы."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Пацвердзіць"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Падказка: двойчы націсніце, каб павялічыць або паменшыць."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Аўтазапаўненне"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 0983b5ee9cbd..27a0f59516b0 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Рестартиране"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Страницата на адрес „<xliff:g id="TITLE">%s</xliff:g>“ съобщава:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Искате ли да напуснете тази страница?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Докоснете „OK“, за да продължите, или „Отказ“, за да останете на нея."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Потвърждение"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Съвет: Докоснете двукратно, за да увеличите или намалите мащаба."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Автопоп."</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index ccea86672fd1..4e68a6b0862f 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Reinicia"</string> <string name="js_dialog_title" msgid="1987483977834603872">"La pàgina de \"<xliff:g id="TITLE">%s</xliff:g>\" diu:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Vols sortir d\'aquesta pàgina?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Selecciona D\'acord per continuar o Cancel·la per seguir a la pàgina actual."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Confirma"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Consell: Pica dos cops per ampliar i per reduir."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Em. aut."</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index c9a84cb211d5..c92d249b76e0 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -155,7 +155,7 @@ <string name="global_action_lock" msgid="2844945191792119712">"Zámek obrazovky"</string> <string name="global_action_power_off" msgid="4471879440839879722">"Vypnout"</string> <string name="global_action_bug_report" msgid="7934010578922304799">"Hlášení chyb"</string> - <string name="bugreport_title" msgid="2667494803742548533">"Zaznamenat zprávu o chybě"</string> + <string name="bugreport_title" msgid="2667494803742548533">"Vytvořit chybové hlášení"</string> <string name="bugreport_message" msgid="398447048750350456">"Shromažďuje informace o aktuálním stavu zařízení. Tyto informace je následně možné poslat v e-mailové zprávě, chvíli však potrvá, než bude hlášení o chybě připraveno k odeslání. Buďte prosím trpěliví."</string> <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Tichý režim"</string> <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zvuk je VYPNUTÝ."</string> @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Restartovat"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Stránka <xliff:g id="TITLE">%s</xliff:g> uvádí:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Chcete opustit tuto stránku?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Chcete-li pokračovat, dotkněte se možnosti OK. Chcete-li zůstat na aktuální stránce, dotkněte se možnosti Zrušit."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Potvrdit"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Tip: Dvojitým klepnutím můžete zobrazení přiblížit nebo oddálit."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Aut.vyp."</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 0c7cf728cf20..29a57761224c 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -156,7 +156,7 @@ <string name="global_action_power_off" msgid="4471879440839879722">"Sluk"</string> <string name="global_action_bug_report" msgid="7934010578922304799">"Fejlrapport"</string> <string name="bugreport_title" msgid="2667494803742548533">"Lav fejlrapport"</string> - <string name="bugreport_message" msgid="398447048750350456">"Der indsamles oplysninger om din enheds aktuelle status, der efterfølgende sendes i en e-mail. Der går lidt tid, fra fejlrapporten påbegyndes, til den er klar til at blive sendt. Tak for tålmodigheden."</string> + <string name="bugreport_message" msgid="398447048750350456">"Der indsamles oplysninger om din enheds aktuelle status, der efterfølgende sendes i en e-mail. Der går lidt tid fra, at fejlrapporten påbegyndes, til den er klar til at blive sendt. Tak for tålmodigheden."</string> <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Lydløs"</string> <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Lyden er slået FRA"</string> <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Lyden er TIL"</string> @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Genstart"</string> <string name="js_dialog_title" msgid="1987483977834603872">"På siden på \"<xliff:g id="TITLE">%s</xliff:g>\" står der:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"Javascript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Vil du gå væk fra denne side?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Tryk på OK for at fortsætte eller Annuller for at blive på den aktuelle side."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Bekræft"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Tip! Dobbeltklik for at zoome ind eller ud."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Autofyld"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index c03aa70a0cb4..dcf27e3ad367 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Neustart"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Auf der Seite \"<xliff:g id="TITLE">%s</xliff:g>\" steht:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Diese Seite verlassen?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Tippen Sie zum Fortfahren auf \"OK\" oder tippen Sie auf \"Abbrechen\", um auf der aktuellen Seite zu bleiben."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Bestätigen"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Tipp: Zum Vergrößern und Verkleinern zweimal tippen"</string> <string name="autofill_this_form" msgid="4616758841157816676">"AutoFill"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 6dcdbf1286ca..414111d44373 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Επανεκκίνηση"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Η σελίδα στον τίτλο \"<xliff:g id="TITLE">%s</xliff:g>\" λέει:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Απομάκρυνση από αυτή τη σελίδα;"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Αγγίξτε το στοιχείο \"OK\" για συνέχεια ή \"Ακύρωση\" για παραμονή στην τρέχουσα σελίδα."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Επιβεβαίωση"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Συμβουλή: Πατήστε δύο φορές για μεγέθυνση και σμίκρυνση."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Αυτόματη συμπλήρωση"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 08283c41bd22..d95c1d9dfa58 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Reboot"</string> <string name="js_dialog_title" msgid="1987483977834603872">"The page at \"<xliff:g id="TITLE">%s</xliff:g>\" says:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Navigate away from this page?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Touch OK to continue or Cancel to stay on the current page."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Confirm"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Tip: double-tap to zoom in and out."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Auto-fill"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 98528f738d98..5005d41d0687 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -773,7 +773,7 @@ <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Presiona el Menú para desbloquear o realizar una llamada de emergencia."</string> <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Presionar Menú para desbloquear."</string> <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Dibujar el patrón de desbloqueo"</string> - <string name="lockscreen_emergency_call" msgid="5347633784401285225">"Llamada de emergencia"</string> + <string name="lockscreen_emergency_call" msgid="5347633784401285225">"Realizar llamada de emergencia"</string> <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Regresar a llamada"</string> <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Correcto"</string> <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Vuelve a intentarlo."</string> @@ -783,7 +783,7 @@ <string name="lockscreen_charged" msgid="321635745684060624">"Cargado"</string> <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Conecta tu cargador."</string> - <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"No hay tarjeta SIM."</string> + <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Sin tarjeta SIM"</string> <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"No hay tarjeta SIM en el tablet."</string> <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"No hay tarjeta SIM en el dispositivo."</string> <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Inserta una tarjeta SIM."</string> @@ -795,7 +795,7 @@ <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Botón Pausa"</string> <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Botón Reproducir"</string> <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Botón Detener"</string> - <string name="emergency_calls_only" msgid="6733978304386365407">"Sólo llamadas de emergencia"</string> + <string name="emergency_calls_only" msgid="6733978304386365407">"Solo llamadas de emergencia"</string> <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Red bloqueada"</string> <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"La tarjeta SIM está bloqueada con PUK."</string> <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulta la guía del usuario o comunícate con el servicio de atención al cliente."</string> @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Reiniciar"</string> <string name="js_dialog_title" msgid="1987483977834603872">"La página \"<xliff:g id="TITLE">%s</xliff:g>\" dice:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"¿Deseas salir de esta página?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Toca Aceptar para continuar o Cancelar para permanecer en la página actual."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Confirmar"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Consejo: Toca dos veces para acercar y alejar la imagen."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Autocompletar"</string> @@ -1437,7 +1444,7 @@ <string name="wifi_display_notification_title" msgid="2223050649240326557">"Se conectó la pantalla inalámbrica"</string> <string name="wifi_display_notification_message" msgid="4498802012464170685">"Esta pantalla se muestra en otro dispositivo."</string> <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Desconectar"</string> - <string name="kg_emergency_call_label" msgid="684946192523830531">"Llamada de emergencia"</string> + <string name="kg_emergency_call_label" msgid="684946192523830531">"Realizar llamada de emergencia"</string> <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"¿Olvidaste el patrón?"</string> <string name="kg_wrong_pattern" msgid="1850806070801358830">"Patrón incorrecto"</string> <string name="kg_wrong_password" msgid="2333281762128113157">"Contraseña incorrecta"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 485e1bf21441..d20f7fa0314b 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Reiniciar"</string> <string name="js_dialog_title" msgid="1987483977834603872">"La página \"<xliff:g id="TITLE">%s</xliff:g>\" dice:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"¿Quieres salir de esta página?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Toca Aceptar para continuar o Cancelar para permanecer en la página actual."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Confirmar"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Sugerencia: toca dos veces para ampliar o reducir el contenido."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Autocompletar"</string> @@ -1195,7 +1202,7 @@ <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Si activas el almacenamiento USB, se detendrán algunas aplicaciones que estás usando y es posible que no estén disponibles hasta que lo desactives."</string> <string name="dlg_error_title" msgid="7323658469626514207">"Error de funcionamiento de USB"</string> <string name="dlg_ok" msgid="7376953167039865701">"Aceptar"</string> - <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Conectado como disp. multimedia"</string> + <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Conectado como dispositivo multimedia"</string> <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Conectado como una cámara"</string> <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Conectado como instalador"</string> <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index d2d4d63abb00..c30e2a9c1f5c 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Taaskäivita"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Leht „<xliff:g id="TITLE">%s</xliff:g>” ütleb järgmist."</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Kas soovite sellelt lehelt lahkuda?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Jätkamiseks puudutage valikut OK, praegusele lehele jäämiseks valikut Tühista."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Kinnita"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Vihje: suurendamiseks ja vähendamiseks puudutage kaks korda."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Automaatne täitmine"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index f723c378e7cd..f254b52852e5 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -622,7 +622,7 @@ <string name="permlab_accessNotifications" msgid="7673416487873432268">"اعلانهای دسترسی"</string> <string name="permdesc_accessNotifications" msgid="458457742683431387">"به برنامه اجازه میدهد به بازیابی، بررسی و پاک کردن اعلانها از جمله موارد پست شده توسط سایر برنامهها بپردازد."</string> <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"اتصال به یک سرویس شنونده اعلان"</string> - <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"به دارنده اجازه میدهد به یک رابط سطح بالای سرویس شنونده اعلان متصل شود. این هرگز برای برنامههای عادی ضروری نیست."</string> + <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"به دارنده اجازه میدهد به یک رابط سطح بالای سرویس شنونده اعلان متصل شود. هرگز نباید برای برنامههای عادی لازم شود."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"تنظیم قوانین رمز ورود"</string> <string name="policydesc_limitPassword" msgid="3252114203919510394">"طول و نویسههای مجاز در گذرواژههای بازکردن قفل صفحه را کنترل کنید."</string> <string name="policylab_watchLogin" msgid="914130646942199503">"نمایش تلاشهای قفل گشایی صفحه"</string> @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"راهاندازی مجدد"</string> <string name="js_dialog_title" msgid="1987483977834603872">"صفحه در \"<xliff:g id="TITLE">%s</xliff:g>\" میگوید:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"جاوا اسکریپت"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"از این صفحه خارج میشوید؟"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"برای ادامه روی تأیید و برای ماندن در همین صفحه روی لغو کلیک کنید."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"تأیید"</string> <string name="double_tap_toast" msgid="4595046515400268881">"نکته: برای بزرگنمایی و کوچکنمایی، دو بار ضربه بزنید."</string> <string name="autofill_this_form" msgid="4616758841157816676">"تکمیل خودکار"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 7f7f07a9ace8..f75d4743f0bb 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Käynnistä uudelleen"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Sivu <xliff:g id="TITLE">%s</xliff:g> sanoo:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Siirrytäänkö pois tältä sivulta?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Valitse OK, jos haluat jatkaa, tai Peruuta, jos et halua siirtyä pois sivulta."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Vahvista"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Vinkki: lähennä ja loitonna kaksoisnapauttamalla."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Aut. täyttö"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 65c4ce57521e..4a87fd04e720 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Redémarrer"</string> <string name="js_dialog_title" msgid="1987483977834603872">"La page \"<xliff:g id="TITLE">%s</xliff:g>\" indique :"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Voulez-vous quitter cette page ?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Appuyez sur \"OK\" pour continuer ou \"Annuler\" pour rester sur la page actuelle."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Confirmer"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Conseil : Appuyez deux fois pour faire un zoom avant ou arrière."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Saisie auto"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 79dbfff32700..b922e401590a 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"रीबूट करें"</string> <string name="js_dialog_title" msgid="1987483977834603872">"\'<xliff:g id="TITLE">%s</xliff:g>\' पर यह पृष्ठ दर्शाता है:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"इस पृष्ठ से दूर नेविगेट करें?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"जारी रखने के लिए ठीक को चुनें, या वर्तमान पृष्ठ पर रहने के लिए रद्द करें को चुनें."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"पुष्टि करें"</string> <string name="double_tap_toast" msgid="4595046515400268881">"युक्ति: ज़ूम इन और आउट करने के लिए डबल-टैप करें."</string> <string name="autofill_this_form" msgid="4616758841157816676">"स्वत: भरण"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 90b44d24697a..128b48c889aa 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Ponovno pokreni"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Stranica na adresi \"<xliff:g id="TITLE">%s</xliff:g>\" sadrži sljedeće:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Želite otići s ove lokacije?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Za nastavak dodirnite U redu, a za ostanak na trenutačnoj stranici dodirnite Odustani."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Potvrdi"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Savjet: Dvaput dotaknite za povećavanje i smanjivanje."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Aut.pop."</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index d71ac239b45b..0e0f13aa1a21 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Újraindítás"</string> <string name="js_dialog_title" msgid="1987483977834603872">"A \"<xliff:g id="TITLE">%s</xliff:g>\" címen található oldal szerint:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Elhagyja ezt az oldalt?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"A folytatáshoz érintse meg az OK, a jelenlegi oldalon maradáshoz a Mégse lehetőséget."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Megerősítés"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Tipp: érintse meg kétszer a nagyításhoz és kicsinyítéshez."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Kitöltés"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index a9b33de4dae5..fd04f2aa7434 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Mulai ulang"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Laman pada \"<xliff:g id="TITLE">%s</xliff:g>\" menyatakan:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Beranjak dari laman ini?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Sentuh Oke untuk melanjutkan atau Batal untuk tetap pada laman ini."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Konfirmasi"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Kiat: Ketuk dua kali untuk memperbesar dan memperkecil."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Isiotomatis"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 560b049b3728..7cda28a6c2ea 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -440,16 +440,16 @@ <string name="permlab_writeCalendar" msgid="8438874755193825647">"aggiunta o modifica di eventi di calendario e invio di email agli ospiti a insaputa dei proprietari"</string> <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Consente all\'applicazione di aggiungere, rimuovere, modificare gli eventi che puoi modificare sul tablet, inclusi quelli di amici o colleghi. Ciò potrebbe consentire all\'applicazione di inviare messaggi apparentemente provenienti dai proprietari del calendario o di modificare eventi all\'insaputa dei proprietari."</string> <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Consente all\'applicazione di aggiungere, rimuovere, modificare gli eventi che puoi modificare sul telefono, inclusi quelli di amici o colleghi. Ciò potrebbe consentire all\'applicazione di inviare messaggi apparentemente provenienti dai proprietari del calendario o di modificare eventi all\'insaputa dei proprietari."</string> - <string name="permlab_accessMockLocation" msgid="8688334974036823330">"fonti di localizzazione fittizie per test"</string> - <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Crea fonti di localizzazione fittizie per i test o installa un nuovo fornitore di posizione. Ciò consente all\'applicazione di ignorare la posizione e/o lo stato restituito da altre fonti di localizzazione, come il GPS o fornitori di posizione."</string> + <string name="permlab_accessMockLocation" msgid="8688334974036823330">"fonti di geolocalizzazione fittizie per test"</string> + <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Crea fonti di geolocalizzazione fittizie per i test o installa un nuovo fornitore di posizione. Ciò consente all\'applicazione di ignorare la posizione e/o lo stato restituito da altre fonti di geolocalizzazione, come il GPS o fornitori di posizione."</string> <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"accesso a comandi aggiuntivi del provider di localizz."</string> - <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Consente all\'applicazione di accedere a ulteriori comandi del fornitore di posizione. Ciò potrebbe consentire all\'applicazione di interferire con il funzionamento del GPS o di altre fonti di localizzazione."</string> + <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Consente all\'applicazione di accedere a ulteriori comandi del fornitore di posizione. Ciò potrebbe consentire all\'applicazione di interferire con il funzionamento del GPS o di altre fonti di geolocalizzazione."</string> <string name="permlab_installLocationProvider" msgid="6578101199825193873">"autorizzazione a installare un provider di localizzazione"</string> - <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Crea fonti di localizzazione fittizie per i test o installa un nuovo fornitore di posizione. Ciò consente all\'applicazione di ignorare la posizione e/o lo stato restituito da altre fonti di localizzazione, come il GPS o fornitori di posizione."</string> + <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Crea fonti di geolocalizzazione fittizie per i test o installa un nuovo fornitore di posizione. Ciò consente all\'applicazione di ignorare la posizione e/o lo stato restituito da altre fonti di geolocalizzazione, come il GPS o fornitori di posizione."</string> <string name="permlab_accessFineLocation" msgid="1191898061965273372">"posizione precisa (GPS e basata sulla rete)"</string> - <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Consente all\'applicazione di ottenere la tua posizione esatta utilizzando il sistema GPS (Global Positioning System) o fonti di localizzazione delle reti come ripetitori di telefonia mobile e Wi-Fi. Questi servizi di localizzazione devono essere attivi e disponibili sul dispositivo per poter essere utilizzati dall\'applicazione. Le applicazioni potrebbero utilizzare questa autorizzazione per stabilire la tua posizione e potrebbero consumare ulteriore batteria."</string> + <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Consente all\'applicazione di ottenere la tua posizione esatta utilizzando il sistema GPS (Global Positioning System) o fonti di geolocalizzazione delle reti come ripetitori di telefonia mobile e Wi-Fi. Questi servizi di localizzazione devono essere attivi e disponibili sul dispositivo per poter essere utilizzati dall\'applicazione. Le applicazioni potrebbero utilizzare questa autorizzazione per stabilire la tua posizione e potrebbero consumare ulteriore batteria."</string> <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"posizione approssimativa (basata sulla rete)"</string> - <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Consente all\'applicazione di ottenere la tua posizione approssimativa. Questa posizione viene ottenuta da servizi di localizzazione utilizzando fonti di localizzazione delle reti come ripetitori di telefonia mobile e Wi-Fi. Questi servizi di localizzazione devono essere attivi e disponibili sul dispositivo per poter essere utilizzati dall\'applicazione. Le applicazioni potrebbero utilizzare questa autorizzazione per stabilire la tua posizione approssimativa."</string> + <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Consente all\'applicazione di ottenere la tua posizione approssimativa. Questa posizione viene ottenuta da servizi di localizzazione utilizzando fonti di geolocalizzazione delle reti come ripetitori di telefonia mobile e Wi-Fi. Questi servizi di localizzazione devono essere attivi e disponibili sul dispositivo per poter essere utilizzati dall\'applicazione. Le applicazioni potrebbero utilizzare questa autorizzazione per stabilire la tua posizione approssimativa."</string> <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"accesso a SurfaceFlinger"</string> <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Consente all\'applicazione l\'utilizzo di funzioni di basso livello SurfaceFlinger."</string> <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"lettura buffer di frame"</string> @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Riavvia"</string> <string name="js_dialog_title" msgid="1987483977834603872">"La pagina all\'indirizzo \"<xliff:g id="TITLE">%s</xliff:g>\" indica:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Uscire da questa pagina?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Tocca OK per continuare o Annulla per rimanere nella pagina corrente."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Conferma"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Suggerimento. Tocca due volte per aumentare e diminuire lo zoom."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Compilazione autom."</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 42f0e2df063f..59b4f650f27b 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"אתחל מחדש"</string> <string name="js_dialog_title" msgid="1987483977834603872">"בדף שבכתובת \'<xliff:g id="TITLE">%s</xliff:g>\' כתוב כך:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"לנווט אל מחוץ לדף זה?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"גע באפשרות \'אישור\' כדי להמשיך, או \'ביטול\' כדי להישאר בדף הנוכחי."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"אשר"</string> <string name="double_tap_toast" msgid="4595046515400268881">"טיפ: הקש פעמיים כדי להגדיל ולהקטין."</string> <string name="autofill_this_form" msgid="4616758841157816676">"מילוי אוטומטי"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index f6b93f9ac6f7..4fafb6026bb2 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"再起動"</string> <string name="js_dialog_title" msgid="1987483977834603872">"<xliff:g id="TITLE">%s</xliff:g> のページ:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"このページから移動しますか?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"移動する場合は[OK]、現在のページに留まる場合は[キャンセル]をタップしてください。"</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"確認"</string> <string name="double_tap_toast" msgid="4595046515400268881">"ヒント: ダブルタップで拡大/縮小できます。"</string> <string name="autofill_this_form" msgid="4616758841157816676">"自動入力"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 5f50ac4ef48a..df408806b85a 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"다시 부팅"</string> <string name="js_dialog_title" msgid="1987483977834603872">"\'<xliff:g id="TITLE">%s</xliff:g>\' 페이지 내용:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"자바스크립트"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"다른 페이지를 탐색하시겠습니까?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"계속하려면 \'확인\'을 터치하고 현재 페이지에 그대로 있으려면 \'취소\'를 터치하세요."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"확인"</string> <string name="double_tap_toast" msgid="4595046515400268881">"도움말: 확대/축소하려면 두 번 탭합니다."</string> <string name="autofill_this_form" msgid="4616758841157816676">"자동완성"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 9237a2cd76f0..ed317629ae94 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Pakartotinai įkelti"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Puslapyje šiuo adresu: <xliff:g id="TITLE">%s</xliff:g>, teigiama:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Išeiti iš šio puslapio?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Palieskite „Gerai“, jei norite tęsti, arba palieskite „Atšaukti“, jei norite likti dabartiniame puslapyje."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Patvirtinti"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Patarimas: palieskite dukart, kad padidintumėte ar sumažintumėte mastelį."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Automatinis pildymas"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 1de841e04d8a..3f3024232f4a 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Atsāknēt"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Lapā <xliff:g id="TITLE">%s</xliff:g> ir teikts:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Vai doties prom no šīs lapas?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Pieskarieties Labi, lai turpinātu, vai Atcelt, lai paliktu pašreizējā lapā."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Apstiprināt"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Padoms. Divreiz pieskarieties, lai tuvinātu un tālinātu."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Automātiskā aizpilde"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index af5b866aa2e1..5f49ed39ae35 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"But semula"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Halaman di \'<xliff:g id="TITLE">%s</xliff:g>\' berkata:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Navigasi keluar dari halaman ini?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Sentuh OK untuk meneruskan, atau Batal untuk terus berada di halaman semasa."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Sahkan"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Petua: Ketik dua kali untuk mengezum masuk dan keluar."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Auto isi"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index e0d9bf27b091..a81f01754528 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Omstart"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Siden på «<xliff:g id="TITLE">%s</xliff:g>» sier:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Vil du navigere bort fra denne siden?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Trykk på OK for å fortsette eller på Avbryt for å bli værende på siden."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Bekreft"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Tips: Dobbelttrykk for å zoome inn og ut."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Autofyll"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 2e92761e466e..0558096a383a 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Opnieuw opstarten"</string> <string name="js_dialog_title" msgid="1987483977834603872">"De pagina op \'<xliff:g id="TITLE">%s</xliff:g>\' meldt het volgende:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Wilt u deze pagina verlaten?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Kies \'OK\' om door te gaan of \'Annuleren\' om op de huidige pagina te blijven."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Bevestigen"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Tip: dubbeltik om in en uit te zoomen."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Autom. aanvullen"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index d8a4bf97e4f5..2fa77a94f35f 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Uruchom ponownie"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Komunikat ze strony pod adresem „<xliff:g id="TITLE">%s</xliff:g>”:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Czy opuścić tę stronę?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Dotknij OK, aby kontynuować, lub Anuluj, aby pozostać na tej stronie."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Potwierdź"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Wskazówka: dotknij dwukrotnie, aby powiększyć lub pomniejszyć."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Autouzupełnianie"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 66d50e63d088..edb34147c8ee 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -144,7 +144,7 @@ <string name="silent_mode_ring" msgid="8592241816194074353">"Campainha ativada"</string> <string name="shutdown_progress" msgid="2281079257329981203">"A encerrar..."</string> <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"O seu tablet irá encerrar."</string> - <string name="shutdown_confirm" product="default" msgid="649792175242821353">"O seu telefone irá encerrar."</string> + <string name="shutdown_confirm" product="default" msgid="649792175242821353">"O seu telefone será encerrado."</string> <string name="shutdown_confirm_question" msgid="2906544768881136183">"Pretende encerrar?"</string> <string name="reboot_safemode_title" msgid="7054509914500140361">"Reiniciar no modo de segurança"</string> <string name="reboot_safemode_confirm" msgid="55293944502784668">"Pretende reiniciar no modo de segurança? Se sim, irá desativar todas as aplicações de terceiros instaladas. Estas serão restauradas quando reiniciar novamente."</string> @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Reiniciar"</string> <string name="js_dialog_title" msgid="1987483977834603872">"A página em \"<xliff:g id="TITLE">%s</xliff:g>\" indica:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Navegar para outra página?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Toque em OK para continuar ou Cancelar para permanecer na página atual."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Confirmar"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Sugestão: toque duas vezes para aumentar ou diminuir o zoom."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Preenchimento Automático"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 3877158780c5..184f704bc937 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -160,9 +160,9 @@ <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencioso"</string> <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Som DESATIVADO"</string> <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"O som está ATIVADO"</string> - <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Modo de avião"</string> - <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Modo de avião ATIVADO"</string> - <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modo de avião DESATIVADO"</string> + <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Modo avião"</string> + <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Modo avião ATIVADO"</string> + <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modo avião DESATIVADO"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string> <string name="safeMode" msgid="2788228061547930246">"Modo de segurança"</string> <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string> @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Reiniciar"</string> <string name="js_dialog_title" msgid="1987483977834603872">"A página em \"<xliff:g id="TITLE">%s</xliff:g>\" diz:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Deseja sair desta página?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Selecione OK para continuar ou Cancelar para permanecer na página atual."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Confirmar"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Dica: toque duas vezes para aumentar e diminuir o zoom."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Preench. aut."</string> diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml index ba863cbdc9f3..7d1037791d48 100644 --- a/core/res/res/values-rm/strings.xml +++ b/core/res/res/values-rm/strings.xml @@ -1398,7 +1398,13 @@ <!-- no translation found for js_dialog_title (1987483977834603872) --> <skip /> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <!-- no translation found for js_dialog_before_unload (730366588032430474) --> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> <skip /> <string name="save_password_label" msgid="6860261758665825069">"Confermar"</string> <!-- no translation found for double_tap_toast (4595046515400268881) --> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 21fcf0488bb5..bad144052024 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -622,7 +622,7 @@ <string name="permlab_accessNotifications" msgid="7673416487873432268">"accesare notificări"</string> <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permite aplicației să recupereze, să examineze și să șteargă notificări, inclusiv pe cele postate de alte aplicații."</string> <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"conectare la un serviciu de citire a notificărilor"</string> - <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permite proprietarului să se conecteze la interfața de nivel superior a unui serviciu de citire a notificărilor. Nu ar trebui să fie niciodată necesară pentru aplicațiile obișnuite."</string> + <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permite proprietarului să se conecteze la interfața de nivel superior a unui serviciu de citire a notificărilor. În mod normal aplicațiile nu ar trebui să aibă nevoie de această permisiune."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Setaţi reguli pentru parolă"</string> <string name="policydesc_limitPassword" msgid="3252114203919510394">"Stabiliţi lungimea şi tipul de caractere permise în parolele pentru deblocarea ecranului."</string> <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizaţi încercările de deblocare a ecranului"</string> @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Reporniţi"</string> <string name="js_dialog_title" msgid="1987483977834603872">"La pagina de la „<xliff:g id="TITLE">%s</xliff:g>” apare:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Doriţi să părăsiţi această pagină?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Apăsaţi pe OK pentru a continua sau pe Anulaţi pentru a rămâne pe pagina curentă."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Confirmaţi"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Sfat: măriţi şi micşoraţi prin dublă atingere."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Automat"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 592271b2ac34..d9bf3e2cfb14 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Перезагрузка"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Подтвердите действие на <xliff:g id="TITLE">%s</xliff:g>"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Покинуть эту страницу?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Нажмите \"ОК\", чтобы продолжить, или \"Отмена\", чтобы остаться."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Подтвердите"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Совет: нажмите дважды, чтобы увеличить и уменьшить масштаб."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Автозаполнение"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 228a9e73d2e5..caedb22bb371 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Reštartovať"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Stránka „<xliff:g id="TITLE">%s</xliff:g>“ uvádza:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Chcete opustiť túto stránku?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Ak chcete pokračovať, dotknite sa tlačidla OK. Ak chcete zostať na stránke, dotknite sa tlačidla Zrušiť."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Potvrdiť"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Tip: Dvojitým klepnutím môžete zobrazenie priblížiť alebo oddialiť."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Aut.dop."</string> @@ -1051,7 +1058,7 @@ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nedostatok ukladacieho priestoru"</string> <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Niektoré systémové funkcie nemusia fungovať"</string> <string name="app_running_notification_title" msgid="8718335121060787914">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je spustená"</string> - <string name="app_running_notification_text" msgid="4653586947747330058">"Dotknutím sa zobrazíte viac informácií alebo zastavíte aplikáciu."</string> + <string name="app_running_notification_text" msgid="4653586947747330058">"Dotykom si zobrazíte viac informácií alebo zastavíte aplikáciu."</string> <string name="ok" msgid="5970060430562524910">"OK"</string> <string name="cancel" msgid="6442560571259935130">"Zrušiť"</string> <string name="yes" msgid="5362982303337969312">"OK"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 906c197ed830..64df43371dbf 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Znova zaženi"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Na strani na »<xliff:g id="TITLE">%s</xliff:g>« piše:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Ali se želite premakniti s te strani"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Če želite nadaljevati, se dotaknite »V redu«, če želite ostati na trenutni strani, izberite »Prekliči«."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Potrdi"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Nasvet: Tapnite dvakrat, če želite povečati ali pomanjšati."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Samoizp."</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 102ced6545fe..ec0384cc7316 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Поново покрени"</string> <string name="js_dialog_title" msgid="1987483977834603872">"На страници на адреси „<xliff:g id="TITLE">%s</xliff:g>“ пише следеће:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Желите ли да напустите ову страницу?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Додирните Потврди да бисте наставили или Откажи да бисте остали на тренутно отвореној страници."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Потврда"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Савет: Додирните двапут да бисте увећали и умањили приказ."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Аутом. поп."</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index adeffc3c59c0..7993bf85f6e8 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Starta om"</string> <string name="js_dialog_title" msgid="1987483977834603872">"På sidan på <xliff:g id="TITLE">%s</xliff:g> står det:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Vill du lämna den här den här sidan?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Tryck på OK om du vill fortsätta eller på Avbryt om du vill vara kvar på den aktuella sidan."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Bekräfta"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Tips! Dubbelknacka om du vill zooma in eller ut."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Autofyll"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index bdc015537aa1..535b805ff95b 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -138,7 +138,7 @@ <string name="turn_on_radio" msgid="3912793092339962371">"Washa mtandao-hewa"</string> <string name="turn_off_radio" msgid="8198784949987062346">"Zima pasiwaya"</string> <string name="screen_lock" msgid="799094655496098153">"Funga skrini"</string> - <string name="power_off" msgid="4266614107412865048">"Nishati imezimwa"</string> + <string name="power_off" msgid="4266614107412865048">"Zima simu"</string> <string name="silent_mode_silent" msgid="319298163018473078">"Programu ya milio imezimwa"</string> <string name="silent_mode_vibrate" msgid="7072043388581551395">"Mtetemo wa programu ya milio"</string> <string name="silent_mode_ring" msgid="8592241816194074353">"Programu ya milio imewashwa"</string> @@ -153,7 +153,7 @@ <string name="global_actions" product="tablet" msgid="408477140088053665">"Chaguo za kompyuta ndogo"</string> <string name="global_actions" product="default" msgid="2406416831541615258">"Chaguo za simu"</string> <string name="global_action_lock" msgid="2844945191792119712">"Funga skrini"</string> - <string name="global_action_power_off" msgid="4471879440839879722">"Nishati imezimwa"</string> + <string name="global_action_power_off" msgid="4471879440839879722">"Zima simu"</string> <string name="global_action_bug_report" msgid="7934010578922304799">"Ripoti ya hitilafu"</string> <string name="bugreport_title" msgid="2667494803742548533">"Chukua ripoti ya hitilafu"</string> <string name="bugreport_message" msgid="398447048750350456">"Hii itakusanya maelezo kuhusu hali yako ya sasa ya kifaa, ili kutuma ujumbe wa barua pepe. Itachukua muda mfupi kuanza ripoti ya hitilafu mpaka itakapokuwa tayari kutumwa; tafadhali vumilia."</string> @@ -519,7 +519,7 @@ <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"zuia simu dhidi ya kulala"</string> <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Inaruhusu programu kuzuia kompyuta kibao kwenda kulala."</string> <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Inaruhusu programu kuzuia simu isiende kulala."</string> - <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"Washa au zima kompyuta ndogo"</string> + <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"Washa au zima kompyuta kibao"</string> <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"washa au zima simu"</string> <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Inaruhusu programu kuwasha au kuzima kompyuta kibao."</string> <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Inaruhusu programu kuwasha au kuzima simu."</string> @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Washa tena"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Ukurasa ulio \"<xliff:g id="TITLE">%s</xliff:g>\" unasema:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"HatiJava"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Toka kwa ukurasa huu?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Gusa Sawa ili kuendelea, au Ghairi ili kubaki kwenye ukurasa wa sasa."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Thibitisha"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Kidokezo: Gonga mara mbili ili kukuza ndani na nje."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Kujaza kiotomatiki"</string> @@ -1060,7 +1067,7 @@ <string name="loading" msgid="7933681260296021180">"Inapakia…"</string> <string name="capital_on" msgid="1544682755514494298">"Washa"</string> <string name="capital_off" msgid="6815870386972805832">"ZIMA"</string> - <string name="whichApplication" msgid="4533185947064773386">"Kamilisha kitendo kwa kutumia"</string> + <string name="whichApplication" msgid="4533185947064773386">"Kamilisha kitendo ukitumia"</string> <string name="alwaysUse" msgid="4583018368000610438">"Tumia kama chaguo-msingi la kitendo hiki."</string> <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Futa chaguo-msingi katika mipangilio ya Mfumo > Apps > iliyopakuliwa."</string> <string name="chooseActivity" msgid="7486876147751803333">"Chagua kitendo"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index a92db7265fda..1c97cb0db113 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"รีบูต"</string> <string name="js_dialog_title" msgid="1987483977834603872">"หน้าเว็บที่ \"<xliff:g id="TITLE">%s</xliff:g>\" ระบุว่า:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"ไปจากหน้าเว็บนี้หรือไม่"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"แตะ \"ตกลง\" เพื่อทำต่อ หรือ \"ยกเลิก\" เพื่ออยู่ที่หน้าเว็บปัจจุบัน"</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"ยืนยัน"</string> <string name="double_tap_toast" msgid="4595046515400268881">"เคล็ดลับ: แตะสองครั้งเพื่อขยายและย่อ"</string> <string name="autofill_this_form" msgid="4616758841157816676">"ป้อนอัตโนมัติ"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index e726333f52a4..45a541058e67 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"I-reboot"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Isinasaad ng pahina sa \"<xliff:g id="TITLE">%s</xliff:g>\" na:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Mag-navigate palayo mula sa pahinang ito?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Pindutin ang OK upang magpatuloy, o Kanselahin upang manatili sa kasalukuyang pahina."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Kumpirmahin"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Tip: Mag-double tap upang mag-zoom in at out."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Autofill"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 9e5e43bed0f0..77b1cc68e5be 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Yeniden başlat"</string> <string name="js_dialog_title" msgid="1987483977834603872">"\"<xliff:g id="TITLE">%s</xliff:g>\" adresindeki sayfada şunlar belirtiliyor:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Bu sayfadan ayrılıyor musunuz?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Devam etmek için Tamam\'ı, mevcut sayfada kalmak için İptal\'i tıklayın."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Onayla"</string> <string name="double_tap_toast" msgid="4595046515400268881">"İpucu: Yakınlaştırmak ve uzaklaştırmak için iki kez hafifçe vurun."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Otomatik Doldur"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index bb223eafd614..0cdedc1ebc3c 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Перезав."</string> <string name="js_dialog_title" msgid="1987483977834603872">"На сторінці за адресою \"<xliff:g id="TITLE">%s</xliff:g>\" написано:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"Javascript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Перейти з цієї сторінки?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Торкніться \"OK\", щоб продовжити, або \"Скасувати\", щоб залишитися на поточній сторінці."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Підтверд."</string> <string name="double_tap_toast" msgid="4595046515400268881">"Порада: двічі торкніться для збільшення чи зменшення."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Автозап."</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index a59214412f9a..7732f4aecff1 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Khởi động lại"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Trang tại \"<xliff:g id="TITLE">%s</xliff:g>\" cho biết:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Điều hướng khỏi trang này?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Chạm OK để tiếp tục hoặc Hủy để ở lại trang hiện tại."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Xác nhận"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Mẹo: Nhấn đúp để phóng to và thu nhỏ."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Tự động điền"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 79c79f3d7205..9d1c48cdd39c 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"重新启动"</string> <string name="js_dialog_title" msgid="1987483977834603872">"网址为“<xliff:g id="TITLE">%s</xliff:g>”的网页显示:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"要从此页面导航至其他页面吗?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"触摸“确定”继续,或触摸“取消”留在当前页面。"</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"确认"</string> <string name="double_tap_toast" msgid="4595046515400268881">"提示:点按两次可放大或缩小。"</string> <string name="autofill_this_form" msgid="4616758841157816676">"自动填充"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index dfd91a47a766..b4c41b434e0f 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"重新開機"</string> <string name="js_dialog_title" msgid="1987483977834603872">"「<xliff:g id="TITLE">%s</xliff:g>」網頁指出:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"離開這個頁面?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"輕觸 [確定] 離開這個頁面,或輕觸 [取消] 停留在這個頁面。"</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"確認"</string> <string name="double_tap_toast" msgid="4595046515400268881">"提示:輕按兩下即可縮放。"</string> <string name="autofill_this_form" msgid="4616758841157816676">"自動填入功能"</string> @@ -1475,7 +1482,7 @@ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除手機的鎖定狀態。"\n\n"請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string> <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string> <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"移除"</string> - <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"要將音量調高到建議等級以上嗎?"\n"長時間聆聽偏高音量可能會損害您的聽力。"</string> + <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"要將音量調高到建議等級以上嗎?"\n"長時間聆聽高音量可能會損害您的聽力。"</string> <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"持續用兩指按住即可啟用協助工具。"</string> <string name="accessibility_enabled" msgid="1381972048564547685">"協助工具已啟用。"</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"協助工具已取消。"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 41ac207fc6a4..e2f14784d52a 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -864,7 +864,14 @@ <string name="factorytest_reboot" msgid="6320168203050791643">"Qalisa kabusha"</string> <string name="js_dialog_title" msgid="1987483977834603872">"Ikhasi eliku <xliff:g id="TITLE">%s</xliff:g> lithi:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"i-JavaScript"</string> - <string name="js_dialog_before_unload" msgid="730366588032430474">"Phuma kuleli khasi? "\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n" Thinta KULUNGILE ukuqhubeka, noma Khansela ukuhlala kuleli khasi."</string> + <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) --> + <skip /> + <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (3468816357095378590) --> + <skip /> <string name="save_password_label" msgid="6860261758665825069">"Qinisekisa"</string> <string name="double_tap_toast" msgid="4595046515400268881">"Ithiphu: thepha kabili ukusondeza ngaphandle nangaphakathi."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Ukugcwalisa Ngokuzenzakalelayo"</string> diff --git a/data/keyboards/Vendor_0079_Product_0011.kl b/data/keyboards/Vendor_0079_Product_0011.kl new file mode 100644 index 000000000000..2ae2a017481f --- /dev/null +++ b/data/keyboards/Vendor_0079_Product_0011.kl @@ -0,0 +1,23 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Classic NES Controller + +key 289 BUTTON_A +key 290 BUTTON_B +key 297 BUTTON_START +key 296 BUTTON_SELECT + +axis 0x00 HAT_X +axis 0x01 HAT_Y diff --git a/data/keyboards/Vendor_045e_Product_028e.kl b/data/keyboards/Vendor_045e_Product_028e.kl index 99f046afc95a..ca6fa5941c26 100644 --- a/data/keyboards/Vendor_045e_Product_028e.kl +++ b/data/keyboards/Vendor_045e_Product_028e.kl @@ -22,9 +22,9 @@ key 307 BUTTON_X key 308 BUTTON_Y key 310 BUTTON_L1 key 311 BUTTON_R1 -key 314 BUTTON_SELECT +key 314 BUTTON_BACK key 315 BUTTON_START -key 316 BUTTON_MODE +key 316 BUTTON_HOME key 317 BUTTON_THUMBL key 318 BUTTON_THUMBR diff --git a/data/keyboards/Vendor_046d_Product_c219.kl b/data/keyboards/Vendor_046d_Product_c219.kl new file mode 100644 index 000000000000..431dd03e886c --- /dev/null +++ b/data/keyboards/Vendor_046d_Product_c219.kl @@ -0,0 +1,35 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Logitech Logitech Cordless RumblePad 2 + +key 305 BUTTON_A +key 306 BUTTON_B +key 304 BUTTON_X +key 307 BUTTON_Y +key 308 BUTTON_L1 +key 309 BUTTON_R1 +key 310 BUTTON_L2 +key 311 BUTTON_R2 +key 313 BUTTON_START +key 312 BUTTON_BACK +key 314 BUTTON_THUMBL +key 315 BUTTON_THUMBR + +axis 0x00 X +axis 0x01 Y +axis 0x02 Z +axis 0x05 RZ +axis 0x10 HAT_X +axis 0x11 HAT_Y diff --git a/data/keyboards/Vendor_046d_Product_c21f.kl b/data/keyboards/Vendor_046d_Product_c21f.kl new file mode 100644 index 000000000000..981d864ecbb1 --- /dev/null +++ b/data/keyboards/Vendor_046d_Product_c21f.kl @@ -0,0 +1,36 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Logitech Wireless Gamepad F710 + +key 304 BUTTON_A +key 305 BUTTON_B +key 307 BUTTON_X +key 308 BUTTON_Y +key 310 BUTTON_L1 +key 311 BUTTON_R1 +key 315 BUTTON_START +key 314 BUTTON_BACK +key 316 BUTTON_HOME +key 317 BUTTON_THUMBL +key 318 BUTTON_THUMBR + +axis 0x00 X +axis 0x01 Y +axis 0x03 Z +axis 0x04 RZ +axis 0x05 RTRIGGER +axis 0x02 LTRIGGER +axis 0x10 HAT_X +axis 0x11 HAT_Y diff --git a/data/keyboards/Vendor_054c_Product_0268.kl b/data/keyboards/Vendor_054c_Product_0268.kl index f8ac6a358753..62c5f4d5800e 100644 --- a/data/keyboards/Vendor_054c_Product_0268.kl +++ b/data/keyboards/Vendor_054c_Product_0268.kl @@ -23,10 +23,10 @@ key 0x127 DPAD_LEFT key 0x120 BUTTON_SELECT key 0x123 BUTTON_START -key 0x12f BUTTON_A -key 0x12c BUTTON_B -key 0x12e BUTTON_X -key 0x12d BUTTON_Y +key 0x12e BUTTON_A +key 0x12d BUTTON_B +key 0x12f BUTTON_X +key 0x12c BUTTON_Y key 0x12a BUTTON_L1 key 0x12b BUTTON_R1 key 0x128 BUTTON_L2 @@ -35,7 +35,7 @@ key 0x121 BUTTON_THUMBL key 0x122 BUTTON_THUMBR # PS key -key 0x2d0 BUTTON_1 +key 0x2d0 BUTTON_HOME # Left Analog Stick axis 0x00 X diff --git a/data/keyboards/Vendor_0583_Product_2060.kl b/data/keyboards/Vendor_0583_Product_2060.kl new file mode 100644 index 000000000000..92c8a14a2fce --- /dev/null +++ b/data/keyboards/Vendor_0583_Product_2060.kl @@ -0,0 +1,27 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ION GO PAD + +key 288 BUTTON_A +key 289 BUTTON_B +key 290 BUTTON_X +key 291 BUTTON_Y +key 294 BUTTON_L1 +key 295 BUTTON_R1 +key 292 BUTTON_L2 +key 293 BUTTON_R2 + +axis 0x00 HAT_X +axis 0x01 HAT_Y diff --git a/data/keyboards/Vendor_0a5c_Product_8502.kl b/data/keyboards/Vendor_0a5c_Product_8502.kl new file mode 100644 index 000000000000..008496969af1 --- /dev/null +++ b/data/keyboards/Vendor_0a5c_Product_8502.kl @@ -0,0 +1,33 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Snakebyte + +key 289 BUTTON_A +key 290 BUTTON_B +key 288 BUTTON_X +key 291 BUTTON_Y +key 292 BUTTON_L1 +key 293 BUTTON_R1 +key 294 BUTTON_L2 +key 295 BUTTON_R2 +key 297 BUTTON_START +key 296 BUTTON_SELECT + +axis 0x00 X +axis 0x01 Y +axis 0x02 Z +axis 0x05 RZ +axis 0x10 HAT_X +axis 0x11 HAT_Y diff --git a/data/keyboards/Vendor_1038_Product_1412.kl b/data/keyboards/Vendor_1038_Product_1412.kl new file mode 100644 index 000000000000..551b0bd75626 --- /dev/null +++ b/data/keyboards/Vendor_1038_Product_1412.kl @@ -0,0 +1,31 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Steelseries Free + +key 304 BUTTON_A +key 305 BUTTON_B +key 307 BUTTON_X +key 308 BUTTON_Y +key 310 BUTTON_L1 +key 311 BUTTON_R1 +key 315 BUTTON_START +key 316 BUTTON_SELECT + +axis 0x00 X +axis 0x01 Y +axis 0x02 Z +axis 0x05 RZ +axis 0x10 HAT_X +axis 0x11 HAT_Y diff --git a/data/keyboards/Vendor_12bd_Product_d015.kl b/data/keyboards/Vendor_12bd_Product_d015.kl new file mode 100644 index 000000000000..557d62f135e0 --- /dev/null +++ b/data/keyboards/Vendor_12bd_Product_d015.kl @@ -0,0 +1,27 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Hitgaming SNES Retro + +key 306 BUTTON_A +key 305 BUTTON_B +key 307 BUTTON_X +key 304 BUTTON_Y +key 308 BUTTON_L1 +key 309 BUTTON_R1 +key 313 BUTTON_START +key 312 BUTTON_SELECT + +axis 0x00 HAT_X +axis 0x01 HAT_Y diff --git a/data/keyboards/Vendor_1689_Product_fd00.kl b/data/keyboards/Vendor_1689_Product_fd00.kl new file mode 100644 index 000000000000..6ce14ed03817 --- /dev/null +++ b/data/keyboards/Vendor_1689_Product_fd00.kl @@ -0,0 +1,38 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Razer Onza Tournament Edition + +key 304 BUTTON_A +key 305 BUTTON_B +key 307 BUTTON_X +key 308 BUTTON_Y +key 307 BUTTON_L1 +key 308 BUTTON_R1 +key 315 BUTTON_START +key 314 BUTTON_BACK +key 316 BUTTON_HOME +key 317 BUTTON_THUMBL +key 318 BUTTON_THUMBR +key 706 DPAD_UP +key 705 DPAD_RIGHT +key 707 DPAD_DOWN +key 704 DPAD_LEFT + +axis 0x00 X +axis 0x01 Y +axis 0x03 Z +axis 0x04 RZ +axis 0x05 RTRIGGER +axis 0x02 LTRIGGER diff --git a/data/keyboards/Vendor_1689_Product_fd01.kl b/data/keyboards/Vendor_1689_Product_fd01.kl new file mode 100644 index 000000000000..81445159c8e2 --- /dev/null +++ b/data/keyboards/Vendor_1689_Product_fd01.kl @@ -0,0 +1,36 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Razer Xbox 360 Gamepad + +key 304 BUTTON_A +key 305 BUTTON_B +key 307 BUTTON_X +key 308 BUTTON_Y +key 310 BUTTON_L1 +key 308 BUTTON_R1 +key 315 BUTTON_START +key 314 BUTTON_BACK +key 316 BUTTON_HOME +key 317 BUTTON_THUMBL +key 318 BUTTON_THUMBR + +axis 0x00 X +axis 0x01 Y +axis 0x03 Z +axis 0x04 RZ +axis 0x05 RTRIGGER +axis 0x02 LTRIGGER +axis 0x10 HAT_X +axis 0x11 HAT_Y diff --git a/data/keyboards/Vendor_1689_Product_fe00.kl b/data/keyboards/Vendor_1689_Product_fe00.kl new file mode 100644 index 000000000000..90fe4afa79fb --- /dev/null +++ b/data/keyboards/Vendor_1689_Product_fe00.kl @@ -0,0 +1,36 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Razer Sabertooth Elite + +key 304 BUTTON_A +key 305 BUTTON_B +key 307 BUTTON_X +key 308 BUTTON_Y +key 310 BUTTON_L1 +key 311 BUTTON_R1 +key 315 BUTTON_START +key 314 BUTTON_BACK +key 316 BUTTON_HOME +key 317 BUTTON_THUMBL +key 318 BUTTON_THUMBR + +axis 0x00 X +axis 0x01 Y +axis 0x03 Z +axis 0x04 RZ +axis 0x05 RTRIGGER +axis 0x02 LTRIGGER +axis 0x10 HAT_X +axis 0x11 HAT_Y diff --git a/data/keyboards/Vendor_1bad_Product_f016.kl b/data/keyboards/Vendor_1bad_Product_f016.kl new file mode 100644 index 000000000000..b72fd5ce5f24 --- /dev/null +++ b/data/keyboards/Vendor_1bad_Product_f016.kl @@ -0,0 +1,36 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Madcatz Gamepad + +key 304 BUTTON_A +key 305 BUTTON_B +key 307 BUTTON_X +key 308 BUTTON_Y +key 310 BUTTON_L1 +key 311 BUTTON_R1 +key 315 BUTTON_START +key 314 BUTTON_BACK +key 316 BUTTON_HOME +key 317 BUTTON_THUMBL +key 318 BUTTON_THUMBR + +axis 0x00 X +axis 0x01 Y +axis 0x03 Z +axis 0x04 RZ +axis 0x05 RTRIGGER +axis 0x02 LTRIGGER +axis 0x10 HAT_X +axis 0x11 HAT_Y diff --git a/data/keyboards/Vendor_1bad_Product_f023.kl b/data/keyboards/Vendor_1bad_Product_f023.kl new file mode 100644 index 000000000000..c1588b2a2e6d --- /dev/null +++ b/data/keyboards/Vendor_1bad_Product_f023.kl @@ -0,0 +1,35 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Mad Catz MLG GamePad for Xbox 360 + +key 304 BUTTON_A +key 305 BUTTON_B +key 307 BUTTON_X +key 308 BUTTON_Y +key 310 BUTTON_L1 +key 311 BUTTON_R1 +key 315 BUTTON_START +key 314 BUTTON_BACK +key 317 BUTTON_THUMBL +key 318 BUTTON_THUMBR + +axis 0x00 X +axis 0x01 Y +axis 0x03 Z +axis 0x04 RZ +axis 0x05 RTRIGGER +axis 0x02 LTRIGGER +axis 0x10 HAT_X +axis 0x11 HAT_Y diff --git a/data/keyboards/Vendor_1bad_Product_f027.kl b/data/keyboards/Vendor_1bad_Product_f027.kl new file mode 100644 index 000000000000..ea0aa7a5218b --- /dev/null +++ b/data/keyboards/Vendor_1bad_Product_f027.kl @@ -0,0 +1,36 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# MadCatz FPS Pro + +key 304 BUTTON_A +key 305 BUTTON_B +key 307 BUTTON_X +key 308 BUTTON_Y +key 310 BUTTON_L1 +key 311 BUTTON_R1 +key 315 BUTTON_START +key 314 BUTTON_BACK +key 316 BUTTON_HOME +key 317 BUTTON_THUMBL +key 318 BUTTON_THUMBR + +axis 0x00 X +axis 0x01 Y +axis 0x03 Z +axis 0x04 RZ +axis 0x05 RTRIGGER +axis 0x02 LTRIGGER +axis 0x10 HAT_X +axis 0x11 HAT_Y diff --git a/data/keyboards/Vendor_1bad_Product_f036.kl b/data/keyboards/Vendor_1bad_Product_f036.kl new file mode 100644 index 000000000000..8cd906a3dfe4 --- /dev/null +++ b/data/keyboards/Vendor_1bad_Product_f036.kl @@ -0,0 +1,36 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# MadCatz Generic XBox Controller + +key 304 BUTTON_A +key 305 BUTTON_B +key 307 BUTTON_X +key 308 BUTTON_Y +key 310 BUTTON_L1 +key 311 BUTTON_R1 +key 315 BUTTON_START +key 314 BUTTON_BACK +key 316 BUTTON_HOME +key 317 BUTTON_THUMBL +key 318 BUTTON_THUMBR + +axis 0x00 X +axis 0x01 Y +axis 0x03 Z +axis 0x04 RZ +axis 0x05 RTRIGGER +axis 0x02 LTRIGGER +axis 0x10 HAT_X +axis 0x11 HAT_Y diff --git a/data/keyboards/Vendor_1d79_Product_0009.kl b/data/keyboards/Vendor_1d79_Product_0009.kl new file mode 100644 index 000000000000..78fe2cd795ca --- /dev/null +++ b/data/keyboards/Vendor_1d79_Product_0009.kl @@ -0,0 +1,36 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Nyko Playpad / Playpad Pro + +key 304 BUTTON_A +key 305 BUTTON_B +key 307 BUTTON_X +key 308 BUTTON_Y +key 310 BUTTON_L1 +key 311 BUTTON_R1 +key 315 BUTTON_START +key 158 BUTTON_BACK +key 172 BUTTON_HOME +key 317 BUTTON_THUMBL +key 318 BUTTON_THUMBR + +axis 0x00 X +axis 0x01 Y +axis 0x02 Z +axis 0x05 RZ +axis 0x09 RTRIGGER +axis 0x0a LTRIGGER +axis 0x10 HAT_X +axis 0x11 HAT_Y diff --git a/data/keyboards/Vendor_2378_Product_100a.kl b/data/keyboards/Vendor_2378_Product_100a.kl new file mode 100644 index 000000000000..d9cd17120464 --- /dev/null +++ b/data/keyboards/Vendor_2378_Product_100a.kl @@ -0,0 +1,35 @@ +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# OnLive, Inc. OnLive Wireless Controller + +key 304 BUTTON_A +key 305 BUTTON_B +key 307 BUTTON_X +key 308 BUTTON_Y +key 310 BUTTON_L1 +key 311 BUTTON_R1 +key 315 BUTTON_START +key 314 BUTTON_SELECT +key 317 BUTTON_THUMBL +key 318 BUTTON_THUMBR + +axis 0x00 X +axis 0x01 Y +axis 0x03 Z +axis 0x04 RZ +axis 0x05 RTRIGGER +axis 0x02 LTRIGGER +axis 0x10 HAT_X +axis 0x11 HAT_Y diff --git a/docs/html/images/mediadrm_decryption_sequence.png b/docs/html/images/mediadrm_decryption_sequence.png Binary files differnew file mode 100644 index 000000000000..2bd95ea63cea --- /dev/null +++ b/docs/html/images/mediadrm_decryption_sequence.png diff --git a/docs/html/images/mediadrm_overview.png b/docs/html/images/mediadrm_overview.png Binary files differnew file mode 100644 index 000000000000..dd66bce47b39 --- /dev/null +++ b/docs/html/images/mediadrm_overview.png diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index ad7edb18c0ab..c277c247dc32 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -237,6 +237,8 @@ public: } bool mergeAllowed() { + if (!state.mMatrix.isPureTranslate()) return false; + // checks that we're unclipped, and srcover const Rect& opBounds = state.mBounds; return fabs(opBounds.getWidth() - mLocalBounds.getWidth()) < 0.1 && diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java index 6872278d70e2..31fbc4ab2dd0 100644 --- a/media/java/android/media/MediaDrm.java +++ b/media/java/android/media/MediaDrm.java @@ -29,25 +29,69 @@ import android.os.Parcel; import android.util.Log; /** - * MediaDrm can be used in conjunction with {@link android.media.MediaCrypto} - * to obtain keys for decrypting protected media data. - * - * Crypto schemes are assigned 16 byte UUIDs, - * the method {@link #isCryptoSchemeSupported} can be used to query if a given - * scheme is supported on the device. - * + * MediaDrm can be used to obtain keys for decrypting protected media streams, in + * conjunction with {@link android.media.MediaCrypto}. The MediaDrm APIs + * are designed to support the ISO/IEC 23001-7: Common Encryption standard, but + * may also be used to implement other encryption schemes. + * <p> + * Encrypted content is prepared using an encryption server and stored in a content + * library. The encrypted content is streamed or downloaded from the content library to + * client devices via content servers. Licenses to view the content are obtained from + * a License Server. + * <p> + * <p><img src="../../../images/mediadrm_overview.png" + * alt="MediaDrm Overview diagram" + * border="0" /></p> + * <p> + * Keys are requested from the license server using a key request. The key + * response is delivered to the client app, which provides the response to the + * MediaDrm API. + * <p> + * A Provisioning server may be required to distribute device-unique credentials to + * the devices. + * <p> + * Enforcing requirements related to the number of devices that may play content + * simultaneously can be performed either through key renewal or using the secure + * stop methods. + * <p> + * The following sequence diagram shows the interactions between the objects + * involved while playing back encrypted content: + * <p> + * <p><img src="../../../images/mediadrm_decryption_sequence.png" + * alt="MediaDrm Overview diagram" + * border="0" /></p> + * <p> + * The app first constructs {@link android.media.MediaExtractor} and + * {@link android.media.MediaCodec} objects. It accesses the DRM-scheme-identifying UUID, + * typically from metadata in the content, and uses this UUID to construct an instance + * of a MediaDrm object that is able to support the DRM scheme required by the content. + * Crypto schemes are assigned 16 byte UUIDs. The method {@link #isCryptoSchemeSupported} + * can be used to query if a given scheme is supported on the device. + * <p> + * The app calls {@link #openSession} to generate a sessionId that will uniquely identify + * the session in subsequent interactions. The app next uses the MediaDrm object to + * obtain a key request message and send it to the license server, then provide + * the server's response to the MediaDrm object. + * <p> + * Once the app has a sessionId, it can construct a MediaCrypto object from the UUID and + * sessionId. The MediaCrypto object is registered with the MediaCodec in the + * {@link MediaCodec.#configure} method to enable the codec to decrypt content. + * <p> + * When the app has constructed {@link android.media.MediaExtractor}, + * {@link android.media.MediaCodec} and {@link android.media.MediaCrypto} objects, + * it proceeds to pull samples from the extractor and queue them into the decoder. For + * encrypted content, the samples returned from the extractor remain encrypted, they + * are only decrypted when the samples are delivered to the decoder. + * <p> * <a name="Callbacks"></a> * <h3>Callbacks</h3> - * <p>Applications may want to register for informational events in order - * to be informed of some internal state update during playback or streaming. + * <p>Applications should register for informational events in order + * to be informed of key state updates during playback or streaming. * Registration for these events is done via a call to - * {@link #setOnEventListener(OnInfoListener)}setOnInfoListener, - * In order to receive the respective callback - * associated with this listener, applications are required to create + * {@link #setOnEventListener}. In order to receive the respective + * callback associated with this listener, applications are required to create * MediaDrm objects on a thread with its own Looper running (main UI * thread by default has a Looper running). - * - * @hide -- don't expose yet */ public final class MediaDrm { @@ -116,7 +160,7 @@ public final class MediaDrm { /** * Interface definition for a callback to be invoked when a drm event - * occurs. + * occurs */ public interface OnEventListener { @@ -132,10 +176,30 @@ public final class MediaDrm { void onEvent(MediaDrm md, byte[] sessionId, int event, int extra, byte[] data); } - public static final int MEDIA_DRM_EVENT_PROVISION_REQUIRED = 1; - public static final int MEDIA_DRM_EVENT_KEY_REQUIRED = 2; - public static final int MEDIA_DRM_EVENT_KEY_EXPIRED = 3; - public static final int MEDIA_DRM_EVENT_VENDOR_DEFINED = 4; + /** + * This event type indicates that the app needs to request a certificate from + * the provisioning server. The request message data is obtained using + * {@link #getProvisionRequest} + */ + public static final int EVENT_PROVISION_REQUIRED = 1; + + /** + * This event type indicates that the app needs to request keys from a license + * server. The request message data is obtained using {@link #getKeyRequest}. + */ + public static final int EVENT_KEY_REQUIRED = 2; + + /** + * This event type indicates that the licensed usage duration for keys in a session + * has expired. The keys are no longer valid. + */ + public static final int EVENT_KEY_EXPIRED = 3; + + /** + * This event may indicate some specific vendor-defined condition, see your + * DRM provider documentation for details + */ + public static final int EVENT_VENDOR_DEFINED = 4; private static final int DRM_EVENT = 200; @@ -183,7 +247,7 @@ public final class MediaDrm { } /* - * Called from native code when an interesting event happens. This method + * This method is called from native code when an event occurs. This method * just uses the EventHandler system to post the event back to the main app thread. * We use a weak reference to the original MediaPlayer object so that the native * code is safe from the object disappearing from underneath it. (This is @@ -203,89 +267,117 @@ public final class MediaDrm { } /** - * Open a new session with the MediaDrm object. A session ID is returned. + * Open a new session with the MediaDrm object. A session ID is returned. */ - public native byte[] openSession() throws MediaDrmException; + public native byte[] openSession(); /** - * Close a session on the MediaDrm object that was previously opened - * with {@link #openSession}. + * Close a session on the MediaDrm object that was previously opened + * with {@link #openSession}. */ - public native void closeSession(byte[] sessionId) throws MediaDrmException; + public native void closeSession(byte[] sessionId); - public static final int MEDIA_DRM_KEY_TYPE_STREAMING = 1; - public static final int MEDIA_DRM_KEY_TYPE_OFFLINE = 2; - public static final int MEDIA_DRM_KEY_TYPE_RELEASE = 3; + /** + * This key request type species that the keys will be for online use, they will + * not be saved to the device for subsequent use when the device is not connected + * to a network. + */ + public static final int KEY_TYPE_STREAMING = 1; + + /** + * This key request type specifies that the keys will be for offline use, they + * will be saved to the device for use when the device is not connected to a network. + */ + public static final int KEY_TYPE_OFFLINE = 2; + + /** + * This key request type specifies that previously saved offline keys should be released. + */ + public static final int KEY_TYPE_RELEASE = 3; + + /** + * Contains the opaque data an app uses to request keys from a license server + */ + public final static class KeyRequest { + KeyRequest() {} + + /** + * Get the opaque message data + */ + public byte[] getData() { return mData; } + + /** + * Get the default URL to use when sending the key request message to a + * server, if known. The app may prefer to use a different license + * server URL from other sources. + */ + public String getDefaultUrl() { return mDefaultUrl; } - public final class KeyRequest { - public KeyRequest() {} - public byte[] data; - public String defaultUrl; + private byte[] mData; + private String mDefaultUrl; }; /** * A key request/response exchange occurs between the app and a license server * to obtain or release keys used to decrypt encrypted content. + * <p> * getKeyRequest() is used to obtain an opaque key request byte array that is * delivered to the license server. The opaque key request byte array is returned * in KeyRequest.data. The recommended URL to deliver the key request to is * returned in KeyRequest.defaultUrl. - * + * <p> * After the app has received the key request response from the server, * it should deliver to the response to the DRM engine plugin using the method * {@link #provideKeyResponse}. * * @param scope may be a sessionId or a keySetId, depending on the specified keyType. - * When the keyType is MEDIA_DRM_KEY_TYPE_STREAMING or MEDIA_DRM_KEY_TYPE_OFFLINE, + * When the keyType is KEY_TYPE_STREAMING or KEY_TYPE_OFFLINE, * scope should be set to the sessionId the keys will be provided to. When the keyType - * is MEDIA_DRM_KEY_TYPE_RELEASE, scope should be set to the keySetId of the keys + * is KEY_TYPE_RELEASE, scope should be set to the keySetId of the keys * being released. Releasing keys from a device invalidates them for all sessions. * @param init container-specific data, its meaning is interpreted based on the * mime type provided in the mimeType parameter. It could contain, for example, * the content ID, key ID or other data obtained from the content metadata that is * required in generating the key request. init may be null when keyType is - * MEDIA_DRM_KEY_TYPE_RELEASE. + * KEY_TYPE_RELEASE. * @param mimeType identifies the mime type of the content * @param keyType specifes the type of the request. The request may be to acquire * keys for streaming or offline content, or to release previously acquired * keys, which are identified by a keySetId. - * @param optionalParameters are included in the key request message to * allow a client application to provide additional message parameters to the server. */ public native KeyRequest getKeyRequest(byte[] scope, byte[] init, String mimeType, int keyType, - HashMap<String, String> optionalParameters) - throws MediaDrmException; + HashMap<String, String> optionalParameters); + /** * A key response is received from the license server by the app, then it is * provided to the DRM engine plugin using provideKeyResponse. The byte array * returned is a keySetId that can be used to later restore the keys to a new - * session with the method {@link restoreKeys}, enabling offline key use. + * session with the method {@link #restoreKeys}, enabling offline key use. * * @param sessionId the session ID for the DRM session * @param response the byte array response from the server */ - public native byte[] provideKeyResponse(byte[] sessionId, byte[] response) - throws MediaDrmException; + public native byte[] provideKeyResponse(byte[] sessionId, byte[] response); /** * Restore persisted offline keys into a new session. keySetId identifies the - * keys to load, obtained from a prior call to {@link provideKeyResponse}. + * keys to load, obtained from a prior call to {@link #provideKeyResponse}. * * @param sessionId the session ID for the DRM session * @param keySetId identifies the saved key set to restore */ - public native void restoreKeys(byte[] sessionId, byte[] keySetId) - throws MediaDrmException; + public native void restoreKeys(byte[] sessionId, byte[] keySetId); /** * Remove the current keys from a session. * * @param sessionId the session ID for the DRM session */ - public native void removeKeys(byte[] sessionId) throws MediaDrmException; + public native void removeKeys(byte[] sessionId); /** * Request an informative description of the key status for the session. The status is @@ -296,25 +388,41 @@ public final class MediaDrm { * * @param sessionId the session ID for the DRM session */ - public native HashMap<String, String> queryKeyStatus(byte[] sessionId) - throws MediaDrmException; + public native HashMap<String, String> queryKeyStatus(byte[] sessionId); + + /** + * Contains the opaque data an app uses to request a certificate from a provisioning + * server + */ + public final static class ProvisionRequest { + ProvisionRequest() {} + + /** + * Get the opaque message data + */ + public byte[] getData() { return mData; } + + /** + * Get the default URL to use when sending the provision request + * message to a server, if known. The app may prefer to use a different + * provisioning server URL obtained from other sources. + */ + public String getDefaultUrl() { return mDefaultUrl; } - public final class ProvisionRequest { - public ProvisionRequest() {} - public byte[] data; - public String defaultUrl; + private byte[] mData; + private String mDefaultUrl; } /** * A provision request/response exchange occurs between the app and a provisioning * server to retrieve a device certificate. If provisionining is required, the - * MEDIA_DRM_EVENT_PROVISION_REQUIRED event will be sent to the event handler. + * EVENT_PROVISION_REQUIRED event will be sent to the event handler. * getProvisionRequest is used to obtain the opaque provision request byte array that * should be delivered to the provisioning server. The provision request byte array * is returned in ProvisionRequest.data. The recommended URL to deliver the provision * request to is returned in ProvisionRequest.defaultUrl. */ - public native ProvisionRequest getProvisionRequest() throws MediaDrmException; + public native ProvisionRequest getProvisionRequest(); /** * After a provision response is received by the app, it is provided to the DRM @@ -323,92 +431,91 @@ public final class MediaDrm { * @param response the opaque provisioning response byte array to provide to the * DRM engine plugin. */ - public native void provideProvisionResponse(byte[] response) - throws MediaDrmException; + public native void provideProvisionResponse(byte[] response); /** - * A means of enforcing the contractual requirement for a concurrent stream limit - * per subscriber across devices is provided via SecureStop. SecureStop is a means - * of securely monitoring the lifetime of sessions. Since playback on a device can - * be interrupted due to reboot, power failure, etc. a means of persisting the - * lifetime information on the device is needed. - * - * A signed version of the sessionID is written to persistent storage on the device - * when each MediaCrypto object is created. The sessionID is signed by the device - * private key to prevent tampering. - * + * A means of enforcing limits on the number of concurrent streams per subscriber + * across devices is provided via SecureStop. This is achieved by securely + * monitoring the lifetime of sessions. + * <p> + * Information from the server related to the current playback session is written + * to persistent storage on the device when each MediaCrypto object is created. + * <p> * In the normal case, playback will be completed, the session destroyed and the - * Secure Stops will be queried. The App queries secure stops and forwards the + * Secure Stops will be queried. The app queries secure stops and forwards the * secure stop message to the server which verifies the signature and notifies the * server side database that the session destruction has been confirmed. The persisted * record on the client is only removed after positive confirmation that the server * received the message using releaseSecureStops(). */ - public native List<byte[]> getSecureStops() throws MediaDrmException; + public native List<byte[]> getSecureStops(); /** * Process the SecureStop server response message ssRelease. After authenticating - * the message, remove the SecureStops identiied in the response. + * the message, remove the SecureStops identified in the response. * * @param ssRelease the server response indicating which secure stops to release */ - public native void releaseSecureStops(byte[] ssRelease) - throws MediaDrmException; + public native void releaseSecureStops(byte[] ssRelease); /** - * Read a DRM engine plugin property value, given the property name string. There are - * several forms of property access functions, depending on the data type returned. - * + * String property name: identifies the maker of the DRM engine plugin + */ + public static final String PROPERTY_VENDOR = "vendor"; + + /** + * String property name: identifies the version of the DRM engine plugin + */ + public static final String PROPERTY_VERSION = "version"; + + /** + * String property name: describes the DRM engine plugin + */ + public static final String PROPERTY_DESCRIPTION = "description"; + + /** + * String property name: a comma-separated list of cipher and mac algorithms + * supported by CryptoSession. The list may be empty if the DRM engine + * plugin does not support CryptoSession operations. + */ + public static final String PROPERTY_ALGORITHM = "algorithm"; + + /** + * Read a DRM engine plugin String property value, given the property name string. + * <p> * Standard fields names are: - * vendor String - identifies the maker of the DRM engine plugin - * version String - identifies the version of the DRM engine plugin - * description String - describes the DRM engine plugin - * deviceUniqueId byte[] - The device unique identifier is established during device - * provisioning and provides a means of uniquely identifying - * each device - * algorithms String - a comma-separate list of cipher and mac algorithms supported - * by CryptoSession. The list may be empty if the DRM engine - * plugin does not support CryptoSession operations. + * {@link #PROPERTY_VENDOR}, {@link #PROPERTY_VERSION}, + * {@link #PROPERTY_DESCRIPTION}, {@link #PROPERTY_ALGORITHM} */ - public native String getPropertyString(String propertyName) - throws MediaDrmException; + public native String getPropertyString(String propertyName); - public native byte[] getPropertyByteArray(String propertyName) - throws MediaDrmException; /** - * Write a DRM engine plugin property value. There are several forms of - * property setting functions, depending on the data type being set. + * The device unique identifier is established during device provisioning and + * provides a means of uniquely identifying each device */ - public native void setPropertyString(String propertyName, String value) - throws MediaDrmException; + public static final String PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId"; + + /** + * Read a DRM engine plugin byte array property value, given the property name string. + * <p> + * Standard fields names are {@link #PROPERTY_DEVICE_UNIQUE_ID} + */ + public native byte[] getPropertyByteArray(String propertyName); - public native void setPropertyByteArray(String propertyName, byte[] value) - throws MediaDrmException; /** - * In addition to supporting decryption of DASH Common Encrypted Media, the - * MediaDrm APIs provide the ability to securely deliver session keys from - * an operator's session key server to a client device, based on the factory-installed - * root of trust, and provide the ability to do encrypt, decrypt, sign and verify - * with the session key on arbitrary user data. - * - * The CryptoSession class implements generic encrypt/decrypt/sign/verify methods - * based on the established session keys. These keys are exchanged using the - * getKeyRequest/provideKeyResponse methods. - * - * Applications of this capability could include securing various types of - * purchased or private content, such as applications, books and other media, - * photos or media delivery protocols. - * - * Operators can create session key servers that are functionally similar to a - * license key server, except that instead of receiving license key requests and - * providing encrypted content keys which are used specifically to decrypt A/V media - * content, the session key server receives session key requests and provides - * encrypted session keys which can be used for general purpose crypto operations. + * Set a DRM engine plugin String property value. + */ + public native void setPropertyString(String propertyName, String value); + + /** + * Set a DRM engine plugin byte array property value. */ + public native void setPropertyByteArray(String propertyName, byte[] value); + private static final native void setCipherAlgorithmNative(MediaDrm drm, byte[] sessionId, String algorithm); @@ -429,61 +536,112 @@ public final class MediaDrm { byte[] keyId, byte[] message, byte[] signature); + /** + * In addition to supporting decryption of DASH Common Encrypted Media, the + * MediaDrm APIs provide the ability to securely deliver session keys from + * an operator's session key server to a client device, based on the factory-installed + * root of trust, and then perform encrypt, decrypt, sign and verify operations + * with the session key on arbitrary user data. + * <p> + * The CryptoSession class implements generic encrypt/decrypt/sign/verify methods + * based on the established session keys. These keys are exchanged using the + * getKeyRequest/provideKeyResponse methods. + * <p> + * Applications of this capability could include securing various types of + * purchased or private content, such as applications, books and other media, + * photos or media delivery protocols. + * <p> + * Operators can create session key servers that are functionally similar to a + * license key server, except that instead of receiving license key requests and + * providing encrypted content keys which are used specifically to decrypt A/V media + * content, the session key server receives session key requests and provides + * encrypted session keys which can be used for general purpose crypto operations. + * <p> + * A CryptoSession is obtained using {@link #getCryptoSession} + */ public final class CryptoSession { private MediaDrm mDrm; private byte[] mSessionId; - /** - * Construct a CryptoSession which can be used to encrypt, decrypt, - * sign and verify messages or data using the session keys established - * for the session using methods {@link getKeyRequest} and - * {@link provideKeyResponse} using a session key server. - * - * @param sessionId the session ID for the session containing keys - * to be used for encrypt, decrypt, sign and/or verify - * - * @param cipherAlgorithm the algorithm to use for encryption and - * decryption ciphers. The algorithm string conforms to JCA Standard - * Names for Cipher Transforms and is case insensitive. For example - * "AES/CBC/PKCS5Padding". - * - * @param macAlgorithm the algorithm to use for sign and verify - * The algorithm string conforms to JCA Standard Names for Mac - * Algorithms and is case insensitive. For example "HmacSHA256". - * - * The list of supported algorithms for a DRM engine plugin can be obtained - * using the method {@link getPropertyString("algorithms")} - */ - - public CryptoSession(MediaDrm drm, byte[] sessionId, - String cipherAlgorithm, String macAlgorithm) - throws MediaDrmException { + CryptoSession(MediaDrm drm, byte[] sessionId, + String cipherAlgorithm, String macAlgorithm) + { mSessionId = sessionId; mDrm = drm; setCipherAlgorithmNative(drm, sessionId, cipherAlgorithm); setMacAlgorithmNative(drm, sessionId, macAlgorithm); } + /** + * Encrypt data using the CryptoSession's cipher algorithm + * + * @param keyid specifies which key to use + * @param input the data to encrypt + * @param iv the initialization vector to use for the cipher + */ public byte[] encrypt(byte[] keyid, byte[] input, byte[] iv) { return encryptNative(mDrm, mSessionId, keyid, input, iv); } + /** + * Decrypt data using the CryptoSessions's cipher algorithm + * + * @param keyid specifies which key to use + * @param input the data to encrypt + * @param iv the initialization vector to use for the cipher + */ public byte[] decrypt(byte[] keyid, byte[] input, byte[] iv) { return decryptNative(mDrm, mSessionId, keyid, input, iv); } + /** + * Sign data using the CryptoSessions's mac algorithm. + * + * @param keyid specifies which key to use + * @param message the data for which a signature is to be computed + */ public byte[] sign(byte[] keyid, byte[] message) { return signNative(mDrm, mSessionId, keyid, message); } + + /** + * Verify a signature using the CryptoSessions's mac algorithm. Return true + * if the signatures match, false if they do no. + * + * @param keyid specifies which key to use + * @param message the data to verify + * @param signature the reference signature which will be compared with the + * computed signature + */ public boolean verify(byte[] keyid, byte[] message, byte[] signature) { return verifyNative(mDrm, mSessionId, keyid, message, signature); } }; + /** + * Obtain a CryptoSession object which can be used to encrypt, decrypt, + * sign and verify messages or data using the session keys established + * for the session using methods {@link #getKeyRequest} and + * {@link #provideKeyResponse} using a session key server. + * + * @param sessionId the session ID for the session containing keys + * to be used for encrypt, decrypt, sign and/or verify + * @param cipherAlgorithm the algorithm to use for encryption and + * decryption ciphers. The algorithm string conforms to JCA Standard + * Names for Cipher Transforms and is case insensitive. For example + * "AES/CBC/NoPadding". + * @param macAlgorithm the algorithm to use for sign and verify + * The algorithm string conforms to JCA Standard Names for Mac + * Algorithms and is case insensitive. For example "HmacSHA256". + * <p> + * The list of supported algorithms for a DRM engine plugin can be obtained + * using the method {@link #getPropertyString} with the property name + * "algorithms". + */ public CryptoSession getCryptoSession(byte[] sessionId, String cipherAlgorithm, String macAlgorithm) - throws MediaDrmException { + { return new CryptoSession(this, sessionId, cipherAlgorithm, macAlgorithm); } @@ -495,8 +653,7 @@ public final class MediaDrm { public native final void release(); private static native final void native_init(); - private native final void native_setup(Object mediadrm_this, byte[] uuid) - throws MediaDrmException; + private native final void native_setup(Object mediadrm_this, byte[] uuid); private native final void native_finalize(); diff --git a/media/java/android/media/MediaDrmException.java b/media/java/android/media/MediaDrmException.java index 6f81f9024537..d6f5ff4ace8b 100644 --- a/media/java/android/media/MediaDrmException.java +++ b/media/java/android/media/MediaDrmException.java @@ -19,8 +19,6 @@ package android.media; /** * Exception thrown if MediaDrm object could not be instantiated for * whatever reason. - * - * @hide -- don't expose yet */ public final class MediaDrmException extends Exception { public MediaDrmException(String detailMessage) { diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp index c32ba9d3fde7..d9d466e75e6c 100644 --- a/media/jni/android_media_MediaDrm.cpp +++ b/media/jni/android_media_MediaDrm.cpp @@ -458,22 +458,22 @@ static void android_media_MediaDrm_native_init(JNIEnv *env) { "(Ljava/lang/Object;IILjava/lang/Object;)V"); jfieldID field; - GET_STATIC_FIELD_ID(field, clazz, "MEDIA_DRM_EVENT_PROVISION_REQUIRED", "I"); + GET_STATIC_FIELD_ID(field, clazz, "EVENT_PROVISION_REQUIRED", "I"); gEventTypes.kEventProvisionRequired = env->GetStaticIntField(clazz, field); - GET_STATIC_FIELD_ID(field, clazz, "MEDIA_DRM_EVENT_KEY_REQUIRED", "I"); + GET_STATIC_FIELD_ID(field, clazz, "EVENT_KEY_REQUIRED", "I"); gEventTypes.kEventKeyRequired = env->GetStaticIntField(clazz, field); - GET_STATIC_FIELD_ID(field, clazz, "MEDIA_DRM_EVENT_KEY_EXPIRED", "I"); + GET_STATIC_FIELD_ID(field, clazz, "EVENT_KEY_EXPIRED", "I"); gEventTypes.kEventKeyExpired = env->GetStaticIntField(clazz, field); - GET_STATIC_FIELD_ID(field, clazz, "MEDIA_DRM_EVENT_VENDOR_DEFINED", "I"); + GET_STATIC_FIELD_ID(field, clazz, "EVENT_VENDOR_DEFINED", "I"); gEventTypes.kEventVendorDefined = env->GetStaticIntField(clazz, field); FIND_CLASS(clazz, "android/media/MediaDrm$KeyRequest"); - GET_FIELD_ID(gFields.keyRequest.data, clazz, "data", "[B"); - GET_FIELD_ID(gFields.keyRequest.defaultUrl, clazz, "defaultUrl", "Ljava/lang/String;"); + GET_FIELD_ID(gFields.keyRequest.data, clazz, "mData", "[B"); + GET_FIELD_ID(gFields.keyRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;"); FIND_CLASS(clazz, "android/media/MediaDrm$ProvisionRequest"); - GET_FIELD_ID(gFields.provisionRequest.data, clazz, "data", "[B"); - GET_FIELD_ID(gFields.provisionRequest.defaultUrl, clazz, "defaultUrl", "Ljava/lang/String;"); + GET_FIELD_ID(gFields.provisionRequest.data, clazz, "mData", "[B"); + GET_FIELD_ID(gFields.provisionRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;"); FIND_CLASS(clazz, "java/util/ArrayList"); GET_METHOD_ID(gFields.arraylist.init, clazz, "<init>", "()V"); diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java index ab7ceb61dbce..235829e6a0d4 100644 --- a/opengl/java/android/opengl/GLSurfaceView.java +++ b/opengl/java/android/opengl/GLSurfaceView.java @@ -184,7 +184,6 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback private int mDebugFlags; private int mEGLContextClientVersion; private boolean mPreserveEGLContextOnPause; - private int mUserRenderMode; /** * The renderer only renders @@ -258,7 +257,6 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback // underlying surface is created and destroyed SurfaceHolder holder = getHolder(); holder.addCallback(this); - mUserRenderMode = RENDERMODE_CONTINUOUSLY; } /** @@ -516,7 +514,6 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback default: throw new IllegalArgumentException("renderMode"); } - mUserRenderMode = renderMode; mGLThread.setRenderMode(renderMode); } @@ -528,7 +525,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback * @see #RENDERMODE_WHEN_DIRTY */ public int getRenderMode() { - return mUserRenderMode; + return mGLThread.getRenderMode(); } /** @@ -608,9 +605,13 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback if (LOG_ATTACH_DETACH) { Log.d(TAG, "onAttachedToWindow reattach =" + mDetached); } + + final int renderMode = mGLThread != null ? + mGLThread.mRenderMode : RENDERMODE_CONTINUOUSLY; + if (mDetached && (mRenderer != null)) { mGLThread = new GLThread(mThisWeakRef); - mGLThread.setRenderMode(mUserRenderMode); + mGLThread.setRenderMode(renderMode); mGLThread.start(); } mDetached = false; @@ -1261,6 +1262,17 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback private Handler mGLHandler; private Choreographer mChoreographer; + // this runnable could be called often, so we keep an instance around + class GetRenderModeRunnable implements Runnable { + volatile public int renderMode; + @Override + public void run() { + renderMode = doGetRenderMode(); + } + }; + + private final GetRenderModeRunnable mGetRenderModeRunnable = new GetRenderModeRunnable(); + /* * Set once at thread construction time, nulled out when the parent view is garbage * called. This weak reference allows the GLSurfaceView to be garbage collected while @@ -1511,7 +1523,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } } - private void doWindowResize(final int width, final int height) { + private void doWindowResize(int width, int height) { // we were not drawing yet. Update the window size and // state and attempt to draw a frame. mSizeChanged = (mWidth != width || mHeight != height); @@ -1522,9 +1534,13 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback executeDraw(); } - private void doSetRenderMode(final int renderMode) { + private void doSetRenderMode(int renderMode) { mRenderMode = renderMode; - requestRender(); + } + + + private int doGetRenderMode() { + return mRenderMode; } /* @@ -1607,6 +1623,11 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback }, 0); } + public int getRenderMode() { + mGLHandler.runWithScissors(mGetRenderModeRunnable, 0); + return mGetRenderModeRunnable.renderMode; + } + public void requestExitAndWait() { getLooper().quit(); try { diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index a28c387c66f6..f872cc3b59a8 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -1595,7 +1595,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub ApplicationInfo ai = mIPackageManager.getApplicationInfo(imm.getPackageName(), PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, mSettings.getCurrentUserId()); - if (ai.enabledSetting + if (ai != null && ai.enabledSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) { mIPackageManager.setApplicationEnabledSetting(imm.getPackageName(), PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index 1f3ac9691872..7a5f55a12512 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -1160,7 +1160,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { boolean setInputFilter = false; AccessibilityInputFilter inputFilter = null; synchronized (mLock) { - if (userState.mIsAccessibilityEnabled) { + // Accessibility enabled means at least one service is enabled. + if (userState.mIsAccessibilityEnabled + || userState.mIsDisplayMagnificationEnabled) { if (!mHasInputFilter) { mHasInputFilter = true; if (mInputFilter == null) { @@ -1174,7 +1176,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { if (userState.mIsDisplayMagnificationEnabled) { flags |= AccessibilityInputFilter.FLAG_FEATURE_SCREEN_MAGNIFIER; } - if (userState.mIsTouchExplorationEnabled) { + // Touch exploration without accessibility makes no sense. + if (userState.mIsAccessibilityEnabled && userState.mIsTouchExplorationEnabled) { flags |= AccessibilityInputFilter.FLAG_FEATURE_TOUCH_EXPLORATION; } mInputFilter.setEnabledFeatures(flags); diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java index 31e01c03f3f2..dbd48d9f7c12 100644 --- a/telephony/java/android/telephony/CellIdentityCdma.java +++ b/telephony/java/android/telephony/CellIdentityCdma.java @@ -93,21 +93,21 @@ public final class CellIdentityCdma implements Parcelable { } /** - * @return Network Id 0..65535 + * @return Network Id 0..65535, Integer.MAX_VALUE if unknown */ public int getNetworkId() { return mNetworkId; } /** - * @return System Id 0..32767 + * @return System Id 0..32767, Integer.MAX_VALUE if unknown */ public int getSystemId() { return mSystemId; } /** - * @return Base Station Id 0..65535 + * @return Base Station Id 0..65535, Integer.MAX_VALUE if unknown */ public int getBasestationId() { return mBasestationId; @@ -118,7 +118,7 @@ public final class CellIdentityCdma implements Parcelable { * specified in 3GPP2 C.S0005-A v6.0. It is represented in units * of 0.25 seconds and ranges from -2592000 to 2592000, both * values inclusive (corresponding to a range of -180 - * to +180 degrees). + * to +180 degrees). Integer.MAX_VALUE if unknown. */ public int getLongitude() { return mLongitude; @@ -129,7 +129,7 @@ public final class CellIdentityCdma implements Parcelable { * specified in 3GPP2 C.S0005-A v6.0. It is represented in units * of 0.25 seconds and ranges from -1296000 to 1296000, both * values inclusive (corresponding to a range of -90 - * to +90 degrees). + * to +90 degrees). Integer.MAX_VALUE if unknown. */ public int getLatitude() { return mLatitude; @@ -162,7 +162,7 @@ public final class CellIdentityCdma implements Parcelable { @Override public String toString() { - StringBuilder sb = new StringBuilder("CellIdentitiyCdma:{"); + StringBuilder sb = new StringBuilder("CellIdentityCdma:{"); sb.append(" mNetworkId="); sb.append(mNetworkId); sb.append(" mSystemId="); sb.append(mSystemId); sb.append(" mBasestationId="); sb.append(mBasestationId); diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java index 98113e737c8b..6f8cc9177b8b 100644 --- a/telephony/java/android/telephony/CellIdentityGsm.java +++ b/telephony/java/android/telephony/CellIdentityGsm.java @@ -21,7 +21,7 @@ import android.os.Parcelable; import android.telephony.Rlog; /** - * CellIdentity to represent a unique GSM or UMTS cell + * CellIdentity to represent a unique GSM cell */ public final class CellIdentityGsm implements Parcelable { @@ -35,10 +35,7 @@ public final class CellIdentityGsm implements Parcelable { // 16-bit Location Area Code, 0..65535 private final int mLac; // 16-bit GSM Cell Identity described in TS 27.007, 0..65535 - // 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455 private final int mCid; - // 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511 - private final int mPsc; /** * @hide @@ -48,7 +45,6 @@ public final class CellIdentityGsm implements Parcelable { mMnc = Integer.MAX_VALUE; mLac = Integer.MAX_VALUE; mCid = Integer.MAX_VALUE; - mPsc = Integer.MAX_VALUE; } /** * public constructor @@ -56,16 +52,14 @@ public final class CellIdentityGsm implements Parcelable { * @param mnc 2 or 3-digit Mobile Network Code, 0..999 * @param lac 16-bit Location Area Code, 0..65535 * @param cid 16-bit GSM Cell Identity or 28-bit UMTS Cell Identity - * @param psc 9-bit UMTS Primary Scrambling Code * * @hide */ - public CellIdentityGsm (int mcc, int mnc, int lac, int cid, int psc) { + public CellIdentityGsm (int mcc, int mnc, int lac, int cid) { mMcc = mcc; mMnc = mnc; mLac = lac; mCid = cid; - mPsc = psc; } private CellIdentityGsm(CellIdentityGsm cid) { @@ -73,7 +67,6 @@ public final class CellIdentityGsm implements Parcelable { mMnc = cid.mMnc; mLac = cid.mLac; mCid = cid.mCid; - mPsc = cid.mPsc; } CellIdentityGsm copy() { @@ -81,21 +74,21 @@ public final class CellIdentityGsm implements Parcelable { } /** - * @return 3-digit Mobile Country Code, 0..999 + * @return 3-digit Mobile Country Code, 0..999, Integer.MAX_VALUE if unknown */ public int getMcc() { return mMcc; } /** - * @return 2 or 3-digit Mobile Network Code, 0..999 + * @return 2 or 3-digit Mobile Network Code, 0..999, Integer.MAX_VALUE if unknown */ public int getMnc() { return mMnc; } /** - * @return 16-bit Location Area Code, 0..65535 + * @return 16-bit Location Area Code, 0..65535, Integer.MAX_VALUE if unknown */ public int getLac() { return mLac; @@ -104,27 +97,24 @@ public final class CellIdentityGsm implements Parcelable { /** * @return CID * Either 16-bit GSM Cell Identity described - * in TS 27.007, 0..65535 - * or 28-bit UMTS Cell Identity described - * in TS 25.331, 0..268435455 + * in TS 27.007, 0..65535, Integer.MAX_VALUE if unknown */ public int getCid() { return mCid; } /** - * @return 9-bit UMTS Primary Scrambling Code described in - * TS 25.331, 0..511 + * @return Integer.MAX_VALUE, undefined for GSM */ + @Deprecated public int getPsc() { - return mPsc; + return Integer.MAX_VALUE; } @Override public int hashCode() { int primeNum = 31; - return (mMcc * primeNum) + (mMnc * primeNum) + (mLac * primeNum) + (mCid * primeNum) + - (mPsc * primeNum); + return (mMcc * primeNum) + (mMnc * primeNum) + (mLac * primeNum) + (mCid * primeNum); } @Override @@ -135,8 +125,7 @@ public final class CellIdentityGsm implements Parcelable { return mMcc == o.mMcc && mMnc == o.mMnc && mLac == o.mLac && - mCid == o.mCid && - mPsc == o.mPsc; + mCid == o.mCid; } catch (ClassCastException e) { return false; } @@ -147,12 +136,11 @@ public final class CellIdentityGsm implements Parcelable { @Override public String toString() { - StringBuilder sb = new StringBuilder("CellIdentitiyGsm:{"); + StringBuilder sb = new StringBuilder("CellIdentityGsm:{"); sb.append(" mMcc=").append(mMcc); sb.append(" mMnc=").append(mMnc); sb.append(" mLac=").append(mLac); sb.append(" mCid=").append(mCid); - sb.append(" mPsc=").append(mPsc); sb.append("}"); return sb.toString(); @@ -172,7 +160,6 @@ public final class CellIdentityGsm implements Parcelable { dest.writeInt(mMnc); dest.writeInt(mLac); dest.writeInt(mCid); - dest.writeInt(mPsc); } /** Construct from Parcel, type has already been processed */ @@ -181,7 +168,6 @@ public final class CellIdentityGsm implements Parcelable { mMnc = in.readInt(); mLac = in.readInt(); mCid = in.readInt(); - mPsc = in.readInt(); if (DBG) log("CellIdentityGsm(Parcel): " + toString()); } diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java index 86924bdb276e..13b39c90fb98 100644 --- a/telephony/java/android/telephony/CellIdentityLte.java +++ b/telephony/java/android/telephony/CellIdentityLte.java @@ -81,35 +81,35 @@ public final class CellIdentityLte implements Parcelable { } /** - * @return 3-digit Mobile Country Code, 0..999 + * @return 3-digit Mobile Country Code, 0..999, Integer.MAX_VALUE if unknown */ public int getMcc() { return mMcc; } /** - * @return 2 or 3-digit Mobile Network Code, 0..999 + * @return 2 or 3-digit Mobile Network Code, 0..999, Integer.MAX_VALUE if unknown */ public int getMnc() { return mMnc; } /** - * @return 28-bit Cell Identity + * @return 28-bit Cell Identity, Integer.MAX_VALUE if unknown */ public int getCi() { return mCi; } /** - * @return Physical Cell Id 0..503 + * @return Physical Cell Id 0..503, Integer.MAX_VALUE if unknown */ public int getPci() { return mPci; } /** - * @return 16-bit Tracking Area Code + * @return 16-bit Tracking Area Code, Integer.MAX_VALUE if unknown */ public int getTac() { return mTac; @@ -142,7 +142,7 @@ public final class CellIdentityLte implements Parcelable { @Override public String toString() { - StringBuilder sb = new StringBuilder("CellIdentitiyLte:{"); + StringBuilder sb = new StringBuilder("CellIdentityLte:{"); sb.append(" mMcc="); sb.append(mMcc); sb.append(" mMnc="); sb.append(mMnc); sb.append(" mCi="); sb.append(mCi); diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java new file mode 100644 index 000000000000..2f8fa4218c13 --- /dev/null +++ b/telephony/java/android/telephony/CellIdentityWcdma.java @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +import android.os.Parcel; +import android.os.Parcelable; +import android.telephony.Rlog; + +/** + * CellIdentity to represent a unique UMTS cell + */ +public final class CellIdentityWcdma implements Parcelable { + + private static final String LOG_TAG = "CellIdentityWcdma"; + private static final boolean DBG = false; + + // 3-digit Mobile Country Code, 0..999 + private final int mMcc; + // 2 or 3-digit Mobile Network Code, 0..999 + private final int mMnc; + // 16-bit Location Area Code, 0..65535 + private final int mLac; + // 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455 + private final int mCid; + // 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511 + private final int mPsc; + + /** + * @hide + */ + public CellIdentityWcdma() { + mMcc = Integer.MAX_VALUE; + mMnc = Integer.MAX_VALUE; + mLac = Integer.MAX_VALUE; + mCid = Integer.MAX_VALUE; + mPsc = Integer.MAX_VALUE; + } + /** + * public constructor + * @param mcc 3-digit Mobile Country Code, 0..999 + * @param mnc 2 or 3-digit Mobile Network Code, 0..999 + * @param lac 16-bit Location Area Code, 0..65535 + * @param cid 28-bit UMTS Cell Identity + * @param psc 9-bit UMTS Primary Scrambling Code + * + * @hide + */ + public CellIdentityWcdma (int mcc, int mnc, int lac, int cid, int psc) { + mMcc = mcc; + mMnc = mnc; + mLac = lac; + mCid = cid; + mPsc = psc; + } + + private CellIdentityWcdma(CellIdentityWcdma cid) { + mMcc = cid.mMcc; + mMnc = cid.mMnc; + mLac = cid.mLac; + mCid = cid.mCid; + mPsc = cid.mPsc; + } + + CellIdentityWcdma copy() { + return new CellIdentityWcdma(this); + } + + /** + * @return 3-digit Mobile Country Code, 0..999, Integer.MAX_VALUE if unknown + */ + public int getMcc() { + return mMcc; + } + + /** + * @return 2 or 3-digit Mobile Network Code, 0..999, Integer.MAX_VALUE if unknown + */ + public int getMnc() { + return mMnc; + } + + /** + * @return 16-bit Location Area Code, 0..65535, Integer.MAX_VALUE if unknown + */ + public int getLac() { + return mLac; + } + + /** + * @return CID + * 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, Integer.MAX_VALUE if unknown + */ + public int getCid() { + return mCid; + } + + /** + * @return 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511, Integer.MAX_VALUE + * if unknown + */ + public int getPsc() { + return mPsc; + } + + @Override + public int hashCode() { + int primeNum = 31; + return (mMcc * primeNum) + (mMnc * primeNum) + (mLac * primeNum) + (mCid * primeNum) + + (mPsc * primeNum); + } + + @Override + public boolean equals(Object other) { + if (super.equals(other)) { + try { + CellIdentityWcdma o = (CellIdentityWcdma)other; + return mMcc == o.mMcc && + mMnc == o.mMnc && + mLac == o.mLac && + mCid == o.mCid && + mPsc == o.mPsc; + } catch (ClassCastException e) { + return false; + } + } else { + return false; + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("CellIdentityWcdma:{"); + sb.append(" mMcc=").append(mMcc); + sb.append(" mMnc=").append(mMnc); + sb.append(" mLac=").append(mLac); + sb.append(" mCid=").append(mCid); + sb.append(" mPsc=").append(mPsc); + sb.append("}"); + + return sb.toString(); + } + + /** Implement the Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** Implement the Parcelable interface */ + @Override + public void writeToParcel(Parcel dest, int flags) { + if (DBG) log("writeToParcel(Parcel, int): " + toString()); + dest.writeInt(mMcc); + dest.writeInt(mMnc); + dest.writeInt(mLac); + dest.writeInt(mCid); + dest.writeInt(mPsc); + } + + /** Construct from Parcel, type has already been processed */ + private CellIdentityWcdma(Parcel in) { + mMcc = in.readInt(); + mMnc = in.readInt(); + mLac = in.readInt(); + mCid = in.readInt(); + mPsc = in.readInt(); + if (DBG) log("CellIdentityWcdma(Parcel): " + toString()); + } + + /** Implement the Parcelable interface */ + @SuppressWarnings("hiding") + public static final Creator<CellIdentityWcdma> CREATOR = + new Creator<CellIdentityWcdma>() { + @Override + public CellIdentityWcdma createFromParcel(Parcel in) { + return new CellIdentityWcdma(in); + } + + @Override + public CellIdentityWcdma[] newArray(int size) { + return new CellIdentityWcdma[size]; + } + }; + + /** + * log + */ + private static void log(String s) { + Rlog.w(LOG_TAG, s); + } +} diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java index fe3c68ba7c00..bfa0942f087e 100644 --- a/telephony/java/android/telephony/CellInfo.java +++ b/telephony/java/android/telephony/CellInfo.java @@ -31,6 +31,8 @@ public abstract class CellInfo implements Parcelable { protected static final int TYPE_CDMA = 2; /** @hide */ protected static final int TYPE_LTE = 3; + /** @hide */ + protected static final int TYPE_WCDMA = 4; // Type to distinguish where time stamp gets recorded. @@ -201,6 +203,7 @@ public abstract class CellInfo implements Parcelable { case TYPE_GSM: return CellInfoGsm.createFromParcelBody(in); case TYPE_CDMA: return CellInfoCdma.createFromParcelBody(in); case TYPE_LTE: return CellInfoLte.createFromParcelBody(in); + case TYPE_WCDMA: return CellInfoWcdma.createFromParcelBody(in); default: throw new RuntimeException("Bad CellInfo Parcel"); } } diff --git a/telephony/java/android/telephony/CellInfoWcdma.java b/telephony/java/android/telephony/CellInfoWcdma.java new file mode 100644 index 000000000000..06157022de34 --- /dev/null +++ b/telephony/java/android/telephony/CellInfoWcdma.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +import android.os.Parcel; +import android.os.Parcelable; +import android.telephony.Rlog; + +/** + * Immutable cell information from a point in time. + */ +public final class CellInfoWcdma extends CellInfo implements Parcelable { + + private static final String LOG_TAG = "CellInfoWcdma"; + private static final boolean DBG = false; + + private CellIdentityWcdma mCellIdentityWcdma; + private CellSignalStrengthWcdma mCellSignalStrengthWcdma; + + /** @hide */ + public CellInfoWcdma() { + super(); + mCellIdentityWcdma = new CellIdentityWcdma(); + mCellSignalStrengthWcdma = new CellSignalStrengthWcdma(); + } + + /** @hide */ + public CellInfoWcdma(CellInfoWcdma ci) { + super(ci); + this.mCellIdentityWcdma = ci.mCellIdentityWcdma.copy(); + this.mCellSignalStrengthWcdma = ci.mCellSignalStrengthWcdma.copy(); + } + + public CellIdentityWcdma getCellIdentity() { + return mCellIdentityWcdma; + } + /** @hide */ + public void setCellIdentity(CellIdentityWcdma cid) { + mCellIdentityWcdma = cid; + } + + public CellSignalStrengthWcdma getCellSignalStrength() { + return mCellSignalStrengthWcdma; + } + /** @hide */ + public void setCellSignalStrength(CellSignalStrengthWcdma css) { + mCellSignalStrengthWcdma = css; + } + + /** + * @return hash code + */ + @Override + public int hashCode() { + return super.hashCode() + mCellIdentityWcdma.hashCode() + mCellSignalStrengthWcdma.hashCode(); + } + + @Override + public boolean equals(Object other) { + if (!super.equals(other)) { + return false; + } + try { + CellInfoWcdma o = (CellInfoWcdma) other; + return mCellIdentityWcdma.equals(o.mCellIdentityWcdma) + && mCellSignalStrengthWcdma.equals(o.mCellSignalStrengthWcdma); + } catch (ClassCastException e) { + return false; + } + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + + sb.append("CellInfoWcdma:{"); + sb.append(super.toString()); + sb.append(" ").append(mCellIdentityWcdma); + sb.append(" ").append(mCellSignalStrengthWcdma); + sb.append("}"); + + return sb.toString(); + } + + /** Implement the Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** Implement the Parcelable interface */ + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags, TYPE_WCDMA); + mCellIdentityWcdma.writeToParcel(dest, flags); + mCellSignalStrengthWcdma.writeToParcel(dest, flags); + } + + /** + * Construct a CellInfoWcdma object from the given parcel + * where the token is already been processed. + */ + private CellInfoWcdma(Parcel in) { + super(in); + mCellIdentityWcdma = CellIdentityWcdma.CREATOR.createFromParcel(in); + mCellSignalStrengthWcdma = CellSignalStrengthWcdma.CREATOR.createFromParcel(in); + } + + /** Implement the Parcelable interface */ + public static final Creator<CellInfoWcdma> CREATOR = new Creator<CellInfoWcdma>() { + @Override + public CellInfoWcdma createFromParcel(Parcel in) { + in.readInt(); // Skip past token, we know what it is + return createFromParcelBody(in); + } + + @Override + public CellInfoWcdma[] newArray(int size) { + return new CellInfoWcdma[size]; + } + }; + + /** @hide */ + protected static CellInfoWcdma createFromParcelBody(Parcel in) { + return new CellInfoWcdma(in); + } + + /** + * log + */ + private static void log(String s) { + Rlog.w(LOG_TAG, s); + } +} diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java index 2c36344bb9c8..d27fcec38351 100644 --- a/telephony/java/android/telephony/CellSignalStrengthGsm.java +++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java @@ -21,7 +21,7 @@ import android.os.Parcelable; import android.telephony.Rlog; /** - * LTE signal strength related information. + * GSM signal strength related information. */ public final class CellSignalStrengthGsm extends CellSignalStrength implements Parcelable { @@ -30,7 +30,7 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P private static final int GSM_SIGNAL_STRENGTH_GREAT = 12; private static final int GSM_SIGNAL_STRENGTH_GOOD = 8; - private static final int GSM_SIGNAL_STRENGTH_MODERATE = 8; + private static final int GSM_SIGNAL_STRENGTH_MODERATE = 5; private int mSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5 private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 @@ -67,7 +67,8 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P /** * Initialize all the values * - * @param SignalStrength + * @param ss SignalStrength as ASU value + * @param ber is Bit Error Rate * * @hide */ @@ -139,7 +140,7 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P } /** - * Get the LTE signal level as an asu value between 0..97, 99 is unknown + * Get the signal level as an asu value between 0..31, 99 is unknown * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 */ @Override diff --git a/telephony/java/android/telephony/CellSignalStrengthWcdma.java b/telephony/java/android/telephony/CellSignalStrengthWcdma.java new file mode 100644 index 000000000000..b94b01da87bb --- /dev/null +++ b/telephony/java/android/telephony/CellSignalStrengthWcdma.java @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +import android.os.Parcel; +import android.os.Parcelable; +import android.telephony.Rlog; + +/** + * Wcdma signal strength related information. + */ +public final class CellSignalStrengthWcdma extends CellSignalStrength implements Parcelable { + + private static final String LOG_TAG = "CellSignalStrengthWcdma"; + private static final boolean DBG = false; + + private static final int WCDMA_SIGNAL_STRENGTH_GREAT = 12; + private static final int WCDMA_SIGNAL_STRENGTH_GOOD = 8; + private static final int WCDMA_SIGNAL_STRENGTH_MODERATE = 5; + + private int mSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5 + private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 + + /** + * Empty constructor + * + * @hide + */ + public CellSignalStrengthWcdma() { + setDefaultValues(); + } + + /** + * Constructor + * + * @hide + */ + public CellSignalStrengthWcdma(int ss, int ber) { + initialize(ss, ber); + } + + /** + * Copy constructors + * + * @param s Source SignalStrength + * + * @hide + */ + public CellSignalStrengthWcdma(CellSignalStrengthWcdma s) { + copyFrom(s); + } + + /** + * Initialize all the values + * + * @param ss SignalStrength as ASU value + * @param ber is Bit Error Rate + * + * @hide + */ + public void initialize(int ss, int ber) { + mSignalStrength = ss; + mBitErrorRate = ber; + } + + /** + * @hide + */ + protected void copyFrom(CellSignalStrengthWcdma s) { + mSignalStrength = s.mSignalStrength; + mBitErrorRate = s.mBitErrorRate; + } + + /** + * @hide + */ + @Override + public CellSignalStrengthWcdma copy() { + return new CellSignalStrengthWcdma(this); + } + + /** @hide */ + @Override + public void setDefaultValues() { + mSignalStrength = Integer.MAX_VALUE; + mBitErrorRate = Integer.MAX_VALUE; + } + + /** + * Get signal level as an int from 0..4 + */ + @Override + public int getLevel() { + int level; + + // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 + // asu = 0 (-113dB or less) is very weak + // signal, its better to show 0 bars to the user in such cases. + // asu = 99 is a special case, where the signal strength is unknown. + int asu = mSignalStrength; + if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + else if (asu >= WCDMA_SIGNAL_STRENGTH_GREAT) level = SIGNAL_STRENGTH_GREAT; + else if (asu >= WCDMA_SIGNAL_STRENGTH_GOOD) level = SIGNAL_STRENGTH_GOOD; + else if (asu >= WCDMA_SIGNAL_STRENGTH_MODERATE) level = SIGNAL_STRENGTH_MODERATE; + else level = SIGNAL_STRENGTH_POOR; + if (DBG) log("getLevel=" + level); + return level; + } + + /** + * Get the signal strength as dBm + */ + @Override + public int getDbm() { + int dBm; + + int level = mSignalStrength; + int asu = (level == 99 ? Integer.MAX_VALUE : level); + if (asu != Integer.MAX_VALUE) { + dBm = -113 + (2 * asu); + } else { + dBm = Integer.MAX_VALUE; + } + if (DBG) log("getDbm=" + dBm); + return dBm; + } + + /** + * Get the signal level as an asu value between 0..31, 99 is unknown + * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 + */ + @Override + public int getAsuLevel() { + // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 + // asu = 0 (-113dB or less) is very weak + // signal, its better to show 0 bars to the user in such cases. + // asu = 99 is a special case, where the signal strength is unknown. + int level = mSignalStrength; + if (DBG) log("getAsuLevel=" + level); + return level; + } + + @Override + public int hashCode() { + int primeNum = 31; + return (mSignalStrength * primeNum) + (mBitErrorRate * primeNum); + } + + @Override + public boolean equals (Object o) { + CellSignalStrengthWcdma s; + + try { + s = (CellSignalStrengthWcdma) o; + } catch (ClassCastException ex) { + return false; + } + + if (o == null) { + return false; + } + + return mSignalStrength == s.mSignalStrength && mBitErrorRate == s.mBitErrorRate; + } + + /** + * @return string representation. + */ + @Override + public String toString() { + return "CellSignalStrengthWcdma:" + + " ss=" + mSignalStrength + + " ber=" + mBitErrorRate; + } + + /** Implement the Parcelable interface */ + @Override + public void writeToParcel(Parcel dest, int flags) { + if (DBG) log("writeToParcel(Parcel, int): " + toString()); + dest.writeInt(mSignalStrength); + dest.writeInt(mBitErrorRate); + } + + /** + * Construct a SignalStrength object from the given parcel + * where the token is already been processed. + */ + private CellSignalStrengthWcdma(Parcel in) { + mSignalStrength = in.readInt(); + mBitErrorRate = in.readInt(); + if (DBG) log("CellSignalStrengthWcdma(Parcel): " + toString()); + } + + /** Implement the Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** Implement the Parcelable interface */ + @SuppressWarnings("hiding") + public static final Parcelable.Creator<CellSignalStrengthWcdma> CREATOR = + new Parcelable.Creator<CellSignalStrengthWcdma>() { + @Override + public CellSignalStrengthWcdma createFromParcel(Parcel in) { + return new CellSignalStrengthWcdma(in); + } + + @Override + public CellSignalStrengthWcdma[] newArray(int size) { + return new CellSignalStrengthWcdma[size]; + } + }; + + /** + * log + */ + private static void log(String s) { + Rlog.w(LOG_TAG, s); + } +} |