diff options
526 files changed, 12906 insertions, 2754 deletions
diff --git a/Android.mk b/Android.mk index 933ac6200a3e..55ea69a7b437 100644 --- a/Android.mk +++ b/Android.mk @@ -292,6 +292,7 @@ LOCAL_SRC_FILES += \ core/java/android/service/euicc/IGetEidCallback.aidl \ core/java/android/service/euicc/IGetEuiccInfoCallback.aidl \ core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl \ + core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl \ core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl \ core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl \ core/java/android/service/gatekeeper/IGateKeeperService.aidl \ diff --git a/api/system-current.txt b/api/system-current.txt index 85e917563602..34bba3873f58 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -50268,6 +50268,7 @@ package android.view { } public abstract interface WindowManager implements android.view.ViewManager { + method public abstract android.graphics.Region getCurrentImeTouchRegion(); method public abstract android.view.Display getDefaultDisplay(); method public abstract void removeViewImmediate(android.view.View); } diff --git a/cmds/vr/src/com/android/commands/vr/Vr.java b/cmds/vr/src/com/android/commands/vr/Vr.java index b765866faef9..8fb1b7b80618 100644 --- a/cmds/vr/src/com/android/commands/vr/Vr.java +++ b/cmds/vr/src/com/android/commands/vr/Vr.java @@ -41,6 +41,7 @@ public final class Vr extends BaseCommand { "set-persistent-vr-mode-enabled"; private static final String COMMAND_SET_VR2D_DISPLAY_PROPERTIES = "set-display-props"; + private static final String COMMAND_ENABLE_VD = "enable-virtual-display"; private IVrManager mVrService; @@ -49,7 +50,8 @@ public final class Vr extends BaseCommand { out.println( "usage: vr [subcommand]\n" + "usage: vr set-persistent-vr-mode-enabled [true|false]\n" + - "usage: vr set-display-props [width] [height] [dpi]\n" + "usage: vr set-display-props [width] [height] [dpi]\n" + + "usage: vr enable-virtual-display [true|false]\n" ); } @@ -69,6 +71,9 @@ public final class Vr extends BaseCommand { case COMMAND_SET_PERSISTENT_VR_MODE_ENABLED: runSetPersistentVrModeEnabled(); break; + case COMMAND_ENABLE_VD: + runEnableVd(); + break; default: throw new IllegalArgumentException ("unknown command '" + command + "'"); } @@ -94,6 +99,23 @@ public final class Vr extends BaseCommand { } } + private void runEnableVd() throws RemoteException { + Vr2dDisplayProperties.Builder builder = new Vr2dDisplayProperties.Builder(); + + String value = nextArgRequired(); + if ("true".equals(value)) { + builder.setEnabled(true); + } else if ("false".equals(value)) { + builder.setEnabled(false); + } // Don't do anything if not exactly true/false + + try { + mVrService.setVr2dDisplayProperties(builder.build()); + } catch (RemoteException re) { + System.err.println("Error: Can't enable (" + value +") virtual display" + re); + } + } + private void runSetPersistentVrModeEnabled() throws RemoteException { String enableStr = nextArg(); boolean enabled = Boolean.parseBoolean(enableStr); diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index bc6e9cd0ab7e..0ff3215e1271 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -6416,17 +6416,7 @@ public class Activity extends ContextThemeWrapper */ @Deprecated public boolean requestVisibleBehind(boolean visible) { - if (!mResumed) { - // Do not permit paused or stopped activities to do this. - visible = false; - } - try { - mVisibleBehind = ActivityManager.getService() - .requestVisibleBehind(mToken, visible) && visible; - } catch (RemoteException e) { - mVisibleBehind = false; - } - return mVisibleBehind; + return false; } /** diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 199e856e7a22..06dbe8218450 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -360,6 +360,13 @@ public class ActivityManager { FIRST_START_NON_FATAL_ERROR_CODE + 1; /** + * Result for IActivityManaqer.startActivity: a new activity start was aborted. Never returned + * externally. + * @hide + */ + public static final int START_ABORTED = FIRST_START_NON_FATAL_ERROR_CODE + 2; + + /** * Flag for IActivityManaqer.startActivity: do special start mode where * a new activity is launched only if it is needed. * @hide diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 8a8f8dd681fd..204df63f600d 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2391,13 +2391,13 @@ public final class ActivityThread { memInfo.nativeSwappablePss, memInfo.nativeSharedDirty, memInfo.nativePrivateDirty, memInfo.nativeSharedClean, memInfo.nativePrivateClean, memInfo.hasSwappedOutPss ? - memInfo.nativeSwappedOut : memInfo.nativeSwappedOutPss, + memInfo.nativeSwappedOutPss : memInfo.nativeSwappedOut, nativeMax, nativeAllocated, nativeFree); printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss, memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty, memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean, memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss ? - memInfo.dalvikSwappedOut : memInfo.dalvikSwappedOutPss, + memInfo.dalvikSwappedOutPss : memInfo.dalvikSwappedOut, dalvikMax, dalvikAllocated, dalvikFree); } else { printRow(pw, HEAP_COLUMN, "", "Pss", "Private", diff --git a/core/java/android/app/Vr2dDisplayProperties.java b/core/java/android/app/Vr2dDisplayProperties.java index a608bb08836f..0eb2af361ae9 100644 --- a/core/java/android/app/Vr2dDisplayProperties.java +++ b/core/java/android/app/Vr2dDisplayProperties.java @@ -16,7 +16,6 @@ package android.app; -import android.content.ComponentName; import android.os.Parcel; import android.os.Parcelable; @@ -27,19 +26,31 @@ import java.io.PrintWriter; * * @hide */ -public class Vr2dDisplayProperties implements Parcelable { +public final class Vr2dDisplayProperties implements Parcelable { - /** - * The actual width, height and dpi. - */ + public static final int FLAG_VIRTUAL_DISPLAY_ENABLED = 1; + + /** + * The actual width, height and dpi. + */ private final int mWidth; private final int mHeight; private final int mDpi; + // Flags describing the virtual display behavior. + private final int mAddedFlags; + private final int mRemovedFlags; + public Vr2dDisplayProperties(int width, int height, int dpi) { + this(width, height, dpi, 0, 0); + } + + private Vr2dDisplayProperties(int width, int height, int dpi, int flags, int removedFlags) { mWidth = width; mHeight = height; mDpi = dpi; + mAddedFlags = flags; + mRemovedFlags = removedFlags; } @Override @@ -52,11 +63,13 @@ public class Vr2dDisplayProperties implements Parcelable { @Override public String toString() { - return "Vr2dDisplayProperties{" + - "mWidth=" + mWidth + - ", mHeight=" + mHeight + - ", mDpi=" + mDpi + - "}"; + return "Vr2dDisplayProperties{" + + "mWidth=" + mWidth + + ", mHeight=" + mHeight + + ", mDpi=" + mDpi + + ", flags=" + toReadableFlags(mAddedFlags) + + ", removed_flags=" + toReadableFlags(mRemovedFlags) + + "}"; } @Override @@ -66,6 +79,8 @@ public class Vr2dDisplayProperties implements Parcelable { Vr2dDisplayProperties that = (Vr2dDisplayProperties) o; + if (getFlags() != that.getFlags()) return false; + if (getRemovedFlags() != that.getRemovedFlags()) return false; if (getWidth() != that.getWidth()) return false; if (getHeight() != that.getHeight()) return false; return getDpi() == that.getDpi(); @@ -81,6 +96,8 @@ public class Vr2dDisplayProperties implements Parcelable { dest.writeInt(mWidth); dest.writeInt(mHeight); dest.writeInt(mDpi); + dest.writeInt(mAddedFlags); + dest.writeInt(mRemovedFlags); } public static final Parcelable.Creator<Vr2dDisplayProperties> CREATOR @@ -100,13 +117,12 @@ public class Vr2dDisplayProperties implements Parcelable { mWidth = source.readInt(); mHeight = source.readInt(); mDpi = source.readInt(); + mAddedFlags = source.readInt(); + mRemovedFlags = source.readInt(); } public void dump(PrintWriter pw, String prefix) { - pw.println(prefix + "Vr2dDisplayProperties:"); - pw.println(prefix + " width=" + mWidth); - pw.println(prefix + " height=" + mHeight); - pw.println(prefix + " dpi=" + mDpi); + pw.println(prefix + toString()); } public int getWidth() { @@ -120,4 +136,83 @@ public class Vr2dDisplayProperties implements Parcelable { public int getDpi() { return mDpi; } + + public int getFlags() { + return mAddedFlags; + } + + public int getRemovedFlags() { + return mRemovedFlags; + } + + private static String toReadableFlags(int flags) { + String retval = "{"; + if ((flags & FLAG_VIRTUAL_DISPLAY_ENABLED) == FLAG_VIRTUAL_DISPLAY_ENABLED) { + retval += "enabled"; + } + return retval + "}"; + } + + /** + * Convenience class for creating Vr2dDisplayProperties. + */ + public static class Builder { + private int mAddedFlags = 0; + private int mRemovedFlags = 0; + + // Negative values are translated as an "ignore" to VrManagerService. + private int mWidth = -1; + private int mHeight = -1; + private int mDpi = -1; + + public Builder() { + } + + /** + * Sets the dimensions to use for the virtual display. + */ + public Builder setDimensions(int width, int height, int dpi) { + mWidth = width; + mHeight = height; + mDpi = dpi; + return this; + } + + /** + * Toggles the virtual display functionality for 2D activities in VR. + */ + public Builder setEnabled(boolean enabled) { + if (enabled) { + addFlags(FLAG_VIRTUAL_DISPLAY_ENABLED); + } else { + removeFlags(FLAG_VIRTUAL_DISPLAY_ENABLED); + } + return this; + } + + /** + * Adds property flags. + */ + public Builder addFlags(int flags) { + mAddedFlags |= flags; + mRemovedFlags &= ~flags; + return this; + } + + /** + * Removes property flags. + */ + public Builder removeFlags(int flags) { + mRemovedFlags |= flags; + mAddedFlags &= ~flags; + return this; + } + + /** + * Builds the Vr2dDisplayProperty instance. + */ + public Vr2dDisplayProperties build() { + return new Vr2dDisplayProperties(mWidth, mHeight, mDpi, mAddedFlags, mRemovedFlags); + } + } } diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index dfcbfc4f8e09..0b8b689ce4e6 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -22,9 +22,9 @@ import android.annotation.Nullable; import android.annotation.RawRes; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; +import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.SdkConstant.SdkConstantType; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; @@ -74,7 +74,6 @@ import java.io.InputStream; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -369,18 +368,17 @@ public class WallpaperManager { } WallpaperColors getWallpaperColors(int which) { - synchronized (this) { - if (which != FLAG_LOCK && which != FLAG_SYSTEM) - throw new IllegalArgumentException( - "which should be either FLAG_LOCK or FLAG_SYSTEM"); + if (which != FLAG_LOCK && which != FLAG_SYSTEM) { + throw new IllegalArgumentException( + "Must request colors for exactly one kind of wallpaper"); + } - try { - return mService.getWallpaperColors(which); - } catch (RemoteException e) { - // Can't get colors, connection lost. - } - return null; + try { + return mService.getWallpaperColors(which); + } catch (RemoteException e) { + // Can't get colors, connection lost. } + return null; } public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault, diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 9eacd2166bfd..ea0829f2ef2d 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -55,7 +55,6 @@ import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.provider.ContactsContract.Directory; -import android.provider.Settings; import android.security.Credentials; import android.service.restrictions.RestrictionsReceiver; import android.telephony.TelephonyManager; @@ -3134,6 +3133,14 @@ public class DevicePolicyManager { public static final int WIPE_RESET_PROTECTION_DATA = 0x0002; /** + * Flag for {@link #wipeData(int)}: also erase the device's eUICC data. + * + * TODO(b/35851809): make this public. + * @hide + */ + public static final int WIPE_EUICC = 0x0004; + + /** * Ask that all user data be wiped. If called as a secondary user, the user will be removed and * other users will remain unaffected. Calling from the primary user will cause the device to * reboot, erasing all device data - including all the secondary users and their data - while diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index 7ff37d29323e..27b802e59c58 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -203,6 +203,34 @@ public final class BluetoothDevice implements Parcelable { "android.bluetooth.device.action.BOND_STATE_CHANGED"; /** + * Broadcast Action: Indicates the battery level of a remote device has + * been retrieved for the first time, or changed since the last retrieval + * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link + * #EXTRA_BATTERY_LEVEL}. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_BATTERY_LEVEL_CHANGED = + "android.bluetooth.device.action.BATTERY_LEVEL_CHANGED"; + + /** + * Used as an Integer extra field in {@link #ACTION_BATTERY_LEVEL_CHANGED} + * intent. It contains the most recently retrieved battery level information + * ranging from 0% to 100% for a remote device, {@link #BATTERY_LEVEL_UNKNOWN} + * when the valid is unknown or there is an error + * @hide + */ + public static final String EXTRA_BATTERY_LEVEL = + "android.bluetooth.device.extra.BATTERY_LEVEL"; + + /** + * Used as the unknown value for {@link #EXTRA_BATTERY_LEVEL} and {@link #getBatteryLevel()} + * @hide + */ + public static final int BATTERY_LEVEL_UNKNOWN = -1; + + /** * Used as a Parcelable {@link BluetoothDevice} extra field in every intent * broadcast by this class. It contains the {@link BluetoothDevice} that * the intent applies to. @@ -861,6 +889,27 @@ public final class BluetoothDevice implements Parcelable { } /** + * Get the most recent identified battery level of this Bluetooth device + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} + * + * @return Battery level in percents from 0 to 100, or {@link #BATTERY_LEVEL_UNKNOWN} if + * Bluetooth is disabled, or device is disconnected, or does not have any battery + * reporting service, or return value is invalid + * @hide + */ + @RequiresPermission(Manifest.permission.BLUETOOTH) + public int getBatteryLevel() { + if (sService == null) { + Log.e(TAG, "Bluetooth disabled. Cannot get remote device battery level"); + return BATTERY_LEVEL_UNKNOWN; + } + try { + return sService.getBatteryLevel(this); + } catch (RemoteException e) {Log.e(TAG, "", e);} + return BATTERY_LEVEL_UNKNOWN; + } + + /** * Start the bonding (pairing) process with the remote device. * <p>This is an asynchronous call, it will return immediately. Register * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java index 57b954f40c6b..c84643fc46b3 100644 --- a/core/java/android/bluetooth/BluetoothHeadset.java +++ b/core/java/android/bluetooth/BluetoothHeadset.java @@ -200,6 +200,37 @@ public final class BluetoothHeadset implements BluetoothProfile { public static final String VENDOR_RESULT_CODE_COMMAND_ANDROID = "+ANDROID"; /** + * A vendor-specific AT command + * @hide + */ + public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XAPL = "+XAPL"; + + /** + * A vendor-specific AT command + * @hide + */ + public static final String VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV = "+IPHONEACCEV"; + + /** + * Battery level indicator associated with + * {@link #VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV} + * @hide + */ + public static final int VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL = 1; + + /** + * A vendor-specific AT command + * @hide + */ + public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT = "+XEVENT"; + + /** + * Battery level indicator associated with {@link #VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT} + * @hide + */ + public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT_BATTERY_LEVEL = "BATTERY"; + + /** * Headset state when SCO audio is not connected. * This state can be one of * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of @@ -227,34 +258,33 @@ public final class BluetoothHeadset implements BluetoothProfile { * * <p>This intent will have 3 extras: * <ul> - * <li> {@link #EXTRA_IND_ID} - The Assigned number of headset Indicator which is supported by - the headset ( as indicated by AT+BIND - command in the SLC sequence).or whose value - is changed (indicated by AT+BIEV command)</li> - * <li> {@link #EXTRA_IND_VALUE}- The updated value of headset indicator. </li> - * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> + * <li> {@link #EXTRA_HF_INDICATORS_IND_ID} - The Assigned number of headset Indicator which + * is supported by the headset ( as indicated by AT+BIND command in the SLC + * sequence) or whose value is changed (indicated by AT+BIEV command) </li> + * <li> {@link #EXTRA_HF_INDICATORS_IND_VALUE} - Updated value of headset indicator. </li> + * <li> {@link BluetoothDevice#EXTRA_DEVICE} - Remote device. </li> * </ul> - * <p>{@link #EXTRA_IND_ID} is defined by Bluetooth SIG and each of the indicators are - * given an assigned number. Below shows the assigned number of Indicator added so far - * - Enhanced Safety - 1 - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to - * receive. + * <p>{@link #EXTRA_HF_INDICATORS_IND_ID} is defined by Bluetooth SIG and each of the indicators + * are given an assigned number. Below shows the assigned number of Indicator added so far + * - Enhanced Safety - 1, Valid Values: 0 - Disabled, 1 - Enabled + * - Battery Level - 2, Valid Values: 0~100 - Remaining level of Battery + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to receive. * @hide */ public static final String ACTION_HF_INDICATORS_VALUE_CHANGED = "android.bluetooth.headset.action.HF_INDICATORS_VALUE_CHANGED"; /** - * A String extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED} - * intents that contains the UUID of the headset indicator (as defined by Bluetooth SIG) - * that is being sent. + * A int extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED} + * intents that contains the assigned number of the headset indicator as defined by + * Bluetooth SIG that is being sent. Value range is 0-65535 as defined in HFP 1.7 * @hide */ public static final String EXTRA_HF_INDICATORS_IND_ID = "android.bluetooth.headset.extra.HF_INDICATORS_IND_ID"; /** - * A int extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED} + * A int extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED} * intents that contains the value of the Headset indicator that is being sent. * @hide */ diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl index 43c5ae4407c9..1d7cfc900e4c 100644 --- a/core/java/android/bluetooth/IBluetooth.aidl +++ b/core/java/android/bluetooth/IBluetooth.aidl @@ -75,6 +75,7 @@ interface IBluetooth ParcelUuid[] getRemoteUuids(in BluetoothDevice device); boolean fetchRemoteUuids(in BluetoothDevice device); boolean sdpSearch(in BluetoothDevice device, in ParcelUuid uuid); + int getBatteryLevel(in BluetoothDevice device); boolean setPin(in BluetoothDevice device, boolean accept, int len, in byte[] pinCode); boolean setPasskey(in BluetoothDevice device, boolean accept, int len, in byte[] diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 852e5f708ec3..f70215b46a5e 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -16,6 +16,8 @@ package android.content; +import static android.content.ContentProvider.maybeAddUserId; + import android.annotation.AnyRes; import android.annotation.BroadcastBehavior; import android.annotation.IntDef; @@ -43,7 +45,7 @@ import android.os.ResultReceiver; import android.os.ShellCommand; import android.os.StrictMode; import android.os.UserHandle; -import android.os.storage.StorageManager; +import android.provider.ContactsContract.QuickContact; import android.provider.DocumentsContract; import android.provider.DocumentsProvider; import android.provider.MediaStore; @@ -51,7 +53,9 @@ import android.provider.OpenableColumns; import android.util.ArraySet; import android.util.AttributeSet; import android.util.Log; + import com.android.internal.util.XmlUtils; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; @@ -69,8 +73,6 @@ import java.util.Locale; import java.util.Objects; import java.util.Set; -import static android.content.ContentProvider.maybeAddUserId; - /** * An intent is an abstract description of an operation to be performed. It * can be used with {@link Context#startActivity(Intent) startActivity} to @@ -9782,6 +9784,7 @@ public class Intent implements Parcelable, Cloneable { && leavingPackage) { switch (mAction) { case ACTION_PROVIDER_CHANGED: + case QuickContact.ACTION_QUICK_CONTACT: // Ignore actions that don't need to grant break; default: diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java index 358787e66428..e9c958857d5c 100644 --- a/core/java/android/content/pm/LauncherActivityInfo.java +++ b/core/java/android/content/pm/LauncherActivityInfo.java @@ -20,12 +20,10 @@ import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; -import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.UserHandle; import android.os.UserManager; import android.util.DisplayMetrics; -import android.util.Log; /** * A representation of an activity that can belong to this user or a managed @@ -173,12 +171,6 @@ public class LauncherActivityInfo { public Drawable getBadgedIcon(int density) { Drawable originalIcon = getIcon(density); - if (originalIcon instanceof BitmapDrawable) { - // TODO: Go through LauncherAppsService - return mPm.getUserBadgedIcon(originalIcon, mUser); - } else { - Log.e(TAG, "Unable to create badged icon for " + mActivityInfo); - } - return originalIcon; + return mPm.getUserBadgedIcon(originalIcon, mUser); } } diff --git a/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl b/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl index 3c3b84d7b2a3..9490e276f228 100644 --- a/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl +++ b/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl @@ -25,4 +25,5 @@ import android.os.RemoteCallback; */ oneway interface IRuntimePermissionPresenter { void getAppPermissions(String packageName, in RemoteCallback callback); + void revokeRuntimePermission(String packageName, String permissionName); } diff --git a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java index 6d55d2f7a860..02d0a6d8bd36 100644 --- a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java +++ b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java @@ -22,7 +22,6 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.content.pm.ApplicationInfo; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -31,6 +30,7 @@ import android.os.RemoteCallback; import android.os.RemoteException; import android.permissionpresenterservice.RuntimePermissionPresenterService; import android.util.Log; + import com.android.internal.annotations.GuardedBy; import com.android.internal.os.SomeArgs; @@ -118,6 +118,22 @@ public final class RuntimePermissionPresenter { mRemoteService.processMessage(message); } + /** + * Revoke the permission {@code permissionName} for app {@code packageName} + * + * @param packageName The package for which to revoke + * @param permissionName The permission to revoke + */ + public void revokeRuntimePermission(String packageName, String permissionName) { + SomeArgs args = SomeArgs.obtain(); + args.arg1 = packageName; + args.arg2 = permissionName; + + Message message = mRemoteService.obtainMessage( + RemoteService.MSG_REVOKE_APP_PERMISSIONS, args); + mRemoteService.processMessage(message); + } + private static final class RemoteService extends Handler implements ServiceConnection { private static final long UNBIND_TIMEOUT_MILLIS = 10000; @@ -125,6 +141,7 @@ public final class RuntimePermissionPresenter { public static final int MSG_GET_APP_PERMISSIONS = 1; public static final int MSG_GET_APPS_USING_PERMISSIONS = 2; public static final int MSG_UNBIND = 3; + public static final int MSG_REVOKE_APP_PERMISSIONS = 4; private final Object mLock = new Object(); @@ -231,6 +248,25 @@ public final class RuntimePermissionPresenter { mRemoteInstance = null; } } break; + + case MSG_REVOKE_APP_PERMISSIONS: { + SomeArgs args = (SomeArgs) msg.obj; + final String packageName = (String) args.arg1; + final String permissionName = (String) args.arg2; + args.recycle(); + final IRuntimePermissionPresenter remoteInstance; + synchronized (mLock) { + remoteInstance = mRemoteInstance; + } + if (remoteInstance == null) { + return; + } + try { + remoteInstance.revokeRuntimePermission(packageName, permissionName); + } catch (RemoteException re) { + Log.e(TAG, "Error getting app permissions", re); + } + } break; } synchronized (mLock) { diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index 6834ba816910..be31d1b0b5e5 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -42,6 +42,9 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Locale; +import static android.view.Surface.ROTATION_0; +import static android.view.Surface.ROTATION_UNDEFINED; + /** * This class describes all device configuration information that can * impact the resources the application retrieves. This includes both @@ -597,6 +600,13 @@ public final class Configuration implements Parcelable, Comparable<Configuration */ public int orientation; + /** + * The mRotation used at the time orientation was determined. + * TODO(b/36812336): Move mRotation out of {@link Configuration}. + * {@hide} + */ + private int mRotation; + /** Constant for {@link #uiMode}: bits that encode the mode type. */ public static final int UI_MODE_TYPE_MASK = 0x0f; /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK} @@ -884,6 +894,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration navigation = o.navigation; navigationHidden = o.navigationHidden; orientation = o.orientation; + mRotation = o.mRotation; screenLayout = o.screenLayout; colorMode = o.colorMode; uiMode = o.uiMode; @@ -1074,6 +1085,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration navigation = NAVIGATION_UNDEFINED; navigationHidden = NAVIGATIONHIDDEN_UNDEFINED; orientation = ORIENTATION_UNDEFINED; + mRotation = ROTATION_UNDEFINED; screenLayout = SCREENLAYOUT_UNDEFINED; colorMode = COLOR_MODE_UNDEFINED; uiMode = UI_MODE_TYPE_UNDEFINED; @@ -1182,6 +1194,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration changed |= ActivityInfo.CONFIG_ORIENTATION; orientation = delta.orientation; } + if (delta.mRotation != ROTATION_UNDEFINED + && mRotation != delta.mRotation) { + changed |= ActivityInfo.CONFIG_ORIENTATION; + mRotation = delta.mRotation; + } if (((delta.screenLayout & SCREENLAYOUT_SIZE_MASK) != SCREENLAYOUT_SIZE_UNDEFINED) && (delta.screenLayout & SCREENLAYOUT_SIZE_MASK) @@ -1376,6 +1393,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration && orientation != delta.orientation) { changed |= ActivityInfo.CONFIG_ORIENTATION; } + if ((compareUndefined || delta.mRotation != ROTATION_UNDEFINED) + && mRotation != delta.mRotation) { + changed |= ActivityInfo.CONFIG_ORIENTATION; + } if ((compareUndefined || getScreenLayoutNoDirection(delta.screenLayout) != (SCREENLAYOUT_SIZE_UNDEFINED | SCREENLAYOUT_LONG_UNDEFINED)) && getScreenLayoutNoDirection(screenLayout) != @@ -1512,6 +1533,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration dest.writeInt(navigation); dest.writeInt(navigationHidden); dest.writeInt(orientation); + dest.writeInt(mRotation); dest.writeInt(screenLayout); dest.writeInt(colorMode); dest.writeInt(uiMode); @@ -1548,6 +1570,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration navigation = source.readInt(); navigationHidden = source.readInt(); orientation = source.readInt(); + mRotation = source.readInt(); screenLayout = source.readInt(); colorMode = source.readInt(); uiMode = source.readInt(); @@ -1632,6 +1655,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration if (n != 0) return n; n = this.orientation - that.orientation; if (n != 0) return n; + n = this.mRotation - that.mRotation; + if (n != 0) return n; n = this.colorMode - that.colorMode; if (n != 0) return n; n = this.screenLayout - that.screenLayout; @@ -1763,6 +1788,24 @@ public final class Configuration implements Parcelable, Comparable<Configuration /** * @hide * + * Setter for orientation converts from {@link Surface} values to internal representation. + */ + public void setRotation(int rotation) { + this.mRotation = rotation; + } + + /** + * @hide + * + * Getter for orientation. Converts from internal representation to {@link Surface} values. + */ + public int getRotation() { + return mRotation != ROTATION_UNDEFINED ? mRotation : ROTATION_0; + } + + /** + * @hide + * * Clears the locale without changing layout direction. */ public void clearLocales() { @@ -2193,6 +2236,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration delta.orientation = change.orientation; } + if (base.mRotation != change.mRotation) { + base.mRotation = change.mRotation; + } + if ((base.screenLayout & SCREENLAYOUT_SIZE_MASK) != (change.screenLayout & SCREENLAYOUT_SIZE_MASK)) { delta.screenLayout |= change.screenLayout & SCREENLAYOUT_SIZE_MASK; @@ -2264,6 +2311,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration private static final String XML_ATTR_NAVIGATION = "nav"; private static final String XML_ATTR_NAVIGATION_HIDDEN = "navHid"; private static final String XML_ATTR_ORIENTATION = "ori"; + private static final String XML_ATTR_ROTATION = "rot"; private static final String XML_ATTR_SCREEN_LAYOUT = "scrLay"; private static final String XML_ATTR_COLOR_MODE = "clrMod"; private static final String XML_ATTR_UI_MODE = "ui"; @@ -2323,6 +2371,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration DENSITY_DPI_UNDEFINED); configOut.appBounds = Rect.unflattenFromString(XmlUtils.readStringAttribute(parser, XML_ATTR_APP_BOUNDS)); + configOut.mRotation = XmlUtils.readIntAttribute(parser, XML_ATTR_ROTATION, + ROTATION_UNDEFINED); // For persistence, we don't care about assetsSeq, so do not read it out. } @@ -2399,6 +2449,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration config.appBounds.flattenToString()); } + if (config.mRotation != ROTATION_UNDEFINED) { + XmlUtils.writeIntAttribute(xml, XML_ATTR_ROTATION, config.mRotation); + } + // For persistence, we do not care about assetsSeq, so do not write it out. } } diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 6a02b6b2e6e7..bda80390a614 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -256,6 +256,15 @@ public final class DisplayManager { */ public static final int VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH = 1 << 6; + /** + * Virtual display flag: Indicates that the orientation of this display device is coupled to + * the rotation of its associated logical display. + * + * @see #createVirtualDisplay + * @hide + */ + public static final int VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT = 1 << 7; + /** @hide */ public DisplayManager(Context context) { mContext = context; diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index fa854b078292..f243f377cb56 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -699,6 +699,7 @@ public final class Debug dest.writeInt(dalvikPrivateClean); dest.writeInt(dalvikSharedClean); dest.writeInt(dalvikSwappedOut); + dest.writeInt(dalvikSwappedOutPss); dest.writeInt(nativePss); dest.writeInt(nativeSwappablePss); dest.writeInt(nativePrivateDirty); @@ -706,6 +707,7 @@ public final class Debug dest.writeInt(nativePrivateClean); dest.writeInt(nativeSharedClean); dest.writeInt(nativeSwappedOut); + dest.writeInt(nativeSwappedOutPss); dest.writeInt(otherPss); dest.writeInt(otherSwappablePss); dest.writeInt(otherPrivateDirty); @@ -726,6 +728,7 @@ public final class Debug dalvikPrivateClean = source.readInt(); dalvikSharedClean = source.readInt(); dalvikSwappedOut = source.readInt(); + dalvikSwappedOutPss = source.readInt(); nativePss = source.readInt(); nativeSwappablePss = source.readInt(); nativePrivateDirty = source.readInt(); @@ -733,6 +736,7 @@ public final class Debug nativePrivateClean = source.readInt(); nativeSharedClean = source.readInt(); nativeSwappedOut = source.readInt(); + nativeSwappedOutPss = source.readInt(); otherPss = source.readInt(); otherSwappablePss = source.readInt(); otherPrivateDirty = source.readInt(); diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index 50b4f8c7facf..56d6e0a62f94 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -369,11 +369,11 @@ public class FileUtils { * constraints remain. * * @param minCount Always keep at least this many files. - * @param minAge Always keep files younger than this age. + * @param minAgeMs Always keep files younger than this age, in milliseconds. * @return if any files were deleted. */ - public static boolean deleteOlderFiles(File dir, int minCount, long minAge) { - if (minCount < 0 || minAge < 0) { + public static boolean deleteOlderFiles(File dir, int minCount, long minAgeMs) { + if (minCount < 0 || minAgeMs < 0) { throw new IllegalArgumentException("Constraints must be positive or 0"); } @@ -393,9 +393,9 @@ public class FileUtils { for (int i = minCount; i < files.length; i++) { final File file = files[i]; - // Keep files newer than minAge + // Keep files newer than minAgeMs final long age = System.currentTimeMillis() - file.lastModified(); - if (age > minAge) { + if (age > minAgeMs) { if (file.delete()) { Log.d(TAG, "Deleted old file " + file); deleted = true; diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java index db9f28b77288..6f458e084a42 100644 --- a/core/java/android/os/RecoverySystem.java +++ b/core/java/android/os/RecoverySystem.java @@ -22,20 +22,26 @@ import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; +import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.PackageManager; import android.os.UserManager; +import android.provider.Settings; +import android.telephony.euicc.EuiccManager; import android.text.TextUtils; import android.util.Log; import android.view.Display; import android.view.WindowManager; +import com.android.internal.logging.MetricsLogger; + import libcore.io.Streams; -import java.io.ByteArrayInputStream; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -46,22 +52,19 @@ import java.io.InputStream; import java.io.RandomAccessFile; import java.security.GeneralSecurityException; import java.security.PublicKey; -import java.security.Signature; import java.security.SignatureException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; -import java.util.Iterator; -import java.util.List; import java.util.Locale; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; -import com.android.internal.logging.MetricsLogger; - import sun.security.pkcs.PKCS7; import sun.security.pkcs.SignerInfo; @@ -84,11 +87,19 @@ public class RecoverySystem { /** Send progress to listeners no more often than this (in ms). */ private static final long PUBLISH_PROGRESS_INTERVAL_MS = 500; + private static final long DEFAULT_EUICC_WIPING_TIMEOUT_MILLIS = 30000L; // 30 s + + private static final long MIN_EUICC_WIPING_TIMEOUT_MILLIS = 5000L; // 5 s + + private static final long MAX_EUICC_WIPING_TIMEOUT_MILLIS = 60000L; // 60 s + /** Used to communicate with recovery. See bootable/recovery/recovery.cpp. */ private static final File RECOVERY_DIR = new File("/cache/recovery"); private static final File LOG_FILE = new File(RECOVERY_DIR, "log"); private static final File LAST_INSTALL_FILE = new File(RECOVERY_DIR, "last_install"); private static final String LAST_PREFIX = "last_"; + private static final String ACTION_WIPE_EUICC_DATA = + "com.android.internal.action.WIPE_EUICC_DATA"; /** * The recovery image uses this file to identify the location (i.e. blocks) @@ -673,18 +684,26 @@ public class RecoverySystem { */ public static void rebootWipeUserData(Context context) throws IOException { rebootWipeUserData(context, false /* shutdown */, context.getPackageName(), - false /* force */); + false /* force */, false /* wipeEuicc */); } /** {@hide} */ public static void rebootWipeUserData(Context context, String reason) throws IOException { - rebootWipeUserData(context, false /* shutdown */, reason, false /* force */); + rebootWipeUserData(context, false /* shutdown */, reason, false /* force */, + false /* wipeEuicc */); } /** {@hide} */ public static void rebootWipeUserData(Context context, boolean shutdown) throws IOException { - rebootWipeUserData(context, shutdown, context.getPackageName(), false /* force */); + rebootWipeUserData(context, shutdown, context.getPackageName(), false /* force */, + false /* wipeEuicc */); + } + + /** {@hide} */ + public static void rebootWipeUserData(Context context, boolean shutdown, String reason, + boolean force) throws IOException { + rebootWipeUserData(context, shutdown, reason, force, false /* wipeEuicc */); } /** @@ -701,6 +720,7 @@ public class RecoverySystem { * @param reason the reason for the wipe that is visible in the logs * @param force whether the {@link UserManager.DISALLOW_FACTORY_RESET} user restriction * should be ignored + * @param wipeEuicc whether wipe the euicc data * * @throws IOException if writing the recovery command file * fails, or if the reboot itself fails. @@ -709,7 +729,7 @@ public class RecoverySystem { * @hide */ public static void rebootWipeUserData(Context context, boolean shutdown, String reason, - boolean force) throws IOException { + boolean force, boolean wipeEuicc) throws IOException { UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); if (!force && um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) { throw new SecurityException("Wiping data is not allowed for this user."); @@ -731,6 +751,10 @@ public class RecoverySystem { // Block until the ordered broadcast has completed. condition.block(); + if (wipeEuicc) { + wipeEuiccData(context); + } + String shutdownArg = null; if (shutdown) { shutdownArg = "--shutdown_after"; @@ -745,6 +769,61 @@ public class RecoverySystem { bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg); } + private static void wipeEuiccData(Context context) { + EuiccManager euiccManager = (EuiccManager) context.getSystemService( + Context.EUICC_SERVICE); + if (euiccManager != null && euiccManager.isEnabled()) { + CountDownLatch euiccFactoryResetLatch = new CountDownLatch(1); + + BroadcastReceiver euiccWipeFinishReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (ACTION_WIPE_EUICC_DATA.equals(intent.getAction())) { + if (getResultCode() != EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) { + int detailedCode = intent.getIntExtra( + EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0); + Log.e(TAG, "Error wiping euicc data, Detailed code = " + + detailedCode); + } else { + Log.d(TAG, "Successfully wiped euicc data."); + } + euiccFactoryResetLatch.countDown(); + } + } + }; + + Intent intent = new Intent(ACTION_WIPE_EUICC_DATA); + intent.setPackage("android"); + PendingIntent callbackIntent = PendingIntent.getBroadcastAsUser( + context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT, UserHandle.SYSTEM); + IntentFilter filterConsent = new IntentFilter(); + filterConsent.addAction(ACTION_WIPE_EUICC_DATA); + HandlerThread euiccHandlerThread = new HandlerThread("euiccWipeFinishReceiverThread"); + euiccHandlerThread.start(); + Handler euiccHandler = new Handler(euiccHandlerThread.getLooper()); + context.registerReceiver(euiccWipeFinishReceiver, filterConsent, null, euiccHandler); + euiccManager.eraseSubscriptions(callbackIntent); + try { + long waitingTimeMillis = Settings.Global.getLong( + context.getContentResolver(), + Settings.Global.EUICC_WIPING_TIMEOUT_MILLIS, + DEFAULT_EUICC_WIPING_TIMEOUT_MILLIS); + if (waitingTimeMillis < MIN_EUICC_WIPING_TIMEOUT_MILLIS) { + waitingTimeMillis = MIN_EUICC_WIPING_TIMEOUT_MILLIS; + } else if (waitingTimeMillis > MAX_EUICC_WIPING_TIMEOUT_MILLIS) { + waitingTimeMillis = MAX_EUICC_WIPING_TIMEOUT_MILLIS; + } + if (!euiccFactoryResetLatch.await(waitingTimeMillis, TimeUnit.MILLISECONDS)) { + Log.e(TAG, "Timeout wiping eUICC data."); + } + context.unregisterReceiver(euiccWipeFinishReceiver); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + Log.e(TAG, "Wiping eUICC data interrupted", e); + } + } + } + /** {@hide} */ public static void rebootPromptAndWipeUserData(Context context, String reason) throws IOException { diff --git a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java index 344d947a3ad3..2931627f0ec0 100644 --- a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java +++ b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java @@ -20,7 +20,6 @@ import android.annotation.SystemApi; import android.app.Service; import android.content.Context; import android.content.Intent; -import android.content.pm.ApplicationInfo; import android.content.pm.permission.IRuntimePermissionPresenter; import android.content.pm.permission.RuntimePermissionPresentationInfo; import android.content.pm.permission.RuntimePermissionPresenter; @@ -30,6 +29,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.RemoteCallback; + import com.android.internal.os.SomeArgs; import java.util.List; @@ -72,6 +72,16 @@ public abstract class RuntimePermissionPresenterService extends Service { */ public abstract List<RuntimePermissionPresentationInfo> onGetAppPermissions(String packageName); + /** + * Revoke the permission {@code permissionName} for app {@code packageName} + * + * @param packageName The package for which to revoke + * @param permissionName The permission to revoke + * + * @hide + */ + public abstract void onRevokeRuntimePermission(String packageName, String permissionName); + @Override public final IBinder onBind(Intent intent) { return new IRuntimePermissionPresenter.Stub() { @@ -83,12 +93,22 @@ public abstract class RuntimePermissionPresenterService extends Service { mHandler.obtainMessage(MyHandler.MSG_GET_APP_PERMISSIONS, args).sendToTarget(); } + + @Override + public void revokeRuntimePermission(String packageName, String permissionName) { + SomeArgs args = SomeArgs.obtain(); + args.arg1 = packageName; + args.arg2 = permissionName; + mHandler.obtainMessage(MyHandler.MSG_REVOKE_APP_PERMISSION, + args).sendToTarget(); + } }; } private final class MyHandler extends Handler { public static final int MSG_GET_APP_PERMISSIONS = 1; public static final int MSG_GET_APPS_USING_PERMISSIONS = 2; + public static final int MSG_REVOKE_APP_PERMISSION = 3; public MyHandler(Looper looper) { super(looper, null, false); @@ -113,6 +133,14 @@ public abstract class RuntimePermissionPresenterService extends Service { callback.sendResult(null); } } break; + case MSG_REVOKE_APP_PERMISSION: { + SomeArgs args = (SomeArgs) msg.obj; + String packageName = (String) args.arg1; + String permissionName = (String) args.arg2; + args.recycle(); + + onRevokeRuntimePermission(packageName, permissionName); + } break; } } } diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java index 2179bd45e303..4306bc47f2b5 100644 --- a/core/java/android/preference/Preference.java +++ b/core/java/android/preference/Preference.java @@ -934,6 +934,7 @@ public class Preference implements Comparable<Preference> { * @param singleLineTitle set {@code true} if the title should be constrained to one line */ public void setSingleLineTitle(boolean singleLineTitle) { + mHasSingleLineTitleAttr = true; mSingleLineTitle = singleLineTitle; notifyChanged(); } diff --git a/core/java/android/provider/AlarmClock.java b/core/java/android/provider/AlarmClock.java index d921ed409d6c..f9030124cc63 100644 --- a/core/java/android/provider/AlarmClock.java +++ b/core/java/android/provider/AlarmClock.java @@ -82,7 +82,8 @@ public final class AlarmClock { * If neither of the above are given then: * <ul> * <li>If exactly one active alarm exists, it is dismissed. - * <li>If more than one active alarm exists, the user is prompted to choose the alarm to dismiss. + * <li>If more than one active alarm exists, the user is prompted to choose the alarm to + * dismiss. * </ul> * </p><p> * If the extra {@link #EXTRA_ALARM_SEARCH_MODE} is used, and the search results contain two or @@ -104,8 +105,7 @@ public final class AlarmClock { * @see #EXTRA_ALARM_SEARCH_MODE */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) - public static final String ACTION_DISMISS_ALARM = - "android.intent.action.DISMISS_ALARM"; + public static final String ACTION_DISMISS_ALARM = "android.intent.action.DISMISS_ALARM"; /** * Activity Action: Snooze a currently ringing alarm. @@ -124,8 +124,7 @@ public final class AlarmClock { * @see #EXTRA_ALARM_SNOOZE_DURATION */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) - public static final String ACTION_SNOOZE_ALARM = - "android.intent.action.SNOOZE_ALARM"; + public static final String ACTION_SNOOZE_ALARM = "android.intent.action.SNOOZE_ALARM"; /** * Activity Action: Set a timer. @@ -155,6 +154,16 @@ public final class AlarmClock { public static final String ACTION_SET_TIMER = "android.intent.action.SET_TIMER"; /** + * Activity Action: Dismiss timers. + * <p> + * Dismiss all currently expired timers. If there are no expired timers, then this is a no-op. + * </p> + * @hide + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_DISMISS_TIMER = "android.intent.action.DISMISS_TIMER"; + + /** * Activity Action: Show the timers. * <p> * This action opens the timers page. @@ -200,8 +209,7 @@ public final class AlarmClock { * @see #ALARM_SEARCH_MODE_LABEL * @see #ACTION_DISMISS_ALARM */ - public static final String EXTRA_ALARM_SEARCH_MODE = - "android.intent.extra.alarm.SEARCH_MODE"; + public static final String EXTRA_ALARM_SEARCH_MODE = "android.intent.extra.alarm.SEARCH_MODE"; /** * Search for the alarm that is most closely matched by the search parameters diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java index 875f286e1a6b..0c2e4b7ada26 100644 --- a/core/java/android/service/euicc/EuiccService.java +++ b/core/java/android/service/euicc/EuiccService.java @@ -97,6 +97,10 @@ public abstract class EuiccService extends Service { public static final String ACTION_RESOLVE_NO_PRIVILEGES = "android.service.euicc.action.RESOLVE_NO_PRIVILEGES"; + /** Intent extra set for resolution requests containing the package name of the calling app. */ + public static final String EXTRA_RESOLUTION_CALLING_PACKAGE = + "android.service.euicc.extra.RESOLUTION_CALLING_PACKAGE"; + /** Result code for a successful operation. */ public static final int RESULT_OK = 0; /** Result code indicating that an active SIM must be deactivated to perform the operation. */ @@ -313,6 +317,21 @@ public abstract class EuiccService extends Service { public abstract int onEraseSubscriptions(int slotId); /** + * Ensure that subscriptions will be retained on the next factory reset. + * + * <p>Called directly before a factory reset. Assumes that a normal factory reset will lead to + * profiles being erased on first boot (to cover fastboot/recovery wipes), so the implementation + * should persist some bit that will remain accessible after the factory reset to bypass this + * flow when this method is called. + * + * @param slotId ID of the SIM slot to use for the operation. This is currently not populated + * but is here to future-proof the APIs. + * @return the result of the operation. May be one of the predefined {@code RESULT_} constants + * or any implementation-specific code starting with {@link #RESULT_FIRST_USER}. + */ + public abstract int onRetainSubscriptionsForFactoryReset(int slotId); + + /** * Wrapper around IEuiccService that forwards calls to implementations of {@link EuiccService}. */ private class IEuiccServiceWrapper extends IEuiccService.Stub { @@ -484,5 +503,21 @@ public abstract class EuiccService extends Service { } }); } + + @Override + public void retainSubscriptionsForFactoryReset(int slotId, + IRetainSubscriptionsForFactoryResetCallback callback) { + mExecutor.execute(new Runnable() { + @Override + public void run() { + int result = EuiccService.this.onRetainSubscriptionsForFactoryReset(slotId); + try { + callback.onComplete(result); + } catch (RemoteException e) { + // Can't communicate with the phone process; ignore. + } + } + }); + } } } diff --git a/core/java/android/service/euicc/IEuiccService.aidl b/core/java/android/service/euicc/IEuiccService.aidl index 18ea915d5dc7..e10dd8cdf616 100644 --- a/core/java/android/service/euicc/IEuiccService.aidl +++ b/core/java/android/service/euicc/IEuiccService.aidl @@ -24,6 +24,7 @@ import android.service.euicc.IGetDownloadableSubscriptionMetadataCallback; import android.service.euicc.IGetEidCallback; import android.service.euicc.IGetEuiccInfoCallback; import android.service.euicc.IGetEuiccProfileInfoListCallback; +import android.service.euicc.IRetainSubscriptionsForFactoryResetCallback; import android.service.euicc.ISwitchToSubscriptionCallback; import android.service.euicc.IUpdateSubscriptionNicknameCallback; import android.telephony.euicc.DownloadableSubscription; @@ -46,4 +47,6 @@ oneway interface IEuiccService { void updateSubscriptionNickname(int slotId, String iccid, String nickname, in IUpdateSubscriptionNicknameCallback callback); void eraseSubscriptions(int slotId, in IEraseSubscriptionsCallback callback); + void retainSubscriptionsForFactoryReset( + int slotId, in IRetainSubscriptionsForFactoryResetCallback callback); }
\ No newline at end of file diff --git a/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl b/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl new file mode 100644 index 000000000000..127683059c02 --- /dev/null +++ b/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.euicc; + +/** @hide */ +oneway interface IRetainSubscriptionsForFactoryResetCallback { + void onComplete(int result); +}
\ No newline at end of file diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java index 951aa8df9ea3..8691136dfedc 100644 --- a/core/java/android/util/Log.java +++ b/core/java/android/util/Log.java @@ -30,8 +30,9 @@ import java.net.UnknownHostException; /** * API for sending log output. * - * <p>Generally, use the Log.v() Log.d() Log.i() Log.w() and Log.e() - * methods. + * <p>Generally, you should use the {@link #v Log.v()}, {@link #d Log.d()}, + * {@link #i Log.i()}, {@link #w Log.w()}, and {@link #e Log.e()} methods to write logs. + * You can then <a href="{@docRoot}studio/debug/am-logcat.html">view the logs in logcat</a>. * * <p>The order in terms of verbosity, from least to most is * ERROR, WARN, INFO, DEBUG, VERBOSE. Verbose should never be compiled diff --git a/core/java/android/util/MergedConfiguration.java b/core/java/android/util/MergedConfiguration.java index 68d0309cfc9e..ae6605043b2e 100644 --- a/core/java/android/util/MergedConfiguration.java +++ b/core/java/android/util/MergedConfiguration.java @@ -161,6 +161,21 @@ public class MergedConfiguration implements Parcelable { return "{mGlobalConfig=" + mGlobalConfig + " mOverrideConfig=" + mOverrideConfig + "}"; } + @Override + public int hashCode() { + return mMergedConfig.hashCode(); + } + + @Override + public boolean equals(Object that) { + if (!(that instanceof MergedConfiguration)) { + return false; + } + + if (that == this) return true; + return mMergedConfig.equals(((MergedConfiguration) that).mMergedConfig); + } + public void dump(PrintWriter pw, String prefix) { pw.println(prefix + "mGlobalConfig=" + mGlobalConfig); pw.println(prefix + "mOverrideConfig=" + mOverrideConfig); diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index cdb9b8229314..7346a215ed8e 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -726,6 +726,17 @@ public final class Display { } /** + * Returns the rotation associated with this display as used during layout. This is currently + * derived from the {@link Configuration}. + * + * @hide + */ + @Surface.Rotation + public int getLayoutRotation() { + return mResources.getConfiguration().getRotation(); + } + + /** * @deprecated use {@link #getRotation} * @return orientation of this display. */ diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 4f9dbd5ad7a0..1b702326cc28 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -131,11 +131,17 @@ public class Surface implements Parcelable { public static final int SCALING_MODE_NO_SCALE_CROP = 3; /** @hide */ - @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270}) + @IntDef({ROTATION_UNDEFINED, ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270}) @Retention(RetentionPolicy.SOURCE) public @interface Rotation {} /** + * Rotation constant: undefined + * @hide + */ + public static final int ROTATION_UNDEFINED = -1; + + /** * Rotation constant: 0 degree rotation (natural orientation) */ public static final int ROTATION_0 = 0; diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index c329db4ff3e1..2646d1c4f528 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -724,6 +724,8 @@ import java.util.function.Predicate; * @attr ref android.R.styleable#View_nextFocusUp * @attr ref android.R.styleable#View_onClick * @attr ref android.R.styleable#View_padding + * @attr ref android.R.styleable#View_paddingHorizontal + * @attr ref android.R.styleable#View_paddingVertical * @attr ref android.R.styleable#View_paddingBottom * @attr ref android.R.styleable#View_paddingLeft * @attr ref android.R.styleable#View_paddingRight diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index cb92a4ca3ad4..ecdfa3fc3336 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -7609,6 +7609,16 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * See * {@link android.R.styleable#ViewGroup_MarginLayout ViewGroup Margin Layout Attributes} * for a list of all child view attributes that this class supports. + * + * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_margin + * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginHorizontal + * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginVertical + * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginLeft + * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginTop + * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginRight + * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginBottom + * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart + * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd */ public static class MarginLayoutParams extends ViewGroup.LayoutParams { /** diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 86b19f4a0929..e38a55f76b7d 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1904,14 +1904,16 @@ public final class ViewRootImpl implements ViewParent, + " outsets=" + mPendingOutsets.toShortString() + " surface=" + mSurface); - final Configuration pendingMergedConfig = - mPendingMergedConfiguration.getMergedConfiguration(); - if (pendingMergedConfig.seq != 0) { + // If the pending {@link MergedConfiguration} handed back from + // {@link #relayoutWindow} does not match the one last reported, + // WindowManagerService has reported back a frame from a configuration not yet + // handled by the client. In this case, we need to accept the configuration so we + // do not lay out and draw with the wrong configuration. + if (!mPendingMergedConfiguration.equals(mLastReportedMergedConfiguration)) { if (DEBUG_CONFIGURATION) Log.v(mTag, "Visible with new config: " - + pendingMergedConfig); + + mPendingMergedConfiguration.getMergedConfiguration()); performConfigurationChange(mPendingMergedConfiguration, !mFirst, INVALID_DISPLAY /* same display */); - pendingMergedConfig.seq = 0; updatedConfiguration = true; } @@ -3596,6 +3598,13 @@ public final class ViewRootImpl implements ViewParent, mView.setLayoutDirection(currentLayoutDirection); } mView.dispatchConfigurationChanged(config); + + // We could have gotten this {@link Configuration} update after we called + // {@link #performTraversals} with an older {@link Configuration}. As a result, our + // window frame may be stale. We must ensure the next pass of {@link #performTraversals} + // catches this. + mForceNextWindowRelayout = true; + requestLayout(); } } @@ -3757,10 +3766,10 @@ public final class ViewRootImpl implements ViewParent, SomeArgs args = (SomeArgs) msg.obj; final int displayId = args.argi3; - final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4; + MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4; final boolean displayChanged = mDisplay.getDisplayId() != displayId; - if (mergedConfiguration != null) { + if (!mLastReportedMergedConfiguration.equals(mergedConfiguration)) { // If configuration changed - notify about that and, maybe, about move to // display. performConfigurationChange(mergedConfiguration, false /* force */, @@ -6094,7 +6103,7 @@ public final class ViewRootImpl implements ViewParent, if (params != null) { if (DBG) Log.d(mTag, "WindowLayout in layoutWindow:" + params); } - mPendingMergedConfiguration.getMergedConfiguration().seq = 0; + //Log.d(mTag, ">>>>>> CALLING relayout"); if (params != null && mOrigWindowType != params.type) { // For compatibility with old apps, don't crash here. @@ -7895,9 +7904,14 @@ public final class ViewRootImpl implements ViewParent, @Override public void run() { - // mSource may be changed in calls below. + // Protect against re-entrant code and attempt to do the right thing in the case that + // we're multithreaded. View source = mSource; mSource = null; + if (source == null) { + Log.e(TAG, "Accessibility content change has no source"); + return; + } // The accessibility may be turned off while we were waiting so check again. if (AccessibilityManager.getInstance(mContext).isEnabled()) { mLastEventTimeMillis = SystemClock.uptimeMillis(); @@ -7914,6 +7928,22 @@ public final class ViewRootImpl implements ViewParent, } public void runOrPost(View source, int changeType) { + if (mHandler.getLooper() != Looper.myLooper()) { + CalledFromWrongThreadException e = new CalledFromWrongThreadException("Only the " + + "original thread that created a view hierarchy can touch its views."); + // TODO: Throw the exception + Log.e(TAG, "Accessibility content change on non-UI thread. Future Android " + + "versions will throw an exception.", e); + // Attempt to recover. This code does not eliminate the thread safety issue, but + // it should force any issues to happen near the above log. + mHandler.removeCallbacks(this); + if (mSource != null) { + // Dispatch whatever was pending. It's still possible that the runnable started + // just before we removed the callbacks, and bad things will happen, but at + // least they should happen very close to the logged error. + run(); + } + } if (mSource != null) { // If there is no common predecessor, then mSource points to // a removed view, hence in this case always prefer the source. @@ -7930,12 +7960,12 @@ public final class ViewRootImpl implements ViewParent, if (timeSinceLastMillis >= minEventIntevalMillis) { removeCallbacksAndRun(); } else { - mSource.postDelayed(this, minEventIntevalMillis - timeSinceLastMillis); + mHandler.postDelayed(this, minEventIntevalMillis - timeSinceLastMillis); } } public void removeCallbacksAndRun() { - mSource.removeCallbacks(this); + mHandler.removeCallbacks(this); run(); } } diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 4c0a1902d6a4..48f3973e87fe 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -18,6 +18,7 @@ package android.view; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; @@ -27,6 +28,7 @@ import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.PixelFormat; import android.graphics.Rect; +import android.graphics.Region; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; @@ -169,6 +171,18 @@ public interface WindowManager extends ViewManager { */ public void requestAppKeyboardShortcuts(final KeyboardShortcutsReceiver receiver, int deviceId); + /** + * Return the touch region for the current IME window, or an empty region if there is none. + * + * @return The region of the IME that is accepting touch inputs, or null if there is no IME, no + * region or there was an error. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) + public Region getCurrentImeTouchRegion(); + public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable { /** * X position for this window. With the default gravity it is ignored. diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index c1b8f04a6865..a8722f101ef4 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -18,6 +18,7 @@ package android.view; import android.annotation.NonNull; import android.content.Context; +import android.graphics.Region; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; @@ -145,4 +146,13 @@ public final class WindowManagerImpl implements WindowManager { public Display getDefaultDisplay() { return mContext.getDisplay(); } + + @Override + public Region getCurrentImeTouchRegion() { + try { + return WindowManagerGlobal.getWindowManagerService().getCurrentImeTouchRegion(); + } catch (RemoteException e) { + } + return null; + } } diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 5b04f41c7ee2..e1e8317d8ccb 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -741,7 +741,8 @@ public final class AutofillManager { } /** - * Returns {@code true} if Autofill is supported for this user. + * Returns {@code true} if autofill is supported by the current device and + * is supported for this user. * * <p>Autofill is typically supported, but it could be unsupported in cases like: * <ol> diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 8fe9100d2011..544afd993b37 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -3103,12 +3103,29 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } /** + * Check if Setup or Post-Setup update is completed on TV + * @return true if completed + */ + private boolean isTvUserSetupComplete() { + boolean isTvSetupComplete = Settings.Secure.getInt(getContext().getContentResolver(), + Settings.Secure.USER_SETUP_COMPLETE, 0) != 0; + isTvSetupComplete &= Settings.Secure.getInt(getContext().getContentResolver(), + Settings.Secure.TV_USER_SETUP_COMPLETE, 0) != 0; + return isTvSetupComplete; + } + + /** * Helper method for adding launch-search to most applications. Opens the * search window using default settings. * * @return true if search window opened */ private boolean launchDefaultSearch(KeyEvent event) { + if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK) + && !isTvUserSetupComplete()) { + // If we are in Setup or Post-Setup update mode on TV, consume the search key + return false; + } boolean result; final Callback cb = getCallback(); if (cb == null || isDestroyed()) { diff --git a/core/java/com/android/internal/policy/PipSnapAlgorithm.java b/core/java/com/android/internal/policy/PipSnapAlgorithm.java index 95d714f1c3c7..749d00c136ec 100644 --- a/core/java/com/android/internal/policy/PipSnapAlgorithm.java +++ b/core/java/com/android/internal/policy/PipSnapAlgorithm.java @@ -49,9 +49,6 @@ public class PipSnapAlgorithm { // Allows snapping on the long edge in each orientation and magnets towards corners private static final int SNAP_MODE_LONG_EDGE_MAGNET_CORNERS = 4; - // The friction multiplier to control how slippery the PIP is when flung - private static final float SCROLL_FRICTION_MULTIPLIER = 8f; - // Threshold to magnet to a corner private static final float CORNER_MAGNET_THRESHOLD = 0.3f; @@ -64,8 +61,8 @@ public class PipSnapAlgorithm { private final float mDefaultSizePercent; private final float mMinAspectRatioForMinSize; private final float mMaxAspectRatioForMinSize; + private final int mFlingDeceleration; - private Scroller mScroller; private int mOrientation = Configuration.ORIENTATION_UNDEFINED; private final int mMinimizedVisibleSize; @@ -81,6 +78,8 @@ public class PipSnapAlgorithm { mMaxAspectRatioForMinSize = res.getFloat( com.android.internal.R.dimen.config_pictureInPictureAspectRatioLimitForMinSize); mMinAspectRatioForMinSize = 1f / mMaxAspectRatioForMinSize; + mFlingDeceleration = mContext.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.pip_fling_deceleration); onConfigurationChanged(); } @@ -107,20 +106,97 @@ public class PipSnapAlgorithm { * those for the given {@param stackBounds}. */ public Rect findClosestSnapBounds(Rect movementBounds, Rect stackBounds, float velocityX, - float velocityY) { - final Rect finalStackBounds = new Rect(stackBounds); - if (mScroller == null) { - final ViewConfiguration viewConfig = ViewConfiguration.get(mContext); - mScroller = new Scroller(mContext); - mScroller.setFriction(viewConfig.getScrollFriction() * SCROLL_FRICTION_MULTIPLIER); + float velocityY, Point dragStartPosition) { + final Rect intersectStackBounds = new Rect(stackBounds); + final Point intersect = getEdgeIntersect(stackBounds, movementBounds, velocityX, velocityY, + dragStartPosition); + intersectStackBounds.offsetTo(intersect.x, intersect.y); + return findClosestSnapBounds(movementBounds, intersectStackBounds); + } + + /** + * @return The point along the {@param movementBounds} that the PIP would intersect with based + * on the provided {@param velX}, {@param velY} along with the position of the PIP when + * the gesture started, {@param dragStartPosition}. + */ + public Point getEdgeIntersect(Rect stackBounds, Rect movementBounds, float velX, float velY, + Point dragStartPosition) { + final boolean isLandscape = mOrientation == Configuration.ORIENTATION_LANDSCAPE; + final int x = stackBounds.left; + final int y = stackBounds.top; + + // Find the line of movement the PIP is on. Line defined by: y = slope * x + yIntercept + final float slope = velY / velX; // slope = rise / run + final float yIntercept = y - slope * x; // rearrange line equation for yIntercept + // The PIP can have two intercept points: + // 1) Where the line intersects with one of the edges of the screen (vertical line) + Point vertPoint = new Point(); + // 2) Where the line intersects with the top or bottom of the screen (horizontal line) + Point horizPoint = new Point(); + + // Find the vertical line intersection, x will be one of the edges + vertPoint.x = velX > 0 ? movementBounds.right : movementBounds.left; + // Sub in x in our line equation to determine y position + vertPoint.y = findY(slope, yIntercept, vertPoint.x); + + // Find the horizontal line intersection, y will be the top or bottom of the screen + horizPoint.y = velY > 0 ? movementBounds.bottom : movementBounds.top; + // Sub in y in our line equation to determine x position + horizPoint.x = findX(slope, yIntercept, horizPoint.y); + + // Now pick one of these points -- first determine if we're flinging along the current edge. + // Only fling along current edge if it's a direction with space for the PIP to move to + int maxDistance; + if (isLandscape) { + maxDistance = velX > 0 + ? movementBounds.right - stackBounds.left + : stackBounds.left - movementBounds.left; + } else { + maxDistance = velY > 0 + ? movementBounds.bottom - stackBounds.top + : stackBounds.top - movementBounds.top; } - mScroller.fling(stackBounds.left, stackBounds.top, - (int) velocityX, (int) velocityY, - movementBounds.left, movementBounds.right, - movementBounds.top, movementBounds.bottom); - finalStackBounds.offsetTo(mScroller.getFinalX(), mScroller.getFinalY()); - mScroller.abortAnimation(); - return findClosestSnapBounds(movementBounds, finalStackBounds); + if (maxDistance > 0) { + // Only fling along the current edge if the start and end point are on the same side + final int startPoint = isLandscape ? dragStartPosition.y : dragStartPosition.x; + final int endPoint = isLandscape ? horizPoint.y : horizPoint.x; + final int center = movementBounds.centerX(); + if ((startPoint < center && endPoint < center) + || (startPoint > center && endPoint > center)) { + // We are flinging along the current edge, figure out how far it should travel + // based on velocity and assumed deceleration. + int distance = (int) (0 - Math.pow(isLandscape ? velX : velY, 2)) + / (2 * mFlingDeceleration); + distance = Math.min(distance, maxDistance); + // Adjust the point for the distance + if (isLandscape) { + horizPoint.x = stackBounds.left + (velX > 0 ? distance : -distance); + } else { + horizPoint.y = stackBounds.top + (velY > 0 ? distance : -distance); + } + return horizPoint; + } + } + // If we're not flinging along the current edge, find the closest point instead. + final double distanceVert = Math.hypot(vertPoint.x - x, vertPoint.y - y); + final double distanceHoriz = Math.hypot(horizPoint.x - x, horizPoint.y - y); + // Ensure that we're actually going somewhere + if (distanceVert == 0) { + return horizPoint; + } + if (distanceHoriz == 0) { + return vertPoint; + } + // Otherwise use the closest point + return Math.abs(distanceVert) > Math.abs(distanceHoriz) ? horizPoint : vertPoint; + } + + private int findY(float slope, float yIntercept, float x) { + return (int) ((slope * x) + yIntercept); + } + + private int findX(float slope, float yIntercept, float y) { + return (int) ((y - yIntercept) / slope); } /** diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java index 1ba92bfb6a77..0c046a92020b 100644 --- a/core/java/com/android/internal/util/NotificationColorUtil.java +++ b/core/java/com/android/internal/util/NotificationColorUtil.java @@ -534,7 +534,7 @@ public class NotificationColorUtil { } public static boolean satisfiesTextContrast(int backgroundColor, int foregroundColor) { - return NotificationColorUtil.calculateContrast(backgroundColor, foregroundColor) >= 4.5; + return NotificationColorUtil.calculateContrast(foregroundColor, backgroundColor) >= 4.5; } /** @@ -613,7 +613,7 @@ public class NotificationColorUtil { */ public static double calculateContrast(@ColorInt int foreground, @ColorInt int background) { if (Color.alpha(background) != 255) { - throw new IllegalArgumentException("background can not be translucent: #" + Log.wtf(TAG, "background can not be translucent: #" + Integer.toHexString(background)); } if (Color.alpha(foreground) < 255) { diff --git a/core/jni/android/graphics/ColorFilter.cpp b/core/jni/android/graphics/ColorFilter.cpp index 5553a3ed22c5..4b6578bdff7f 100644 --- a/core/jni/android/graphics/ColorFilter.cpp +++ b/core/jni/android/graphics/ColorFilter.cpp @@ -30,9 +30,12 @@ using namespace uirenderer; class SkColorFilterGlue { public: - static void SafeUnref(JNIEnv* env, jobject clazz, jlong skFilterHandle) { - SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(skFilterHandle); - SkSafeUnref(filter); + static void SafeUnref(SkShader* shader) { + SkSafeUnref(shader); + } + + static jlong GetNativeFinalizer(JNIEnv*, jobject) { + return static_cast<jlong>(reinterpret_cast<uintptr_t>(&SafeUnref)); } static jlong CreatePorterDuffFilter(JNIEnv* env, jobject, jint srcColor, jint modeHandle) { @@ -57,7 +60,7 @@ public: }; static const JNINativeMethod colorfilter_methods[] = { - {"nSafeUnref", "(J)V", (void*) SkColorFilterGlue::SafeUnref} + {"nativeGetFinalizer", "()J", (void*) SkColorFilterGlue::GetNativeFinalizer } }; static const JNINativeMethod porterduff_methods[] = { diff --git a/core/jni/android_os_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp index cdd3c094e009..6c6fa66c422e 100644 --- a/core/jni/android_os_HwBinder.cpp +++ b/core/jni/android_os_HwBinder.cpp @@ -370,7 +370,7 @@ static jobject JHwBinder_native_getService( if (transport != IServiceManager::Transport::HWBINDER && !vintfLegacy) { LOG(ERROR) << "service " << ifaceName << " declares transport method " << toString(transport) << " but framework expects hwbinder."; - signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */); + signalExceptionForError(env, NAME_NOT_FOUND, true /* canThrowRemoteException */); return NULL; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index b4c5025e2f64..be27048c1232 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -146,6 +146,7 @@ <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL" /> <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST" /> <protected-broadcast android:name="android.bluetooth.device.action.SDP_RECORD" /> + <protected-broadcast android:name="android.bluetooth.device.action.BATTERY_LEVEL_CHANGED" /> <protected-broadcast android:name="android.bluetooth.devicepicker.action.LAUNCH" /> <protected-broadcast android:name="android.bluetooth.devicepicker.action.DEVICE_SELECTED" /> <protected-broadcast @@ -302,6 +303,7 @@ <protected-broadcast android:name="com.android.server.WifiManager.action.DEVICE_IDLE" /> <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED" /> <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED" /> + <protected-broadcast android:name="com.android.server.action.WIPE_EUICC_DATA" /> <protected-broadcast android:name="com.android.server.usb.ACTION_OPEN_IN_APPS" /> <protected-broadcast android:name="com.android.server.am.DELETE_DUMPHEAP" /> <protected-broadcast android:name="com.android.server.net.action.SNOOZE_WARNING" /> diff --git a/core/res/res/anim/task_close_enter.xml b/core/res/res/anim/task_close_enter.xml index b07f470dd5f5..bea0ee51d593 100644 --- a/core/res/res/anim/task_close_enter.xml +++ b/core/res/res/anim/task_close_enter.xml @@ -18,7 +18,7 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal"> + android:shareInterpolator="false" android:zAdjustment="normal"> <alpha android:fromAlpha="0.6" android:toAlpha="1.0" android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" diff --git a/core/res/res/anim/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml index d23c74ffc160..b6a08070c3ce 100644 --- a/core/res/res/anim/task_close_exit.xml +++ b/core/res/res/anim/task_close_exit.xml @@ -18,7 +18,7 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top"> + android:shareInterpolator="false" android:zAdjustment="top"> <alpha android:fromAlpha="1.0" android:toAlpha="0" android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" diff --git a/core/res/res/layout-land/time_picker_material.xml b/core/res/res/layout-land/time_picker_material.xml index 863efef5c661..d83ccb23f64f 100644 --- a/core/res/res/layout-land/time_picker_material.xml +++ b/core/res/res/layout-land/time_picker_material.xml @@ -17,6 +17,7 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layoutDirection="ltr" android:layout_width="match_parent" android:layout_height="wrap_content"> @@ -30,6 +31,7 @@ <LinearLayout android:id="@+id/time_layout" + android:layoutDirection="ltr" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingTop="@dimen/timepicker_radial_picker_top_margin" diff --git a/core/res/res/layout/notification_template_right_icon.xml b/core/res/res/layout/notification_template_right_icon.xml index aa4e05b15d19..fbf75387b786 100644 --- a/core/res/res/layout/notification_template_right_icon.xml +++ b/core/res/res/layout/notification_template_right_icon.xml @@ -26,8 +26,9 @@ android:layout_gravity="top|end" android:layout_marginTop="36dp" android:layout_marginEnd="@dimen/notification_content_margin_end" - android:scaleType="centerCrop"/> - <ImageView android:id="@+id/reply_icon_action" + android:scaleType="centerCrop" + android:importantForAccessibility="no" /> + <ImageButton android:id="@+id/reply_icon_action" android:layout_width="16dp" android:layout_height="16dp" android:layout_gravity="top|end" @@ -36,6 +37,7 @@ android:background="@drawable/notification_reply_background" android:src="@drawable/ic_reply_notification" android:scaleType="center" + android:contentDescription="@string/notification_reply_button_accessibility" visiblity="gone"/> </FrameLayout> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 3c74328ddb6d..b0b6404f1382 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Soek vir diens"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-oproepe"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra jou diensverskaffer eers om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan."</item> + <item msgid="3910386316304772394">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra eers jou diensverskaffer om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan. (Foutkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registreer by jou diensverskaffer"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Oop Wi-Fi-netwerke beskikbaar</item> <item quantity="one">Oop Wi-Fi-netwerk beskikbaar</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Koppel aan oop Wi-Fi-netwerk"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Koppel tans aan oop Wi‑Fi-netwerk"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Aan Wi-Fi-netwerk gekoppel"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kon nie aan Wi-Fi-netwerk koppel nie"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerke te sien"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koppel"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle netwerke"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Meld aan by Wi-Fi-netwerk"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Meld by netwerk aan"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index d1611d7c4631..28889fecc7e0 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"አገልግሎት ፍለጋ"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"የWi-Fi ጥሪ ማድረጊያ"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ መጠየቅ አለብዎት። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ።"</item> + <item msgid="3910386316304772394">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ መጠየቅ አለብዎት። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ። (የስህተት ኮድ፦ <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"የአገልግሎት አቅራቢዎ ጋር ይመዝገቡ"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">የሚገኙ የWi-Fi አውታረ መረቦችን ክፈት</item> <item quantity="other">የሚገኙ የWi-Fi አውታረ መረቦችን ክፈት</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"ከክፍት የWi‑Fi አውታረ መረብ ጋር ያገናኙ"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ከክፍት የWi‑Fi አውታረ መረብ ጋር በመገናኘት ላይ"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"ከWi‑Fi አውታረ መረብ ጋር ተገናኝቷል"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ከWi‑Fi አውታረ መረብ ጋር መገናኘት አልተቻለም"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ሁሉንም አውታረ መረቦችን ለማየት መታ ያድርጉ"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"አገናኝ"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ሁሉም አውታረ መረቦች"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"ወደ Wi-Fi አውታረ መረብ በመለያ ግባ"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"ወደ አውታረ መረብ በመለያ ይግቡ"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index bd023a598824..39348f209b4b 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -135,7 +135,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"البحث عن خدمة"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"الاتصال عبر Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذا الجهاز، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات."</item> + <item msgid="3910386316304772394">"لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذه الخدمة، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات. (رمز الخطأ: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"التسجيل لدى مشغّل شبكة الجوّال"</item> @@ -1194,20 +1194,13 @@ <item quantity="other">تتوفر شبكات Wi-Fi مفتوحة</item> <item quantity="one">تتوفر شبكة Wi-Fi واحدة مفتوحة</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"الاتصال بشبكة Wi-Fi المفتوحة"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"جارٍ الاتصال بشبكة Wi-Fi المفتوحة"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"تم الاتصال بشبكة Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"تعذَّر الاتصال بشبكة Wi‑Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"انقر للاطلاع على جميع الشبكات"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"اتصال"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"جميع الشبكات"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"تسجيل الدخول إلى شبكة Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"تسجيل الدخول إلى الشبكة"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 0cac6e808e64..6f39f7bf2aee 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Xidmət axtarılır"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi zəngi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi üzərindən zəng etmək və mesaj göndərmək üçün ilk öncə operatordan bu xidməti ayarlamağı tələb edin. Sonra Ayarlardan Wi-Fi çağrısını aktivləşdirin."</item> + <item msgid="3910386316304772394">"Zəng etmək və Wi-Fi üzərindən mesaj göndərmək üçün əvvəlcə operatordan bu cihazı quraşdırmağı tələb edin. Sonra Ayarlardan Wi-Fi zəngini deaktiv edin. (Xəta kodu: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Operatorla qeydiyyatdan keçin"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Əlçatan açıq Wi-Fi şəbəkələri</item> <item quantity="one">Əlçatan açıq Wi-Fi şəbəkəsi</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Açıq Wi‑Fi şəbəkəsinə qoşulun"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Açıq Wi‑Fi şəbəkəsinə qoşulur"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi şəbəkəsinə qoşuldu"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi şəbəkəsinə qoşulmaq mümkün deyil"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Bütün şəbəkələri görmək üçün klikləyin"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Qoşulun"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Bütün Şəbəkələr"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi şəbəkəsinə daxil ol"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Şəbəkəyə daxil olun"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 574a1816543a..0be7892f79dc 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -132,7 +132,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Pretraživanje usluge"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Pozivanje preko Wi-Fi-ja"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Da biste upućivali pozive i slali poruke preko Wi-Fi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko Wi-Fi-ja."</item> + <item msgid="3910386316304772394">"Da biste upućivali pozive i slali poruke preko Wi-Fi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko Wi-Fi-ja. (kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registrujte se kod mobilnog operatera"</item> @@ -1128,20 +1128,13 @@ <item quantity="few">Otvorene Wi-Fi mreže su dostupne</item> <item quantity="other">Otvorene Wi-Fi mreže su dostupne</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Povežite se sa otvorenom Wi‑Fi mrežom"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Povezujete se sa otvorenom Wi‑Fi mrežom"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Povezali ste se sa Wi‑Fi mrežom"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Povezivanje sa Wi‑Fi mrežom nije uspelo"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite da biste videli sve mreže"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Poveži"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Sve mreže"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavljivanje na Wi-Fi mrežu"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Prijavite se na mrežu"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index e883e979a103..5f1cad3da261 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -133,7 +133,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Пошук службы"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-тэлефанія"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Каб рабіць выклікі і адпраўляць паведамленні па Wi-Fi, спачатку папрасіце свайго аператара наладзіць гэту паслугу. Затым зноў уключыце Wi-Fi-тэлефанію ў меню Налады."</item> + <item msgid="3910386316304772394">"Каб рабіць выклікі і адпраўляць паведамленні па Wi-Fi, спачатку папрасіце свайго аператара наладзіць гэту паслугу. Затым зноў уключыце Wi-Fi-тэлефанію ў меню Налады. (Код памылкі: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Зарэгіструйцеся ў свайго аператара"</item> @@ -1150,20 +1150,13 @@ <item quantity="many">адкрытых сетак Wi-Fi даступна</item> <item quantity="other">адкрытай сеткі Wi-Fi даступна</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Падключыцеся да адкрытай сеткі Wi-Fi"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ідзе падключэнне да адкрытай сеткі Wi‑Fi"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Выканана падключэнне да адкрытай сеткі Wi‑Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не атрымалася падключыцца да адкрытай сеткі Wi‑Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Дакраніцеся, каб убачыць усе сеткі"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Падключыцца"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Усе сеткі"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Уваход у сетку Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Увайдзіце ў сетку"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 7f81b4e3e91f..301805441040 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Търси се покритие"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Обаждания през Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"За да извършвате обаждания и да изпращате съобщения през Wi-Fi, първо помолете оператора си да настрои тази услуга. След това включете отново функцията за обаждания през Wi-Fi от настройките."</item> + <item msgid="3910386316304772394">"За да извършвате обаждания и да изпращате съобщения през Wi-Fi, първо, помолете оператора си да настрои тази услуга. След това включете отново функцията за обаждания през Wi-Fi от настройките. (Код на грешката: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Регистриране с оператора ви"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Има достъпни отворени Wi-Fi мрежи</item> <item quantity="one">Има достъпна отворена Wi-Fi мрежа</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Свързване с отворена Wi‑Fi мрежа"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Установява се връзка с отворена Wi‑Fi мрежа"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Установихте връзка с Wi-Fi мрежата"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не можа да се установи връзка с Wi‑Fi мрежата"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Докоснете, за да видите всички мрежи"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Свързване"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Всички мрежи"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Влизане в Wi-Fi мрежа"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Вход в мрежата"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 2b49abd1814d..77ea9214c6f0 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -130,9 +130,7 @@ <string name="roamingText12" msgid="1189071119992726320">"রোমিং ব্যানার বন্ধ আছে"</string> <string name="roamingTextSearching" msgid="8360141885972279963">"পরিষেবা অনুসন্ধান করা হচ্ছে"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ওয়াই-ফাই কলিং"</string> - <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"ওয়াই-ফাই এর মাধ্যমে কল করতে ও বার্তা পাঠাতে, প্রথমে আপনার পরিষেবা প্রদানকারীকে এই পরিষেবার সেট আপ করার বিষয়ে জিজ্ঞাসা করুন। তারপরে আবার সেটিংস থেকে ওয়াই-ফাই কলিং চালু করুন।"</item> - </string-array> + <!-- no translation found for wfcOperatorErrorAlertMessages:0 (3910386316304772394) --> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"আপনার পরিষেবা প্রদানকারীকে নথিভুক্ত করুন"</item> </string-array> @@ -1106,20 +1104,13 @@ <item quantity="one">খোলা ওয়াই-ফাই নেটওয়ার্কগুলি উপলব্ধ রয়েছে</item> <item quantity="other">খোলা ওয়াই-ফাই নেটওয়ার্কগুলি উপলব্ধ রয়েছে</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"উন্মুক্ত ওয়াই-ফাই নেটওয়ার্কে সংযোগ করুন"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"উন্মুক্ত ওয়াই-ফাই নেটওয়ার্কে সংযোগ করা হচ্ছে"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"উন্মুক্ত ওয়াই-ফাই নেটওয়ার্কে সংযুক্ত করা হয়েছে"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ওয়াই-ফাই নেটওয়ার্কে সংযোগ করা গেল না"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"সমস্ত নেটওয়ার্ক দেখতে ট্যাপ করুন"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"সংযুক্ত করুন"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"সমস্ত নেটওয়ার্ক"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"ওয়াই-ফাই নেটওয়ার্কে প্রবেশ করুন"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"নেটওয়ার্কে প্রবেশ করুন"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 002689f6a4c9..5188743457c1 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -132,7 +132,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Traženje usluge"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi pozivanje"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Da biste pozivali i slali poruke preko Wi-Fi-ja, prvo zatražite od operatera da postavi tu uslugu. Potom u Postavkama ponovo uključite Wi-Fi pozivanje."</item> + <item msgid="3910386316304772394">"Da biste pozivali i slali poruke koristeći Wi-Fi mrežu, prvo zatražite od operatera da postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozivanje u Postavkama. (Kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registrirajte se kod svog operatera"</item> @@ -1130,20 +1130,13 @@ <item quantity="few">Otvorene Wi-Fi mreže su dostupne</item> <item quantity="other">Otvorene Wi-Fi mreže su dostupne</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Povežite se na otvorenu Wi‑Fi mrežu"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Povezivanje na otvorenu Wi‑Fi mrežu"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Povezani ste na Wi‑Fi mrežu"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nije se moguće povezati na Wi‑Fi mrežu"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite da vidite sve mreže"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Povežite se"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Sve mreže"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavljivanje na Wi-Fi mrežu"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava na mrežu"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index f7a41cc0d339..fc86c878d62c 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"S\'està cercant el servei"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Trucades per Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Per fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi des de Configuració."</item> + <item msgid="3910386316304772394">"Per fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi a Configuració. (Codi d\'error: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registra\'t amb el teu operador de telefonia mòbil"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Xarxes Wi-Fi obertes disponibles</item> <item quantity="one">Xarxa Wi-Fi oberta disponible</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Connecta\'t a una xarxa Wi-Fi oberta"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"S\'està connectant a una xarxa Wi-Fi oberta"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"S\'ha connectat a la xarxa Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"No s\'ha pogut connectar a una xarxa Wi-Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca per veure totes les xarxes"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connecta"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Totes les xarxes"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Inicia la sessió a la xarxa Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Inicia la sessió a la xarxa"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> @@ -1631,9 +1624,9 @@ <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"No es pot deixar de fixar aquesta aplicació"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fixada"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"Fixació de la pantalla anul·lada"</string> - <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Sol·licita el codi PIN per anul·lar"</string> - <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Sol·licita el patró de desbloqueig per anul·lar"</string> - <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demana la contrasenya per anul·lar"</string> + <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Sol·licita el codi PIN per deixar de fixar"</string> + <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Sol·licita el patró de desbloqueig per deixar de fixar"</string> + <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demana la contrasenya per deixar de fixar"</string> <string name="package_installed_device_owner" msgid="6875717669960212648">"Instal·lat per l\'administrador"</string> <string name="package_updated_device_owner" msgid="1847154566357862089">"Actualitzat per l\'administrador"</string> <string name="package_deleted_device_owner" msgid="2307122077550236438">"Suprimit per l\'administrador"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 6d0f373d12cb..74c24740a6f8 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -133,7 +133,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Vyhledávání služby"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Volání přes Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Chcete-li volat a odesílat textové zprávy přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení."</item> + <item msgid="3910386316304772394">"Chcete-li volat a odesílat SMS přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení. (Kód chyby: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registrace u operátora"</item> @@ -1150,20 +1150,13 @@ <item quantity="other">K dispozici jsou veřejné sítě Wi-Fi</item> <item quantity="one">K dispozici je veřejná síť Wi-Fi</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Připojení k otevřené síti Wi-Fi"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Připojování k otevřené síti Wi-Fi"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Připojeno k síti Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Připojení k síti Wi-Fi se nezdařilo"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Klepnutím zobrazíte všechny sítě"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Připojit"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Všechny sítě"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Přihlásit se k síti Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Přihlásit se k síti"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index bd216a6d6af5..48a4f9e29592 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Søger efter tjeneste"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Opkald via Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Hvis du vil foretage opkald og sende beskeder via Wi-Fi, skal du først anmode dit mobilselskab om at konfigurere denne tjeneste. Derefter skal du slå Wi-Fi-opkald til igen fra Indstillinger."</item> + <item msgid="3910386316304772394">"Hvis du vil foretage opkald og sende beskeder via Wi-Fi, skal du først anmode dit mobilselskab om at konfigurere denne tjeneste. Derefter skal du aktivere Wi-Fi-opkald igen fra Indstillinger. (Fejlkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registrer dig hos dit mobilselskab"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">Åbne Wi-Fi-netværk er tilgængelige</item> <item quantity="other">Åbne Wi-Fi-netværk er tilgængelige</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Opret forbindelse til et åbent Wi-Fi-netværk"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Opretter forbindelse til et åbent Wi‑Fi-netværk"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Forbundet til Wi-Fi-netværket"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Der kan ikke oprettes forbindelse til Wi-Fi-netværket"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryk for at se alle netværk"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Opret forbindelse"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle netværk"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Log ind på Wi-Fi-netværk"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Log ind på netværk"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index f6c914350ce7..4b4a60402d61 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Suche nach Dienst"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Anrufe über WLAN"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann erneut über die Einstellungen."</item> + <item msgid="3910386316304772394">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann noch einmal über die Einstellungen. (Fehlercode: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registriere dich bei deinem Mobilfunkanbieter."</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Verfügbare WLAN-Netzwerke öffnen</item> <item quantity="one">Verfügbares WLAN-Netzwerk öffnen</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Mit offenem WLAN verbinden"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Verbindung mit offenem WLAN wird hergestellt"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Mit WLAN verbunden"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"WLAN-Verbindung konnte nicht hergestellt werden"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tippen, um alle Netzwerke zu sehen"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Verbinden"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle Netzwerke"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"In WLAN-Netzwerk anmelden"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Im Netzwerk anmelden"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index cf8567e90e6b..969ef24af926 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Αναζήτηση υπηρεσιών"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Κλήση Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά τη λειτουργία κλήσεων μέσω Wi-Fi από τις Ρυθμίσεις."</item> + <item msgid="3910386316304772394">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά την Κλήση Wi-Fi από τις Ρυθμίσεις. (Κωδικός σφάλματος: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Εγγραφείτε μέσω της εταιρείας κινητής τηλεφωνίας"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Υπάρχουν διαθέσιμα ανοικτά δίκτυα Wi-Fi</item> <item quantity="one">Υπάρχει διαθέσιμο ανοικτό δίκτυο Wi-Fi</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Σύνδεση σε ανοιχτό δίκτυο Wi‑Fi"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Σύνδεση σε ανοιχτό δίκτυο Wi‑Fi"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ολοκληρώθηκε η σύνδεση στο δίκτυο Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Δεν ήταν δυνατή η σύνδεση σε δίκτυο Wi‑Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Πατήστε για να δείτε όλα τα δίκτυα"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Σύνδεση"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Όλα τα δίκτυα"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Συνδεθείτε στο δίκτυο Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Σύνδεση στο δίκτυο"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 36d458b4beb6..fea0c6960ebb 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Searching for Service"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item> + <item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Register with your operator"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Open Wi-Fi networks available</item> <item quantity="one">Open Wi-Fi network available</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Connect to open Wi‑Fi network"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connecting to open Wi‑Fi network"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connected to Wi‑Fi network"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Could not connect to Wi‑Fi network"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"All Networks"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Sign in to a Wi-Fi network"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 36d458b4beb6..fea0c6960ebb 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Searching for Service"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item> + <item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Register with your operator"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Open Wi-Fi networks available</item> <item quantity="one">Open Wi-Fi network available</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Connect to open Wi‑Fi network"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connecting to open Wi‑Fi network"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connected to Wi‑Fi network"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Could not connect to Wi‑Fi network"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"All Networks"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Sign in to a Wi-Fi network"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 36d458b4beb6..fea0c6960ebb 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Searching for Service"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item> + <item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Register with your operator"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Open Wi-Fi networks available</item> <item quantity="one">Open Wi-Fi network available</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Connect to open Wi‑Fi network"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connecting to open Wi‑Fi network"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connected to Wi‑Fi network"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Could not connect to Wi‑Fi network"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"All Networks"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Sign in to a Wi-Fi network"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 01487ddaa60c..e8d25c6df178 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Buscando servicio"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Llamada por Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Para realizar llamadas o enviar mensajes por Wi-Fi, primero solicítale al proveedor que instale el servicio. Luego, vuelve a activar las llamadas por Wi-Fi desde Configuración."</item> + <item msgid="3910386316304772394">"Para hacer llamadas y enviar mensajes mediante Wi-Fi, solicítale a tu proveedor que configure este servicio. Luego, vuelve a activar la Llamada con Wi-Fi en Configuración. (código de error: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Regístrate con tu proveedor."</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Abrir redes de Wi-Fi disponibles</item> <item quantity="one">Abrir red de Wi-Fi disponible</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Conectarse a una red Wi-Fi abierta"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectándose a una red Wi-Fi abierta"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Se conectó a la red Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"No fue posible conectarse a la red Wi‑Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Presiona para ver todas las redes"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas las redes"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Accede a una red Wi-Fi."</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Acceder a la red"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 8e01520e3dbf..33bfa1affd12 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Buscando servicio"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Llamadas Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Para hacer llamadas y enviar mensajes por Wi-Fi, debes pedir antes a tu operador que configure este servicio. Una vez hecho esto, vuelva a activar las llamadas Wi-Fi en Ajustes."</item> + <item msgid="3910386316304772394">"Para hacer llamadas y enviar mensajes por Wi-Fi, pide antes a tu operador que configure este servicio. Una vez hecho esto, vuelva a activar la llamada por Wi-Fi en Ajustes. (Código de error: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Regístrate con tu operador"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Redes Wi-Fi abiertas disponibles</item> <item quantity="one">Red Wi-Fi abierta disponible</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Conectarse a una red Wi-Fi abierta"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectándose a una red Wi-Fi abierta"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectado a la red Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"No se ha podido conectar a la red Wi-Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca para ver todas las redes"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectarse"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas las redes"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Iniciar sesión en red Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Iniciar sesión en la red"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 9e676634e89d..070ce299f643 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Teenuse otsimine"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"WiFi-kõned"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Üle WiFi-võrgu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse."</item> + <item msgid="3910386316304772394">"WiFi-võrgu kaudu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse. (Veakood: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registreeruge operaatori juures"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Avatud WiFi-võrgud on saadaval</item> <item quantity="one">Avatud WiFi-võrk on saadaval</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Looge ühendus avatud WiFi-võrguga"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ühenduse loomine avatud WiFi-võrguga"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ühendatud WiFi-võrguga"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"WiFi-võrguga ei õnnestunud ühendust luua"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Puudutage kõikide võrkude nägemiseks"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ühenda"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Kõik võrgud"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Logi sisse WiFi-võrku"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Võrku sisselogimine"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 2b13cd964068..cea36c14e932 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Zerbitzu bila"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi bidezko deiak"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean."</item> + <item msgid="3910386316304772394">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean. (Errore-kodea: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Erregistratu operadorearekin"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Wi-Fi sare irekiak erabilgarri</item> <item quantity="one">Wi-Fi sare irekia erabilgarri</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Konektatu Wi‑Fi sare irekira"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Wi‑Fi sare irekira konektatzen"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi sare irekira konektatuta"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Ezin izan da konektatu Wi‑Fi sare irekira"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Sakatu hau sare guztiak ikusteko"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Konektatu"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Sare guztiak"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Hasi saioa Wi-Fi sarean"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Hasi saioa sarean"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index aaf6ea3ec29b..edcfbc2419e4 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"جستجوی سرویس"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"تماس از طریق Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"برای برقراری تماس و ارسال پیام از طریق Wi-Fi، ابتدا از شرکت مخابراتیتان درخواست کنید این سرویس را راهاندازی کند. سپس دوباره از تنظیمات، تماس Wi-Fi را روشن کنید."</item> + <item msgid="3910386316304772394">"برای برقراری تماس و ارسال پیام ازطریق Wi-Fi، ابتدا از شرکت مخابراتی خود بخواهید این سرویس را تنظیم کند. سپس در «تنظیمات»۷ دوباره «تماس ازطریق Wi-Fi» را روشن کنید. (کد خطا: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"ثبتنام با شرکت مخابراتی شما"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">شبکه Wi-Fi باز در دسترس</item> <item quantity="other">شبکه Wi-Fi باز در دسترس</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"اتصال به شبکه Wi‑Fi باز"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"درحال اتصال به شبکه Wi‑Fi باز"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"به شبکه Wi‑Fi متصل شد"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"به شبکه Wi-Fi متصل نشد"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"برای دیدن همه شبکهها ضربه بزنید"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"اتصال"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"همه شبکهها"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"ورود به شبکه Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"ورود به سیستم شبکه"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 3eef3e5b8065..6e8346b9b773 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Etsitään signaalia"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-puhelut"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa."</item> + <item msgid="3910386316304772394">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa. (Virhekoodi: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Rekisteröidy operaattorisi asiakkaaksi."</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Avoimia Wi-Fi-verkkoja käytettävissä</item> <item quantity="one">Avoin Wi-Fi-verkko käytettävissä</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Yhdistä avoimeen Wi‑Fi-verkkoon"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Yhdistetään avoimeen Wi‑Fi-verkkoon"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Yhdistetty Wi-Fi-verkkoon"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi-verkkoon yhdistäminen epäonnistui"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Napauta, niin näet kaikki verkot."</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Yhdistä"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Kaikki verkot"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Kirjaudu Wi-Fi-verkkoon"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Kirjaudu verkkoon"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 9cdf01696bfb..57e5fd19db11 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Recherche des services disponibles"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Appels Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item> + <item msgid="3910386316304772394">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres. (Code d\'erreur : <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Inscrivez-vous auprès de votre fournisseur de services"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">Réseau Wi-Fi ouvert à proximité</item> <item quantity="other">Réseaux Wi-Fi ouverts à proximité</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Connectez-vous pour ouvrir un réseau Wi-Fi"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connexion en cours au réseau Wi-Fi ouvert…"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connecté au réseau Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Impossible de se connecter au réseau Wi-Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Touchez pour afficher tous les réseaux"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connexion"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tous les réseaux"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Connectez-vous au réseau Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Connectez-vous au réseau"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index adacfa519ae3..b5fd4543a5ff 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Recherche des services disponibles"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Appels Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Pour effectuer des appels et envoyer des messages via le Wi-Fi, demandez tout d\'abord à votre opérateur de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item> + <item msgid="3910386316304772394">"Pour passer des appels et envoyer des messages via le Wi-Fi, demandez d\'abord à votre opérateur de configurer ce service. Ensuite, réactivez les appels Wi-Fi dans les paramètres. (Code d\'erreur : <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Inscrivez-vous auprès de votre opérateur."</item> @@ -1106,20 +1106,13 @@ <item quantity="one">Réseau Wi-Fi ouvert disponible</item> <item quantity="other">Réseaux Wi-Fi ouverts disponibles</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Se connecter pour ouvrir le réseau Wi-Fi"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connexion pour ouvrir un réseau Wi-Fi…"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connecté au réseau Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Impossible de se connecter au réseau Wi-Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Appuyer pour afficher tous les réseaux"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Se connecter"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tous les réseaux"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Connectez-vous au réseau Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Se connecter au réseau"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index ba56c6253d80..b62ca2d7fc0c 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Buscando servizo"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas por wifi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro pídelle ao teu operador que configure este servizo. A continuación, activa de novo as chamadas wifi en Configuración."</item> + <item msgid="3910386316304772394">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro solicítalle ao operador que configure este servizo. Despois, activa de novo as chamadas por wifi en Configuración. (Código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Rexístrate co teu operador"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Abrir redes wifi dispoñibles</item> <item quantity="one">Abrir rede wifi dispoñible</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Conéctate a unha rede wifi aberta"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectándose á rede wifi aberta"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectouse á rede wifi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Non se puido conectar á rede wifi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca para ver todas as redes"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectarse"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Inicia sesión na rede wifi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Inicia sesión na rede"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 02311be9c69b..6dc0e0c69ee3 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"સેવા શોધી રહ્યું છે"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi કૉલિંગ"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi પર કૉલ્સ કરવા અને સંદેશા મોકલવા માટે, પહેલા તમારા કેરીઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી Wi-Fi કૉલિંગ ચાલુ કરો."</item> + <item msgid="3910386316304772394">"Wi-Fi પરથી કૉલ કરવા અને સંદેશા મોકલવા માટે પહેલા તમારા કૅરિઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી Wi-Fi કૉલિંગ ફરીથી ચાલુ કરો. (ભૂલ કોડ: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"તમારા કેરીઅર સાથે નોંધણી કરો"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">ખુલ્લા Wi-Fi નેટવર્ક્સ ઉપલબ્ધ છે</item> <item quantity="other">ખુલ્લા Wi-Fi નેટવર્ક્સ ઉપલબ્ધ છે</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"ખુલ્લા Wi‑Fi નેટવર્ક સાથે કનેક્ટ કરો"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ખુલ્લા Wi‑Fi નેટવર્ક સાથે કનેક્ટ કરી રહ્યાં છીએ"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi નેટવર્ક સાથે કનેક્ટ કર્યુ"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi નેટવર્ક સાથે કનેક્ટ કરી શકાયું નથી"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"બધા નેટવર્ક જોવા ટૅપ કરો"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"કનેક્ટ કરો"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"બધા નેટવર્ક"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi નેટવર્ક પર સાઇન ઇન કરો"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"નેટવર્ક પર સાઇન ઇન કરો"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index be1233a06763..e534488e26a8 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"सेवा खोज रहा है"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"वाई-फ़ाई कॉलिंग"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"वाई-फ़ाई से कॉल करने और संदेश भेजने के लिए, सबसे पहले अपने वाहक से इस सेवा को सेट करने के लिए कहें. उसके बाद सेटिंग से पुन: वाई-फ़ाई कॉलिंग चालू करें."</item> + <item msgid="3910386316304772394">"वाई-फ़ाई से कॉल करने और संदेश भेजने के लिए, सबसे पहले अपने वाहक से इस सेवा को सेट करने के लिए कहें. उसके बाद सेटिंग से वाई-फ़ाई कॉलिंग को दोबारा चालू करें. (गड़बड़ी कोड: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"अपने वाहक के साथ पंजीकृत करें"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">खुले वाई-फ़ाई नेटवर्क उपलब्ध</item> <item quantity="other">खुले वाई-फ़ाई नेटवर्क उपलब्ध</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"खुले वाई-फ़ाई नेटवर्क से कनेक्ट करें"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"खुले वाई-फ़ाई नेटवर्क से कनेक्ट हो रहा है"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"वाई-फ़ाई नेटवर्क से कनेक्ट हो गया है"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"वाई-फ़ाई नेटवर्क से कनेक्ट नहीं हो सका"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सभी नेटवर्क देखने के लिए यहां पर टैप करें"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"कनेक्ट करें"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"सभी नेटवर्क"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"वाई-फ़ाई नेटवर्क में प्रवेश करें"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"नेटवर्क में प्रवेश करें"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 507920a582c0..ae5bdead36d6 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -132,7 +132,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Pretraživanje usluge"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi pozivi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Da biste telefonirali i slali pozive putem Wi-Fi-ja, morate tražiti od mobilnog operatera da vam postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u Postavkama."</item> + <item msgid="3910386316304772394">"Da biste telefonirali i slali poruke putem Wi-Fi-ja, od mobilnog operatera morate tražiti da postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u postavkama. (Kôd pogreške: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registrirajte se kod mobilnog operatera"</item> @@ -1128,20 +1128,13 @@ <item quantity="few">Dostupne su otvorene Wi-Fi mreže</item> <item quantity="other">Dostupne su otvorene Wi-Fi mreže</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Povezivanje s otvorenom Wi‑Fi mrežom"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Povezivanje s otvorenom Wi‑Fi mrežom"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Povezano s Wi-Fi mrežom"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nije uspjelo povezivanje s Wi-Fi mrežom"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite za prikaz svih mreža"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Poveži"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Sve mreže"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijava na Wi-Fi mrežu"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava na mrežu"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 7562bbcb7e22..cc71deff61d4 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Szolgáltatás keresése"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-hívás"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Ha Wi-Fi-n szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután a Beállítások menüben kapcsolhatja be újra a Wi-Fi-hívást."</item> + <item msgid="3910386316304772394">"Ha Wi-Fi-hálózaton szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután kapcsolja be újra a Wi-Fi-hívást a Beállításokban. (Hibakód: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Regisztráljon a szolgáltatójánál"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Nyílt Wi-Fi hálózatok érhetők el</item> <item quantity="one">Nyílt Wi-Fi hálózat érhető el</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Nyílt Wi-Fi-hálózathoz kapcsolódhat"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Kapcsolódás nyílt Wi‑Fi-hálózathoz…"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Sikeres kapcsolódás a Wi-Fi-hálózathoz"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nem sikerült kapcsolódni a Wi‑Fi-hálózathoz"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Koppintással megjelenítheti az összes hálózatot"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kapcsolódás"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Összes hálózat"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Bejelentkezés Wi-Fi hálózatba"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Bejelentkezés a hálózatba"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index c3a2e902eb05..0f67744f0109 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Ծառայության որոնում..."</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Զանգեր Wi-Fi-ի միջոցով"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi-ի միջոցով զանգեր կատարելու և հաղորդագրություններ ուղարկելու համար նախ դիմեք ձեր օպերատորին՝ ծառայությունը կարգավորելու համար: Ապա նորից միացրեք Wi-Fi զանգերը Կարգավորումներում:"</item> + <item msgid="3910386316304772394">"Wi-Fi-ի միջոցով զանգեր կատարելու և հաղորդագրություններ ուղարկելու համար նախ դիմեք ձեր օպերատորին՝ այս ծառայությունը կարգավորելու համար: Այնուհետև նորից միացրեք «Զանգեր Wi-Fi-ի միջոցով» ընտրանքը Կարգավորումներից: (Սխալի կոդ՝ <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Գրանցվեք օպերատորի մոտ"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">Հասանելի են չպաշտպանված Wi-Fi ցանցեր</item> <item quantity="other">Հասանելի են չպաշտպանված Wi-Fi ցանցեր</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Միացեք բաց Wi‑Fi ցանցին"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Միացում բաց Wi‑Fi ցանցին"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Միացել է Wi‑Fi ցանցին"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Չհաջողվեց միանալ Wi‑Fi ցանցին"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Հպեք՝ բոլոր ցանցերը տեսնելու համար"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Միանալ"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Բոլոր ցանցերը"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Մուտք գործեք Wi-Fi ցանց"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Մուտք գործեք ցանց"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 4561c6c96ecb..99f9f098ad73 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Mencari layanan"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Panggilan Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Untuk melakukan panggilan telepon dan mengirim pesan melalui Wi-Fi, terlebih dahulu minta operator untuk menyiapkan layanan ini. Lalu, aktifkan lagi panggilan telepon Wi-Fi dari Setelan."</item> + <item msgid="3910386316304772394">"Untuk menelepon dan mengirim pesan melalui Wi-Fi, tanyalah ke operator Anda terlebih dahulu untuk menyiapkan layanan ini. Kemudian, aktifkan kembali panggilan Wi-Fi dari Setelan. (Kode error: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Harap daftarkan ke operator"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Jaringan Wi-Fi terbuka tersedia</item> <item quantity="one">Jaringan Wi-Fi terbuka tersedia</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Hubungkan ke jaringan Wi-Fi terbuka"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Menghubungkan ke jaringan Wi-Fi terbuka"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Terhubung ke jaringan Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Tidak dapat menghubungkan ke jaringan Wi‑Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap untuk melihat semua jaringan"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Hubungkan"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Semua Jaringan"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Masuk ke jaringan Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Masuk ke jaringan"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index e645da9dfedc..32d5c10e84d4 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Leitar að þjónustu"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi símtöl"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum."</item> + <item msgid="3910386316304772394">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum. (Villukóði: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Skráðu þig hjá símafyrirtækinu"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">Opin Wi-Fi net í boði</item> <item quantity="other">Opin Wi-Fi net í boði</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Tengjast opnu Wi-Fi neti"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Tengist opnu Wi‑Fi neti"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Tengt við Wi‑Fi net"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Ekki hægt að tengjast Wi-Fi neti"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ýttu til að sjá öll netkerfi"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Tengjast"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Öll netkerfi"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Skrá inn á Wi-Fi net"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Skrá inn á net"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 7f7f881f0fe1..ccaffaeeb1e8 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Ricerca servizio"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chiamate Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Per effettuare chiamate e inviare messaggi tramite Wi-Fi, è necessario prima chiedere all\'operatore telefonico di attivare il servizio. Successivamente, riattiva le chiamate Wi-Fi dalle Impostazioni."</item> + <item msgid="3910386316304772394">"Per effettuare chiamate e inviare messaggi tramite Wi-Fi, chiedi prima al tuo operatore di impostare questo servizio. Dopodiché, attiva di nuovo la funzione Chiamate Wi-Fi nelle impostazioni. (Codice di errore: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registrati con il tuo operatore"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Apri reti Wi-Fi disponibili</item> <item quantity="one">Apri rete Wi-Fi disponibile</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Stabilisci la connessione per aprire la rete Wi‑Fi"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connessione per aprire la rete Wi‑Fi"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connessione alla rete Wi-Fi stabilita"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Impossibile connettersi alla rete Wi-Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tocca per vedere tutte le reti"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connetti"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tutte le reti"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Accedi a rete Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Accedi alla rete"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> @@ -1383,7 +1376,7 @@ <string name="action_menu_overflow_description" msgid="2295659037509008453">"Altre opzioni"</string> <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string> <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string> - <string name="storage_internal" msgid="3570990907910199483">"Archivio condiviso interno"</string> + <string name="storage_internal" msgid="3570990907910199483">"Memoria condivisa interna"</string> <string name="storage_sd_card" msgid="3282948861378286745">"Scheda SD"</string> <string name="storage_sd_card_label" msgid="6347111320774379257">"Scheda SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string> <string name="storage_usb_drive" msgid="6261899683292244209">"Unità USB"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 89f157ebd381..d765403aa704 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -133,7 +133,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"מחפש שירות"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"שיחות ב-Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב התקשרות Wi-Fi מ\'הגדרות\'."</item> + <item msgid="3910386316304772394">"כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב שיחות Wi-Fi ב\'הגדרות\'. (קוד שגיאה: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"הירשם אצל הספק"</item> @@ -1150,20 +1150,13 @@ <item quantity="other">יש רשתות Wi-Fi פתוחות וזמינות</item> <item quantity="one">יש רשת Wi-Fi פתוחה וזמינה</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"התחברות לרשת Wi‑Fi פתוחה"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"מתחבר לרשת Wi‑Fi פתוחה"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"מחובר לרשת Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"לא ניתן היה להתחבר לרשת Wi-Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"יש להקיש כדי לראות את כל הרשתות"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"התחבר"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"כל הרשתות"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"היכנס לרשת Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"היכנס לרשת"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 6c700809f6c6..e223eec83af3 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"サービスを検索中"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi通話"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社にWi-Fiサービスを申し込んだ上で、設定画面でWi-Fi発信を再度ONにしてください。"</item> + <item msgid="3910386316304772394">"Wi-Fi 経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社に Wi-Fi サービスを申し込んだ上で、設定画面で Wi-Fi 発信を再度 ON にしてください(エラーコード: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"携帯通信会社に登録してください"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">複数のWi-Fiオープンネットワークが利用できます</item> <item quantity="one">Wi-Fiオープンネットワークが利用できます</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Wi-Fi オープン ネットワークに接続"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Wi-Fi オープン ネットワークに接続しています"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi-Fi ネットワークに接続しました"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi ネットワークに接続できませんでした"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"すべてのネットワークを表示するにはタップします"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"接続"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"すべてのネットワーク"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fiネットワークにログイン"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"ネットワークにログインしてください"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index b63434c9862e..5b8a8bcd3ae5 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"სერვისის ძიება"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"დარეკვა Wi-Fi-ს მეშვეობით"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi-ს მეშვეობით ზარების განხორციელების ან შეტყობინების გაგზავნისათვის, პირველ რიგში დაეკითხეთ თქვენს ოპერატორს აღნიშნულ მომსახურებაზე. შემდეგ ხელახლა ჩართეთ Wi-Fi ზარები პარამეტრებიდან."</item> + <item msgid="3910386316304772394">"Wi-Fi-ს მეშვეობით ზარების განსახორციელებლად ან შეტყობინებების გასაგზავნად, პირველ რიგში, ამ სერვისის გააქტიურება თქვენს ოპერატორს უნდა თხოვოთ. შემდეგ კი ხელახლა ჩართეთ Wi-Fi დარეკვა პარამეტრებიდან.. (შეცდომის კოდი: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"დაარეგისტრირეთ თქვენი ოპერატორი"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">ხელმისაწვდომია ღია Wi-Fi ქსელები</item> <item quantity="one">ხელმისაწვდომია ღია Wi-Fi ქსელი</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"დაუკავშირდით ღია Wi‑Fi ქსელს"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"მიმდინარეობს ღია Wi‑Fi ქსელთან დაკავშირება"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi ქსელთან დაკავშირება წარმატებით მოხერხდა"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi ქსელთან დაკავშირება ვერ მოხერხდა"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"შეეხეთ ყველა ქსელის სანახავად"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"დაკავშირება"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ყველა ქსელი"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi ქსელთან დაკავშირება"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"ქსელში შესვლა"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index a03884cd41dd..bedcc4372005 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Қызметті іздеу"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi қоңыраулары"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi арқылы қоңырау шалу және хабарларды жіберу үшін алдымен жабдықтаушыңыздан осы қызметті орнатуды сұраңыз. Содан кейін Параметрлерден Wi-Fi қоңырау шалуын іске қосыңыз."</item> + <item msgid="3910386316304772394">"Wi-Fi арқылы қоңырау шалу немесе хабарлар жіберу үшін, алдымен операторыңыздан құрылғыны реттеуді сұраңыз. Содан кейін \"Параметрлер\" бөлімінен Wi-Fi қоңырауларын қайта қосыңыз. (Қате коды: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Жабдықтаушыңыз арқылы тіркелу"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Ашық Wi-Fi желілері қол жетімді</item> <item quantity="one">Ашық Wi-Fi желісі қол жетімді</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Ашық Wi‑Fi желісіне қосылу"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ашық Wi‑Fi желісіне қосылуда"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi желісіне қосылды"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi желісіне қосылмады"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Барлық желілерді көру үшін түртіңіз"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Қосылу"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Барлық желілер"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi желісіне кіру"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Желіге кіру"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 1a93326d653c..270e46727e61 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"ស្វែងរកសេវាកម្ម"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ការហៅតាម Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"ដើម្បីធ្វើការហៅ និងផ្ញើសារតាម Wi-Fi ដំបូងឡើយអ្នកត្រូវស្នើឲ្យក្រុមហ៊ុនរបស់អ្នកដំឡើងសេវាកម្មនេះសិន។ បន្ទាប់មកបើកការហៅតាម Wi-Fi ម្តងទៀតចេញពីការកំណត់។"</item> + <item msgid="3910386316304772394">"ដើម្បីធ្វើការហៅ និងផ្ញើសារតាម Wi-Fi អ្នកត្រូវស្នើឲ្យក្រុមហ៊ុនបម្រើសេវាទូរសព្ទរបស់អ្នកដំឡើងសេវាកម្មនេះជាមុនសិន។ បន្ទាប់មកបើកការហៅតាម Wi-Fi ម្តងទៀតនៅក្នុងការកំណត់។ (លេខកូដបញ្ហា៖ <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"ចុះឈ្មោះជាមួយក្រុមហ៊ុនរបស់អ្នក"</item> @@ -1108,20 +1108,13 @@ <item quantity="other">បើកបណ្តាញ Wi-Fi ដែលមាន</item> <item quantity="one">បើកបណ្តាញ Wi-Fi ដែលមាន</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"ភ្ជាប់ទៅបណ្តាញ Wi‑Fi ចំហ"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"កំពុងភ្ជាប់ទៅបណ្តាញ Wi‑Fi ចំហ"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"បានភ្ជាប់ទៅបណ្តាញ Wi‑Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"មិនអាចភ្ជាប់ទៅបណ្តាញ Wi‑Fi បានទេ"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ចុចដើម្បីមើលបណ្តាញទាំងអស់"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"ភ្ជាប់"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"បណ្តាញទាំងអស់"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"ចូលបណ្ដាញវ៉ាយហ្វាយ"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"ចូលទៅបណ្តាញ"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 0b008b08e004..7783692e567f 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"ಸೇವೆ ಹುಡುಕಲಾಗುತ್ತಿದೆ"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"ವೈ-ಫೈ ಬಳಸಿಕೊಂಡು ಕರೆ ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಮೊದಲು ಈ ಸಾಧನವನ್ನು ಹೊಂದಿಸಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ತದನಂತರ ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ಮತ್ತೆ ವೈ-ಫೈ ಆನ್ ಮಾಡಿ."</item> + <item msgid="3910386316304772394">"ವೈ-ಫೈ ಮೂಲಕ ಕರೆಗಳನ್ನು ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಈ ಸೇವೆಯನ್ನು ಹೊಂದಿಸಲು ಮೊದಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ಆ ನಂತರ ಸೆಟ್ಟಿಂಗ್ಗಳಿಂದ ವೈ-ಫೈ ಕರೆಮಾಡುವಿಕೆಯನ್ನು ಅನ್ನು ಆನ್ ಮಾಡಿ. (ದೋಷ ಕೋಡ್: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"ನಿಮ್ಮ ವಾಹಕದಲ್ಲಿ ನೋಂದಾಯಿಸಿಕೊಳ್ಳಿ"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳು ಲಭ್ಯವಿವೆ</item> <item quantity="other">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳು ಲಭ್ಯವಿವೆ</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಪಡಿಸಿ"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗುತ್ತಿದೆ"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ಎಲ್ಲಾ ನೆಟ್ವರ್ಕ್ಗಳನ್ನು ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"ಸಂಪರ್ಕಿಸಿ"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ಎಲ್ಲಾ ನೆಟ್ವರ್ಕ್ಗಳು"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"ನೆಟ್ವರ್ಕ್ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index d48c0766b5ba..739f128c77a8 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"서비스 검색 중"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi 통화"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 이 기능을 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다."</item> + <item msgid="3910386316304772394">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 서비스를 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다. (오류 코드: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"이동통신사에 등록"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">개방형 Wi-Fi 네트워크 사용 가능</item> <item quantity="one">개방형 Wi-Fi 네트워크 사용 가능</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"공개 Wi‑Fi 네트워크에 연결"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"공개 Wi‑Fi 네트워크에 연결 중"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi 네트워크에 연결됨"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi 네트워크에 연결할 수 없음"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"모든 네트워크를 보려면 탭하세요."</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"연결"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"모든 네트워크"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi 네트워크에 로그인"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"네트워크에 로그인"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index e374edcdd06c..569bf2ce87ab 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Кызмат изделүүдө"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Чалуу"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз."</item> + <item msgid="3910386316304772394">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде байланыш операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз. (Ката коду: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Операторуңузга катталыңыз"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Ачык Wi-Fi тармагы жеткиликтүү</item> <item quantity="one">Ачык Wi-Fi тармагы жеткиликтүү</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Ачык Wi‑Fi тармагына туташуу"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ачык Wi‑Fi тармагына туташууда"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ачык Wi‑Fi тармагына туташты"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi-Fi тармагына туташпай калды"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Бардык тармактарды көрүү үчүн басыңыз"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Туташуу"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Бардык тармактар"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi түйүнүнө кирүү"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Тармакка кирүү"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index f55ee059161f..6c8603e8898f 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"ຊອກຫາບໍລິການ"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ການໂທ Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"ເພື່ອໂທ ແລະສົ່ງຂໍ້ຄວາມຢູ່ເທິງ Wi-Fi, ກ່ອນອື່ນໝົດໃຫ້ຖ້າມຜູ້ໃຫ້ບໍລິການເຄືອຂ່າຍຂອງທ່ານ ເພື່ອຕັ້ງການບໍລິການນີ້. ຈາກນັ້ນເປີດການໂທ Wi-Fi ອີກຈາກການຕັ້ງຄ່າ."</item> + <item msgid="3910386316304772394">"ເພື່ອໂທ ແລະ ສົ່ງຂໍ້ຄວາມຜ່ານ Wi-Fi, ໃຫ້ແຈ້ງໃຫ້ຜູ້ໃຫ້ບໍລິການຂອງທ່ານຕັ້ງບໍລິການນີ້. ຈາກນັ້ນເປີດໃຊ້ການໂທ Wi-Fi ອີກຄັ້ງຈາກການຕັ້ງຄ່າ. (ລະຫັດຂໍ້ຜິດພາດ: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"ລົງທະບຽນກັບຜູ້ໃຫ້ບໍລິການເຄືອຂ່າຍຂອງທ່ານ"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">ເປີດເຄືອຂ່າຍ Wi-Fi ທີ່ມີໃຫ້</item> <item quantity="one">ເປີດເຄືອຂ່າຍ Wi-Fi ທີ່ມີໃຫ້</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"ເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi ແບບເປີດ"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ກຳລັງເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"ເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi ແລ້ວ"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ບໍ່ສາມາດເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi ໄດ້"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ແຕະເພື່ອເບິ່ງເຄືອຂ່າຍທັງໝົດ"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"ເຊື່ອມຕໍ່"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ເຄືອຂ່າຍທັງໝົດ"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"ເຂົ້າສູ່ລະບົບເຄືອຂ່າຍ Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"ລົງຊື່ເຂົ້າເຄືອຂ່າຍ"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index affea3c733d9..2a82845accab 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -133,7 +133,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Ieškoma paslaugos"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"„Wi-Fi“ skambinimas"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Jei norite skambinti ir siųsti pranešimus „Wi-Fi“ ryšiu, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite skambinimą „Wi-Fi“ ryšiu „Nustatymų“ skiltyje."</item> + <item msgid="3910386316304772394">"Jei norite skambinti ir siųsti pranešimus naudodami „Wi-Fi“, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite „Wi-Fi“ skambinimą skiltyje „Nustatymai“. (Klaidos kodas: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Užregistruokite pas operatorių"</item> @@ -1150,20 +1150,13 @@ <item quantity="many">Pasiekiami atvirieji „Wi-Fi“ tinklai</item> <item quantity="other">Pasiekiami atvirieji „Wi-Fi“ tinklai</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Prisijunkite prie atviro „Wi‑Fi“ tinklo"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Prisijungiama prie atviro „Wi‑Fi“ tinklo"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Prisijungta prie „Wi-Fi“ tinklo"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nepavyko prisijungti prie „Wi‑Fi“ tinklo"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Palieskite, jei norite matyti visus tinklus"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Prisijungti"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Visi tinklai"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prisijungti prie „Wi-Fi“ tinklo"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Prisijungti prie tinklo"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index ab82849d6de2..cfe036924a3a 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -132,7 +132,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Pakalpojuma meklēšana"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi zvani"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoru iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus."</item> + <item msgid="3910386316304772394">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoram iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus. (Kļūdas kods: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Reģistrēt to pie sava mobilo sakaru operatora"</item> @@ -1128,20 +1128,13 @@ <item quantity="one">Ir pieejami atvērti Wi-Fi tīkli</item> <item quantity="other">Ir pieejami atvērti Wi-Fi tīkli</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Savienojuma izveide ar atvērtu Wi-Fi tīklu"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Notiek savienojuma izveide ar atvērtu Wi-Fi tīklu"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ir izveidots savienojums ar Wi-Fi tīklu"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nevarēja izveidot savienojumu ar Wi‑Fi tīklu"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Pieskarieties, lai skatītu visus tīklus"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Izveidot savienojumu"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Visi tīkli"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Pierakstieties Wi-Fi tīklā"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Pierakstīšanās tīklā"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-mcc302-mnc370-af/strings.xml b/core/res/res/values-mcc302-mnc370-af/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-af/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-am/strings.xml b/core/res/res/values-mcc302-mnc370-am/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-am/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-ar/strings.xml b/core/res/res/values-mcc302-mnc370-ar/strings.xml new file mode 100644 index 000000000000..f1c8176cb706 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-ar/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s مع Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-az/strings.xml b/core/res/res/values-mcc302-mnc370-az/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-az/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-b+sr+Latn/strings.xml b/core/res/res/values-mcc302-mnc370-b+sr+Latn/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-b+sr+Latn/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-be/strings.xml b/core/res/res/values-mcc302-mnc370-be/strings.xml new file mode 100644 index 000000000000..74d4f17ce643 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-be/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-bg/strings.xml b/core/res/res/values-mcc302-mnc370-bg/strings.xml new file mode 100644 index 000000000000..b3a9589b1eac --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-bg/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi от %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-bn/strings.xml b/core/res/res/values-mcc302-mnc370-bn/strings.xml new file mode 100644 index 000000000000..efd9b4b4f8ca --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-bn/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s ওয়াই-ফাই"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-bs/strings.xml b/core/res/res/values-mcc302-mnc370-bs/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-bs/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-ca/strings.xml b/core/res/res/values-mcc302-mnc370-ca/strings.xml new file mode 100644 index 000000000000..74d4f17ce643 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-ca/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-cs/strings.xml b/core/res/res/values-mcc302-mnc370-cs/strings.xml new file mode 100644 index 000000000000..74d4f17ce643 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-cs/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-da/strings.xml b/core/res/res/values-mcc302-mnc370-da/strings.xml new file mode 100644 index 000000000000..709530cc56ae --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-da/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi fra %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-de/strings.xml b/core/res/res/values-mcc302-mnc370-de/strings.xml new file mode 100644 index 000000000000..6aa76438581a --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-de/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"WLAN: %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-el/strings.xml b/core/res/res/values-mcc302-mnc370-el/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-el/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-en-rAU/strings.xml b/core/res/res/values-mcc302-mnc370-en-rAU/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-en-rAU/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-en-rGB/strings.xml b/core/res/res/values-mcc302-mnc370-en-rGB/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-en-rGB/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-en-rIN/strings.xml b/core/res/res/values-mcc302-mnc370-en-rIN/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-en-rIN/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-es-rUS/strings.xml b/core/res/res/values-mcc302-mnc370-es-rUS/strings.xml new file mode 100644 index 000000000000..5ba6413304a6 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-es-rUS/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi de %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-es/strings.xml b/core/res/res/values-mcc302-mnc370-es/strings.xml new file mode 100644 index 000000000000..5ba6413304a6 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-es/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi de %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-et/strings.xml b/core/res/res/values-mcc302-mnc370-et/strings.xml new file mode 100644 index 000000000000..648544d81555 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-et/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s WiFi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-eu/strings.xml b/core/res/res/values-mcc302-mnc370-eu/strings.xml new file mode 100644 index 000000000000..960e1e563b07 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-eu/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi sarea"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-fa/strings.xml b/core/res/res/values-mcc302-mnc370-fa/strings.xml new file mode 100644 index 000000000000..74d4f17ce643 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-fa/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-fi/strings.xml b/core/res/res/values-mcc302-mnc370-fi/strings.xml new file mode 100644 index 000000000000..74d4f17ce643 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-fi/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-fr-rCA/strings.xml b/core/res/res/values-mcc302-mnc370-fr-rCA/strings.xml new file mode 100644 index 000000000000..5ba6413304a6 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-fr-rCA/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi de %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-fr/strings.xml b/core/res/res/values-mcc302-mnc370-fr/strings.xml new file mode 100644 index 000000000000..74d4f17ce643 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-fr/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-gl/strings.xml b/core/res/res/values-mcc302-mnc370-gl/strings.xml new file mode 100644 index 000000000000..b64447160530 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-gl/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wifi de %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-gu/strings.xml b/core/res/res/values-mcc302-mnc370-gu/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-gu/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-hi/strings.xml b/core/res/res/values-mcc302-mnc370-hi/strings.xml new file mode 100644 index 000000000000..3521dd408d6e --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-hi/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s वाई-फ़ाई"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-hr/strings.xml b/core/res/res/values-mcc302-mnc370-hr/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-hr/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-hu/strings.xml b/core/res/res/values-mcc302-mnc370-hu/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-hu/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-hy/strings.xml b/core/res/res/values-mcc302-mnc370-hy/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-hy/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-in/strings.xml b/core/res/res/values-mcc302-mnc370-in/strings.xml new file mode 100644 index 000000000000..74d4f17ce643 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-in/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-is/strings.xml b/core/res/res/values-mcc302-mnc370-is/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-is/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-it/strings.xml b/core/res/res/values-mcc302-mnc370-it/strings.xml new file mode 100644 index 000000000000..74d4f17ce643 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-it/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-iw/strings.xml b/core/res/res/values-mcc302-mnc370-iw/strings.xml new file mode 100644 index 000000000000..90b73ad4518b --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-iw/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-ja/strings.xml b/core/res/res/values-mcc302-mnc370-ja/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-ja/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-ka/strings.xml b/core/res/res/values-mcc302-mnc370-ka/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-ka/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-kk/strings.xml b/core/res/res/values-mcc302-mnc370-kk/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-kk/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-km/strings.xml b/core/res/res/values-mcc302-mnc370-km/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-km/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-kn/strings.xml b/core/res/res/values-mcc302-mnc370-kn/strings.xml new file mode 100644 index 000000000000..636eb01d3eb0 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-kn/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s ವೈ-ಫೈ"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-ko/strings.xml b/core/res/res/values-mcc302-mnc370-ko/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-ko/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-ky/strings.xml b/core/res/res/values-mcc302-mnc370-ky/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-ky/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-lo/strings.xml b/core/res/res/values-mcc302-mnc370-lo/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-lo/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-lt/strings.xml b/core/res/res/values-mcc302-mnc370-lt/strings.xml new file mode 100644 index 000000000000..95746fb21691 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-lt/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"„%s“ „Wi-Fi“"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-lv/strings.xml b/core/res/res/values-mcc302-mnc370-lv/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-lv/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-mk/strings.xml b/core/res/res/values-mcc302-mnc370-mk/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-mk/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-ml/strings.xml b/core/res/res/values-mcc302-mnc370-ml/strings.xml new file mode 100644 index 000000000000..810b72ccea3a --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-ml/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s വൈഫൈ"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-mn/strings.xml b/core/res/res/values-mcc302-mnc370-mn/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-mn/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-mr/strings.xml b/core/res/res/values-mcc302-mnc370-mr/strings.xml new file mode 100644 index 000000000000..4b033335bb48 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-mr/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s वाय-फाय"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-ms/strings.xml b/core/res/res/values-mcc302-mnc370-ms/strings.xml new file mode 100644 index 000000000000..74d4f17ce643 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-ms/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-my/strings.xml b/core/res/res/values-mcc302-mnc370-my/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-my/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-nb/strings.xml b/core/res/res/values-mcc302-mnc370-nb/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-nb/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-ne/strings.xml b/core/res/res/values-mcc302-mnc370-ne/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-ne/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-nl/strings.xml b/core/res/res/values-mcc302-mnc370-nl/strings.xml new file mode 100644 index 000000000000..036633506e93 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-nl/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wifi via %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-pa/strings.xml b/core/res/res/values-mcc302-mnc370-pa/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-pa/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-pl/strings.xml b/core/res/res/values-mcc302-mnc370-pl/strings.xml new file mode 100644 index 000000000000..f359c0300628 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-pl/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi – %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-pt-rBR/strings.xml b/core/res/res/values-mcc302-mnc370-pt-rBR/strings.xml new file mode 100644 index 000000000000..74d4f17ce643 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-pt-rBR/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-pt-rPT/strings.xml b/core/res/res/values-mcc302-mnc370-pt-rPT/strings.xml new file mode 100644 index 000000000000..74d4f17ce643 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-pt-rPT/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-pt/strings.xml b/core/res/res/values-mcc302-mnc370-pt/strings.xml new file mode 100644 index 000000000000..74d4f17ce643 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-pt/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-ro/strings.xml b/core/res/res/values-mcc302-mnc370-ro/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-ro/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-ru/strings.xml b/core/res/res/values-mcc302-mnc370-ru/strings.xml new file mode 100644 index 000000000000..5fdf802c9883 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-ru/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Сеть Wi-Fi \"%s\""</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-si/strings.xml b/core/res/res/values-mcc302-mnc370-si/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-si/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-sk/strings.xml b/core/res/res/values-mcc302-mnc370-sk/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-sk/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-sl/strings.xml b/core/res/res/values-mcc302-mnc370-sl/strings.xml new file mode 100644 index 000000000000..74d4f17ce643 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-sl/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-sq/strings.xml b/core/res/res/values-mcc302-mnc370-sq/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-sq/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-sr/strings.xml b/core/res/res/values-mcc302-mnc370-sr/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-sr/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-sv/strings.xml b/core/res/res/values-mcc302-mnc370-sv/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-sv/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-sw/strings.xml b/core/res/res/values-mcc302-mnc370-sw/strings.xml new file mode 100644 index 000000000000..8c1c88798030 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-sw/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi ya %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-ta/strings.xml b/core/res/res/values-mcc302-mnc370-ta/strings.xml new file mode 100644 index 000000000000..58075938c1da --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-ta/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s வைஃபை"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-te/strings.xml b/core/res/res/values-mcc302-mnc370-te/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-te/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-th/strings.xml b/core/res/res/values-mcc302-mnc370-th/strings.xml new file mode 100644 index 000000000000..fa5ff47fb62f --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-th/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi ของ %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-tl/strings.xml b/core/res/res/values-mcc302-mnc370-tl/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-tl/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-tr/strings.xml b/core/res/res/values-mcc302-mnc370-tr/strings.xml new file mode 100644 index 000000000000..2f9ff047c700 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-tr/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s kablosuz"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-uk/strings.xml b/core/res/res/values-mcc302-mnc370-uk/strings.xml new file mode 100644 index 000000000000..74d4f17ce643 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-uk/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-ur/strings.xml b/core/res/res/values-mcc302-mnc370-ur/strings.xml new file mode 100644 index 000000000000..81d28880fd84 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-ur/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-uz/strings.xml b/core/res/res/values-mcc302-mnc370-uz/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-uz/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-vi/strings.xml b/core/res/res/values-mcc302-mnc370-vi/strings.xml new file mode 100644 index 000000000000..74d4f17ce643 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-vi/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-zh-rCN/strings.xml b/core/res/res/values-mcc302-mnc370-zh-rCN/strings.xml new file mode 100644 index 000000000000..a89f6a288197 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-zh-rCN/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s WLAN"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-zh-rHK/strings.xml b/core/res/res/values-mcc302-mnc370-zh-rHK/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-zh-rHK/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-zh-rTW/strings.xml b/core/res/res/values-mcc302-mnc370-zh-rTW/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-zh-rTW/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc370-zu/strings.xml b/core/res/res/values-mcc302-mnc370-zu/strings.xml new file mode 100644 index 000000000000..b93949e190c7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc370-zu/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="5022384999749536798">"%s"</item> + <item msgid="8117276330682171665">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-af/strings.xml b/core/res/res/values-mcc302-mnc720-af/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-af/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-am/strings.xml b/core/res/res/values-mcc302-mnc720-am/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-am/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-ar/strings.xml b/core/res/res/values-mcc302-mnc720-ar/strings.xml new file mode 100644 index 000000000000..869678fdbf4a --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-ar/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s مع Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-az/strings.xml b/core/res/res/values-mcc302-mnc720-az/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-az/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-b+sr+Latn/strings.xml b/core/res/res/values-mcc302-mnc720-b+sr+Latn/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-b+sr+Latn/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-be/strings.xml b/core/res/res/values-mcc302-mnc720-be/strings.xml new file mode 100644 index 000000000000..20e4f47ad6e1 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-be/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-bg/strings.xml b/core/res/res/values-mcc302-mnc720-bg/strings.xml new file mode 100644 index 000000000000..890f19b4dd90 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-bg/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi от %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-bn/strings.xml b/core/res/res/values-mcc302-mnc720-bn/strings.xml new file mode 100644 index 000000000000..543ec7aeed8f --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-bn/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s ওয়াই-ফাই"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-bs/strings.xml b/core/res/res/values-mcc302-mnc720-bs/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-bs/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-ca/strings.xml b/core/res/res/values-mcc302-mnc720-ca/strings.xml new file mode 100644 index 000000000000..20e4f47ad6e1 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-ca/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-cs/strings.xml b/core/res/res/values-mcc302-mnc720-cs/strings.xml new file mode 100644 index 000000000000..20e4f47ad6e1 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-cs/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-da/strings.xml b/core/res/res/values-mcc302-mnc720-da/strings.xml new file mode 100644 index 000000000000..483dee583459 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-da/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi fra %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-de/strings.xml b/core/res/res/values-mcc302-mnc720-de/strings.xml new file mode 100644 index 000000000000..825fa0087cd8 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-de/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"WLAN: %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-el/strings.xml b/core/res/res/values-mcc302-mnc720-el/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-el/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-en-rAU/strings.xml b/core/res/res/values-mcc302-mnc720-en-rAU/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-en-rAU/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-en-rGB/strings.xml b/core/res/res/values-mcc302-mnc720-en-rGB/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-en-rGB/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-en-rIN/strings.xml b/core/res/res/values-mcc302-mnc720-en-rIN/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-en-rIN/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-es-rUS/strings.xml b/core/res/res/values-mcc302-mnc720-es-rUS/strings.xml new file mode 100644 index 000000000000..c8c4c5eaeace --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-es-rUS/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi de %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-es/strings.xml b/core/res/res/values-mcc302-mnc720-es/strings.xml new file mode 100644 index 000000000000..c8c4c5eaeace --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-es/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi de %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-et/strings.xml b/core/res/res/values-mcc302-mnc720-et/strings.xml new file mode 100644 index 000000000000..3e5a7efaf7d5 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-et/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s WiFi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-eu/strings.xml b/core/res/res/values-mcc302-mnc720-eu/strings.xml new file mode 100644 index 000000000000..802df65c5348 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-eu/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi sarea"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-fa/strings.xml b/core/res/res/values-mcc302-mnc720-fa/strings.xml new file mode 100644 index 000000000000..20e4f47ad6e1 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-fa/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-fi/strings.xml b/core/res/res/values-mcc302-mnc720-fi/strings.xml new file mode 100644 index 000000000000..20e4f47ad6e1 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-fi/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-fr-rCA/strings.xml b/core/res/res/values-mcc302-mnc720-fr-rCA/strings.xml new file mode 100644 index 000000000000..c8c4c5eaeace --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-fr-rCA/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi de %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-fr/strings.xml b/core/res/res/values-mcc302-mnc720-fr/strings.xml new file mode 100644 index 000000000000..20e4f47ad6e1 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-fr/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-gl/strings.xml b/core/res/res/values-mcc302-mnc720-gl/strings.xml new file mode 100644 index 000000000000..d3a9055d8a09 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-gl/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wifi de %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-gu/strings.xml b/core/res/res/values-mcc302-mnc720-gu/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-gu/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-hi/strings.xml b/core/res/res/values-mcc302-mnc720-hi/strings.xml new file mode 100644 index 000000000000..9a10eed9a140 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-hi/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s वाई-फ़ाई"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-hr/strings.xml b/core/res/res/values-mcc302-mnc720-hr/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-hr/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-hu/strings.xml b/core/res/res/values-mcc302-mnc720-hu/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-hu/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-hy/strings.xml b/core/res/res/values-mcc302-mnc720-hy/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-hy/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-in/strings.xml b/core/res/res/values-mcc302-mnc720-in/strings.xml new file mode 100644 index 000000000000..20e4f47ad6e1 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-in/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-is/strings.xml b/core/res/res/values-mcc302-mnc720-is/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-is/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-it/strings.xml b/core/res/res/values-mcc302-mnc720-it/strings.xml new file mode 100644 index 000000000000..20e4f47ad6e1 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-it/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-iw/strings.xml b/core/res/res/values-mcc302-mnc720-iw/strings.xml new file mode 100644 index 000000000000..d0a799f8e379 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-iw/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-ja/strings.xml b/core/res/res/values-mcc302-mnc720-ja/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-ja/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-ka/strings.xml b/core/res/res/values-mcc302-mnc720-ka/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-ka/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-kk/strings.xml b/core/res/res/values-mcc302-mnc720-kk/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-kk/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-km/strings.xml b/core/res/res/values-mcc302-mnc720-km/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-km/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-kn/strings.xml b/core/res/res/values-mcc302-mnc720-kn/strings.xml new file mode 100644 index 000000000000..6438ffb536ba --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-kn/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s ವೈ-ಫೈ"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-ko/strings.xml b/core/res/res/values-mcc302-mnc720-ko/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-ko/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-ky/strings.xml b/core/res/res/values-mcc302-mnc720-ky/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-ky/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-lo/strings.xml b/core/res/res/values-mcc302-mnc720-lo/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-lo/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-lt/strings.xml b/core/res/res/values-mcc302-mnc720-lt/strings.xml new file mode 100644 index 000000000000..2d3b87a58034 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-lt/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"„%s“ „Wi-Fi“"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-lv/strings.xml b/core/res/res/values-mcc302-mnc720-lv/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-lv/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-mk/strings.xml b/core/res/res/values-mcc302-mnc720-mk/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-mk/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-ml/strings.xml b/core/res/res/values-mcc302-mnc720-ml/strings.xml new file mode 100644 index 000000000000..325b5db249e7 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-ml/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s വൈഫൈ"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-mn/strings.xml b/core/res/res/values-mcc302-mnc720-mn/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-mn/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-mr/strings.xml b/core/res/res/values-mcc302-mnc720-mr/strings.xml new file mode 100644 index 000000000000..9708843f5413 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-mr/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s वाय-फाय"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-ms/strings.xml b/core/res/res/values-mcc302-mnc720-ms/strings.xml new file mode 100644 index 000000000000..20e4f47ad6e1 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-ms/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-my/strings.xml b/core/res/res/values-mcc302-mnc720-my/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-my/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-nb/strings.xml b/core/res/res/values-mcc302-mnc720-nb/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-nb/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-ne/strings.xml b/core/res/res/values-mcc302-mnc720-ne/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-ne/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-nl/strings.xml b/core/res/res/values-mcc302-mnc720-nl/strings.xml new file mode 100644 index 000000000000..4c5caddb9dcd --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-nl/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wifi via %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-pa/strings.xml b/core/res/res/values-mcc302-mnc720-pa/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-pa/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-pl/strings.xml b/core/res/res/values-mcc302-mnc720-pl/strings.xml new file mode 100644 index 000000000000..4e78857d94bc --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-pl/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi – %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-pt-rBR/strings.xml b/core/res/res/values-mcc302-mnc720-pt-rBR/strings.xml new file mode 100644 index 000000000000..20e4f47ad6e1 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-pt-rBR/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-pt-rPT/strings.xml b/core/res/res/values-mcc302-mnc720-pt-rPT/strings.xml new file mode 100644 index 000000000000..20e4f47ad6e1 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-pt-rPT/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-pt/strings.xml b/core/res/res/values-mcc302-mnc720-pt/strings.xml new file mode 100644 index 000000000000..20e4f47ad6e1 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-pt/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-ro/strings.xml b/core/res/res/values-mcc302-mnc720-ro/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-ro/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-ru/strings.xml b/core/res/res/values-mcc302-mnc720-ru/strings.xml new file mode 100644 index 000000000000..b88013beef37 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-ru/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Сеть Wi-Fi \"%s\""</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-si/strings.xml b/core/res/res/values-mcc302-mnc720-si/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-si/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-sk/strings.xml b/core/res/res/values-mcc302-mnc720-sk/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-sk/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-sl/strings.xml b/core/res/res/values-mcc302-mnc720-sl/strings.xml new file mode 100644 index 000000000000..20e4f47ad6e1 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-sl/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-sq/strings.xml b/core/res/res/values-mcc302-mnc720-sq/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-sq/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-sr/strings.xml b/core/res/res/values-mcc302-mnc720-sr/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-sr/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-sv/strings.xml b/core/res/res/values-mcc302-mnc720-sv/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-sv/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-sw/strings.xml b/core/res/res/values-mcc302-mnc720-sw/strings.xml new file mode 100644 index 000000000000..ee780df78ca5 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-sw/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi ya %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-ta/strings.xml b/core/res/res/values-mcc302-mnc720-ta/strings.xml new file mode 100644 index 000000000000..61c8b84800cc --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-ta/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s வைஃபை"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-te/strings.xml b/core/res/res/values-mcc302-mnc720-te/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-te/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-th/strings.xml b/core/res/res/values-mcc302-mnc720-th/strings.xml new file mode 100644 index 000000000000..d536f4510138 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-th/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi ของ %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-tl/strings.xml b/core/res/res/values-mcc302-mnc720-tl/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-tl/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-tr/strings.xml b/core/res/res/values-mcc302-mnc720-tr/strings.xml new file mode 100644 index 000000000000..e41287af104b --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-tr/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s kablosuz"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-uk/strings.xml b/core/res/res/values-mcc302-mnc720-uk/strings.xml new file mode 100644 index 000000000000..20e4f47ad6e1 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-uk/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-ur/strings.xml b/core/res/res/values-mcc302-mnc720-ur/strings.xml new file mode 100644 index 000000000000..566f852435e2 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-ur/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-uz/strings.xml b/core/res/res/values-mcc302-mnc720-uz/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-uz/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-vi/strings.xml b/core/res/res/values-mcc302-mnc720-vi/strings.xml new file mode 100644 index 000000000000..20e4f47ad6e1 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-vi/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"Wi-Fi %s"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-zh-rCN/strings.xml b/core/res/res/values-mcc302-mnc720-zh-rCN/strings.xml new file mode 100644 index 000000000000..c5526b24cb94 --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-zh-rCN/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s WLAN"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-zh-rHK/strings.xml b/core/res/res/values-mcc302-mnc720-zh-rHK/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-zh-rHK/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-zh-rTW/strings.xml b/core/res/res/values-mcc302-mnc720-zh-rTW/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-zh-rTW/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc302-mnc720-zu/strings.xml b/core/res/res/values-mcc302-mnc720-zu/strings.xml new file mode 100644 index 000000000000..9b2336d8006d --- /dev/null +++ b/core/res/res/values-mcc302-mnc720-zu/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcSpnFormats"> + <item msgid="2776657861851140021">"%s"</item> + <item msgid="5094669985484060934">"%s Wi-Fi"</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc404/config.xml b/core/res/res/values-mcc404/config.xml index 17539d81fa65..d6655f2361d4 100644 --- a/core/res/res/values-mcc404/config.xml +++ b/core/res/res/values-mcc404/config.xml @@ -25,4 +25,6 @@ </string-array> <!-- Whether camera shutter sound is forced or not (country specific). --> <bool name="config_camera_sound_forced">true</bool> + <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app --> + <bool name="config_showAreaUpdateInfoSettings">true</bool> </resources> diff --git a/core/res/res/values-mcc724/config.xml b/core/res/res/values-mcc724/config.xml new file mode 100644 index 000000000000..98f70d5441d2 --- /dev/null +++ b/core/res/res/values-mcc724/config.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app --> + <bool name="config_showAreaUpdateInfoSettings">true</bool> +</resources> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 4e9f7ce1ee51..599eabc748a5 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Пребарување за услуга"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Повикување преку Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"За повикување и испраќање пораки преку Wi-Fi, прво побарајте од операторот да ви ја постави оваа услуга. Потоа повторно вклучете повикување преку Wi-Fi во Поставки."</item> + <item msgid="3910386316304772394">"За да воспоставувате повици и да испраќате пораки преку Wi-Fi, прво побарајте од операторот да ја постави услугава. Потоа, вклучете ја повторно „Повикување преку Wi-Fi“ во „Поставки“. (Код за грешка: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Регистрирајте се со операторот"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">Отворени Wi-Fi мрежи се достапни</item> <item quantity="other">Отворени Wi-Fi мрежи се достапни</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Поврзете се на отворена Wi‑Fi-мрежа"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Поврзување на отворена Wi‑Fi-мрежа"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Се поврзавте на Wi‑Fi-мрежа"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не можеше да се поврзе на Wi‑Fi-мрежа"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Допрете за да ги видите сите мрежи"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Поврзете се"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Сите мрежи"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Најавете се на мрежа на Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Најавете се на мрежа"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index bbeb71b61035..418392c5ea9d 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"സേവനത്തിനായി തിരയുന്നു"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"വൈഫൈ കോളിംഗ്"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"വൈഫൈ വഴി കോളുകൾ വിളിക്കാനും സന്ദേശങ്ങൾ അയയ്ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക."</item> + <item msgid="3910386316304772394">"വൈഫൈ വഴി കോളുകൾ ചെയ്യാനും സന്ദേശങ്ങൾ അയയ്ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക. (പിശക് കോഡ്: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"നിങ്ങളുടെ കാരിയറിൽ രജിസ്റ്റർ ചെയ്യുക"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">ലഭ്യമായ വൈഫൈ നെറ്റ്വർക്കുകൾ തുറക്കുക</item> <item quantity="one">ലഭ്യമായ വൈഫൈ നെറ്റ്വർക്ക് തുറക്കുക</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"ലഭ്യമായ വൈഫൈ നെറ്റ്വർക്കിലേക്ക് കണക്റ്റുചെയ്യുക"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ലഭ്യമായ വൈഫൈ നെറ്റ്വർക്കിലേക്ക് കണക്റ്റുചെയ്യുന്നു"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"വൈഫൈ നെറ്റ്വർക്കിലേക്ക് കണക്റ്റുചെയ്തു"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"വൈ-ഫൈ നെറ്റ്വർക്കിലേക്ക് കണക്റ്റുചെയ്യാനായില്ല"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"എല്ലാ നെറ്റ്വർക്കുകളും കാണാൻ ടാപ്പുചെയ്യുക"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"കണക്റ്റുചെയ്യുക"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"എല്ലാ നെറ്റ്വർക്കുകളും"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"വൈഫൈ നെറ്റ്വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"നെറ്റ്വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index dec7746ca495..4a8698a234ec 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Үйлчилгээг хайж байна…"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi-аар дуудлага хийх болон мессеж илгээхээр бол эхлээд оператороосоо энэ төхөөрөмжийг тохируулж өгөхийг хүсээрэй. Дараа нь Тохиргооноос Wi-Fi дуудлага хийх үйлдлийг асаагаарай."</item> + <item msgid="3910386316304772394">"Wi-Fi-аар дуудлага хийх, мессеж илгээх бол эхлээд оператор компаниасаа энэ үйлчилгээг тохируулж өгөхийг хүснэ үү. Дараа нь Тохиргооноос Wi-Fi дуудлага хийх үйлдлийг асаана уу. (Алдааны код: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Операторт бүртгүүлэх"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Нээлттэй Wi-Fi сүлжээ ашиглах боломжтой</item> <item quantity="one">Нээлттэй Wi-Fi сүлжээ ашиглах боломжтой</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Нээлттэй Wi‑Fi сүлжээнд холбогдох"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Нээлттэй Wi‑Fi сүлжээнд холбогдож байна"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi сүлжээнд холбогдлоо"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi сүлжээнд холбогдож чадсангүй"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Бүх сүлжээг харахын тулд товшино уу"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Холбогдох"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Бүх сүлжээ"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi сүлжээнд нэвтэрнэ үү"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Сүлжээнд нэвтэрнэ үү"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 99c4391d4004..849f14d8cc7c 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"सेवा शोधत आहे"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"वाय-फाय कॉलिंग"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठविण्यासाठी, प्रथम आपल्या वाहकास ही सेवा सेट करण्यास सांगा. नंतर सेटिंग्जमधून पुन्हा वाय-फाय कॉलिंग चालू करा."</item> + <item msgid="3910386316304772394">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठवण्यासाठी आधी तुमच्या कॅरियरला ही सेवा सेट अप करण्यास सांगा. नंतर सेटिंग्जमधून वाय-फाय वापरून कॉल करणे पुन्हा चालू करा. (एरर कोड <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"आपल्या वाहकासह नोंदणी करा"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">खुले वाय-फाय नेटवर्क उपलब्ध</item> <item quantity="other">खुले वाय-फाय नेटवर्क उपलब्ध</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"खुल्या वाय-फाय नेटवर्कशी कनेक्ट करा"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"खुल्या वाय-फाय नेटवर्कशी कनेक्ट करत आहे"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"वाय-फाय नेटवर्कशी कनेक्ट केले"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"वाय-फाय नेटवर्कशी कनेक्ट करू शकत नाही"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सर्व नेटवर्क पाहण्यासाठी टॅप करा"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"कनेक्ट करा"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"सर्व नेटवर्क"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"वाय-फाय नेटवर्कमध्ये साइन इन करा"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"नेटवर्कवर साइन इन करा"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 1976bb79c2c6..d400f9624f9a 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Mencari Perkhidmatan"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Panggilan Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, mula-mula minta pembawa anda untuk menyediakan perkhidmatan ini. Kemudian hidupkan panggilan Wi-Fi semula daripada Tetapan."</item> + <item msgid="3910386316304772394">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, minta pembawa anda menyediakan perkhidmatan ini terlebih dahulu. Kemudian, hidupkan panggilan Wi-Fi sekali lagi daripada Tetapan. (Kod ralat: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Daftar dengan pembawa anda"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Rangkaian Wi-Fi terbuka tersedia</item> <item quantity="one">Rangkaian Wi-Fi terbuka tersedia</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Sambung ke rangkaian Wi-Fi terbuka"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Menyambung ke rangkaian Wi‑Fi terbuka"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Disambungkan ke rangkaian Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Tidak dapat menyambung ke rangkaian Wi-Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ketik untuk melihat semua rangkaian"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Sambung"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Semua Rangkaian"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Log masuk ke rangkaian Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Log masuk ke rangkaian"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 0f9fb0cce7e3..a33bec8fe52a 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"ဆားဗစ်အားရှာဖွေနေသည်"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi ခေါ်ဆိုမှု"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi သုံး၍ ဖုန်းခေါ်ဆိုရန်နှင့် မက်ဆေ့ဂျ်များပို့ရန်၊ ဤဝန်ဆောင်မှုအား စတင်သုံးနိုင်ရန်အတွက် သင့် မိုဘိုင်းဝန်ဆောင်မှုအား ဦးစွာမေးမြန်းပါ။ ထို့နောက် ဆက်တင်မှတဆင့် Wi-Fi ခေါ်ဆိုမှုအား ထပ်ဖွင့်ပါ။"</item> + <item msgid="3910386316304772394">"Wi-Fi အသုံးပြု၍ ဖုန်းခေါ်ရန်နှင့် မက်ဆေ့ဂျ်ပို့ရန်အတွက် သင့်ဝန်ဆောင်မှုပေးသူကို ဤဝန်ဆောင်မှုအား သတ်မှတ်ပေးရန် ဦးစွာတောင်းဆိုပါ။ ထို့နောက် ဆက်တင်ထဲသို့ သွား၍ Wi-Fi ဖြင့် ဖုန်းခေါ်ခြင်းကို ဖွင့်ရပါမည်။ (အမှားကုဒ်- <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"သင့် မိုဘိုင်းဝန်ဆောင်မှုဖြင့် မှတ်ပုံတင်ရန်"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Wi-Fi ကွန်ယက်များရရှိနိုင်သည်အား ဖွင့်ပါ</item> <item quantity="one">Wi-Fi ကွန်ယက်ရရှိနိုင်သည်အား ဖွင့်ပါ</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"အများသုံး Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်ပါ"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"အများသုံး Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်နေသည်"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်ပြီးပါပြီ"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi ကွန်ရက်သို့ ချိတ်ဆက်၍ မရပါ"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ကွန်ရက်အားလုံးကို ကြည့်ရန် တို့ပါ"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"ချိတ်ဆက်ရန်"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ကွန်ရက်အားလုံး"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"ဝိုင်ဖိုင်ကွန်ရက်သို့ လက်မှတ်ထိုးဝင်ပါ"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"ကွန်ယက်သို့ လက်မှတ်ထိုးဝင်ရန်"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index cc3ecb9771ca..f38c260b9370 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Leter etter tjeneste"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-anrop"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"For å ringe og sende meldinger over Wi-Fi må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger."</item> + <item msgid="3910386316304772394">"For å ringe og sende meldinger over Wi-Fi må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger. (Feilkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registrer deg hos operatøren din"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Åpne Wi-Fi-nettverk er tilgjengelig</item> <item quantity="one">Åpent Wi-Fi-nettverk er tilgjengelig</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Koble til et åpent Wi‑Fi-nettverk"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Kobler til åpent Wi-Fi-nettverk"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Koblet til Wi-Fi-nettverk"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kunne ikke koble til Wi-Fi-nettverket"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trykk for å se alle nettverkene"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koble til"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle nettverk"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Logg på Wi-Fi-nettverket"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Logg på nettverk"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 5eddfbf73acb..2098b51d612a 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"सेवाको खोजी गर्दै…"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi कलिङ"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi बाट कल गर्न र सन्देशहरू पठाउन, सबभन्दा पहिला यो सेवा सेटअप गर्न तपाईँको वाहकलाई भन्नुहोस्। त्यसपछि फेरि सेटिङहरूबाट Wi-Fi कलिङ सक्रिय पार्नुहोस्।"</item> + <item msgid="3910386316304772394">"Wi-Fi मार्फत कलहरू गर्न र सन्देशहरू पठाउन सबभन्दा पहिला आफ्नो सेवा प्रदायकलाई यो सेवा सेट गर्न भन्नुहोस्। त्यसपछि सेटिङहरूबाट Wi-Fi कलिङलाई सक्रिय पार्नुहोस्। (त्रुटिसम्बन्धी कोड: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"तपाईँको वाहकसँग दर्ता गर्नुहोस्"</item> @@ -1112,20 +1112,13 @@ <item quantity="other"> खुल्ला Wi-Fi सञ्जालहरू उपलब्ध छन्</item> <item quantity="one">खुल्ला Wi-Fi सञ्जाल उपलब्ध छ</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"खुला Wi‑Fi नेटवर्कमा जडान गर्नुहोस्"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"खुला Wi‑Fi नेटवर्कमा जडान गर्दै"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi नेटवर्कमा जडान गरियो"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi नेटवर्कमा जडान गर्न सकिएन"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सबै नेटवर्कहरू हेर्न ट्याप गर्नुहोस्"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"जडान गर्नुहोस्"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"सबै नेटवर्कहरू"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi नेटवर्कमा साइन इन गर्नुहोस्"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"सञ्जालमा साइन इन गर्नुहोस्"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index b5ba93f3db3a..4d0beecd40ac 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Service zoeken"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Bellen via wifi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via \'Instellingen\'."</item> + <item msgid="3910386316304772394">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via Instellingen. (Foutcode: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registreren bij je provider"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Open wifi-netwerken beschikbaar</item> <item quantity="one">Open wifi-netwerk beschikbaar</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Verbinding maken met een open wifi-netwerk"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Verbinding maken met een open wifi-netwerk…"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Verbonden met een wifi-netwerk"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kan geen verbinding maken met het wifi-netwerk"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerken te bekijken"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Verbinding maken"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alle netwerken"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Inloggen bij wifi-netwerk"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Inloggen bij netwerk"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 5a30637e3148..a89872f0a6ef 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -130,9 +130,7 @@ <string name="roamingText12" msgid="1189071119992726320">"ਰੋਮਿੰਗ ਬੈਨਰ ਬੰਦ"</string> <string name="roamingTextSearching" msgid="8360141885972279963">"ਸੇਵਾ ਦੀ ਖੋਜ ਕਰ ਰਿਹਾ ਹੈ"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi ਕਾਲਿੰਗ"</string> - <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi ਤੇ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਸੁਨੇਹੇ ਭੇਜਣ ਲਈ, ਪਹਿਲਾਂ ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਇਹ ਸੇਵਾ ਸੈਟ ਅਪ ਕਰਨ ਲਈ ਕਹੋ। ਫਿਰ ਸੈਟਿੰਗਾਂ ਵਿੱਚੋਂ Wi-Fi ਕਾਲਿੰਗ ਦੁਬਾਰਾ ਚਾਲੂ ਕਰੋ।"</item> - </string-array> + <!-- no translation found for wfcOperatorErrorAlertMessages:0 (3910386316304772394) --> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਰਜਿਸਟਰ ਕਰੋ"</item> </string-array> @@ -1106,20 +1104,13 @@ <item quantity="one">ਉਪਲਬਧ Wi-Fi ਨੈੱਟਵਰਕ ਖੋਲ੍ਹੋ</item> <item quantity="other">ਉਪਲਬਧ Wi-Fi ਨੈੱਟਵਰਕ ਖੋਲ੍ਹੋ</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"ਖੁੱਲ੍ਹੇ Wi‑Fi ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਹੋਵੋ"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"ਖੁੱਲ੍ਹੇ Wi‑Fi ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ਸਾਰੇ ਨੈੱਟਵਰਕਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"ਕਨੈਕਟ ਕਰੋ"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"ਸਾਰੇ ਨੈੱਟਵਰਕ"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi ਨੈੱਟਵਰਕ ਵਿੱਚ ਸਾਈਨ ਇਨ ਕਰੋ"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"ਨੈੱਟਵਰਕ ਤੇ ਸਾਈਨ ਇਨ ਕਰੋ"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 2d90ebd9d2ba..f3d53872f1d7 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -133,7 +133,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Wyszukiwanie usługi"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Połączenia przez Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach."</item> + <item msgid="3910386316304772394">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach. (Kod błędu: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Zarejestruj u operatora"</item> @@ -1150,20 +1150,13 @@ <item quantity="other">Dostępne są otwarte sieci Wi-Fi</item> <item quantity="one">Dostępna jest otwarta sieć Wi-Fi</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Połącz się z otwartą siecią Wi-Fi"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Łączę się z otwartą siecią Wi-Fi"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Połączono z siecią Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nie udało się połączyć z siecią Wi‑Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Kliknij, by zobaczyć wszystkie sieci"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Połącz"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Wszystkie sieci"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Zaloguj się w sieci Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Zaloguj się do sieci"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index f9561be81c69..6c224429b07b 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Pesquisando serviço"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas por Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item> + <item msgid="3910386316304772394">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois, ative novamente a chamada no Wi-Fi nas configurações. Código de erro: <xliff:g id="CODE">%1$s</xliff:g>"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Faça registro na sua operadora"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">Abrir redes Wi-Fi disponíveis</item> <item quantity="other">Abrir redes Wi-Fi disponíveis</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Conectar-se a uma rede Wi‑Fi aberta"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectando-se a uma rede Wi‑Fi aberta"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectado a uma rede Wi‑Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Não foi possível conectar-se à rede Wi‑Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Fazer login na rede Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Fazer login na rede"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index bee7e673b33f..2d9a6d47583b 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"A procurar Serviço"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar este serviço. Em seguida, nas Definições, ative novamente as chamadas por Wi-Fi."</item> + <item msgid="3910386316304772394">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar este serviço. De seguida, nas Definições, ative novamente as Chamadas Wi-Fi. (Código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registar-se junto do seu operador"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">Open Wi-Fi networks available</item> <item quantity="other">Redes Wi-Fi abertas disponíveis</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Ligar à rede Wi-Fi aberta"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"A ligar à rede Wi-Fi aberta…"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ligado à rede Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Não foi possível ligar à rede Wi-Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ligar"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Iniciar sessão na rede Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Início de sessão na rede"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index f9561be81c69..6c224429b07b 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Pesquisando serviço"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas por Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item> + <item msgid="3910386316304772394">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois, ative novamente a chamada no Wi-Fi nas configurações. Código de erro: <xliff:g id="CODE">%1$s</xliff:g>"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Faça registro na sua operadora"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">Abrir redes Wi-Fi disponíveis</item> <item quantity="other">Abrir redes Wi-Fi disponíveis</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Conectar-se a uma rede Wi‑Fi aberta"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Conectando-se a uma rede Wi‑Fi aberta"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Conectado a uma rede Wi‑Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Não foi possível conectar-se à rede Wi‑Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Todas as redes"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Fazer login na rede Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Fazer login na rede"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 48b112a3d62e..320dfb5acc61 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -132,7 +132,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Se caută serviciul"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Apelare prin Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Pentru a apela și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări."</item> + <item msgid="3910386316304772394">"Pentru a efectua apeluri și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări. (Cod de eroare: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Înregistrați-vă la operatorul dvs."</item> @@ -1128,20 +1128,13 @@ <item quantity="other">Rețele Wi-Fi deschise disponibile</item> <item quantity="one">Rețea Wi-Fi deschisă disponibilă</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Conectați-vă la o rețea Wi‑Fi deschisă"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Se stabilește conexiunea la o rețea Wi‑Fi deschisă"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"S-a realizat conexiunea la rețeaua Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nu s-a putut stabili conexiunea la rețeaua Wi-Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Atingeți pentru a vedea toate rețelele"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectați-vă"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Toate rețelele"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Conectați-vă la rețeaua Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Conectați-vă la rețea"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index d2f0952e1592..f81c8735fef2 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -133,7 +133,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Поиск службы"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Звонки по Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо сначала обратиться к оператору связи и подключить эту услугу. После этого вы сможете снова выбрать этот параметр в настройках."</item> + <item msgid="3910386316304772394">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо подключить эту услугу через оператора связи. После этого вы сможете выбрать этот параметр в настройках. Код ошибки: <xliff:g id="CODE">%1$s</xliff:g>."</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Укажите оператора и зарегистрируйтесь"</item> @@ -1150,20 +1150,13 @@ <item quantity="many">Есть открытые сети Wi-Fi</item> <item quantity="other">Есть открытые сети Wi-Fi</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Подключитесь к открытой сети Wi‑Fi"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Подключение к открытой сети Wi‑Fi…"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Подключено к сети Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не удалось подключиться к сети Wi‑Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Нажмите, чтобы увидеть список сетей"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Подключиться"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Все сети"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Подключение к Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Регистрация в сети"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 821be36ffd4f..3ed2c87d50eb 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"සේවාව සඳහා සොයමින්"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi ඇමතීම"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi හරහා ඇමතුම් සිදු කිරීමට සහ පණිවිඩ යැවීමට, පළමුව මෙම සේවාව පිහිටුවන ලෙස ඔබේ වාහකයෙන් ඉල්ලන්න. අනතුරුව සැකසීම් වෙතින් Wi-Fi ඇමතුම නැවත ක්රියාත්මක කරන්න."</item> + <item msgid="3910386316304772394">"Wi-Fi හරහා ඇමතුම් සිදු කිරීමට සහ පණිවිඩ යැවීමට, පළමුව මෙම සේවාව පිහිටුවන ලෙස ඔබේ වාහකයෙන් ඉල්ලන්න. අනතුරුව සැකසීම් වෙතින් Wi-Fi ඇමතුම නැවත ක්රියාත්මක කරන්න. (දෝෂ කේතය <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"ඔබගේ වාහකය සමඟ ලියාපදිංචි වන්න"</item> @@ -1108,20 +1108,13 @@ <item quantity="one">විවෘත Wi-Fi ජාල තිබේ</item> <item quantity="other">විවෘත Wi-Fi ජාල තිබේ</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"විවෘත Wi-Fi ජාලය වෙත සම්බන්ධ වෙන්න"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"විවෘත Wi-Fi ජාලය වෙත සම්බන්ධ වෙමින්"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi-Fi ජාලයක් වෙත සම්බන්ධ විය"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi-Fi ජාලයක් වෙත සම්බන්ධ විය නොහැකි විය"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"සියලු ජාල බැලීමට තට්ටු කරන්න"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"සම්බන්ධ කරන්න"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"සියලු ජාල"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi ජාලයට පුරනය වන්න"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"ජාලයට පුරනය වන්න"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 0ad0721e62da..e0767ce5ab3a 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -133,7 +133,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Vyhľadávanie služby"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Volanie cez Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Ak chcete volať a odosielať správy prostredníctvom siete Wi-Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi-Fi."</item> + <item msgid="3910386316304772394">"Ak chcete volať a odosielať správy prostredníctvom siete Wi-Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi-Fi. (Kód chyby: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registrujte sa so svojím operátorom"</item> @@ -1150,20 +1150,13 @@ <item quantity="other">K dispozícii sú verejné siete Wi-Fi</item> <item quantity="one">K dispozícii je verejná sieť Wi-Fi</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Pripojenie k otvorenej sieti Wi-Fi"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Pripája sa k otvorenej sieti Wi-Fi"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Pripojenie k sieti Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"K sieti Wi‑Fi sa nepodarilo pripojiť"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Klepnutím zobrazíte všetky siete"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Pripojiť"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Všetky siete"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prihlásiť sa do siete Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Prihlásenie do siete"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index c6bbd315289e..9f0d64634ff5 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -133,7 +133,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Iskanje storitve"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Klicanje prek Wi-Fi-ja"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi."</item> + <item msgid="3910386316304772394">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi. (Koda napake: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registracija pri operaterju"</item> @@ -286,7 +286,7 @@ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"dostop do koledarja"</string> <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string> <string name="permgroupdesc_sms" msgid="4656988620100940350">"pošiljanje in ogled sporočil SMS"</string> - <string name="permgrouplab_storage" msgid="1971118770546336966">"Prostor za shranjevanje"</string> + <string name="permgrouplab_storage" msgid="1971118770546336966">"Shramba"</string> <string name="permgroupdesc_storage" msgid="637758554581589203">"dostop do fotografij, predstavnosti in datotek v napravi"</string> <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string> <string name="permgroupdesc_microphone" msgid="4988812113943554584">"snemanje zvoka"</string> @@ -1150,20 +1150,13 @@ <item quantity="few">Na voljo so odprta omrežja Wi-Fi</item> <item quantity="other">Na voljo so odprta omrežja Wi-Fi</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Vzpostavite povezavo z odprtim omrežjem Wi‑Fi"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Vzpostavljanje povezave z odprtim omrežjem Wi‑Fi"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Povezava z omrežjem Wi-Fi je vzpostavljena"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Povezave z omrežjem Wi-Fi ni bilo mogoče vzpostaviti"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dotaknite se, če si želite ogledati vsa omrežja"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Vzpostavi povezavo"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Vsa omrežja"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavite se v omrežje Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava v omrežje"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index bac599083221..68a3642dbf7b 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Po kërkon për shërbim"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Telefonatë me Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Për të bërë telefonata dhe për të dërguar mesazhe me Wi-Fi, në fillim kërkoji operatorit celular ta konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi, nga Cilësimet."</item> + <item msgid="3910386316304772394">"Për të bërë telefonata dhe për të dërguar mesazhe nëpërmjet Wi-Fi, në fillim kërkoji operatorit celular të konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi nga \"Cilësimet\". (Kodi i gabimit: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Regjistrohu me operatorin tënd celular"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Rrjete të hapura Wi-Fi në përdorim</item> <item quantity="one">Rrjet i hapur Wi-Fi në përdorim</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Lidhu me rrjetin e hapur Wi‑Fi"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Po lidhet me rrjetin e hapur Wi‑Fi"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Lidhur me rrjetin e hapur Wi‑Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Nuk mund të lidhet me rrjetin Wi‑Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trokit për të parë të gjitha rrjetet"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Lidhu"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Të gjitha rrjetet"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Identifikohu në rrjetin Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Identifikohu në rrjet"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 960ee8581904..88fb1f2aba57 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -132,7 +132,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Претраживање услуге"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Позивање преко Wi-Fi-ја"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја."</item> + <item msgid="3910386316304772394">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја. (кôд грешке: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Региструјте се код мобилног оператера"</item> @@ -1128,20 +1128,13 @@ <item quantity="few">Отворене Wi-Fi мреже су доступне</item> <item quantity="other">Отворене Wi-Fi мреже су доступне</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Повежите се са отвореном Wi‑Fi мрежом"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Повезујете се са отвореном Wi‑Fi мрежом"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Повезали сте се са Wi‑Fi мрежом"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Повезивање са Wi‑Fi мрежом није успело"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Додирните да бисте видели све мреже"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Повежи"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Све мреже"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Пријављивање на Wi-Fi мрежу"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Пријавите се на мрежу"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 7e1b65584617..6075f72cfddb 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Söker efter tjänst"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi-samtal"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar."</item> + <item msgid="3910386316304772394">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar. (Felkod: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Registrera dig hos operatören"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Öppna Wi-Fi-nätverk är tillgängliga</item> <item quantity="one">Öppet Wi-Fi-nätverk är tillgängligt</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Anslut till ett öppet Wi-Fi-nätverk"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ansluter till ett öppet Wi-Fi-nätverk"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Ansluten till Wi-Fi-nätverket"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Det gick inte att ansluta till Wi‑Fi-nätverket"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryck för att visa alla nätverk"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Anslut"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Alla nätverk"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Logga in på ett Wi-Fi-nätverk"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Logga in på nätverket"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 3e626d896046..673f335a1507 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Inatafuta Huduma"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Upigaji Simu kwa Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako asanidi huduma hii kwanza. Kisha uwashe tena upigaji simu kwa Wi-Fi kutoka kwenye Mipangilio."</item> + <item msgid="3910386316304772394">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako aweke mipangilio ya huduma hii kwanza. Kisha uwashe tena kipengele cha kupiga simu kupitia Wi-Fi kwenye Mipangilio. (Msimbo wa hitilafu: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Jisajili na mtoa huduma wako"</item> @@ -1104,20 +1104,13 @@ <item quantity="other">Fungua mitandao ya Wi-Fi inayopatikana</item> <item quantity="one">Fungua mtandao wa Wi-Fi unaopatikana</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Unganisha kwenye mtandao wa Wi‑Fi unaotumiwa na mtu yeyote"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Inaunganisha kwenye mtandao wa Wi‑Fi unaotumiwa na mtu yeyote"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Imeunganisha kwenye mtandao wa Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Imeshindwa kuunganisha kwenye mtandao wa Wi‑Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Gonga ili uone mitandao yote"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Unganisha"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Mitandao Yote"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Ingia kwa mtandao wa Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Ingia katika mtandao"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 588e05711922..bb9e85f8b186 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"சேவையைத் தேடுகிறது"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"வைஃபை அழைப்பு"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"வைஃபை மூலம் அழைக்க மற்றும் செய்திகள் அனுப்ப, முதலில் மொபைல் நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும்."</item> + <item msgid="3910386316304772394">"வைஃபை மூலம் அழைக்கவும் செய்திகளை அனுப்பவும், முதலில் தொலைத்தொடர்பு நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும். (பிழைக் குறியீடு <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"உங்கள் மொபைல் நிறுவனத்தில் பதிவுசெய்யவும்"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">பொது வைஃபை நெட்வொர்க்குகள் உள்ளன</item> <item quantity="one">பொது வைஃபை நெட்வொர்க் உள்ளது</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"திறந்த வைஃபை நெட்வொர்க்குடன் இணைக்கவும்"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"திறந்த வைஃபை நெட்வொர்க்குடன் இணைக்கிறது"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"வைஃபை நெட்வொர்க்குடன் இணைக்கப்பட்டது"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"வைஃபை நெட்வொர்க்குடன் இணைக்க முடியவில்லை"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"எல்லா நெட்வொர்க்குகளையும் பார்க்க, தட்டவும்"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"இணை"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"எல்லா நெட்வொர்க்குகளும்"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"வைஃபை நெட்வொர்க்கில் உள்நுழையவும்"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"நெட்வொர்க்கில் உள்நுழையவும்"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 099eb9cd9799..0d5e69f22b59 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"సేవ కోసం శోధిస్తోంది"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi కాలింగ్"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fiలో కాల్లు చేయడం మరియు సందేశాలు పంపడం కోసం ముందుగా ఈ సేవను సెటప్ చేయడానికి మీ క్యారియర్ను అడగండి. ఆపై సెట్టింగ్ల నుండి మళ్లీ Wi-Fi కాలింగ్ను ఆన్ చేయండి."</item> + <item msgid="3910386316304772394">"Wi-Fiతో కాల్లను చేయడానికి మరియు సందేశాలను పంపించడానికి, మొదట ఈ సేవను సెటప్ చేయాల్సిందిగా మీ క్యారియర్కి చెప్పండి. ఆ తర్వాత సెట్టింగ్ల నుండి Wi-Fi కాలింగ్ని మళ్లీ ఆన్ చేయండి. (లోపం కోడ్: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"మీ క్యారియర్తో నమోదు చేయండి"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">ఓపెన్ Wi-Fi నెట్వర్క్లు అందుబాటులో ఉన్నాయి</item> <item quantity="one">ఓపెన్ Wi-Fi నెట్వర్క్ అందుబాటులో ఉంది</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"బహిరంగ Wi‑Fi నెట్వర్క్కు కనెక్ట్ చేయండి"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"బహిరంగ Wi‑Fi నెట్వర్క్కు కనెక్ట్ చేస్తోంది"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi నెట్వర్క్కు కనెక్ట్ చేయబడింది"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi నెట్వర్క్కు కనెక్ట్ చేయడం సాధ్యపడలేదు"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"అన్ని నెట్వర్క్లు చూడటానికి నొక్కండి"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"కనెక్ట్ చేయి"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"అన్ని నెట్వర్క్లు"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi నెట్వర్క్కి సైన్ ఇన్ చేయండి"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"నెట్వర్క్కి సైన్ ఇన్ చేయండి"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index e6f439f6d4fc..463db4e535a3 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"กำลังค้นหาบริการ"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"การโทรผ่าน Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"หากต้องการโทรออกและส่งข้อความผ่าน Wi-Fi โปรดสอบถามผู้ให้บริการของคุณก่อนเพื่อตั้งค่าบริการนี้ แล้วเปิดการโทรผ่าน Wi-Fi อีกครั้งจากการตั้งค่า"</item> + <item msgid="3910386316304772394">"หากต้องการโทรออกและส่งข้อความผ่าน Wi-Fi โปรดสอบถามผู้ให้บริการของคุณก่อนเพื่อตั้งค่าบริการนี้ แล้วเปิดการโทรผ่าน Wi-Fi อีกครั้งจากการตั้งค่า (รหัสข้อผิดพลาด: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"ลงทะเบียนกับผู้ให้บริการ"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">มีหลายเครือข่าย Wi-Fi สาธารณะที่ใช้งานได้</item> <item quantity="one">มี 1 เครือข่าย Wi-Fi สาธารณะที่ใช้งานได้</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"เชื่อมต่อเครือข่าย Wi‑Fi แบบเปิด"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"กำลังเชื่อมต่อเครือข่าย Wi‑Fi แบบเปิด"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"เชื่อมต่อเครือข่าย Wi-Fi แล้ว"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ไม่สามารถเชื่อมต่อเครือข่าย Wi‑Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"แตะเพื่อดูเครือข่ายทั้งหมด"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"เชื่อมต่อ"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"เครือข่ายทั้งหมด"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"ลงชื่อเข้าใช้เครือข่าย WiFi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"ลงชื่อเข้าใช้เครือข่าย"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 0f15b2cc968f..dc0bf9ea6db2 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Naghahanap ng Serbisyo"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Pagtawag sa pamamagitan ng Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Upang tumawag at magpadala ng mga mensahe sa pamamagitan ng Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay muling i-on ang pagtawag sa Wi-Fi mula sa Mga Setting."</item> + <item msgid="3910386316304772394">"Upang makatawag at makapagpadala ng mga mensahe sa Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay i-on muli ang pagtawag gamit ang Wi-Fi mula sa Mga Setting. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Magparehistro sa iyong carrier"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">Available ang mga bukas na Wi-Fi network</item> <item quantity="other">Available ang mga bukas na Wi-Fi network</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Kumonekta sa bukas na Wi‑Fi network"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Kumokonekta sa bukas na Wi‑Fi network"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Nakakonekta sa Wi‑Fi network"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Hindi makakonekta sa Wi‑Fi network"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"I-tap upang makita ang lahat ng network"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kumonekta"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Lahat ng Network"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Mag-sign in sa Wi-Fi network"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Mag-sign in sa network"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 02f36f08ebef..c97746579360 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Hizmet Aranıyor"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Kablosuz Çağrı"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Kablosuz ağ üzerinden telefon etmek ve ileti göndermek için ilk önce operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra tekrar Ayarlar\'dan Kablosuz çağrı özelliğini açın."</item> + <item msgid="3910386316304772394">"Kablosuz ağ üzerinden telefon etmek ve mesaj göndermek için öncelikle operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra, Ayarlar\'dan Kablosuz çağrı özelliğini tekrar açın. (Hata kodu: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Operatörünüze kaydolun"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Kullanılabilir Kablosuz ağları aç</item> <item quantity="one">Kullanılabilir Kablosuz ağı aç</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Açık kablosuz ağa bağlanın"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Açık kablosuz ağa bağlandı"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Kablosuz ağa bağlanıldı"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Kablosuz ağa bağlanamadı"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tüm ağları görmek için dokunun"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Bağlan"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tüm Ağlar"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Kablosuz ağda oturum açın"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Ağda oturum açın"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 64daf067de78..9b65f5768f08 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -133,7 +133,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Пошук служби"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Дзвінок через Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спочатку попросіть свого оператора налаштувати цю послугу. Після цього ввімкніть дзвінки через Wi-Fi у налаштуваннях."</item> + <item msgid="3910386316304772394">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спершу попросіть свого оператора налаштувати цю послугу. Після цього знову ввімкніть дзвінки через Wi-Fi у налаштуваннях. (Код помилки: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Зареєструйтеся в оператора"</item> @@ -1150,20 +1150,13 @@ <item quantity="many">Відкриті мережі Wi-Fi доступні</item> <item quantity="other">Відкриті мережі Wi-Fi доступні</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Під’єднайтеся до відкритої мережі Wi-Fi"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Під’єднання до відкритої мережі Wi-Fi"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Під’єднано до мережі Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Не вдалося під’єднатися до мережі Wi-Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Торкніться, щоб побачити всі мережі"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Під’єднатися"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Усі мережі"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Вхід у мережу Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Вхід у мережу"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index bb72b8e600f8..e61a0624abf6 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -130,9 +130,7 @@ <string name="roamingText12" msgid="1189071119992726320">"رومنگ بینر آف"</string> <string name="roamingTextSearching" msgid="8360141885972279963">"سروس کی تلاش کر رہا ہے"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi کالنگ"</string> - <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi سے کالز کرنے اور پیغامات بھیجنے کیلئے، پہلے اپنے کیریئر سے اس سروس کو ترتیب دینے کیلئے کہیں۔ پھر ترتیبات سے دوبارہ Wi-Fi کالنگ آن کریں۔"</item> - </string-array> + <!-- no translation found for wfcOperatorErrorAlertMessages:0 (3910386316304772394) --> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"اپنے کیریئر کے ساتھ رجسٹر کریں"</item> </string-array> @@ -1106,20 +1104,13 @@ <item quantity="other">عوامی Wi-Fi نیٹ ورکس دستیاب ہیں</item> <item quantity="one">عوامی Wi-Fi نیٹ ورک دستیاب ہے</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"عوامی Wi‑Fi نیٹ ورک سے منسلک ہوں"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"عوامی Wi‑Fi نیٹ ورک سے منسلک ہو رہا ہے"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"عوامی Wi‑Fi نیٹ ورک سے منسلک ہو گيا"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi‑Fi نیٹ ورک سے منسلک نہیں ہو سکا"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"تمام نیٹ ورکس دیکھنے کیلئے تھپتھپائيں"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"منسلک کریں"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"تمام نیٹ ورکس"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi نیٹ ورک میں سائن ان کریں"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"نیٹ ورک میں سائن ان کریں"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index 98fdc3d52489..36a74fe6df91 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Xizmatlar qidirilmoqda"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi qo‘ng‘iroq"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Wi-Fi orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin."</item> + <item msgid="3910386316304772394">"Wi-Fi orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin. (Xato kodi: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Mobil operatoringiz yordamida ro‘yxatdan o‘ting"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Ochiq Wi-Fi tarmoqlari aniqlandi</item> <item quantity="one">Ochiq Wi-Fi tarmog‘i aniqlandi</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Ochiq Wi‑Fi tarmoqqa ulaning"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ochiq Wi‑Fi tarmoqqa ulanilmoqda"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Wi‑Fi tarmoqqa ulanildi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Wi-Fi tarmoqqa ulanib bo‘lmadi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Barcha tarmoqlarni ko‘rish uchun bosing"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ulanish"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Barcha tarmoqlar"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi tarmoqqa kirish"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Tarmoqqa kirish"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> @@ -1454,7 +1447,7 @@ <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string> <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", xavfsiz"</string> <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Grafik kalit esimdan chiqdi"</string> - <string name="kg_wrong_pattern" msgid="1850806070801358830">"Grafik kalit noto‘g‘ri"</string> + <string name="kg_wrong_pattern" msgid="1850806070801358830">"Grafik kalit xato"</string> <string name="kg_wrong_password" msgid="2333281762128113157">"Parol noto‘g‘ri"</string> <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN-kod noto‘g‘ri"</string> <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> soniyadan so‘ng qayta urinib ko‘ring."</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index f2c06e5b8204..d15a48f978a3 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Đang tìm kiếm Dịch vụ"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Gọi qua Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại gọi qua Wi-Fi từ Cài đặt."</item> + <item msgid="3910386316304772394">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại gọi qua Wi-Fi từ Cài đặt. (Mã lỗi: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Đăng ký với nhà cung cấp dịch vụ của bạn"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">Mở các mạng Wi-Fi khả dụng</item> <item quantity="one">Mở mạng Wi-Fi khả dụng</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Kết nối với mạng Wi-Fi đang mở"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Đang kết nối với mạng Wi‑Fi đang mở"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Đã kết nối với mạng Wi-Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Không thể kết nối với mạng Wi‑Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Nhấn để xem tất cả các mạng"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kết nối"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Tất cả các mạng"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Đăng nhập vào mạng Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Đăng nhập vào mạng"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 5e8eb687a23c..6e10594326d0 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜索服务"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"WLAN 通话"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能。"</item> + <item msgid="3910386316304772394">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能(错误代码:<xliff:g id="CODE">%1$s</xliff:g>)。"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"向您的运营商注册"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">有可用的开放 WLAN 网络</item> <item quantity="one">有可用的开放 WLAN 网络</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"连接到开放的 WLAN 网络"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"正在连接到开放的 WLAN 网络"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"已连接到 WLAN 网络"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"无法连接到 WLAN 网络"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"点按即可查看所有网络"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"连接"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"所有网络"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"登录到WLAN网络"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"登录到网络"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index b5301dde9509..c7b59f406d39 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜尋服務"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi 通話"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"如要透過 Wi-Fi 撥打電話及傳送訊息,請先向您的流動網絡供應商要求設定此服務。然後再次在「設定」中開啟 Wi-Fi 通話。"</item> + <item msgid="3910386316304772394">"如要透過 Wi-Fi 撥打電話和傳送訊息,請先向流動網絡供應商要求設定此服務,然後再次在「設定」中開啟「Wi-Fi 通話」。(錯誤代碼:<xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"向您的流動網絡供應商註冊"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">有可用的公開 Wi-Fi 網絡</item> <item quantity="one">有可用的公開 Wi-Fi 網絡</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"連線至開放的 Wi-Fi 網絡"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"正在連線至開放的 Wi-Fi 網絡"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"已連線至 Wi-Fi 網絡"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"無法連線至 Wi-Fi 網絡"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"輕按即可查看所有網絡"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"連線"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"所有網絡"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"登入 Wi-Fi 網絡"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"登入網絡"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index c1fc9bb1b76d..87117e4ae37b 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜尋服務"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi 通話"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"如要透過 Wi-FI 撥打電話及傳送訊息,請先要求你的電信業者開通這項服務,然後再到「設定」啟用 Wi-Fi 通話功能。"</item> + <item msgid="3910386316304772394">"如要透過 Wi-Fi 網路撥打電話及傳送訊息,請先要求電信業者為你設定這項服務,然後再次前往「設定」頁面啟用 Wi-Fi 通話功能。(錯誤代碼:<xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"向你的電信業者註冊"</item> @@ -1106,20 +1106,13 @@ <item quantity="other">有多個可用的開放 Wi-Fi 網路</item> <item quantity="one">有多個可用的開放 Wi-Fi 網路</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"連線至開放的 Wi‑Fi 網路"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"正在連線至開放的 Wi‑Fi 網路"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"已連線至 Wi-Fi 網路"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"無法連線至 Wi‑Fi 網路"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"輕觸即可查看所有網路"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"連線"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"所有網路"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"登入 Wi-Fi 網路"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"登入網路"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> @@ -1202,7 +1195,7 @@ <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"不支援的音訊配件"</string> <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"輕觸即可瞭解詳情"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string> - <string name="adb_active_notification_message" msgid="4948470599328424059">"輕觸即可停用 USB 偵錯。"</string> + <string name="adb_active_notification_message" msgid="4948470599328424059">"輕觸即可停用 USB 偵錯功能。"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取以停用 USB 偵錯。"</string> <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在接收錯誤報告…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享錯誤報告嗎?"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 6cd74c7d26f7..4d57f3c9afb1 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -131,7 +131,7 @@ <string name="roamingTextSearching" msgid="8360141885972279963">"Iseshela Isevisi"</string> <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Ukushaya kwe-Wi-Fi"</string> <string-array name="wfcOperatorErrorAlertMessages"> - <item msgid="2254967670088539682">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-FI, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le divayisi. Bese uvula ukushaya kwe-Wi-FI futhi kusukela kuzilungiselelo."</item> + <item msgid="3910386316304772394">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-Fi, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le sevisi. Bese uvula ukushaya kwe-Wi-Fi futhi kusukela kuzilungiselelo (Ikhodi yephutha: <xliff:g id="CODE">%1$s</xliff:g>)"</item> </string-array> <string-array name="wfcOperatorErrorNotificationMessages"> <item msgid="6177300162212449033">"Bhalisa ngenkampani yakho yenethiwekhi"</item> @@ -1106,20 +1106,13 @@ <item quantity="one">Vula amanethiwekhi we-Wi-Fi atholakalayo</item> <item quantity="other">Vula amanethiwekhi we-Wi-Fi atholakalayo</item> </plurals> - <!-- no translation found for wifi_available_title (3817100557900599505) --> - <skip /> - <!-- no translation found for wifi_available_title_connecting (1557292688310330032) --> - <skip /> - <!-- no translation found for wifi_available_title_connected (7542672851522241548) --> - <skip /> - <!-- no translation found for wifi_available_title_failed_to_connect (6861772233582618132) --> - <skip /> - <!-- no translation found for wifi_available_content_failed_to_connect (3377406637062802645) --> - <skip /> - <!-- no translation found for wifi_available_action_connect (2635699628459488788) --> - <skip /> - <!-- no translation found for wifi_available_action_all_networks (1100098935861622985) --> - <skip /> + <string name="wifi_available_title" msgid="3817100557900599505">"Xhuma kunethiwekhi evulekile ye-Wi‑Fi"</string> + <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Ixhuma kunethiwekhi evulekile ye-Wi‑Fi"</string> + <string name="wifi_available_title_connected" msgid="7542672851522241548">"Kuxhumeke kunethiwekhi ye-Wi‑Fi"</string> + <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Ayikwazanga ukuxhumeka kunethiwekhi ye-Wi-Fi"</string> + <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Thepha ukuze ubone onke amanethiwekhi"</string> + <string name="wifi_available_action_connect" msgid="2635699628459488788">"Xhuma"</string> + <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"Onke amanethiwekhi"</string> <string name="wifi_available_sign_in" msgid="9157196203958866662">"Ngena ngemvume kunethiwekhi ye-Wi-Fi"</string> <string name="network_available_sign_in" msgid="1848877297365446605">"Ngena ngemvume kunethiwekhi"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 062da9584305..69bb0b9da5e5 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2980,4 +2980,10 @@ <!-- An array of packages that need to be treated as type service in battery settings --> <string-array translatable="false" name="config_batteryPackageTypeService"/> + + <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app --> + <bool name="config_showAreaUpdateInfoSettings">false</bool> + + <!-- Enable the RingtonePickerActivity in 'com.android.providers.media'. --> + <bool name="config_defaultRingtonePickerEnabled">true</bool> </resources> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 5e2334d20da1..fa33d567983e 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -67,6 +67,9 @@ <!-- The amount to leave on-screen when the PIP is minimized. --> <dimen name="pip_minimized_visible_size">48dp</dimen> + <!-- The the PIP decelerates at while moving from a fling. --> + <dimen name="pip_fling_deceleration">-3000dp</dimen> + <!-- Min width for a tablet device --> <dimen name="min_xlarge_screen_width">800dp</dimen> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index ce701a735816..bd8e14ea4127 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4713,6 +4713,9 @@ <!-- Primary ETWS (Earthquake and Tsunami Warning System) default message for test --> <string name="etws_primary_default_message_test">Emergency messages test</string> + <!-- Content description for the reply button in the notification area [CHAR LIMIT=NONE]--> + <string name="notification_reply_button_accessibility">Reply</string> + <!-- Primary ETWS (Earthquake and Tsunami Warning System) default message for others --> <string name="etws_primary_default_message_others"></string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 3b3879f00d4e..99807f93834f 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1583,6 +1583,7 @@ <java-symbol type="dimen" name="docked_stack_divider_insets" /> <java-symbol type="dimen" name="docked_stack_minimize_thickness" /> <java-symbol type="dimen" name="pip_minimized_visible_size" /> + <java-symbol type="dimen" name="pip_fling_deceleration" /> <java-symbol type="integer" name="config_dockedStackDividerSnapMode" /> <java-symbol type="integer" name="config_pictureInPictureSnapMode" /> <java-symbol type="fraction" name="docked_stack_divider_fixed_ratio" /> @@ -3052,7 +3053,9 @@ <java-symbol type="drawable" name="stat_sys_vitals" /> + <java-symbol type="color" name="text_color_primary" /> + <java-symbol type="array" name="config_batteryPackageTypeSystem" /> <java-symbol type="array" name="config_batteryPackageTypeService" /> - + <java-symbol type="bool" name="config_showAreaUpdateInfoSettings" /> </resources> diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 7dc72db7cd4c..f02c45c44ffe 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -17,24 +17,25 @@ package android.provider; import static com.google.android.collect.Sets.newHashSet; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.is; + import static java.lang.reflect.Modifier.isFinal; import static java.lang.reflect.Modifier.isPublic; import static java.lang.reflect.Modifier.isStatic; -import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; +import org.junit.Test; +import org.junit.runner.RunWith; + import java.lang.reflect.Field; import java.util.HashSet; import java.util.Set; -import org.junit.Test; -import org.junit.runner.RunWith; - /** Tests that ensure appropriate settings are backed up. */ @RunWith(AndroidJUnit4.class) @SmallTest @@ -446,6 +447,8 @@ public class SettingsBackupTest { Settings.Secure.MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, Settings.Secure.MULTI_PRESS_TIMEOUT, Settings.Secure.NFC_PAYMENT_FOREGROUND, + Settings.Secure.NIGHT_DISPLAY_ACTIVATED, + Settings.Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, Settings.Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME, Settings.Secure.PACKAGE_VERIFIER_STATE, Settings.Secure.PACKAGE_VERIFIER_USER_CONSENT, diff --git a/graphics/java/android/graphics/ColorFilter.java b/graphics/java/android/graphics/ColorFilter.java index 0ca3729dcc0e..b24b9885d1b0 100644 --- a/graphics/java/android/graphics/ColorFilter.java +++ b/graphics/java/android/graphics/ColorFilter.java @@ -14,19 +14,22 @@ * limitations under the License. */ -// This file was generated from the C++ include file: SkColorFilter.h -// Any changes made to this file will be discarded by the build. -// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, -// or one of the auxilary file specifications in device/tools/gluemaker. - package android.graphics; +import libcore.util.NativeAllocationRegistry; + /** * A color filter can be used with a {@link Paint} to modify the color of * each pixel drawn with that paint. This is an abstract class that should * never be used directly. */ public class ColorFilter { + + private static class NoImagePreloadHolder { + public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry( + ColorFilter.class.getClassLoader(), nativeGetFinalizer(), 50); + } + /** * @deprecated Use subclass constructors directly instead. */ @@ -34,9 +37,11 @@ public class ColorFilter { public ColorFilter() {} /** - * Holds the pointer to the native SkColorFilter instance. + * Current native SkColorFilter instance. */ private long mNativeInstance; + // Runnable to do immediate destruction + private Runnable mCleaner; long createNativeInstance() { return 0; @@ -44,35 +49,28 @@ public class ColorFilter { void discardNativeInstance() { if (mNativeInstance != 0) { - nSafeUnref(mNativeInstance); + mCleaner.run(); + mCleaner = null; mNativeInstance = 0; } } - @Override - protected void finalize() throws Throwable { - try { - if (mNativeInstance != 0) { - nSafeUnref(mNativeInstance); - } - mNativeInstance = -1; - } finally { - super.finalize(); - } - } - /** @hide */ public long getNativeInstance() { - if (mNativeInstance == -1) { - throw new IllegalStateException("attempting to use a finalized ColorFilter"); - } - if (mNativeInstance == 0) { mNativeInstance = createNativeInstance(); + + if (mNativeInstance != 0) { + // Note: we must check for null here, since it's possible for createNativeInstance() + // to return nullptr if the native SkColorFilter would be a no-op at draw time. + // See native implementations of subclass create methods for more info. + mCleaner = NoImagePreloadHolder.sRegistry.registerNativeAllocation( + this, mNativeInstance); + } } return mNativeInstance; } - static native void nSafeUnref(long native_instance); + private static native long nativeGetFinalizer(); } diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java index 8616d58a0319..1d0cfa5ff082 100644 --- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java +++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java @@ -289,6 +289,9 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback } private void updateLayerBounds(Rect bounds) { + if (bounds.isEmpty()) { + return; + } try { suspendChildInvalidation(); updateLayerBoundsInternal(bounds); @@ -1109,4 +1112,4 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback mCheckedStateful = false; } } -}
\ No newline at end of file +} diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp index 2e9a6e895d8a..c19c1a11e3e2 100644 --- a/libs/hwui/GlopBuilder.cpp +++ b/libs/hwui/GlopBuilder.cpp @@ -457,11 +457,13 @@ GlopBuilder& GlopBuilder::setFillTextureLayer(GlLayer& layer, float alpha) { return *this; } -GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture, Matrix4& textureTransform) { +GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture, Matrix4& textureTransform, + bool requiresFilter) { TRIGGER_STAGE(kFillStage); REQUIRE_STAGES(kMeshStage | kRoundRectClipStage); - mOutGlop->fill.texture = { &texture, GL_LINEAR, GL_CLAMP_TO_EDGE, &textureTransform }; + GLenum filter = requiresFilter ? GL_LINEAR : GL_NEAREST; + mOutGlop->fill.texture = { &texture, filter, GL_CLAMP_TO_EDGE, &textureTransform }; setFill(SK_ColorWHITE, 1.0f, SkBlendMode::kSrc, Blend::ModeOrderSwap::NoSwap, nullptr, nullptr); diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h index 87b1568ed72b..6d11da19e138 100644 --- a/libs/hwui/GlopBuilder.h +++ b/libs/hwui/GlopBuilder.h @@ -75,7 +75,8 @@ public: GlopBuilder& setFillTextureLayer(GlLayer& layer, float alpha); // TODO: setFillLayer normally forces its own wrap & filter mode, // which isn't always correct. - GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform); + GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform, + bool requiresFilter); GlopBuilder& setTransform(const Matrix4& canvas, const int transformFlags); diff --git a/libs/hwui/OpenGLReadback.cpp b/libs/hwui/OpenGLReadback.cpp index b073070b58b6..19d5d9d2250e 100644 --- a/libs/hwui/OpenGLReadback.cpp +++ b/libs/hwui/OpenGLReadback.cpp @@ -199,6 +199,7 @@ inline CopyResult copyTextureInto(Caches& caches, RenderState& renderState, GL_TEXTURE_2D, texture, 0); { + bool requiresFilter; // Draw & readback renderState.setViewport(destWidth, destHeight); renderState.scissor().setEnabled(false); @@ -216,12 +217,17 @@ inline CopyResult copyTextureInto(Caches& caches, RenderState& renderState, croppedTexTransform.scale(srcRect.getWidth() / sourceTexture.width(), srcRect.getHeight() / sourceTexture.height(), 1); croppedTexTransform.multiply(sFlipV); + requiresFilter = srcRect.getWidth() != (float) destWidth + || srcRect.getHeight() != (float) destHeight; + } else { + requiresFilter = sourceTexture.width() != (uint32_t) destWidth + || sourceTexture.height() != (uint32_t) destHeight; } Glop glop; GlopBuilder(renderState, caches, &glop) .setRoundRectClipState(nullptr) .setMeshTexturedUnitQuad(nullptr) - .setFillExternalTexture(sourceTexture, croppedTexTransform) + .setFillExternalTexture(sourceTexture, croppedTexTransform, requiresFilter) .setTransform(Matrix4::identity(), TransformFlags::None) .setModelViewMapUnitToRect(Rect(destWidth, destHeight)) .build(); diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java index 912551f5e4a9..b2903c4689e0 100644 --- a/location/java/android/location/GnssStatus.java +++ b/location/java/android/location/GnssStatus.java @@ -97,13 +97,12 @@ public final class GnssStatus { CONSTELLATION_QZSS, CONSTELLATION_BEIDOU, CONSTELLATION_GALILEO}) public @interface ConstellationType {} - /* These package private values are modified by the LocationManager class */ - /* package */ int[] mSvidWithFlags; - /* package */ float[] mCn0DbHz; - /* package */ float[] mElevations; - /* package */ float[] mAzimuths; - /* package */ int mSvCount; - /* package */ float[] mCarrierFrequencies; + final int[] mSvidWithFlags; + final float[] mCn0DbHz; + final float[] mElevations; + final float[] mAzimuths; + final int mSvCount; + final float[] mCarrierFrequencies; GnssStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations, float[] azimuths, float[] carrierFrequencies) { diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 26ac2a23d8c5..968f596e0cc5 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -74,7 +74,8 @@ public class LocationManager { new HashMap<>(); private final HashMap<OnNmeaMessageListener, GnssStatusListenerTransport> mGnssNmeaListeners = new HashMap<>(); - private GnssStatus mGnssStatus; + // volatile + GnssStatus final-fields pattern to avoid a partially published object + private volatile GnssStatus mGnssStatus; private int mTimeToFirstFix; /** @@ -1563,7 +1564,7 @@ public class LocationManager { float[] cn0s, float[] elevations, float[] azimuths, float[] carrierFreqs) { if (mGnssCallback != null) { mGnssStatus = new GnssStatus(svCount, prnWithFlags, cn0s, elevations, azimuths, - carrierFreqs); + carrierFreqs); Message msg = Message.obtain(); msg.what = GpsStatus.GPS_EVENT_SATELLITE_STATUS; @@ -1949,7 +1950,7 @@ public class LocationManager { status = new GpsStatus(); } // When mGnssStatus is null, that means that this method is called outside - // onGpsStatusChanged(). Return an empty status to maintain backwards compatibility. + // onGpsStatusChanged(). Return an empty status to maintain backwards compatibility. if (mGnssStatus != null) { status.setStatus(mGnssStatus, mTimeToFirstFix); } diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index c1e81c54f117..f4039889aded 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -218,6 +218,7 @@ public final class AudioAttributes implements Parcelable { SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_COMMUNICATION_DELAYED,SUPPRESSIBLE_NOTIFICATION); SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_EVENT, SUPPRESSIBLE_NOTIFICATION); SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_ACCESSIBILITY, SUPPRESSIBLE_NEVER); + SUPPRESSIBLE_USAGES.put(USAGE_VOICE_COMMUNICATION, SUPPRESSIBLE_NEVER); } /** diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java index 0a1de33b845b..2b5ac5e6ec20 100644 --- a/media/java/android/media/AudioManagerInternal.java +++ b/media/java/android/media/AudioManagerInternal.java @@ -59,4 +59,15 @@ public abstract class AudioManagerInternal { int getRingerModeAffectedStreams(int streams); } + + /** + * Disable or restore the ability to play audio for a given UID. + * When a UID isn't meant to be tracked anymore (e.g. client died), re-enable audio for this UID + * to prevent disabling audio for future UIDs that would reuse the same value. + * This operation is asynchronous. + * @param disable when true, prevents playback of audio streams from the given uid. If false, + * restores the ability to play, or no-op if playback hadn't been disabled before. + * @param uid the client UID whose ability to play will be affected. + */ + public abstract void disableAudioForUid(boolean disable, int uid); } diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 6ef3091dcc70..29fe275777b0 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -424,7 +424,8 @@ public class AudioSystem DEVICE_OUT_BLUETOOTH_SCO_HEADSET | DEVICE_OUT_BLUETOOTH_SCO_CARKIT); public static final int DEVICE_OUT_ALL_USB = (DEVICE_OUT_USB_ACCESSORY | - DEVICE_OUT_USB_DEVICE); + DEVICE_OUT_USB_DEVICE | + DEVICE_OUT_USB_HEADSET); public static final int DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO = (DEVICE_OUT_AUX_LINE | DEVICE_OUT_HDMI_ARC | DEVICE_OUT_SPDIF); @@ -486,7 +487,8 @@ public class AudioSystem DEVICE_IN_DEFAULT); public static final int DEVICE_IN_ALL_SCO = DEVICE_IN_BLUETOOTH_SCO_HEADSET; public static final int DEVICE_IN_ALL_USB = (DEVICE_IN_USB_ACCESSORY | - DEVICE_IN_USB_DEVICE); + DEVICE_IN_USB_DEVICE | + DEVICE_IN_USB_HEADSET); // device states, must match AudioSystem::device_connection_state public static final int DEVICE_STATE_UNAVAILABLE = 0; diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index dfd2bb35d6ea..44bd252a349e 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -43,6 +43,7 @@ import android.service.media.MediaBrowserService; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; +import android.view.ViewConfiguration; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -200,8 +201,7 @@ public final class MediaSession { return; } if (mCallback != null) { - // We're updating the callback, clear the session from the old - // one. + // We're updating the callback, clear the session from the old one. mCallback.mCallback.mSession = null; } if (handler == null) { @@ -735,6 +735,8 @@ public final class MediaSession { */ public abstract static class Callback { private MediaSession mSession; + private CallbackMessageHandler mHandler; + private boolean mMediaPlayPauseKeyPending; public Callback() { } @@ -766,13 +768,41 @@ public final class MediaSession { * @return True if the event was handled, false otherwise. */ public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) { - if (mSession != null + if (mSession != null && mHandler != null && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) { KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) { PlaybackState state = mSession.mPlaybackState; long validActions = state == null ? 0 : state.getActions(); switch (ke.getKeyCode()) { + case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: + case KeyEvent.KEYCODE_HEADSETHOOK: + if (ke.getRepeatCount() > 0) { + // Consider long-press as a single tap. + handleMediaPlayPauseKeySingleTapIfPending(); + } else if (mMediaPlayPauseKeyPending) { + // Consider double tap as the next. + mHandler.removeMessages(CallbackMessageHandler + .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT); + mMediaPlayPauseKeyPending = false; + if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) { + onSkipToNext(); + } + } else { + mMediaPlayPauseKeyPending = true; + mHandler.sendEmptyMessageDelayed(CallbackMessageHandler + .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT, + ViewConfiguration.getDoubleTapTimeout()); + } + return true; + default: + // If another key is pressed within double tap timeout, consider the + // pending play/pause as a single tap to handle media keys in order. + handleMediaPlayPauseKeySingleTapIfPending(); + break; + } + + switch (ke.getKeyCode()) { case KeyEvent.KEYCODE_MEDIA_PLAY: if ((validActions & PlaybackState.ACTION_PLAY) != 0) { onPlay(); @@ -815,28 +845,33 @@ public final class MediaSession { return true; } break; - case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: - case KeyEvent.KEYCODE_HEADSETHOOK: - boolean isPlaying = state == null ? false - : state.getState() == PlaybackState.STATE_PLAYING; - boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE - | PlaybackState.ACTION_PLAY)) != 0; - boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE - | PlaybackState.ACTION_PAUSE)) != 0; - if (isPlaying && canPause) { - onPause(); - return true; - } else if (!isPlaying && canPlay) { - onPlay(); - return true; - } - break; } } } return false; } + private void handleMediaPlayPauseKeySingleTapIfPending() { + if (!mMediaPlayPauseKeyPending) { + return; + } + mMediaPlayPauseKeyPending = false; + mHandler.removeMessages(CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT); + PlaybackState state = mSession.mPlaybackState; + long validActions = state == null ? 0 : state.getActions(); + boolean isPlaying = state != null + && state.getState() == PlaybackState.STATE_PLAYING; + boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE + | PlaybackState.ACTION_PLAY)) != 0; + boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE + | PlaybackState.ACTION_PAUSE)) != 0; + if (isPlaying && canPause) { + onPause(); + } else if (!isPlaying && canPlay) { + onPlay(); + } + } + /** * Override to handle requests to prepare playback. During the preparation, a session should * not hold audio focus in order to allow other sessions play seamlessly. The state of @@ -1294,12 +1329,14 @@ public final class MediaSession { private static final int MSG_CUSTOM_ACTION = 20; private static final int MSG_ADJUST_VOLUME = 21; private static final int MSG_SET_VOLUME = 22; + private static final int MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT = 23; private MediaSession.Callback mCallback; public CallbackMessageHandler(Looper looper, MediaSession.Callback callback) { super(looper, null, true); mCallback = callback; + mCallback.mHandler = this; } public void post(int what, Object obj, Bundle bundle) { @@ -1401,6 +1438,9 @@ public final class MediaSession { vp.onSetVolumeTo((int) msg.obj); } break; + case MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT: + mCallback.handleMediaPlayPauseKeySingleTapIfPending(); + break; } } } diff --git a/media/jni/soundpool/SoundPoolThread.cpp b/media/jni/soundpool/SoundPoolThread.cpp index 3d988773ff04..ba3b482935dd 100644 --- a/media/jni/soundpool/SoundPoolThread.cpp +++ b/media/jni/soundpool/SoundPoolThread.cpp @@ -20,8 +20,6 @@ #include "SoundPoolThread.h" -static const int kMaxWorkers = 3; - namespace android { void SoundPoolThread::write(SoundPoolMsg msg) { @@ -33,21 +31,14 @@ void SoundPoolThread::write(SoundPoolMsg msg) { // if thread is quitting, don't add to queue if (mRunning) { mMsgQueue.push(msg); - if (mNumWorkers < kMaxWorkers) { - if (createThreadEtc(beginThread, this, "SoundPoolThread")) { - mNumWorkers++; - ALOGV("created worker thread"); - } - } + mCondition.signal(); } } const SoundPoolMsg SoundPoolThread::read() { Mutex::Autolock lock(&mLock); - if (mMsgQueue.size() == 0) { - mNumWorkers--; - mCondition.signal(); - return SoundPoolMsg(SoundPoolMsg::KILL, 0); + while (mMsgQueue.size() == 0) { + mCondition.wait(mLock); } SoundPoolMsg msg = mMsgQueue[0]; mMsgQueue.removeAt(0); @@ -60,20 +51,20 @@ void SoundPoolThread::quit() { if (mRunning) { mRunning = false; mMsgQueue.clear(); - mCondition.broadcast(); // wake up any blocked writers - while (mNumWorkers > 0) { - mCondition.wait(mLock); - } + mMsgQueue.push(SoundPoolMsg(SoundPoolMsg::KILL, 0)); + mCondition.signal(); + mCondition.wait(mLock); } ALOGV("return from quit"); } SoundPoolThread::SoundPoolThread(SoundPool* soundPool) : - mSoundPool(soundPool), - mNumWorkers(0), - mRunning(true) + mSoundPool(soundPool) { mMsgQueue.setCapacity(maxMessages); + if (createThreadEtc(beginThread, this, "SoundPoolThread")) { + mRunning = true; + } } SoundPoolThread::~SoundPoolThread() diff --git a/media/jni/soundpool/SoundPoolThread.h b/media/jni/soundpool/SoundPoolThread.h index 5d7bf0c07803..7b3e1dda0a23 100644 --- a/media/jni/soundpool/SoundPoolThread.h +++ b/media/jni/soundpool/SoundPoolThread.h @@ -58,7 +58,6 @@ private: Condition mCondition; Vector<SoundPoolMsg> mMsgQueue; SoundPool* mSoundPool; - int32_t mNumWorkers; bool mRunning; }; diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java index e38cca739253..a487632b92f3 100644 --- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java +++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java @@ -377,6 +377,9 @@ public class CaptivePortalLoginActivity extends Activity { return; } else if (mPagesLoaded == 2) { // Prevent going back to empty first page. + // Fix for missing focus, see b/62449959 for details. Remove it once we get a + // newer version of WebView (60.x.y). + view.requestFocus(); view.clearHistory(); } testForCaptivePortal(); diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java index 3b29a6cd7b6c..1e262314284d 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java @@ -77,7 +77,7 @@ public class DeviceDiscoveryService extends Service { private BluetoothAdapter mBluetoothAdapter; private WifiManager mWifiManager; - private BluetoothLeScanner mBLEScanner; + @Nullable private BluetoothLeScanner mBLEScanner; private ScanSettings mDefaultScanSettings = new ScanSettings.Builder().build(); private List<DeviceFilter<?>> mFilters; @@ -185,7 +185,7 @@ public class DeviceDiscoveryService extends Service { mBluetoothAdapter.startDiscovery(); } - if (shouldScan(mBLEFilters)) { + if (shouldScan(mBLEFilters) && mBLEScanner != null) { mBLEScanCallback = new BLEScanCallback(); mBLEScanner.startScan(mBLEScanFilters, mDefaultScanSettings, mBLEScanCallback); } @@ -224,7 +224,7 @@ public class DeviceDiscoveryService extends Service { unregisterReceiver(mBluetoothBroadcastReceiver); mBluetoothBroadcastReceiver = null; } - mBLEScanner.stopScan(mBLEScanCallback); + if (mBLEScanner != null) mBLEScanner.stopScan(mBLEScanCallback); if (mWifiBroadcastReceiver != null) { unregisterReceiver(mWifiBroadcastReceiver); mWifiBroadcastReceiver = null; diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index 0484645cbcb4..7f2d85ac6384 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -110,7 +110,7 @@ <string name="unknown" msgid="1592123443519355854">"Sconosciuta"</string> <string name="running_process_item_user_label" msgid="3129887865552025943">"Utente: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string> <string name="launch_defaults_some" msgid="313159469856372621">"Alcune opzioni predefinite impostate"</string> - <string name="launch_defaults_none" msgid="4241129108140034876">"Nessuna app predefinita impostata"</string> + <string name="launch_defaults_none" msgid="4241129108140034876">"Nessuna impostazione predefinita"</string> <string name="tts_settings" msgid="8186971894801348327">"Impostazioni di sintesi vocale"</string> <string name="tts_settings_title" msgid="1237820681016639683">"Output sintesi vocale"</string> <string name="tts_default_rate_title" msgid="6030550998379310088">"Velocità voce"</string> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index fd994b572981..a4302880dfaf 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -130,6 +130,15 @@ <!-- Bluetooth settings. Message when connected to a device, except for phone/media audio. [CHAR LIMIT=40] --> <string name="bluetooth_connected_no_headset_no_a2dp">Connected (no phone or media)</string> + <!-- Bluetooth settings. Message when connected to a device, showing remote device battery level. [CHAR LIMIT=NONE] --> + <string name="bluetooth_connected_battery_level">Connected, battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string> + <!-- Bluetooth settings. Message when connected to a device, except for phone audio, showing remote device battery level. [CHAR LIMIT=NONE] --> + <string name="bluetooth_connected_no_headset_battery_level">Connected (no phone), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string> + <!-- Bluetooth settings. Message when connected to a device, except for media audio, showing remote device battery level. [CHAR LIMIT=NONE] --> + <string name="bluetooth_connected_no_a2dp_battery_level">Connected (no media), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string> + <!-- Bluetooth settings. Message when connected to a device, except for phone/media audio, showing remote device battery level. [CHAR LIMIT=NONE] --> + <string name="bluetooth_connected_no_headset_no_a2dp_battery_level">Connected (no phone or media), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string> + <!-- Bluetooth settings. The user-visible string that is used whenever referring to the A2DP profile. --> <string name="bluetooth_profile_a2dp">Media audio</string> <!-- Bluetooth settings. The user-visible string that is used whenever referring to the headset or handsfree profile. --> diff --git a/packages/SettingsLib/src/com/android/settingslib/TronUtils.java b/packages/SettingsLib/src/com/android/settingslib/TronUtils.java index bea6e8f77dd2..945cb5797e8f 100644 --- a/packages/SettingsLib/src/com/android/settingslib/TronUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/TronUtils.java @@ -16,48 +16,18 @@ package com.android.settingslib; import android.content.Context; -import android.net.NetworkBadging; import com.android.internal.logging.MetricsLogger; +import com.android.settingslib.wifi.AccessPoint.Speed; /** Utilites for Tron Logging. */ public final class TronUtils { - private TronUtils() {}; - - public static void logWifiSettingsBadge(Context context, int badgeEnum) { - logNetworkBadgeMetric(context, "settings_wifibadging", badgeEnum); - } + private static final String TAG = "TronUtils"; - /** - * Logs an occurrence of the given network badge to a Histogram. - * - * @param context Context - * @param histogram the Tron histogram name to write to - * @param badgeEnum the {@link NetworkBadging.Badging} badge value - * @throws IllegalArgumentException if the given badge enum is not supported - */ - private static void logNetworkBadgeMetric( - Context context, String histogram, int badgeEnum) - throws IllegalArgumentException { - int bucket; - switch (badgeEnum) { - case NetworkBadging.BADGING_NONE: - bucket = 0; - break; - case NetworkBadging.BADGING_SD: - bucket = 1; - break; - case NetworkBadging.BADGING_HD: - bucket = 2; - break; - case NetworkBadging.BADGING_4K: - bucket = 3; - break; - default: - throw new IllegalArgumentException("Unsupported badge enum: " + badgeEnum); - } + private TronUtils() {}; - MetricsLogger.histogram(context, histogram, bucket); + public static void logWifiSettingsSpeed(Context context, @Speed int speedEnum) { + MetricsLogger.histogram(context, "settings_wifi_speed_labels", speedEnum); } } diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java index b06b0328f8fd..7357fe63d9b0 100644 --- a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java @@ -107,4 +107,20 @@ public class AppUtils { return false; } + /** Returns the label for a given package. */ + public static CharSequence getApplicationLabel( + PackageManager packageManager, String packageName) { + try { + final ApplicationInfo appInfo = + packageManager.getApplicationInfo( + packageName, + PackageManager.MATCH_DISABLED_COMPONENTS + | PackageManager.MATCH_ANY_USER); + return appInfo.loadLabel(packageManager); + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, "Unable to find info for package: " + packageName); + } + return null; + } + } diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java index 1bb141706736..426dc7c20a96 100755 --- a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java +++ b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java @@ -28,6 +28,7 @@ import android.graphics.Paint; import android.graphics.Path; import android.graphics.Path.Direction; import android.graphics.Path.FillType; +import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Typeface; import android.graphics.drawable.Drawable; @@ -82,6 +83,7 @@ public class BatteryMeterDrawableBase extends Drawable { private final float[] mPlusPoints; private final Path mPlusPath = new Path(); + private final Rect mPadding = new Rect(); private final RectF mFrame = new RectF(); private final RectF mButtonFrame = new RectF(); private final RectF mBoltFrame = new RectF(); @@ -219,12 +221,40 @@ public class BatteryMeterDrawableBase extends Drawable { @Override public void setBounds(int left, int top, int right, int bottom) { super.setBounds(left, top, right, bottom); - mHeight = bottom - top; - mWidth = right - left; + updateSize(); + } + + private void updateSize() { + final Rect bounds = getBounds(); + + mHeight = (bounds.bottom - mPadding.bottom) - (bounds.top + mPadding.top); + mWidth = (bounds.right - mPadding.right) - (bounds.left + mPadding.left); mWarningTextPaint.setTextSize(mHeight * 0.75f); mWarningTextHeight = -mWarningTextPaint.getFontMetrics().ascent; } + @Override + public boolean getPadding(Rect padding) { + if (mPadding.left == 0 + && mPadding.top == 0 + && mPadding.right == 0 + && mPadding.bottom == 0) { + return super.getPadding(padding); + } + + padding.set(mPadding); + return true; + } + + public void setPadding(int left, int top, int right, int bottom) { + mPadding.left = left; + mPadding.top = top; + mPadding.right = right; + mPadding.bottom = bottom; + + updateSize(); + } + private int getColorForLevel(int percent) { // If we are in power save mode, always use the normal color. if (mPowerSaveEnabled) { @@ -251,10 +281,15 @@ public class BatteryMeterDrawableBase extends Drawable { mIconTint = fillColor; mFramePaint.setColor(backgroundColor); mBoltPaint.setColor(fillColor); + mPlusPaint.setColor(fillColor); mChargeColor = fillColor; invalidateSelf(); } + protected int batteryColorForLevel(int level) { + return mCharging ? mChargeColor : getColorForLevel(level); + } + @Override public void draw(Canvas c) { final int level = mLevel; @@ -264,11 +299,10 @@ public class BatteryMeterDrawableBase extends Drawable { float drawFrac = (float) level / 100f; final int height = mHeight; final int width = (int) (ASPECT_RATIO * mHeight); - int px = (mWidth - width) / 2; - + final int px = (mWidth - width) / 2; final int buttonHeight = Math.round(height * mButtonHeightFraction); - mFrame.set(0, 0, width, height); + mFrame.set(mPadding.left, mPadding.top, width + mPadding.left, height + mPadding.top); mFrame.offset(px, 0); // button-frame: area above the battery body @@ -282,7 +316,7 @@ public class BatteryMeterDrawableBase extends Drawable { mFrame.top += buttonHeight; // set the battery charging color - mBatteryPaint.setColor(mCharging ? mChargeColor : getColorForLevel(level)); + mBatteryPaint.setColor(batteryColorForLevel(level)); if (level >= FULL) { drawFrac = 1f; diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java index d45ed1922aa4..4a5445163650 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java @@ -16,6 +16,7 @@ package com.android.settingslib.wifi; +import android.annotation.IntDef; import android.annotation.Nullable; import android.app.AppGlobals; import android.content.Context; @@ -53,6 +54,8 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.R; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; @@ -82,35 +85,30 @@ public class AccessPoint implements Comparable<AccessPoint> { */ public static final int HIGHER_FREQ_5GHZ = 5900; - /** - * Constant value representing an unlabeled / unscored network. - */ - @VisibleForTesting - static final int SPEED_NONE = 0; - - /** - * Constant value representing a slow speed network connection. - */ - @VisibleForTesting - static final int SPEED_SLOW = 5; - - /** - * Constant value representing a medium speed network connection. - */ - @VisibleForTesting - static final int SPEED_MEDIUM = 10; - - /** - * Constant value representing a fast speed network connection. - */ - @VisibleForTesting - static final int SPEED_FAST = 20; - - /** - * Constant value representing a very fast speed network connection. - */ - @VisibleForTesting - static final int SPEED_VERY_FAST = 30; + @IntDef({Speed.NONE, Speed.SLOW, Speed.MODERATE, Speed.FAST, Speed.VERY_FAST}) + @Retention(RetentionPolicy.SOURCE) + public @interface Speed { + /** + * Constant value representing an unlabeled / unscored network. + */ + int NONE = 0; + /** + * Constant value representing a slow speed network connection. + */ + int SLOW = 5; + /** + * Constant value representing a medium speed network connection. + */ + int MODERATE = 10; + /** + * Constant value representing a fast speed network connection. + */ + int FAST = 20; + /** + * Constant value representing a very fast speed network connection. + */ + int VERY_FAST = 30; + } /** * Experimental: we should be able to show the user the list of BSSIDs and bands @@ -177,7 +175,7 @@ public class AccessPoint implements Comparable<AccessPoint> { private Object mTag; private int mRankingScore = Integer.MIN_VALUE; - private int mSpeed = AccessPoint.SPEED_NONE; + private int mSpeed = Speed.NONE; private boolean mIsScoredNetworkMetered = false; // used to co-relate internal vs returned accesspoint. @@ -322,8 +320,15 @@ public class AccessPoint implements Comparable<AccessPoint> { if (difference != 0) { return difference; } + // Sort by ssid. - return getSsidStr().compareToIgnoreCase(other.getSsidStr()); + difference = getSsidStr().compareToIgnoreCase(other.getSsidStr()); + if (difference != 0) { + return difference; + } + + // Do a case sensitive comparison to distinguish SSIDs that differ in case only + return getSsidStr().compareTo(other.getSsidStr()); } @Override @@ -368,7 +373,7 @@ public class AccessPoint implements Comparable<AccessPoint> { if (mRankingScore != Integer.MIN_VALUE) { builder.append(",rankingScore=").append(mRankingScore); } - if (mSpeed != SPEED_NONE) { + if (mSpeed != Speed.NONE) { builder.append(",speed=").append(mSpeed); } builder.append(",metered=").append(isMetered()); @@ -399,7 +404,7 @@ public class AccessPoint implements Comparable<AccessPoint> { private boolean updateScores(WifiNetworkScoreCache scoreCache) { int oldSpeed = mSpeed; int oldRankingScore = mRankingScore; - mSpeed = SPEED_NONE; + mSpeed = Speed.NONE; mRankingScore = Integer.MIN_VALUE; for (ScanResult result : mScanResultCache.values()) { @@ -675,7 +680,7 @@ public class AccessPoint implements Comparable<AccessPoint> { // TODO(b/62354743): Standardize and international delimiter usage final String concatenator = " / "; - if (mSpeed != SPEED_NONE) { + if (mSpeed != Speed.NONE) { summary.append(getSpeedLabel() + concatenator); } @@ -799,7 +804,7 @@ public class AccessPoint implements Comparable<AccessPoint> { if (mRankingScore != Integer.MIN_VALUE) { visibility.append(" rankingScore=").append(getRankingScore()); } - if (mSpeed != SPEED_NONE) { + if (mSpeed != Speed.NONE) { visibility.append(" speed=").append(getSpeedLabel()); } visibility.append(String.format(" tx=%.1f,", mInfo.txSuccessRate)); @@ -1053,6 +1058,12 @@ public class AccessPoint implements Comparable<AccessPoint> { final int oldLevel = getLevel(); if (info != null && isInfoForThisAccessPoint(config, info)) { updated = (mInfo == null); + if (mConfig != config) { + // We do not set updated = true as we do not want to increase the amount of sorting + // and copying performed in WifiTracker at this time. If issues involving refresh + // are still seen, we will investigate further. + update(config); // Notifies the AccessPointListener of the change + } if (mRssi != info.getRssi()) { mRssi = info.getRssi(); updated = true; @@ -1104,15 +1115,15 @@ public class AccessPoint implements Comparable<AccessPoint> { @Nullable String getSpeedLabel() { switch (mSpeed) { - case SPEED_VERY_FAST: + case Speed.VERY_FAST: return mContext.getString(R.string.speed_label_very_fast); - case SPEED_FAST: + case Speed.FAST: return mContext.getString(R.string.speed_label_fast); - case SPEED_MEDIUM: + case Speed.MODERATE: return mContext.getString(R.string.speed_label_okay); - case SPEED_SLOW: + case Speed.SLOW: return mContext.getString(R.string.speed_label_slow); - case SPEED_NONE: + case Speed.NONE: default: return null; } diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java index e7525f3edbc4..92995a8e850d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java @@ -70,6 +70,19 @@ public class AccessPointPreference extends Preference { R.string.accessibility_wifi_signal_full }; + public static String generatePreferenceKey(AccessPoint accessPoint) { + StringBuilder builder = new StringBuilder(); + + if (TextUtils.isEmpty(accessPoint.getBssid())) { + builder.append(accessPoint.getSsidStr()); + } else { + builder.append(accessPoint.getBssid()); + } + + builder.append(',').append(accessPoint.getSecurity()); + return builder.toString(); + } + // Used for dummy pref. public AccessPointPreference(Context context, AttributeSet attrs) { super(context, attrs); @@ -161,7 +174,7 @@ public class AccessPointPreference extends Preference { safeSetDefaultIcon(); return; } - TronUtils.logWifiSettingsBadge(context, mWifiSpeed); + TronUtils.logWifiSettingsSpeed(context, mWifiSpeed); // TODO(b/62355275): Revert this to N code after deleting NetworkBadging API Drawable drawable = NetworkBadging.getWifiIcon( diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/TestAccessPointBuilder.java b/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java index 2213ae647e98..4307cb0f1b7b 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/TestAccessPointBuilder.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java @@ -26,9 +26,9 @@ import android.os.Bundle; /** * Build and return a valid AccessPoint. * -* Only intended for testing the AccessPoint class; -* AccessPoints were designed to only be populated -* by the mechanisms of scan results and wifi configurations. +* Only intended for testing the AccessPoint class or creating Access points to be used in testing +* applications. AccessPoints were designed to only be populated by the mechanisms of scan results +* and wifi configurations. */ public class TestAccessPointBuilder { // match the private values in WifiManager @@ -36,12 +36,14 @@ public class TestAccessPointBuilder { private static final int MAX_RSSI = -55; // set some sensible defaults + private String mBssid = null; private int mRssi = AccessPoint.UNREACHABLE_RSSI; private int mNetworkId = WifiConfiguration.INVALID_NETWORK_ID; private String ssid = "TestSsid"; private NetworkInfo mNetworkInfo = null; private String mFqdn = null; private String mProviderFriendlyName = null; + private int mSecurity = AccessPoint.SECURITY_NONE; private WifiConfiguration mWifiConfig; private WifiInfo mWifiInfo; @@ -56,6 +58,7 @@ public class TestAccessPointBuilder { WifiConfiguration wifiConfig = new WifiConfiguration(); wifiConfig.networkId = mNetworkId; + wifiConfig.BSSID = mBssid; bundle.putString(AccessPoint.KEY_SSID, ssid); bundle.putParcelable(AccessPoint.KEY_CONFIG, wifiConfig); @@ -67,6 +70,8 @@ public class TestAccessPointBuilder { if (mProviderFriendlyName != null) { bundle.putString(AccessPoint.KEY_PROVIDER_FRIENDLY_NAME, mProviderFriendlyName); } + bundle.putInt(AccessPoint.KEY_SECURITY, mSecurity); + AccessPoint ap = new AccessPoint(mContext, bundle); ap.setRssi(mRssi); return ap; @@ -141,6 +146,11 @@ public class TestAccessPointBuilder { return this; } + public TestAccessPointBuilder setSecurity(int security) { + mSecurity = security; + return this; + } + public TestAccessPointBuilder setSsid(String newSsid) { ssid = newSsid; return this; @@ -171,4 +181,9 @@ public class TestAccessPointBuilder { mNetworkId = networkId; return this; } + + public TestAccessPointBuilder setBssid(String bssid) { + mBssid = bssid; + return this; + } } diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index 9083d90b9085..596eaefcd054 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -16,6 +16,7 @@ package com.android.settingslib.wifi; import android.annotation.MainThread; +import android.annotation.Nullable; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -36,7 +37,6 @@ import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiNetworkScoreCache; import android.net.wifi.WifiNetworkScoreCache.CacheListener; -import android.os.ConditionVariable; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -91,7 +91,7 @@ public class WifiTracker { private final boolean mIncludeScans; private final boolean mIncludePasspoints; @VisibleForTesting final MainHandler mMainHandler; - private final WorkHandler mWorkHandler; + @VisibleForTesting final WorkHandler mWorkHandler; private WifiTrackerNetworkCallback mNetworkCallback; @@ -247,7 +247,10 @@ public class WifiTracker { mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_ACCESS_POINTS); mLastInfo = mWifiManager.getConnectionInfo(); mLastNetworkInfo = mConnectivityManager.getNetworkInfo(mWifiManager.getCurrentNetwork()); - updateAccessPointsLocked(); + + final List<ScanResult> newScanResults = mWifiManager.getScanResults(); + List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks(); + updateAccessPointsLocked(newScanResults, configs); if (DBG) { Log.d(TAG, "force update - internal access point list:\n" + mInternalAccessPoints); @@ -377,7 +380,7 @@ public class WifiTracker { mNetworkScoreManager.unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI, mScoreCache); mScoreCache.clearScores(); - // Synchronize on mLock to avoid concurrent modification during updateAccessPointsLocked + // Synchronize on mLock to avoid concurrent modification during updateAccessPoints synchronized (mLock) { mRequestedScores.clear(); } @@ -427,9 +430,8 @@ public class WifiTracker { mScanId = 0; } - private Collection<ScanResult> fetchScanResults() { + private Collection<ScanResult> updateScanResultCache(final List<ScanResult> newResults) { mScanId++; - final List<ScanResult> newResults = mWifiManager.getScanResults(); for (ScanResult newResult : newResults) { if (newResult.SSID == null || newResult.SSID.isEmpty()) { continue; @@ -457,8 +459,8 @@ public class WifiTracker { return mScanResultCache.values(); } - private WifiConfiguration getWifiConfigurationForNetworkId(int networkId) { - final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks(); + private WifiConfiguration getWifiConfigurationForNetworkId( + int networkId, final List<WifiConfiguration> configs) { if (configs != null) { for (WifiConfiguration config : configs) { if (mLastInfo != null && networkId == config.networkId && @@ -470,20 +472,37 @@ public class WifiTracker { return null; } - /** Safely modify {@link #mInternalAccessPoints} by acquiring {@link #mLock} first. */ - private void updateAccessPointsLocked() { + /** + * Safely modify {@link #mInternalAccessPoints} by acquiring {@link #mLock} first. + * + * <p>Will not perform the update if {@link #mStaleScanResults} is true + */ + private void updateAccessPoints() { + List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks(); + final List<ScanResult> newScanResults = mWifiManager.getScanResults(); + synchronized (mLock) { - updateAccessPoints(); + if(!mStaleScanResults) { + updateAccessPointsLocked(newScanResults, configs); + } } } /** * Update the internal list of access points. * - * <p>Should never be called directly, use {@link #updateAccessPointsLocked()} instead. + * <p>Do not called directly (except for forceUpdate), use {@link #updateAccessPoints()} which + * respects {@link #mStaleScanResults}. */ @GuardedBy("mLock") - private void updateAccessPoints() { + private void updateAccessPointsLocked(final List<ScanResult> newScanResults, + List<WifiConfiguration> configs) { + WifiConfiguration connectionConfig = null; + if (mLastInfo != null) { + connectionConfig = getWifiConfigurationForNetworkId( + mLastInfo.getNetworkId(), mWifiManager.getConfiguredNetworks()); + } + // Swap the current access points into a cached list. List<AccessPoint> cachedAccessPoints = new ArrayList<>(mInternalAccessPoints); ArrayList<AccessPoint> accessPoints = new ArrayList<>(); @@ -496,14 +515,9 @@ public class WifiTracker { /* Lookup table to more quickly update AccessPoints by only considering objects with the * correct SSID. Maps SSID -> List of AccessPoints with the given SSID. */ Multimap<String, AccessPoint> apMap = new Multimap<String, AccessPoint>(); - WifiConfiguration connectionConfig = null; - if (mLastInfo != null) { - connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId()); - } - final Collection<ScanResult> results = fetchScanResults(); + final Collection<ScanResult> results = updateScanResultCache(newScanResults); - final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks(); if (configs != null) { for (WifiConfiguration config : configs) { if (config.selfAdded && config.numAssociation == 0) { @@ -653,6 +667,7 @@ public class WifiTracker { /* sticky broadcasts can call this when wifi is disabled */ if (!mWifiManager.isWifiEnabled()) { mMainHandler.sendEmptyMessage(MainHandler.MSG_PAUSE_SCANNING); + clearAccessPointsAndConditionallyUpdate(); return; } @@ -670,7 +685,8 @@ public class WifiTracker { WifiConfiguration connectionConfig = null; mLastInfo = mWifiManager.getConnectionInfo(); if (mLastInfo != null) { - connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId()); + connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId(), + mWifiManager.getConfiguredNetworks()); } boolean updated = false; @@ -696,6 +712,17 @@ public class WifiTracker { } } + private void clearAccessPointsAndConditionallyUpdate() { + synchronized (mLock) { + if (!mInternalAccessPoints.isEmpty()) { + mInternalAccessPoints.clear(); + if (!mMainHandler.hasMessages(MainHandler.MSG_ACCESS_POINT_CHANGED)) { + mMainHandler.sendEmptyMessage(MainHandler.MSG_ACCESS_POINT_CHANGED); + } + } + } + } + /** * Update all the internal access points rankingScores, badge and metering. * @@ -720,6 +747,9 @@ public class WifiTracker { private void updateWifiState(int state) { mWorkHandler.obtainMessage(WorkHandler.MSG_UPDATE_WIFI_STATE, state, 0).sendToTarget(); + if (!mWifiManager.isWifiEnabled()) { + clearAccessPointsAndConditionallyUpdate(); + } } public static List<AccessPoint> getCurrentAccessPoints(Context context, boolean includeSaved, @@ -803,8 +833,15 @@ public class WifiTracker { mListener.onWifiStateChanged(msg.arg1); break; case MSG_ACCESS_POINT_CHANGED: - copyAndNotifyListeners(true /*notifyListeners*/); - mListener.onAccessPointsChanged(); + // Only notify listeners of changes if we have fresh scan results, otherwise the + // UI will be updated with stale results. We want to copy the APs regardless, + // for instances where forceUpdate was invoked by the caller. + if (mStaleScanResults) { + copyAndNotifyListeners(false /*notifyListeners*/); + } else { + copyAndNotifyListeners(true /*notifyListeners*/); + mListener.onAccessPointsChanged(); + } break; case MSG_RESUME_SCANNING: if (mScanner != null) { @@ -828,7 +865,8 @@ public class WifiTracker { } } - private final class WorkHandler extends Handler { + @VisibleForTesting + final class WorkHandler extends Handler { private static final int MSG_UPDATE_ACCESS_POINTS = 0; private static final int MSG_UPDATE_NETWORK_INFO = 1; private static final int MSG_RESUME = 2; @@ -845,15 +883,12 @@ public class WifiTracker { } } - @GuardedBy("mLock") private void processMessage(Message msg) { if (!mRegistered) return; switch (msg.what) { case MSG_UPDATE_ACCESS_POINTS: - if (!mStaleScanResults) { - updateAccessPointsLocked(); - } + updateAccessPoints(); break; case MSG_UPDATE_NETWORK_INFO: updateNetworkInfo((NetworkInfo) msg.obj); diff --git a/packages/SettingsLib/tests/integ/AndroidManifest.xml b/packages/SettingsLib/tests/integ/AndroidManifest.xml index 0d5ff2ca05a5..e8e0b41ffd41 100644 --- a/packages/SettingsLib/tests/integ/AndroidManifest.xml +++ b/packages/SettingsLib/tests/integ/AndroidManifest.xml @@ -21,6 +21,7 @@ <uses-permission android:name="android.permission.MANAGE_USERS" /> <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY"/> <uses-permission android:name="android.permission.SET_TIME_ZONE" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java index 83667ea00629..01df0ecfdb11 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java @@ -3,6 +3,7 @@ package com.android.settingslib.graph; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; +import android.graphics.Rect; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; @@ -12,6 +13,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import static com.google.common.truth.Truth.assertThat; +import static junit.framework.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyFloat; import static org.mockito.Matchers.anyString; @@ -68,4 +70,49 @@ public class BatteryMeterDrawableBaseTest { } } } + + @Test + public void testPadding_returnsCorrectValues() { + // different pads on each side to differentiate + final int left = 1; + final int top = 2; + final int right = 3; + final int bottom = 4; + + final Rect expected = new Rect(left, top, right, bottom); + final Rect padding = new Rect(); + + mBatteryDrawable.setPadding(left, top, right, bottom); + + assertThat(mBatteryDrawable.getPadding(padding)).isEqualTo(true); + assertThat(padding).isEqualTo(expected); + } + + @Test + public void testPadding_falseIfUnsetOrZero() { + final Rect padding = new Rect(); + assertThat(mBatteryDrawable.getPadding(padding)).isEqualTo(false); + assertThat(isRectZero(padding)).isEqualTo(true); + + mBatteryDrawable.setPadding(0, 0, 0, 0); + assertThat(mBatteryDrawable.getPadding(padding)).isEqualTo(false); + assertThat(isRectZero(padding)).isEqualTo(true); + } + + private boolean isRectZero(Rect r) { + return r.left == 0 && r.top == 0 && r.right == 0 && r.bottom == 0; + } + + @Test + public void testPlusPaint_isEqualToBoltPaint() { + // Before setting color + assertTrue(mBatteryDrawable.mPlusPaint.hasEqualAttributes(mBatteryDrawable.mBoltPaint)); + + final int fakeFillColor = 123; + final int fakeBackgrundColor = 456; + + // After + mBatteryDrawable.setColors(fakeFillColor, fakeBackgrundColor); + assertTrue(mBatteryDrawable.mPlusPaint.hasEqualAttributes(mBatteryDrawable.mBoltPaint)); + } } diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java index 89328ee47f1c..5c64cff78a88 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java @@ -20,6 +20,8 @@ import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; @@ -169,6 +171,21 @@ public class AccessPointTest { } @Test + public void testCompareTo_GivesSsidCasePrecendenceAfterAlphabetical() { + + final String firstName = "aaAaaa"; + final String secondName = "aaaaaa"; + final String thirdName = "BBBBBB"; + + AccessPoint firstAp = new TestAccessPointBuilder(mContext).setSsid(firstName).build(); + AccessPoint secondAp = new TestAccessPointBuilder(mContext).setSsid(secondName).build(); + AccessPoint thirdAp = new TestAccessPointBuilder(mContext).setSsid(thirdName).build(); + + assertSortingWorks(firstAp, secondAp); + assertSortingWorks(secondAp, thirdAp); + } + + @Test public void testCompareTo_AllSortingRulesCombined() { AccessPoint active = new TestAccessPointBuilder(mContext).setActive(true).build(); @@ -334,11 +351,11 @@ public class AccessPointTest { when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) .thenReturn(buildScoredNetworkWithMockBadgeCurve()); - when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.SPEED_VERY_FAST); + when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); - assertThat(ap.getSpeed()).isEqualTo(AccessPoint.SPEED_VERY_FAST); + assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.VERY_FAST); assertThat(ap.getSpeedLabel()) .isEqualTo(mContext.getString(R.string.speed_label_very_fast)); } @@ -349,11 +366,11 @@ public class AccessPointTest { when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) .thenReturn(buildScoredNetworkWithMockBadgeCurve()); - when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.SPEED_FAST); + when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.FAST); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); - assertThat(ap.getSpeed()).isEqualTo(AccessPoint.SPEED_FAST); + assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.FAST); assertThat(ap.getSpeedLabel()) .isEqualTo(mContext.getString(R.string.speed_label_fast)); } @@ -364,11 +381,11 @@ public class AccessPointTest { when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) .thenReturn(buildScoredNetworkWithMockBadgeCurve()); - when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.SPEED_MEDIUM); + when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.MODERATE); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); - assertThat(ap.getSpeed()).isEqualTo(AccessPoint.SPEED_MEDIUM); + assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.MODERATE); assertThat(ap.getSpeedLabel()) .isEqualTo(mContext.getString(R.string.speed_label_okay)); } @@ -379,11 +396,11 @@ public class AccessPointTest { when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) .thenReturn(buildScoredNetworkWithMockBadgeCurve()); - when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.SPEED_SLOW); + when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.SLOW); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); - assertThat(ap.getSpeed()).isEqualTo(AccessPoint.SPEED_SLOW); + assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.SLOW); assertThat(ap.getSpeedLabel()) .isEqualTo(mContext.getString(R.string.speed_label_slow)); } @@ -394,7 +411,7 @@ public class AccessPointTest { when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) .thenReturn(buildScoredNetworkWithMockBadgeCurve()); - when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.SPEED_VERY_FAST); + when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); @@ -408,7 +425,7 @@ public class AccessPointTest { when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) .thenReturn(buildScoredNetworkWithMockBadgeCurve()); - when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.SPEED_VERY_FAST); + when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST); ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */); @@ -607,4 +624,36 @@ public class AccessPointTest { NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values assertThat(ap.update(config, wifiInfo, newInfo)).isFalse(); } + + @Test + public void testUpdateWithConfigChangeOnly_returnsFalseButInvokesListener() { + int networkId = 123; + int rssi = -55; + WifiConfiguration config = new WifiConfiguration(); + config.networkId = networkId; + config.numNoInternetAccessReports = 1; + + WifiInfo wifiInfo = new WifiInfo(); + wifiInfo.setNetworkId(networkId); + wifiInfo.setRssi(rssi); + + NetworkInfo networkInfo = + new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); + networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); + + AccessPoint ap = new TestAccessPointBuilder(mContext) + .setNetworkInfo(networkInfo) + .setNetworkId(networkId) + .setRssi(rssi) + .setWifiInfo(wifiInfo) + .build(); + + AccessPoint.AccessPointListener mockListener = mock(AccessPoint.AccessPointListener.class); + ap.setListener(mockListener); + WifiConfiguration newConfig = new WifiConfiguration(config); + config.validatedInternetAccess = true; + + assertThat(ap.update(newConfig, wifiInfo, networkInfo)).isFalse(); + verify(mockListener).onAccessPointChanged(ap); + } } diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java index 340ef016d74d..071f9216ea56 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java @@ -59,6 +59,7 @@ import android.provider.Settings; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; +import android.support.test.filters.FlakyTest; import org.junit.After; import org.junit.Before; @@ -94,7 +95,7 @@ public class WifiTrackerTest { new NetworkKey(new WifiKey('"' + SSID_1 + '"', BSSID_1)); private static final int RSSI_1 = -30; private static final byte SCORE_1 = 10; - private static final int BADGE_1 = AccessPoint.SPEED_MEDIUM; + private static final int BADGE_1 = AccessPoint.Speed.MODERATE; private static final String SSID_2 = "ssid2"; private static final String BSSID_2 = "AA:AA:AA:AA:AA:AA"; @@ -102,7 +103,7 @@ public class WifiTrackerTest { new NetworkKey(new WifiKey('"' + SSID_2 + '"', BSSID_2)); private static final int RSSI_2 = -30; private static final byte SCORE_2 = 15; - private static final int BADGE_2 = AccessPoint.SPEED_FAST; + private static final int BADGE_2 = AccessPoint.Speed.FAST; private static final int CONNECTED_NETWORK_ID = 123; private static final int CONNECTED_RSSI = -50; @@ -256,6 +257,7 @@ public class WifiTrackerTest { } sendScanResultsAndProcess(tracker); + waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker); return tracker; } @@ -341,6 +343,23 @@ public class WifiTrackerTest { return createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(intent); } + private void waitForHandlersToProcessCurrentlyEnqueuedMessages(WifiTracker tracker) + throws InterruptedException { + CountDownLatch workerLatch = new CountDownLatch(1); + tracker.mWorkHandler.post(() -> { + workerLatch.countDown(); + }); + assertTrue("Latch timed out while waiting for WorkerHandler", + workerLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS)); + + CountDownLatch mainLatch = new CountDownLatch(1); + tracker.mMainHandler.post(() -> { + mainLatch.countDown(); + }); + assertTrue("Latch timed out while waiting for MainHandler", + mainLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS)); + } + @Test public void testAccessPointListenerSetWhenLookingUpUsingScanResults() { ScanResult scanResult = new ScanResult(); @@ -426,7 +445,7 @@ public class WifiTrackerTest { @Test public void startTrackingShouldSetConnectedAccessPointAsActive() throws InterruptedException { - WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected(); + WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected(); List<AccessPoint> aps = tracker.getAccessPoints(); @@ -460,18 +479,21 @@ public class WifiTrackerTest { startTracking(tracker); sendScanResultsAndProcess(tracker); - updateScoresAndWaitForAccessPointsChangedCallback(); + updateScoresAndWaitForAccessPointsChangedCallback(tracker); } - private void updateScoresAndWaitForAccessPointsChangedCallback() throws InterruptedException { + private void updateScoresAndWaitForAccessPointsChangedCallback(WifiTracker tracker) + throws InterruptedException { // Updating scores can happen together or one after the other, so the latch countdown is set // to 2. - mAccessPointsChangedLatch = new CountDownLatch(2); + mAccessPointsChangedLatch = new CountDownLatch(1); updateScores(); - assertTrue("onAccessPointChanged was not called twice", + assertTrue("onAccessPointChanged was not called after updating scores", mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS)); + waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker); } + @FlakyTest @Test public void scoreCacheUpdateScoresShouldChangeSortOrder() throws InterruptedException { WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(); @@ -480,7 +502,7 @@ public class WifiTrackerTest { assertEquals(aps.get(0).getSsidStr(), SSID_1); assertEquals(aps.get(1).getSsidStr(), SSID_2); - updateScoresAndWaitForAccessPointsChangedCallback(); + updateScoresAndWaitForAccessPointsChangedCallback(tracker); aps = tracker.getAccessPoints(); assertTrue(aps.size() == 2); @@ -502,7 +524,7 @@ public class WifiTrackerTest { assertEquals(aps.get(0).getSsidStr(), SSID_1); assertEquals(aps.get(1).getSsidStr(), SSID_2); - updateScoresAndWaitForAccessPointsChangedCallback(); + updateScoresAndWaitForAccessPointsChangedCallback(tracker); aps = tracker.getAccessPoints(); assertTrue(aps.size() == 2); @@ -510,11 +532,12 @@ public class WifiTrackerTest { assertEquals(aps.get(1).getSsidStr(), SSID_2); } + @FlakyTest @Test public void scoreCacheUpdateScoresShouldInsertSpeedIntoAccessPoint() throws InterruptedException { WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(); - updateScoresAndWaitForAccessPointsChangedCallback(); + updateScoresAndWaitForAccessPointsChangedCallback(tracker); List<AccessPoint> aps = tracker.getAccessPoints(); @@ -531,7 +554,7 @@ public class WifiTrackerTest { public void scoreCacheUpdateMeteredShouldUpdateAccessPointMetering() throws InterruptedException { WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(); - updateScoresAndWaitForAccessPointsChangedCallback(); + updateScoresAndWaitForAccessPointsChangedCallback(tracker); List<AccessPoint> aps = tracker.getAccessPoints(); @@ -553,15 +576,15 @@ public class WifiTrackerTest { 0 /* disabled */); WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(); - updateScoresAndWaitForAccessPointsChangedCallback(); + updateScoresAndWaitForAccessPointsChangedCallback(tracker); List<AccessPoint> aps = tracker.getAccessPoints(); for (AccessPoint ap : aps) { if (ap.getSsidStr().equals(SSID_1)) { - assertEquals(AccessPoint.SPEED_NONE, ap.getSpeed()); + assertEquals(AccessPoint.Speed.NONE, ap.getSpeed()); } else if (ap.getSsidStr().equals(SSID_2)) { - assertEquals(AccessPoint.SPEED_NONE, ap.getSpeed()); + assertEquals(AccessPoint.Speed.NONE, ap.getSpeed()); } } } @@ -754,13 +777,10 @@ public class WifiTrackerTest { throws Exception { WifiTracker tracker = createMockedWifiTracker(); startTracking(tracker); - tracker.stopTracking(); + waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker); - CountDownLatch latch1 = new CountDownLatch(1); - tracker.mMainHandler.post(() -> { - latch1.countDown(); - }); - assertTrue("Latch 1 timed out", latch1.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS)); + tracker.stopTracking(); + waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker); startTracking(tracker); @@ -770,14 +790,24 @@ public class WifiTrackerTest { tracker.mReceiver.onReceive( mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION)); - CountDownLatch latch2 = new CountDownLatch(1); - tracker.mMainHandler.post(() -> { - latch2.countDown(); - }); - assertTrue("Latch 2 timed out", latch2.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS)); + waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker); verify(mockWifiListener, never()).onAccessPointsChanged(); sendScanResultsAndProcess(tracker); // verifies onAccessPointsChanged is invoked } + + @Test + public void disablingWifiShouldClearExistingAccessPoints() throws Exception { + WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected(); + + when(mockWifiManager.isWifiEnabled()).thenReturn(false); + mAccessPointsChangedLatch = new CountDownLatch(1); + tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION)); + + mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS); + waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker); + + assertThat(tracker.getAccessPoints()).isEmpty(); + } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java new file mode 100644 index 000000000000..335653bc2f18 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.settingslib.wifi; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; + +import com.android.settingslib.SettingLibRobolectricTestRunner; +import com.android.settingslib.TestConfig; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(SettingLibRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class AccessPointPreferenceTest { + + private Context mContext = RuntimeEnvironment.application; + + @Test + public void generatePreferenceKey_shouldReturnSsidPlusSecurity() { + String ssid = "ssid"; + int security = AccessPoint.SECURITY_WEP; + String expectedKey = ssid + ',' + security; + + TestAccessPointBuilder builder = new TestAccessPointBuilder(mContext); + builder.setSsid(ssid).setSecurity(security); + + assertThat(AccessPointPreference.generatePreferenceKey(builder.build())) + .isEqualTo(expectedKey); + } + + @Test + public void generatePreferenceKey_shouldReturnBssidPlusSecurity() { + String bssid = "bssid"; + int security = AccessPoint.SECURITY_WEP; + String expectedKey = bssid + ',' + security; + + TestAccessPointBuilder builder = new TestAccessPointBuilder(mContext); + builder.setBssid(bssid).setSecurity(security); + + assertThat(AccessPointPreference.generatePreferenceKey(builder.build())) + .isEqualTo(expectedKey); + } +} diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java index 1e171d3f8210..8abdc641d675 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java @@ -37,10 +37,12 @@ import android.provider.Settings; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.ArraySet; +import android.util.Slog; import java.util.Locale; public class SettingsHelper { + private static final String TAG = "SettingsHelper"; private static final String SILENT_RINGTONE = "_silent"; private Context mContext; private AudioManager mAudioManager; @@ -324,11 +326,17 @@ public class SettingsHelper { */ void setLocaleData(byte[] data, int size) { // Check if locale was set by the user: - Configuration conf = mContext.getResources().getConfiguration(); - // TODO: The following is not working as intended because the network is forcing a locale - // change after registering. Need to find some other way to detect if the user manually - // changed the locale - if (conf.userSetLocale) return; // Don't change if user set it in the SetupWizard + final ContentResolver cr = mContext.getContentResolver(); + final boolean userSetLocale = mContext.getResources().getConfiguration().userSetLocale; + final boolean provisioned = Settings.Global.getInt(cr, + Settings.Global.DEVICE_PROVISIONED, 0) != 0; + if (userSetLocale || provisioned) { + // Don't change if user set it in the SetupWizard, or if this is a post-setup + // deferred restore operation + Slog.i(TAG, "Not applying restored locale; " + + (userSetLocale ? "user already specified" : "device already provisioned")); + return; + } final String[] availableLocales = mContext.getAssets().getLocales(); // Replace "_" with "-" to deal with older backups. diff --git a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java index d9719f356f14..f59c4a56bf3b 100644 --- a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java +++ b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java @@ -29,6 +29,7 @@ import android.util.Range; import com.google.android.colorextraction.ColorExtractor.GradientColors; +import java.util.Arrays; import java.util.List; /** @@ -311,6 +312,12 @@ public class Tonal implements ExtractionType { final float maxHue; TonalPalette(float[] h, float[] s, float[] l) { + if (h.length != s.length || s.length != l.length) { + throw new IllegalArgumentException("All arrays should have the same size. h: " + + Arrays.toString(h) + " s: " + Arrays.toString(s) + " l: " + + Arrays.toString(l)); + } + this.h = h; this.s = s; this.l = l; @@ -388,7 +395,7 @@ public class Tonal implements ExtractionType { new float[] {0.70f, 0.72f, 0.69f, 0.6703296703296703f, 0.728813559322034f, 0.5657142857142856f, 0.5076923076923077f, 0.3944223107569721f, 0.6206896551724138f, 0.8931297709923666f, 1f, 1f, 1f}, - new float[] {0.05f, 0.08f, 0.1784313725490196f, 0.23137254901960785f, + new float[] {0.05f, 0.08f, 0.14f, 0.1784313725490196f, 0.23137254901960785f, 0.3431372549019608f, 0.38235294117647056f, 0.49215686274509807f, 0.6588235294117647f, 0.7431372549019608f, 0.8176470588235294f, 0.8784313725490196f, 0.9294117647058824f} @@ -442,7 +449,7 @@ public class Tonal implements ExtractionType { 0.8285256410256411f, 0.821522309711286f, 0.8083333333333333f, 0.8046594982078853f, 0.8005822416302766f, 0.7842377260981912f, 0.7771084337349398f, 0.7747747747747749f}, - new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, + new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 0.737142857142857f, 0.6434108527131781f, 0.46835443037974644f}, new float[] {0.05f, 0.08f, 0.12745098039215685f, 0.15490196078431373f, 0.20392156862745098f, 0.24901960784313726f, 0.3137254901960784f, diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java new file mode 100644 index 000000000000..925214e3ab3a --- /dev/null +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui.plugins; + +import android.app.Activity; +import android.content.Context; +import android.content.res.Resources; +import android.os.Bundle; + +import com.android.systemui.plugins.annotations.ProvidesInterface; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * A PluginActivity is an activity that replaces another full activity (e.g. RecentsActivity) + * at runtime within the sysui process. + */ +@ProvidesInterface(version = PluginActivity.VERSION) +public abstract class PluginActivity extends Activity implements Plugin { + + public static final int VERSION = 1; + + public static final String ACTION_RECENTS = "com.android.systemui.action.PLUGIN_RECENTS"; + + private Context mSysuiContext; + private boolean mSettingActionBar; + + @Override + public final void onCreate(Context sysuiContext, Context pluginContext) { + mSysuiContext = sysuiContext; + super.attachBaseContext(pluginContext); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Theme theme = getClass().getDeclaredAnnotation(Theme.class); + if (theme != null && theme.value() != 0) { + setTheme(theme.value()); + } + mSettingActionBar = true; + getActionBar(); + mSettingActionBar = false; + } + + @Override + public Resources getResources() { + return mSettingActionBar ? mSysuiContext.getResources() : super.getResources(); + } + + @Override + protected void attachBaseContext(Context newBase) { + mSysuiContext = newBase; + } + + @Override + public void onDestroy() { + super.onDestroy(); + } + + public Context getSysuiContext() { + return mSysuiContext; + } + + public Context getPluginContext() { + return getBaseContext(); + } + + /** + * Since PluginActivities are declared as services instead of activities (since they + * are plugins), they can't have a theme attached to them. Instead a PluginActivity + * can annotate itself with @Theme to specify the resource of the style it wants + * to be themed with. + */ + @Retention(RetentionPolicy.RUNTIME) + public @interface Theme { + int value(); + } +} diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java index 25ce3ddf8169..db2e3765d2d0 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java @@ -21,6 +21,11 @@ public class PluginDependency { public static final int VERSION = 1; static DependencyProvider sProvider; + /** + * Allows a plugin to get a hold of static dependencies if they have declared dependence + * on their interface. For one-shot plugins this will only work during onCreate and will + * not work afterwards. + */ public static <T> T get(Plugin p, Class<T> cls) { return sProvider.get(p, cls); } diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml deleted file mode 100644 index b003e92f7a15..000000000000 --- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2014 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. ---> -<set xmlns:android="http://schemas.android.com/apk/res/android" > - <set - android:ordering="sequentially" > - <objectAnimator - android:duration="367" - android:propertyName="fillAlpha" - android:valueFrom="1" - android:valueTo="1" - android:interpolator="@android:interpolator/linear" /> - <objectAnimator - android:duration="33" - android:propertyName="fillAlpha" - android:valueFrom="1" - android:valueTo="0" - android:interpolator="@android:interpolator/linear" /> - </set> -</set> diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml deleted file mode 100644 index b003e92f7a15..000000000000 --- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2014 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. ---> -<set xmlns:android="http://schemas.android.com/apk/res/android" > - <set - android:ordering="sequentially" > - <objectAnimator - android:duration="367" - android:propertyName="fillAlpha" - android:valueFrom="1" - android:valueTo="1" - android:interpolator="@android:interpolator/linear" /> - <objectAnimator - android:duration="33" - android:propertyName="fillAlpha" - android:valueFrom="1" - android:valueTo="0" - android:interpolator="@android:interpolator/linear" /> - </set> -</set> diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml deleted file mode 100644 index fa10b1194977..000000000000 --- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2014 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. ---> -<set xmlns:android="http://schemas.android.com/apk/res/android" > - <set - android:ordering="sequentially" > - <objectAnimator - android:duration="50" - android:propertyName="fillAlpha" - android:valueFrom="0" - android:valueTo="0" - android:interpolator="@android:interpolator/linear" /> - <objectAnimator - android:duration="33" - android:propertyName="fillAlpha" - android:valueFrom="0" - android:valueTo="1" - android:interpolator="@android:interpolator/linear" /> - </set> -</set> diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml deleted file mode 100644 index fa10b1194977..000000000000 --- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2014 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. ---> -<set xmlns:android="http://schemas.android.com/apk/res/android" > - <set - android:ordering="sequentially" > - <objectAnimator - android:duration="50" - android:propertyName="fillAlpha" - android:valueFrom="0" - android:valueTo="0" - android:interpolator="@android:interpolator/linear" /> - <objectAnimator - android:duration="33" - android:propertyName="fillAlpha" - android:valueFrom="0" - android:valueTo="1" - android:interpolator="@android:interpolator/linear" /> - </set> -</set> diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml deleted file mode 100644 index aa22c3b72540..000000000000 --- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2014 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. ---> -<set xmlns:android="http://schemas.android.com/apk/res/android" > - <set - android:ordering="sequentially" > - <objectAnimator - android:duration="67" - android:propertyName="pathData" - android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z" - android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z" - android:valueType="pathType" - android:interpolator="@android:interpolator/fast_out_slow_in" /> - <objectAnimator - android:duration="217" - android:propertyName="pathData" - android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z" - android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z" - android:valueType="pathType" - android:interpolator="@android:interpolator/fast_out_slow_in" /> - </set> -</set> diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml index 2530f08179a2..8fdad809f0d1 100644 --- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml +++ b/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,11 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. --> -<set xmlns:android="http://schemas.android.com/apk/res/android" > +<set + xmlns:android="http://schemas.android.com/apk/res/android" > <objectAnimator - android:duration="400" + android:duration="616" android:propertyName="rotation" - android:valueFrom="-45" - android:valueTo="0" + android:valueFrom="-90.0" + android:valueTo="0.0" + android:valueType="floatType" android:interpolator="@android:interpolator/fast_out_slow_in" /> </set> diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml index 682dcf35e076..3c3c131ef16b 100644 --- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml +++ b/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,20 +14,23 @@ See the License for the specific language governing permissions and limitations under the License. --> -<set xmlns:android="http://schemas.android.com/apk/res/android" > +<set + xmlns:android="http://schemas.android.com/apk/res/android" > <set android:ordering="sequentially" > <objectAnimator android:duration="50" android:propertyName="fillAlpha" - android:valueFrom="0" - android:valueTo="0" + android:valueFrom="0.0" + android:valueTo="0.0" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> <objectAnimator android:duration="83" android:propertyName="fillAlpha" - android:valueFrom="0" - android:valueTo="1" + android:valueFrom="0.0" + android:valueTo="1.0" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> </set> </set> diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml new file mode 100644 index 000000000000..57132e19dcc5 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <objectAnimator + android:duration="466" + android:propertyName="scaleX" + android:valueFrom="1.0" + android:valueTo="0.909" + android:valueType="floatType" + android:interpolator="@interpolator/ic_landscape_to_rotate_animation_interpolator_0" /> + <objectAnimator + android:duration="466" + android:propertyName="scaleY" + android:valueFrom="1.0" + android:valueTo="0.909" + android:valueType="floatType" + android:interpolator="@interpolator/ic_landscape_to_rotate_animation_interpolator_0" /> + <set + android:ordering="sequentially" > + <objectAnimator + android:duration="50" + android:propertyName="rotation" + android:valueFrom="0.0" + android:valueTo="0.0" + android:valueType="floatType" + android:interpolator="@android:interpolator/linear" /> + <objectAnimator + android:duration="400" + android:propertyName="rotation" + android:valueFrom="0.0" + android:valueTo="45.0" + android:valueType="floatType" + android:interpolator="@android:interpolator/fast_out_slow_in" /> + </set> +</set> diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml deleted file mode 100644 index 92b19add4bcb..000000000000 --- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2014 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. ---> -<set xmlns:android="http://schemas.android.com/apk/res/android" > - <set - android:ordering="sequentially" > - <objectAnimator - android:duration="167" - android:propertyName="pathData" - android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z" - android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z" - android:valueType="pathType" - android:interpolator="@android:interpolator/fast_out_slow_in" /> - <objectAnimator - android:duration="217" - android:propertyName="pathData" - android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z" - android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z" - android:valueType="pathType" - android:interpolator="@android:interpolator/fast_out_slow_in" /> - </set> -</set> diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml index 61bdfeaa27a0..ad2a5fad5268 100644 --- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml +++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,41 +14,40 @@ See the License for the specific language governing permissions and limitations under the License. --> -<set xmlns:android="http://schemas.android.com/apk/res/android" > +<set + xmlns:android="http://schemas.android.com/apk/res/android" > <set android:ordering="sequentially" > <objectAnimator - android:duration="117" + android:duration="116" android:propertyName="scaleX" - android:valueFrom="1" - android:valueTo="1" + android:valueFrom="1.0" + android:valueTo="1.0" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> <objectAnimator android:duration="333" android:propertyName="scaleX" - android:valueFrom="1" + android:valueFrom="1.0" android:valueTo="0.9" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> </set> <set android:ordering="sequentially" > <objectAnimator - android:duration="117" + android:duration="116" android:propertyName="scaleY" - android:valueFrom="1" - android:valueTo="1" + android:valueFrom="1.0" + android:valueTo="1.0" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> <objectAnimator android:duration="333" android:propertyName="scaleY" - android:valueFrom="1" + android:valueFrom="1.0" android:valueTo="0.9" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> </set> - <objectAnimator - android:duration="617" - android:propertyName="rotation" - android:valueFrom="0" - android:valueTo="-221" - android:interpolator="@android:interpolator/fast_out_slow_in" /> </set> diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml index 27fd65324bab..cdb7890dc170 100644 --- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml +++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,11 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. --> -<set xmlns:android="http://schemas.android.com/apk/res/android" > +<set + xmlns:android="http://schemas.android.com/apk/res/android" > <objectAnimator - android:duration="400" + android:duration="616" android:propertyName="rotation" - android:valueFrom="0" - android:valueTo="-45" + android:valueFrom="0.0" + android:valueTo="-221.0" + android:valueType="floatType" android:interpolator="@android:interpolator/fast_out_slow_in" /> </set> diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml index 4e20d8190bbc..46100b407831 100644 --- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml +++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,20 +14,23 @@ See the License for the specific language governing permissions and limitations under the License. --> -<set xmlns:android="http://schemas.android.com/apk/res/android" > +<set + xmlns:android="http://schemas.android.com/apk/res/android" > <set android:ordering="sequentially" > <objectAnimator android:duration="400" android:propertyName="fillAlpha" - android:valueFrom="1" - android:valueTo="1" + android:valueFrom="1.0" + android:valueTo="1.0" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> <objectAnimator android:duration="83" android:propertyName="fillAlpha" - android:valueFrom="1" - android:valueTo="0" + android:valueFrom="1.0" + android:valueTo="0.0" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> </set> </set> diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml index 6a0a20bd1242..8f6d24d0d61d 100644 --- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml +++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,11 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. --> -<set xmlns:android="http://schemas.android.com/apk/res/android" > +<set + xmlns:android="http://schemas.android.com/apk/res/android" > <objectAnimator android:duration="400" android:propertyName="rotation" - android:valueFrom="0" - android:valueTo="-135" + android:valueFrom="0.0" + android:valueTo="-135.0" + android:valueType="floatType" android:interpolator="@android:interpolator/fast_out_slow_in" /> </set> diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml index aa086c9399d4..300ed53052a8 100644 --- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml +++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,18 +14,19 @@ See the License for the specific language governing permissions and limitations under the License. --> -<set xmlns:android="http://schemas.android.com/apk/res/android" > +<set + xmlns:android="http://schemas.android.com/apk/res/android" > <set android:ordering="sequentially" > <objectAnimator - android:duration="67" + android:duration="66" android:propertyName="pathData" android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z" android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z" android:valueType="pathType" - android:interpolator="@android:interpolator/fast_out_slow_in" /> + android:interpolator="@android:interpolator/linear" /> <objectAnimator - android:duration="217" + android:duration="216" android:propertyName="pathData" android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z" android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z" diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml index 9fa8ec0d65d4..ad2a5fad5268 100644 --- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml +++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,41 +14,40 @@ See the License for the specific language governing permissions and limitations under the License. --> -<set xmlns:android="http://schemas.android.com/apk/res/android" > +<set + xmlns:android="http://schemas.android.com/apk/res/android" > <set android:ordering="sequentially" > <objectAnimator - android:duration="133" + android:duration="116" android:propertyName="scaleX" - android:valueFrom="0.9" - android:valueTo="0.9" + android:valueFrom="1.0" + android:valueTo="1.0" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> <objectAnimator android:duration="333" android:propertyName="scaleX" - android:valueFrom="0.9" - android:valueTo="1" + android:valueFrom="1.0" + android:valueTo="0.9" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> </set> <set android:ordering="sequentially" > <objectAnimator - android:duration="133" + android:duration="116" android:propertyName="scaleY" - android:valueFrom="0.9" - android:valueTo="0.9" + android:valueFrom="1.0" + android:valueTo="1.0" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> <objectAnimator android:duration="333" android:propertyName="scaleY" - android:valueFrom="0.9" - android:valueTo="1" + android:valueFrom="1.0" + android:valueTo="0.9" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> </set> - <objectAnimator - android:duration="617" - android:propertyName="rotation" - android:valueFrom="-221" - android:valueTo="0" - android:interpolator="@android:interpolator/fast_out_slow_in" /> </set> diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml new file mode 100644 index 000000000000..c1521520c427 --- /dev/null +++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <objectAnimator + android:duration="616" + android:propertyName="rotation" + android:valueFrom="0.0" + android:valueTo="-180.0" + android:valueType="floatType" + android:interpolator="@android:interpolator/fast_out_slow_in" /> +</set> diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml index 4e20d8190bbc..b2c1eb8b93a3 100644 --- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml +++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,20 +14,23 @@ See the License for the specific language governing permissions and limitations under the License. --> -<set xmlns:android="http://schemas.android.com/apk/res/android" > +<set + xmlns:android="http://schemas.android.com/apk/res/android" > <set android:ordering="sequentially" > <objectAnimator - android:duration="400" + android:duration="200" android:propertyName="fillAlpha" - android:valueFrom="1" - android:valueTo="1" + android:valueFrom="1.0" + android:valueTo="1.0" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> <objectAnimator android:duration="83" android:propertyName="fillAlpha" - android:valueFrom="1" - android:valueTo="0" + android:valueFrom="1.0" + android:valueTo="0.0" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> </set> </set> diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml index 5c374797e7dd..2a9bbe32975e 100644 --- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml +++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,41 +14,47 @@ See the License for the specific language governing permissions and limitations under the License. --> -<set xmlns:android="http://schemas.android.com/apk/res/android" > +<set + xmlns:android="http://schemas.android.com/apk/res/android" > <set android:ordering="sequentially" > <objectAnimator - android:duration="117" + android:duration="116" android:propertyName="scaleX" - android:valueFrom="1" - android:valueTo="1" + android:valueFrom="0.909" + android:valueTo="0.909" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> <objectAnimator - android:duration="333" + android:duration="166" android:propertyName="scaleX" - android:valueFrom="1" - android:valueTo="0.9" - android:interpolator="@android:interpolator/linear" /> + android:valueFrom="0.909" + android:valueTo="1.0" + android:valueType="floatType" + android:interpolator="@interpolator/ic_rotate_to_landscape_animation_interpolator_0" /> </set> <set android:ordering="sequentially" > <objectAnimator - android:duration="117" + android:duration="116" android:propertyName="scaleY" - android:valueFrom="1" - android:valueTo="1" + android:valueFrom="0.909" + android:valueTo="0.909" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> <objectAnimator - android:duration="333" + android:duration="166" android:propertyName="scaleY" - android:valueFrom="1" - android:valueTo="0.9" - android:interpolator="@android:interpolator/linear" /> + android:valueFrom="0.909" + android:valueTo="1.0" + android:valueType="floatType" + android:interpolator="@interpolator/ic_rotate_to_landscape_animation_interpolator_0" /> </set> <objectAnimator - android:duration="450" + android:duration="616" android:propertyName="rotation" - android:valueFrom="0" - android:valueTo="-135" - android:interpolator="@interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator" /> + android:valueFrom="45.0" + android:valueTo="0.0" + android:valueType="floatType" + android:interpolator="@android:interpolator/fast_out_slow_in" /> </set> diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml index caae73a1445c..ce267704dac5 100644 --- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml +++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,23 +14,20 @@ See the License for the specific language governing permissions and limitations under the License. --> -<set xmlns:android="http://schemas.android.com/apk/res/android" > +<set + xmlns:android="http://schemas.android.com/apk/res/android" > <objectAnimator - android:duration="333" + android:duration="466" android:propertyName="scaleX" android:valueFrom="0.9" - android:valueTo="1" - android:interpolator="@android:interpolator/linear" /> + android:valueTo="1.0" + android:valueType="floatType" + android:interpolator="@interpolator/ic_rotate_to_portrait_animation_interpolator_0" /> <objectAnimator - android:duration="333" + android:duration="466" android:propertyName="scaleY" android:valueFrom="0.9" - android:valueTo="1" - android:interpolator="@android:interpolator/linear" /> - <objectAnimator - android:duration="450" - android:propertyName="rotation" - android:valueFrom="-135" - android:valueTo="0" - android:interpolator="@interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator" /> + android:valueTo="1.0" + android:valueType="floatType" + android:interpolator="@interpolator/ic_rotate_to_portrait_animation_interpolator_0" /> </set> diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml new file mode 100644 index 000000000000..6e8941d608cd --- /dev/null +++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<set + xmlns:android="http://schemas.android.com/apk/res/android" > + <objectAnimator + android:duration="616" + android:propertyName="rotation" + android:valueFrom="-221.0" + android:valueTo="0.0" + android:valueType="floatType" + android:interpolator="@android:interpolator/fast_out_slow_in" /> +</set> diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml index 682dcf35e076..3c3c131ef16b 100644 --- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml +++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,20 +14,23 @@ See the License for the specific language governing permissions and limitations under the License. --> -<set xmlns:android="http://schemas.android.com/apk/res/android" > +<set + xmlns:android="http://schemas.android.com/apk/res/android" > <set android:ordering="sequentially" > <objectAnimator android:duration="50" android:propertyName="fillAlpha" - android:valueFrom="0" - android:valueTo="0" + android:valueFrom="0.0" + android:valueTo="0.0" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> <objectAnimator android:duration="83" android:propertyName="fillAlpha" - android:valueFrom="0" - android:valueTo="1" + android:valueFrom="0.0" + android:valueTo="1.0" + android:valueType="floatType" android:interpolator="@android:interpolator/linear" /> </set> </set> diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml index 3208eee2c2c6..fd8e4f881160 100644 --- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml +++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,20 +14,23 @@ See the License for the specific language governing permissions and limitations under the License. --> -<set xmlns:android="http://schemas.android.com/apk/res/android" > +<set + xmlns:android="http://schemas.android.com/apk/res/android" > <set android:ordering="sequentially" > <objectAnimator android:duration="50" android:propertyName="rotation" - android:valueFrom="-135" - android:valueTo="-135" - android:interpolator="@android:interpolator/fast_out_slow_in" /> + android:valueFrom="-135.0" + android:valueTo="-135.0" + android:valueType="floatType" + android:interpolator="@android:interpolator/linear" /> <objectAnimator android:duration="400" android:propertyName="rotation" - android:valueFrom="-135" - android:valueTo="0" + android:valueFrom="-135.0" + android:valueTo="0.0" + android:valueType="floatType" android:interpolator="@android:interpolator/fast_out_slow_in" /> </set> </set> diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml index c1124af4e234..a77a536e46c0 100644 --- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml +++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. --> -<set xmlns:android="http://schemas.android.com/apk/res/android" > +<set + xmlns:android="http://schemas.android.com/apk/res/android" > <set android:ordering="sequentially" > <objectAnimator @@ -23,7 +24,7 @@ android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z" android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z" android:valueType="pathType" - android:interpolator="@android:interpolator/fast_out_slow_in" /> + android:interpolator="@android:interpolator/linear" /> <objectAnimator android:duration="500" android:propertyName="pathData" diff --git a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml index 8b2585bb9958..061f9fe81a75 100644 --- a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml +++ b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,49 +14,52 @@ See the License for the specific language governing permissions and limitations under the License. --> -<vector xmlns:android="http://schemas.android.com/apk/res/android" +<vector + xmlns:android="http://schemas.android.com/apk/res/android" + android:name="ic_rotate_to_landscape" android:height="48dp" android:width="48dp" android:viewportHeight="48" android:viewportWidth="48" android:tint="?android:attr/colorControlNormal" > <group - android:name="ic_screen_rotation_48px_outlines" + android:name="device" android:translateX="24" android:translateY="24" > <group - android:name="ic_screen_rotation_48px_outlines_pivot" + android:name="device_pivot" android:translateX="-24.15" android:translateY="-24.25" > <group - android:name="arrows" - android:translateX="24.1" - android:translateY="24.1" > - <group - android:name="arrows_pivot" - android:translateX="-24.1" - android:translateY="-24.1" > - <path - android:name="arrow_top" - android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - <path - android:name="arrow_bottom" - android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> + android:name="landscape" + android:translateX="24" + android:translateY="24" + android:scaleX="0.909" + android:scaleY="0.909" + android:rotation="45" > + <path + android:name="device_merged" + android:pathData="M -21.9799957275,-10.0 c 0.0,0.0 -0.0200042724609,20.0 -0.0200042724609,20.0 c 0.0,2.19999694824 1.80000305176,4.0 4.0,4.0 c 0.0,0.0 36.0,0.0 36.0,0.0 c 2.19999694824,0.0 4.0,-1.80000305176 4.0,-4.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,-2.19999694824 -1.80000305176,-4.0 -4.0,-4.0 c 0.0,0.0 -36.0,0.0 -36.0,0.0 c -2.19999694824,0.0 -3.97999572754,1.80000305176 -3.97999572754,4.0 Z M 14.0,10.0 c 0.0,0.0 -28.0,0.0 -28.0,0.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,0.0 28.0,0.0 28.0,0.0 c 0.0,0.0 0.0,20.0 0.0,20.0 Z" + android:fillColor="#FFFFFFFF" /> </group> + </group> + </group> + <group + android:name="arrows" + android:translateX="24" + android:translateY="24" > + <group + android:name="arrows_pivot" + android:translateX="-24.0798" + android:translateY="-24.23" > <group - android:name="device" - android:translateX="24.14999" - android:translateY="24.25" > + android:name="arrows_0" + android:translateX="12.2505" + android:translateY="37.2145" > <path - android:name="body" - android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> + android:name="bottom_merged" + android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z" + android:fillColor="#FFFFFFFF" /> </group> </group> </group> diff --git a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml index 400a28ba4e7d..00bcaf6e2359 100644 --- a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml +++ b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,21 +14,19 @@ See the License for the specific language governing permissions and limitations under the License. --> -<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" +<animated-vector + xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_landscape_from_auto_rotate" > <target - android:name="arrows" - android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrows" /> - <target - android:name="arrow_top" - android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrow_top" /> + android:name="landscape" + android:animation="@anim/ic_rotate_to_landscape_landscape_animation" /> <target - android:name="arrow_bottom" - android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrow_bottom" /> + android:name="arrows" + android:animation="@anim/ic_rotate_to_landscape_arrows_animation" /> <target - android:name="device" - android:animation="@anim/ic_landscape_from_auto_rotate_animation_device" /> + android:name="arrows_0" + android:animation="@anim/ic_rotate_to_landscape_arrows_0_animation" /> <target - android:name="body" - android:animation="@anim/ic_landscape_from_auto_rotate_animation_body" /> + android:name="bottom_merged" + android:animation="@anim/ic_rotate_to_landscape_bottom_merged_animation" /> </animated-vector> diff --git a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml index 603d0bfd11bc..cde67976337e 100644 --- a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml +++ b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,53 +14,51 @@ See the License for the specific language governing permissions and limitations under the License. --> -<vector xmlns:android="http://schemas.android.com/apk/res/android" +<vector + xmlns:android="http://schemas.android.com/apk/res/android" + android:name="ic_landscape_to_rotate" android:height="48dp" android:width="48dp" android:viewportHeight="48" android:viewportWidth="48" android:tint="?android:attr/colorControlNormal" > <group - android:name="ic_screen_rotation_48px_outlines" + android:name="device" android:translateX="24" android:translateY="24" > <group - android:name="ic_screen_rotation_48px_outlines_pivot" + android:name="device_pivot" android:translateX="-24.15" android:translateY="-24.25" > <group - android:name="arrows" - android:translateX="24.1" - android:translateY="24.1" - android:scaleX="0.9" - android:scaleY="0.9" - android:rotation="-135" > - <group - android:name="arrows_pivot" - android:translateX="-24.1" - android:translateY="-24.1" > - <path - android:name="arrow_top" - android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="0" /> - <path - android:name="arrow_bottom" - android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="0" /> - </group> + android:name="landscape" + android:translateX="24" + android:translateY="24" > + <path + android:name="device_merged" + android:pathData="M -21.9799957275,-10.0 c 0.0,0.0 -0.0200042724609,20.0 -0.0200042724609,20.0 c 0.0,2.19999694824 1.80000305176,4.0 4.0,4.0 c 0.0,0.0 36.0,0.0 36.0,0.0 c 2.19999694824,0.0 4.0,-1.80000305176 4.0,-4.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,-2.19999694824 -1.80000305176,-4.0 -4.0,-4.0 c 0.0,0.0 -36.0,0.0 -36.0,0.0 c -2.19999694824,0.0 -3.97999572754,1.80000305176 -3.97999572754,4.0 Z M 14.0,10.0 c 0.0,0.0 -28.0,0.0 -28.0,0.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,0.0 28.0,0.0 28.0,0.0 c 0.0,0.0 0.0,20.0 0.0,20.0 Z" + android:fillColor="#FFFFFFFF" /> </group> + </group> + </group> + <group + android:name="arrows" + android:translateX="24" + android:translateY="24" + android:rotation="-90" > + <group + android:name="arrows_pivot" + android:translateX="-24.0798" + android:translateY="-24.23" > <group - android:name="device" - android:translateX="24.14999" - android:translateY="24.25" - android:rotation="-45" > + android:name="arrows_0" + android:translateX="12.2505" + android:translateY="37.2145" > <path - android:name="body" - android:pathData="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z" + android:name="bottom_merged" + android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z" android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> + android:fillAlpha="0" /> </group> </group> </group> diff --git a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml index 5263eb49df66..86dc6ce978bf 100644 --- a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml +++ b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,21 +14,16 @@ See the License for the specific language governing permissions and limitations under the License. --> -<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" +<animated-vector + xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_landscape_to_auto_rotate" > <target - android:name="arrows" - android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrows" /> - <target - android:name="arrow_top" - android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrow_top" /> + android:name="landscape" + android:animation="@anim/ic_landscape_to_rotate_landscape_animation" /> <target - android:name="arrow_bottom" - android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrow_bottom" /> - <target - android:name="device" - android:animation="@anim/ic_landscape_to_auto_rotate_animation_device" /> + android:name="arrows" + android:animation="@anim/ic_landscape_to_rotate_arrows_animation" /> <target - android:name="body" - android:animation="@anim/ic_landscape_to_auto_rotate_animation_body" /> + android:name="bottom_merged" + android:animation="@anim/ic_landscape_to_rotate_bottom_merged_animation" /> </animated-vector> diff --git a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml index 17185a7c36b0..bce494c975ed 100644 --- a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml +++ b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,50 +14,51 @@ See the License for the specific language governing permissions and limitations under the License. --> -<vector xmlns:android="http://schemas.android.com/apk/res/android" +<vector + xmlns:android="http://schemas.android.com/apk/res/android" + android:name="ic_portrait_to_rotate" android:height="48dp" android:width="48dp" android:viewportHeight="48" android:viewportWidth="48" android:tint="?android:attr/colorControlNormal" > <group - android:name="icon" + android:name="device" android:translateX="24" android:translateY="24" > <group - android:name="icon_pivot" + android:name="device_pivot" android:translateX="-24.15" android:translateY="-24.25" > <group - android:name="arrows" - android:translateX="24.1" - android:translateY="24.1" > - <group - android:name="arrows_pivot" - android:translateX="-24.1" - android:translateY="-24.1" > - <path - android:name="arrow_top" - android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - <path - android:name="arrow_bottom" - android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - </group> - <group - android:name="device" + android:name="device_0" android:translateX="24.14999" android:translateY="24.25" > <path - android:name="device_1" + android:name="device_merged" android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> + android:fillColor="#FFFFFFFF" /> + </group> + </group> + </group> + <group + android:name="arrows" + android:translateX="24" + android:translateY="24" > + <group + android:name="arrows_pivot" + android:translateX="-24.0798" + android:translateY="-24.23" > + <group + android:name="arrows_0" + android:translateX="12.2505" + android:translateY="37.2145" > + <path + android:name="bottom_merged" + android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z" + android:fillColor="#FFFFFFFF" /> </group> </group> </group> </vector> + diff --git a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml index 565ef269743d..b8465f4ba6b6 100644 --- a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml +++ b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,21 +14,22 @@ See the License for the specific language governing permissions and limitations under the License. --> -<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" - android:drawable="@drawable/ic_portrait_from_auto_rotate" > +<animated-vector + xmlns:android="http://schemas.android.com/apk/res/android" + android:drawable="@drawable/ic_portrait_to_auto_rotate" > <target - android:name="arrows" - android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrows" /> + android:name="device_0" + android:animation="@anim/ic_portrait_to_rotate_device_0_animation" /> <target - android:name="arrow_top" - android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrow_top" /> + android:name="device_merged" + android:animation="@anim/ic_portrait_to_rotate_device_merged_animation" /> <target - android:name="arrow_bottom" - android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrow_bottom" /> + android:name="arrows" + android:animation="@anim/ic_portrait_to_rotate_arrows_animation" /> <target - android:name="device" - android:animation="@anim/ic_portrait_from_auto_rotate_animation_device" /> + android:name="arrows_0" + android:animation="@anim/ic_portrait_to_rotate_arrows_0_animation" /> <target - android:name="device_1" - android:animation="@anim/ic_portrait_from_auto_rotate_animation_device_1" /> + android:name="bottom_merged" + android:animation="@anim/ic_portrait_to_rotate_bottom_merged_animation" /> </animated-vector> diff --git a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml index 88bf486be459..0ef15f0582f7 100644 --- a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml +++ b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,53 +14,54 @@ See the License for the specific language governing permissions and limitations under the License. --> -<vector xmlns:android="http://schemas.android.com/apk/res/android" +<vector + xmlns:android="http://schemas.android.com/apk/res/android" + android:name="ic_rotate_to_portrait" android:height="48dp" android:width="48dp" android:viewportHeight="48" android:viewportWidth="48" android:tint="?android:attr/colorControlNormal" > <group - android:name="icon" + android:name="device" android:translateX="24" android:translateY="24" > <group - android:name="icon_pivot" + android:name="device_pivot" android:translateX="-24.15" android:translateY="-24.25" > <group - android:name="arrows" - android:translateX="24.1" - android:translateY="24.1" - android:scaleX="0.9" - android:scaleY="0.9" - android:rotation="-221" > - <group - android:name="arrows_pivot" - android:translateX="-24.1" - android:translateY="-24.1" > - <path - android:name="arrow_top" - android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="0" /> - <path - android:name="arrow_bottom" - android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="0" /> - </group> - </group> - <group - android:name="device" + android:name="device_0" android:translateX="24.14999" android:translateY="24.25" android:rotation="-135" > <path - android:name="device_1" + android:name="device_merged" android:pathData="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z" + android:fillColor="#FFFFFFFF" /> + </group> + </group> + </group> + <group + android:name="arrows" + android:translateX="24" + android:translateY="24" + android:rotation="-221" > + <group + android:name="arrows_pivot" + android:translateX="-24.0798" + android:translateY="-24.23" > + <group + android:name="arrows_0" + android:translateX="12.2505" + android:translateY="37.2145" + android:scaleX="0.9" + android:scaleY="0.9" > + <path + android:name="bottom_merged" + android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z" android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> + android:fillAlpha="0" /> </group> </group> </group> diff --git a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml index f75617f04bef..6d3fd372b222 100644 --- a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml +++ b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,21 +14,22 @@ See the License for the specific language governing permissions and limitations under the License. --> -<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" - android:drawable="@drawable/ic_portrait_to_auto_rotate" > +<animated-vector + xmlns:android="http://schemas.android.com/apk/res/android" + android:drawable="@drawable/ic_portrait_from_auto_rotate" > <target - android:name="arrows" - android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrows" /> + android:name="device_0" + android:animation="@anim/ic_rotate_to_portrait_device_0_animation" /> <target - android:name="arrow_top" - android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrow_top" /> + android:name="device_merged" + android:animation="@anim/ic_rotate_to_portrait_device_merged_animation" /> <target - android:name="arrow_bottom" - android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrow_bottom" /> + android:name="arrows" + android:animation="@anim/ic_rotate_to_portrait_arrows_animation" /> <target - android:name="device" - android:animation="@anim/ic_portrait_to_auto_rotate_animation_device" /> + android:name="arrows_0" + android:animation="@anim/ic_rotate_to_portrait_arrows_0_animation" /> <target - android:name="device_1" - android:animation="@anim/ic_portrait_to_auto_rotate_animation_device_1" /> + android:name="bottom_merged" + android:animation="@anim/ic_rotate_to_portrait_bottom_merged_animation" /> </animated-vector> diff --git a/packages/SystemUI/res/drawable/recents_dismiss_dark.xml b/packages/SystemUI/res/drawable/recents_dismiss_dark.xml index 951269bd37b1..b837ebef78eb 100644 --- a/packages/SystemUI/res/drawable/recents_dismiss_dark.xml +++ b/packages/SystemUI/res/drawable/recents_dismiss_dark.xml @@ -14,11 +14,16 @@ Copyright (C) 2014 The Android Open Source Project limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="48.0dp" - android:height="48.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> - <path - android:fillColor="@color/recents_task_bar_dark_icon_color" - android:pathData="M38.000000,12.800000l-2.799999,-2.800000 -11.200001,11.200001 -11.200000,-11.200001 -2.800000,2.800000 11.200001,11.200000 -11.200001,11.200001 2.800000,2.799999 11.200000,-11.200001 11.200001,11.200001 2.799999,-2.799999 -11.200001,-11.200001z"/> +android:width="24dp" +android:height="24dp" +android:viewportWidth="24" +android:viewportHeight="24"> + +<path + android:fillColor="@color/recents_task_bar_dark_icon_color" + android:pathData="M18.3 5.71a.996 .996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996 .996 0 1 0 5.7 +7.11L10.59 12 5.7 16.89a.996 .996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996 .996 0 +1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38 .38 -1.02 0-1.4z" /> +<path + android:pathData="M0 0h24v24H0z" /> </vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/recents_dismiss_light.xml b/packages/SystemUI/res/drawable/recents_dismiss_light.xml index 1f44c1c846bb..2b2081404b69 100644 --- a/packages/SystemUI/res/drawable/recents_dismiss_light.xml +++ b/packages/SystemUI/res/drawable/recents_dismiss_light.xml @@ -14,11 +14,16 @@ Copyright (C) 2014 The Android Open Source Project limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="48.0dp" - android:height="48.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> - <path - android:fillColor="@color/recents_task_bar_light_icon_color" - android:pathData="M38.000000,12.800000l-2.799999,-2.800000 -11.200001,11.200001 -11.200000,-11.200001 -2.800000,2.800000 11.200001,11.200000 -11.200001,11.200001 2.800000,2.799999 11.200000,-11.200001 11.200001,11.200001 2.799999,-2.799999 -11.200001,-11.200001z"/> +android:width="24dp" +android:height="24dp" +android:viewportWidth="24" +android:viewportHeight="24"> + +<path + android:fillColor="@color/recents_task_bar_light_icon_color" + android:pathData="M18.3 5.71a.996 .996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996 .996 0 1 0 5.7 +7.11L10.59 12 5.7 16.89a.996 .996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996 .996 0 +1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38 .38 -1.02 0-1.4z" /> +<path + android:pathData="M0 0h24v24H0z" /> </vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_landscape_to_rotate_animation_interpolator_0.xml index ac27e4dae373..793e7fff11e0 100644 --- a/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml +++ b/packages/SystemUI/res/interpolator/ic_landscape_to_rotate_animation_interpolator_0.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,5 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. --> -<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" - android:pathData="M 0,0 c 0.4,0.143709151 0.2,1 1,1" /> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" /> diff --git a/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_rotate_to_landscape_animation_interpolator_0.xml index 76f5667f5fcc..793e7fff11e0 100644 --- a/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml +++ b/packages/SystemUI/res/interpolator/ic_rotate_to_landscape_animation_interpolator_0.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,5 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. --> -<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" - android:pathData="M 0,0 c 0.458031162,0 0.299442342,0.748308635 1,1" /> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" /> diff --git a/packages/SystemUI/res/interpolator/ic_rotate_to_portrait_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_rotate_to_portrait_animation_interpolator_0.xml new file mode 100644 index 000000000000..793e7fff11e0 --- /dev/null +++ b/packages/SystemUI/res/interpolator/ic_rotate_to_portrait_animation_interpolator_0.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" /> diff --git a/packages/SystemUI/res/layout/back.xml b/packages/SystemUI/res/layout/back.xml index 4e8726b3a634..43bec91ad053 100644 --- a/packages/SystemUI/res/layout/back.xml +++ b/packages/SystemUI/res/layout/back.xml @@ -22,8 +22,10 @@ android:layout_height="match_parent" android:layout_weight="0" systemui:keyCode="4" - android:scaleType="center" + android:scaleType="fitCenter" android:contentDescription="@string/accessibility_back" + android:paddingTop="15dp" + android:paddingBottom="15dp" android:paddingStart="@dimen/navigation_key_padding" android:paddingEnd="@dimen/navigation_key_padding" /> diff --git a/packages/SystemUI/res/layout/home.xml b/packages/SystemUI/res/layout/home.xml index 95863272b9bf..53ef2ab247e7 100644 --- a/packages/SystemUI/res/layout/home.xml +++ b/packages/SystemUI/res/layout/home.xml @@ -21,8 +21,10 @@ android:layout_height="match_parent" android:layout_weight="0" systemui:keyCode="3" - android:scaleType="center" + android:scaleType="fitCenter" android:contentDescription="@string/accessibility_home" + android:paddingTop="13dp" + android:paddingBottom="13dp" android:paddingStart="@dimen/navigation_key_padding" android:paddingEnd="@dimen/navigation_key_padding" /> diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml index 2bf4d9cb535f..a621c7c0f836 100644 --- a/packages/SystemUI/res/layout/navigation_layout.xml +++ b/packages/SystemUI/res/layout/navigation_layout.xml @@ -18,7 +18,11 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:layout_marginStart="@dimen/rounded_corner_content_padding" + android:layout_marginEnd="@dimen/rounded_corner_content_padding" + android:paddingStart="8dp" + android:paddingEnd="8dp"> <FrameLayout android:id="@+id/nav_buttons" diff --git a/packages/SystemUI/res/layout/navigation_layout_rot90.xml b/packages/SystemUI/res/layout/navigation_layout_rot90.xml index 7601efc92a78..bf48c7f337d7 100644 --- a/packages/SystemUI/res/layout/navigation_layout_rot90.xml +++ b/packages/SystemUI/res/layout/navigation_layout_rot90.xml @@ -18,7 +18,11 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:layout_marginTop="@dimen/rounded_corner_content_padding" + android:layout_marginBottom="@dimen/rounded_corner_content_padding" + android:paddingTop="8dp" + android:paddingBottom="8dp"> <FrameLayout android:id="@+id/nav_buttons" diff --git a/packages/SystemUI/res/layout/recent_apps.xml b/packages/SystemUI/res/layout/recent_apps.xml index 870bcf7547a7..c84d28051286 100644 --- a/packages/SystemUI/res/layout/recent_apps.xml +++ b/packages/SystemUI/res/layout/recent_apps.xml @@ -21,8 +21,10 @@ android:layout_width="@dimen/navigation_key_width" android:layout_height="match_parent" android:layout_weight="0" - android:scaleType="center" + android:scaleType="fitCenter" android:contentDescription="@string/accessibility_recent" + android:paddingTop="15dp" + android:paddingBottom="15dp" android:paddingStart="@dimen/navigation_key_padding" android:paddingEnd="@dimen/navigation_key_padding" /> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 1b9851079028..652e35bbe289 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -459,11 +459,11 @@ <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string> <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"Άνοιγμα αξιόπιστων διαπιστευτηρίων"</string> <string name="monitoring_description_network_logging" msgid="7223505523384076027">"Ο διαχειριστής σας έχει ενεργοποιήσει την καταγραφή δικτύου, η οποία παρακολουθεί την επισκεψιμότητα στη συσκευή σας.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή σας."</string> - <string name="monitoring_description_vpn" msgid="4445150119515393526">"Παραχωρήσατε σε μια εφαρμογή άδεια για τη ρύθμιση σύνδεσης VPN.\n\nΑυτή η εφαρμογή μπορεί να παρακολουθεί τη δραστηριότητα της συσκευής και του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστότοπων."</string> - <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"Η διαχείριση του προφίλ εργασίας γίνεται από τον οργανισμό <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nΟ διαχειριστής έχει τη δυνατότητα παρακολούθησης της δραστηριότητας του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστότοπων.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή.\n\nΕπίσης, είστε συνδεδεμένοι σε VPN, το οποίο μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου σας."</string> + <string name="monitoring_description_vpn" msgid="4445150119515393526">"Παραχωρήσατε σε μια εφαρμογή άδεια για τη ρύθμιση σύνδεσης VPN.\n\nΑυτή η εφαρμογή μπορεί να παρακολουθεί τη δραστηριότητα της συσκευής και του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string> + <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"Η διαχείριση του προφίλ εργασίας γίνεται από τον οργανισμό <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nΟ διαχειριστής έχει τη δυνατότητα παρακολούθησης της δραστηριότητας του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή.\n\nΕπίσης, είστε συνδεδεμένοι σε VPN, το οποίο μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου σας."</string> <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string> <string name="monitoring_description_app" msgid="1828472472674709532">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string> - <string name="monitoring_description_app_personal" msgid="484599052118316268">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του προσωπικού σας δικτύου, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστότοπων."</string> + <string name="monitoring_description_app_personal" msgid="484599052118316268">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του προσωπικού σας δικτύου, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string> <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του προσωπικού σας δικτύου, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string> <string name="monitoring_description_app_work" msgid="4612997849787922906">"Ο οργανισμός <xliff:g id="ORGANIZATION">%1$s</xliff:g> διαχειρίζεται το προφίλ εργασίας σας. Το προφίλ είναι συνδεδεμένο στην εφαρμογή <xliff:g id="APPLICATION">%2$s</xliff:g>, η οποία μπορεί να παρακολουθήσει τη δραστηριότητα του δικτύου εργασίας σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή σας."</string> <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Ο οργανισμός <xliff:g id="ORGANIZATION">%1$s</xliff:g> διαχειρίζεται το προφίλ εργασίας σας. Το προφίλ συνδέεται με την εφαρμογή <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου της εργασίας σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων.\n\nΕπίσης, είστε συνδεδεμένοι στην εφαρμογή <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, που έχει τη δυνατότητα παρακολούθησης της δραστηριότητας του προσωπικού σας δικτύου."</string> diff --git a/packages/SystemUI/res/values-mcc311-mnc480/config.xml b/packages/SystemUI/res/values-mcc311-mnc480/config.xml new file mode 100644 index 000000000000..7dadae7f9107 --- /dev/null +++ b/packages/SystemUI/res/values-mcc311-mnc480/config.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<!-- These resources are around just to allow their values to be customized + for different hardware and product builds. --> +<resources> + <!-- Enable 5 bar signal strength icon --> + <bool name="config_inflateSignalStrength">true</bool> +</resources> + diff --git a/packages/SystemUI/res/values-sw372dp/config.xml b/packages/SystemUI/res/values-sw372dp/config.xml new file mode 100644 index 000000000000..07b797a32428 --- /dev/null +++ b/packages/SystemUI/res/values-sw372dp/config.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<!-- These resources are around just to allow their values to be customized + for different hardware and product builds. --> +<resources> + <!-- Nav bar button default ordering/layout --> + <string name="config_navBarLayout" translatable="false">left[.25W],back[.5WC];home;recent[.5WC],right[.25W]</string> +</resources> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 74b0702ce5f6..2ad6f2da7fb0 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -293,7 +293,7 @@ <string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIFactory</string> <!-- Nav bar button default ordering/layout --> - <string name="config_navBarLayout" translatable="false">left,back;home;recent,right</string> + <string name="config_navBarLayout" translatable="false">left[.5W],back[1WC];home;recent[1WC],right[.5W]</string> <bool name="quick_settings_show_full_alarm">false</bool> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 93d2072e955c..4a1d953c3bfe 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -827,7 +827,4 @@ <!-- How far to inset the rounded edges --> <dimen name="stat_sys_mobile_signal_circle_inset">0.9dp</dimen> - <!-- Width of the hollow triangle for empty signal state --> - <dimen name="mobile_signal_empty_strokewidth">2dp</dimen> - </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 570438af341e..7eabf3995042 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -741,6 +741,8 @@ <string name="quick_settings_done">Done</string> <!-- QuickSettings: Control panel: Label for connected device. [CHAR LIMIT=NONE] --> <string name="quick_settings_connected">Connected</string> + <!-- QuickSettings: Control panel: Label for connected device, showing remote device battery level. [CHAR LIMIT=NONE] --> + <string name="quick_settings_connected_battery_level">Connected, battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string> <!-- QuickSettings: Control panel: Label for connecting device. [CHAR LIMIT=NONE] --> <string name="quick_settings_connecting">Connecting...</string> <!-- QuickSettings: Tethering. [CHAR LIMIT=NONE] --> diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java index d8bebabf0c5e..12f75bb2d56c 100644 --- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java +++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java @@ -29,10 +29,8 @@ import android.graphics.Rect; import android.graphics.Typeface; import android.os.PowerManager; import android.os.SystemClock; -import android.os.UserHandle; import android.provider.Settings; import android.text.InputType; -import android.text.TextUtils; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; @@ -252,9 +250,9 @@ public class PasswordTextView extends View { mText = mText.substring(0, length - 1); CharState charState = mTextChars.get(length - 1); charState.startRemoveAnimation(0, 0); + sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0); } userActivity(); - sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0); } public String getText() { diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index 1b694b372124..bb4412375ff8 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -31,6 +31,7 @@ import com.android.systemui.assist.AssistManager; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.fragments.FragmentService; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.PluginActivityManager; import com.android.systemui.plugins.PluginDependencyProvider; import com.android.systemui.plugins.PluginManager; import com.android.systemui.plugins.PluginManagerImpl; @@ -276,6 +277,9 @@ public class Dependency extends SystemUI { mProviders.put(UiOffloadThread.class, UiOffloadThread::new); + mProviders.put(PluginActivityManager.class, + () -> new PluginActivityManager(mContext, getDependency(PluginManager.class))); + // Put all dependencies above here so the factory can override them if it wants. SystemUIFactory.getInstance().injectDependencies(mProviders, mContext); } diff --git a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java index 6397eb5d756b..74a150551c15 100644 --- a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java +++ b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java @@ -98,10 +98,6 @@ public class RoundedCorners extends SystemUI implements Tunable { TunablePadding.addTunablePadding(statusBar.findViewById(R.id.keyguard_header), PADDING, padding, FLAG_END); - FragmentHostManager.get(sb.getNavigationBarWindow()).addTagListener( - NavigationBarFragment.TAG, - new TunablePaddingTagListener(padding, 0)); - FragmentHostManager fragmentHostManager = FragmentHostManager.get(statusBar); fragmentHostManager.addTagListener(CollapsedStatusBarFragment.TAG, new TunablePaddingTagListener(padding, R.id.status_bar)); diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index 4a459974fcb6..fe6eb4b5acfe 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -16,6 +16,7 @@ package com.android.systemui; +import android.app.Activity; import android.app.ActivityThread; import android.app.Application; import android.content.BroadcastReceiver; @@ -39,6 +40,7 @@ import com.android.systemui.pip.PipUI; import com.android.systemui.plugins.GlobalActions; import com.android.systemui.plugins.OverlayPlugin; import com.android.systemui.plugins.Plugin; +import com.android.systemui.plugins.PluginActivityManager; import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.PluginManager; import com.android.systemui.power.PowerUI; @@ -266,4 +268,10 @@ public class SystemUIApplication extends Application implements SysUiServiceProv public SystemUI[] getServices() { return mServices; } + + @Override + public Activity instantiateActivity(ClassLoader cl, String className, Intent intent) { + if (!mServicesStarted) return null; + return Dependency.get(PluginActivityManager.class).instantiate(cl, className, intent); + } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index ae936db7b0e2..8d1d6e0ce460 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -39,6 +39,7 @@ import com.android.systemui.util.Assert; import com.android.systemui.util.wakelock.WakeLock; import java.io.PrintWriter; +import java.util.function.IntConsumer; /** * Handles triggers for ambient state changes. @@ -98,18 +99,44 @@ public class DozeTriggers implements DozeMachine.Part { requestPulse(DozeLog.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */); } + private void proximityCheckThenCall(IntConsumer callback, + boolean alreadyPerformedProxCheck, + int pulseReason) { + if (alreadyPerformedProxCheck) { + callback.accept(ProximityCheck.RESULT_NOT_CHECKED); + } else { + final long start = SystemClock.uptimeMillis(); + new ProximityCheck() { + @Override + public void onProximityResult(int result) { + final long end = SystemClock.uptimeMillis(); + DozeLog.traceProximityResult(mContext, result == RESULT_NEAR, + end - start, pulseReason); + callback.accept(result); + } + }.check(); + } + } + private void onSensor(int pulseReason, boolean sensorPerformedProxCheck, float screenX, float screenY) { boolean isDoubleTap = pulseReason == DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP; boolean isPickup = pulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP; if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)) { - if (isDoubleTap) { - mDozeHost.onDoubleTap(screenX, screenY); - mMachine.wakeUp(); - } else { - mDozeHost.extendPulse(); - } + proximityCheckThenCall((result) -> { + if (result == ProximityCheck.RESULT_NEAR) { + // In pocket, drop event. + return; + } + if (isDoubleTap) { + mDozeHost.onDoubleTap(screenX, screenY); + mMachine.wakeUp(); + } else { + mDozeHost.extendPulse(); + } + }, sensorPerformedProxCheck, pulseReason); + return; } else { requestPulse(pulseReason, sensorPerformedProxCheck); } @@ -158,13 +185,16 @@ public class DozeTriggers implements DozeMachine.Part { break; case DOZE: case DOZE_AOD: - case DOZE_AOD_PAUSED: mDozeSensors.setProxListening(newState != DozeMachine.State.DOZE); mDozeSensors.setListening(true); if (oldState != DozeMachine.State.INITIALIZED) { mDozeSensors.reregisterAllSensors(); } break; + case DOZE_AOD_PAUSED: + mDozeSensors.setProxListening(true); + mDozeSensors.setListening(false); + break; case DOZE_PULSING: mDozeSensors.setProxListening(true); break; @@ -199,33 +229,15 @@ public class DozeTriggers implements DozeMachine.Part { } mPulsePending = true; - if (!mDozeParameters.getProxCheckBeforePulse() || performedProxCheck) { - // skip proximity check - continuePulseRequest(reason); - return; - } - - final long start = SystemClock.uptimeMillis(); - new ProximityCheck() { - @Override - public void onProximityResult(int result) { - final long end = SystemClock.uptimeMillis(); - DozeLog.traceProximityResult(mContext, result == RESULT_NEAR, - end - start, reason); - if (performedProxCheck) { - // we already continued - return; - } - // avoid pulsing in pockets - if (result == RESULT_NEAR) { - mPulsePending = false; - return; - } - - // not in-pocket, continue pulsing + proximityCheckThenCall((result) -> { + if (result == ProximityCheck.RESULT_NEAR) { + // in pocket, abort pulse + mPulsePending = false; + } else { + // not in pocket, continue pulsing continuePulseRequest(reason); } - }.check(); + }, !mDozeParameters.getProxCheckBeforePulse() || performedProxCheck, reason); } private boolean canPulse() { @@ -259,6 +271,7 @@ public class DozeTriggers implements DozeMachine.Part { protected static final int RESULT_UNKNOWN = 0; protected static final int RESULT_NEAR = 1; protected static final int RESULT_FAR = 2; + protected static final int RESULT_NOT_CHECKED = 3; private boolean mRegistered; private boolean mFinished; diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index 80a641870f5b..1a8a474a4187 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -339,6 +339,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogIn long id) { final Action action = mAdapter.getItem(position); if (action instanceof LongPressAction) { + mDialog.dismiss(); return ((LongPressAction) action).onLongPress(); } return false; diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java index b8771d7e0fb6..cebb22f07aaf 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java @@ -241,14 +241,14 @@ public class PipMotionHelper implements Handler.Callback { /** * Flings the minimized PiP to the closest minimized snap target. */ - Rect flingToMinimizedState(float velocityY, Rect movementBounds) { + Rect flingToMinimizedState(float velocityY, Rect movementBounds, Point dragStartPosition) { cancelAnimations(); // We currently only allow flinging the minimized stack up and down, so just lock the // movement bounds to the current stack bounds horizontally movementBounds = new Rect(mBounds.left, movementBounds.top, mBounds.left, movementBounds.bottom); Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds, - 0 /* velocityX */, velocityY); + 0 /* velocityX */, velocityY, dragStartPosition); if (!mBounds.equals(toBounds)) { mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN); mFlingAnimationUtils.apply(mBoundsAnimator, 0, @@ -281,10 +281,11 @@ public class PipMotionHelper implements Handler.Callback { * Flings the PiP to the closest snap target. */ Rect flingToSnapTarget(float velocity, float velocityX, float velocityY, Rect movementBounds, - AnimatorUpdateListener updateListener, AnimatorListener listener) { + AnimatorUpdateListener updateListener, AnimatorListener listener, + Point startPosition) { cancelAnimations(); Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds, - velocityX, velocityY); + velocityX, velocityY, startPosition); if (!mBounds.equals(toBounds)) { mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN); mFlingAnimationUtils.apply(mBoundsAnimator, 0, diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index 3682ae655f7c..9588b03b53bd 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -185,7 +185,7 @@ public class PipTouchHandler { mDismissViewController = new PipDismissViewController(context); mSnapAlgorithm = new PipSnapAlgorithm(mContext); mTouchState = new PipTouchState(mViewConfig); - mFlingAnimationUtils = new FlingAnimationUtils(context, 2f); + mFlingAnimationUtils = new FlingAnimationUtils(context, 2.5f); mGestures = new PipTouchGesture[] { mDefaultMovementGesture }; @@ -534,6 +534,7 @@ public class PipTouchHandler { private PipTouchGesture mDefaultMovementGesture = new PipTouchGesture() { // Whether the PiP was on the left side of the screen at the start of the gesture private boolean mStartedOnLeft; + private Point mStartPosition; @Override public void onDown(PipTouchState touchState) { @@ -541,7 +542,9 @@ public class PipTouchHandler { return; } - mStartedOnLeft = mMotionHelper.getBounds().left < mMovementBounds.centerX(); + Rect bounds = mMotionHelper.getBounds(); + mStartPosition = new Point(bounds.left, bounds.top); + mStartedOnLeft = bounds.left < mMovementBounds.centerX(); mMovementWithinMinimize = true; mMovementWithinDismiss = touchState.getDownTouchPosition().y >= mMovementBounds.bottom; @@ -687,7 +690,8 @@ public class PipTouchHandler { if (isFling) { mMotionHelper.flingToSnapTarget(velocity, vel.x, vel.y, mMovementBounds, - mUpdateScrimListener, postAnimationCallback); + mUpdateScrimListener, postAnimationCallback, + mStartPosition); } else { mMotionHelper.animateToClosestSnapTarget(mMovementBounds, mUpdateScrimListener, postAnimationCallback); diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java new file mode 100644 index 000000000000..9becc38d760e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui.plugins; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.util.ArrayMap; + +public class PluginActivityManager { + + private final Context mContext; + private final PluginManager mPluginManager; + private final ArrayMap<String, String> mActionLookup = new ArrayMap<>(); + + public PluginActivityManager(Context context, PluginManager pluginManager) { + mContext = context; + mPluginManager = pluginManager; + } + + public void addActivityPlugin(String className, String action) { + mActionLookup.put(className, action); + } + + public Activity instantiate(ClassLoader cl, String className, Intent intent) { + String action = mActionLookup.get(className); + if (TextUtils.isEmpty(action)) return null; + return mPluginManager.getOneShotPlugin(action, PluginActivity.class); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java index 493d244f5e99..a96839943cad 100644 --- a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java @@ -42,7 +42,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.systemui.Dependency; import com.android.systemui.plugins.PluginInstanceManager.PluginContextWrapper; -import com.android.systemui.plugins.PluginInstanceManager.PluginInfo; import com.android.systemui.plugins.annotations.ProvidesInterface; import dalvik.system.PathClassLoader; @@ -120,14 +119,21 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage } PluginInstanceManager<T> p = mFactory.createPluginInstanceManager(mContext, action, null, false, mLooper, cls, this); + PluginListener<Plugin> listener = new PluginListener<Plugin>() { + @Override + public void onPluginConnected(Plugin plugin, Context pluginContext) { } + }; + mPluginMap.put(listener, p); mPluginPrefs.addAction(action); - PluginInfo<T> info = p.getPlugin(); + PluginInstanceManager.PluginInfo<T> info = p.getPlugin(); if (info != null) { mOneShotPackages.add(info.mPackage); mHasOneShot = true; startListening(); + mPluginMap.remove(listener); return info.mPlugin; } + mPluginMap.remove(listener); return null; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java index 6b507645e4d0..8f1880039857 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java @@ -161,7 +161,8 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha QSTileLayout tileLayout = mQsPanel.getTileLayout(); mAllViews.add((View) tileLayout); - int heightDiff = mQsPanel.getBottom() - mQs.getHeader().getBottom() + int height = mQs.getView() != null ? mQs.getView().getMeasuredHeight() : 0; + int heightDiff = height - mQs.getHeader().getBottom() + mQs.getHeader().getPaddingBottom(); firstPageBuilder.addFloat(tileLayout, "translationY", heightDiff, 0); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index 90275c50b54a..bb3672511c48 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -253,7 +253,8 @@ public class QSFragment extends Fragment implements QS { } mHeader.setExpansion(mKeyguardShowing ? 1 : expansion); mFooter.setExpansion(mKeyguardShowing ? 1 : expansion); - int heightDiff = mQSPanel.getBottom() - mHeader.getBottom() + mHeader.getPaddingBottom(); + int heightDiff = mQSPanel.getBottom() - mHeader.getBottom() + mHeader.getPaddingBottom() + + mFooter.getHeight(); mQSPanel.setTranslationY(translationScaleY * heightDiff); mQSDetail.setFullyExpanded(expansion == 1); @@ -262,7 +263,7 @@ public class QSFragment extends Fragment implements QS { } // Set bounds on the QS panel so it doesn't run over the header. - mQsBounds.top = (int) (mQSPanel.getHeight() * (1 - expansion)); + mQsBounds.top = (int) -mQSPanel.getTranslationY(); mQsBounds.right = mQSPanel.getWidth(); mQsBounds.bottom = mQSPanel.getHeight(); mQSPanel.setClipBounds(mQsBounds); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java index 918c00c2337f..089d07a567dd 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java @@ -15,10 +15,13 @@ */ package com.android.systemui.qs.tiles; +import android.content.Context; import android.content.Intent; +import android.graphics.drawable.Drawable; import android.service.quicksettings.Tile; import android.widget.Switch; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.settingslib.graph.BatteryMeterDrawableBase; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSTile.BooleanState; @@ -79,7 +82,9 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements protected void handleUpdateState(BooleanState state, Object arg) { state.state = mCharging ? Tile.STATE_UNAVAILABLE : mPowerSave ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE; - state.icon = ResourceIcon.get(R.drawable.ic_qs_battery_saver); + BatterySaverIcon bsi = new BatterySaverIcon(); + bsi.mState = state.state; + state.icon = bsi; state.label = mContext.getString(R.string.battery_detail_switch_title); state.contentDescription = state.label; state.value = mPowerSave; @@ -99,4 +104,41 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements mPowerSave = isPowerSave; refreshState(null); } -}
\ No newline at end of file + + public static class BatterySaverIcon extends Icon { + private int mState; + + @Override + public Drawable getDrawable(Context context) { + BatterySaverDrawable b = new BatterySaverDrawable(context, 0); + b.mState = mState; + final int pad = context.getResources() + .getDimensionPixelSize(R.dimen.qs_tile_divider_height); + b.setPadding(pad, pad, pad, pad); + return b; + } + } + + private static class BatterySaverDrawable extends BatteryMeterDrawableBase { + private int mState; + private static final int MAX_BATTERY = 100; + + BatterySaverDrawable(Context context, int frameColor) { + super(context, frameColor); + // Show as full so it's always uniform color + super.setBatteryLevel(MAX_BATTERY); + setPowerSave(true); + setCharging(false); + } + + @Override + protected int batteryColorForLevel(int level) { + return QSTileImpl.getColorForState(mContext, mState); + } + + @Override + public void setBatteryLevel(int val) { + // Don't change the actual level, otherwise this won't draw correctly + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index 9ba32b354d8f..de2ace4c30d1 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -43,11 +43,14 @@ import android.widget.Toast; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.systemui.Dependency; import com.android.systemui.EventLogConstants; import com.android.systemui.EventLogTags; import com.android.systemui.R; import com.android.systemui.RecentsComponent; import com.android.systemui.SystemUI; +import com.android.systemui.plugins.PluginActivity; +import com.android.systemui.plugins.PluginActivityManager; import com.android.systemui.recents.events.EventBus; import com.android.systemui.recents.events.activity.ConfigurationChangedEvent; import com.android.systemui.recents.events.activity.DockedTopTaskEvent; @@ -234,6 +237,8 @@ public class Recents extends SystemUI registerWithSystemUser(); } putComponent(Recents.class, this); + Dependency.get(PluginActivityManager.class).addActivityPlugin(RecentsImpl.RECENTS_ACTIVITY, + PluginActivity.ACTION_RECENTS); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java index eec818b2c9b3..29b720cdcd88 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java @@ -943,6 +943,10 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView } } + public boolean isDrawingAppearAnimation() { + return mDrawingAppearAnimation; + } + @Override protected void dispatchDraw(Canvas canvas) { if (mDrawingAppearAnimation) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 6abf35ffc713..ed4f6855c515 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -756,6 +756,19 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return getShowingLayout().getVisibleNotificationHeader(); } + + /** + * @return the contracted notification header. This can be different from + * {@link #getNotificationHeader()} and also {@link #getVisibleNotificationHeader()} and only + * returns the contracted version. + */ + public NotificationHeaderView getContractedNotificationHeader() { + if (mIsSummaryWithChildren) { + return mChildrenContainer.getHeaderView(); + } + return mPrivateLayout.getContractedNotificationHeader(); + } + public void setOnExpandClickListener(OnExpandClickListener onExpandClickListener) { mOnExpandClickListener = onExpandClickListener; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java index 75704b1612d7..9e059c89ffe1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java @@ -1308,6 +1308,14 @@ public class NotificationContentView extends FrameLayout { return header; } + + public NotificationHeaderView getContractedNotificationHeader() { + if (mContractedChild != null) { + return mContractedWrapper.getNotificationHeader(); + } + return null; + } + public NotificationHeaderView getVisibleNotificationHeader() { NotificationViewWrapper wrapper = getVisibleWrapper(mVisibleType); return wrapper == null ? null : wrapper.getNotificationHeader(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java index c0691c11a286..e5b1afe31370 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java @@ -568,8 +568,6 @@ public class NotificationData { mTmpRanking.getImportance()); pw.print(indent); pw.println(" notification=" + n.getNotification()); - pw.print(indent); - pw.println(" tickerText=\"" + n.getNotification().tickerText + "\""); } private static boolean isSystemNotification(StatusBarNotification sbn) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java index 7f95d48f36d4..43018174de44 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java @@ -267,9 +267,10 @@ public class NotificationHeaderUtil { if (!mApply) { return; } - NotificationHeaderView header = row.getNotificationHeader(); + NotificationHeaderView header = row.getContractedNotificationHeader(); if (header == null) { - mApply = false; + // No header found. We still consider this to be the same to avoid weird flickering + // when for example showing an undo notification return; } Object childData = mExtractor == null ? null : mExtractor.extractData(row); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java index 5a163d4d56c2..f8591247f1d0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java @@ -417,7 +417,7 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl @Override public void onHeightUpdate() { - if (mParent == null || mMenuItems.size() == 0) { + if (mParent == null || mMenuItems.size() == 0 || mMenuContainer == null) { return; } int parentHeight = mParent.getCollapsedHeight(); @@ -477,7 +477,7 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl private void setMenuLocation() { boolean showOnLeft = mTranslation > 0; - if ((mIconsPlaced && showOnLeft == mOnLeft) || mSnapping + if ((mIconsPlaced && showOnLeft == mOnLeft) || mSnapping || mMenuContainer == null || !mMenuContainer.isAttachedToWindow()) { // Do nothing return; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 97e2f6d3e6f1..a60102854618 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -16,15 +16,18 @@ package com.android.systemui.statusbar; +import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE; +import static com.android.systemui.statusbar.phone.NotificationIconContainer.OVERFLOW_EARLY_AMOUNT; + import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.os.SystemProperties; import android.util.AttributeSet; -import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; + import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.ViewInvertHelper; @@ -315,26 +318,65 @@ public class NotificationShelf extends ActivatableNotificationView implements private float updateIconAppearance(ExpandableNotificationRow row, float expandAmount, boolean scrolling, boolean scrollingFast, boolean expandingAnimated, boolean isLastChild) { + StatusBarIconView icon = row.getEntry().expandedIcon; + NotificationIconContainer.IconState iconState = getIconState(icon); + if (iconState == null) { + return 0.0f; + } + // Let calculate how much the view is in the shelf float viewStart = row.getTranslationY(); int fullHeight = row.getActualHeight() + mPaddingBetweenElements; float iconTransformDistance = getIntrinsicHeight() * 1.5f; iconTransformDistance *= NotificationUtils.interpolate(1.f, 1.5f, expandAmount); + iconTransformDistance = Math.min(iconTransformDistance, fullHeight); if (isLastChild) { fullHeight = Math.min(fullHeight, row.getMinHeight() - getIntrinsicHeight()); iconTransformDistance = Math.min(iconTransformDistance, row.getMinHeight() - getIntrinsicHeight()); } float viewEnd = viewStart + fullHeight; + if (expandingAnimated && mAmbientState.getScrollY() == 0 + && !mAmbientState.isOnKeyguard() && !iconState.isLastExpandIcon) { + // We are expanding animated. Because we switch to a linear interpolation in this case, + // the last icon may be stuck in between the shelf position and the notification + // position, which looks pretty bad. We therefore optimize this case by applying a + // shorter transition such that the icon is either fully in the notification or we clamp + // it into the shelf if it's close enough. + // We need to persist this, since after the expansion, the behavior should still be the + // same. + float position = mAmbientState.getIntrinsicPadding() + + mHostLayout.getPositionInLinearLayout(row); + int maxShelfStart = mMaxLayoutHeight - getIntrinsicHeight(); + if (position < maxShelfStart && position + row.getIntrinsicHeight() >= maxShelfStart + && row.getTranslationY() < position) { + iconState.isLastExpandIcon = true; + iconState.customTransformHeight = NO_VALUE; + // Let's check if we're close enough to snap into the shelf + boolean forceInShelf = mMaxLayoutHeight - getIntrinsicHeight() - position + < getIntrinsicHeight(); + if (!forceInShelf) { + // We are overlapping the shelf but not enough, so the icon needs to be + // repositioned + iconState.customTransformHeight = (int) (mMaxLayoutHeight + - getIntrinsicHeight() - position); + } + } + } float fullTransitionAmount; float iconTransitionAmount; float shelfStart = getTranslationY(); + if (iconState.hasCustomTransformHeight()) { + fullHeight = iconState.customTransformHeight; + iconTransformDistance = iconState.customTransformHeight; + } + boolean fullyInOrOut = true; if (viewEnd >= shelfStart && (!mAmbientState.isUnlockHintRunning() || row.isInShelf()) && (mAmbientState.isShadeExpanded() || (!row.isPinned() && !row.isHeadsUpAnimatingAway()))) { if (viewStart < shelfStart) { - float fullAmount = (shelfStart - viewStart) / fullHeight; + fullAmount = Math.min(1.0f, fullAmount); float interpolatedAmount = Interpolators.ACCELERATE_DECELERATE.getInterpolation( fullAmount); interpolatedAmount = NotificationUtils.interpolate( @@ -344,7 +386,7 @@ public class NotificationShelf extends ActivatableNotificationView implements iconTransitionAmount = (shelfStart - viewStart) / iconTransformDistance; iconTransitionAmount = Math.min(1.0f, iconTransitionAmount); iconTransitionAmount = 1.0f - iconTransitionAmount; - + fullyInOrOut = false; } else { fullTransitionAmount = 1.0f; iconTransitionAmount = 1.0f; @@ -353,6 +395,10 @@ public class NotificationShelf extends ActivatableNotificationView implements fullTransitionAmount = 0.0f; iconTransitionAmount = 0.0f; } + if (fullyInOrOut && !expandingAnimated && iconState.isLastExpandIcon) { + iconState.isLastExpandIcon = false; + iconState.customTransformHeight = NO_VALUE; + } updateIconPositioning(row, iconTransitionAmount, fullTransitionAmount, iconTransformDistance, scrolling, scrollingFast, expandingAnimated, isLastChild); return fullTransitionAmount; @@ -366,9 +412,10 @@ public class NotificationShelf extends ActivatableNotificationView implements if (iconState == null) { return; } + boolean forceInShelf = iconState.isLastExpandIcon && !iconState.hasCustomTransformHeight(); float clampedAmount = iconTransitionAmount > 0.5f ? 1.0f : 0.0f; if (clampedAmount == fullTransitionAmount) { - iconState.noAnimations = scrollingFast || expandingAnimated; + iconState.noAnimations = (scrollingFast || expandingAnimated) && !forceInShelf; iconState.useFullTransitionAmount = iconState.noAnimations || (!ICON_ANMATIONS_WHILE_SCROLLING && fullTransitionAmount == 0.0f && scrolling); iconState.useLinearTransitionAmount = !ICON_ANMATIONS_WHILE_SCROLLING @@ -376,12 +423,18 @@ public class NotificationShelf extends ActivatableNotificationView implements iconState.translateContent = mMaxLayoutHeight - getTranslationY() - getIntrinsicHeight() > 0; } - if (scrollingFast || (expandingAnimated && iconState.useFullTransitionAmount - && !ViewState.isAnimatingY(icon))) { + if (!forceInShelf && (scrollingFast || (expandingAnimated + && iconState.useFullTransitionAmount && !ViewState.isAnimatingY(icon)))) { iconState.cancelAnimations(icon); iconState.useFullTransitionAmount = true; iconState.noAnimations = true; } + if (iconState.hasCustomTransformHeight()) { + iconState.useFullTransitionAmount = true; + } + if (iconState.isLastExpandIcon) { + iconState.translateContent = false; + } float transitionAmount; if (isLastChild || !USE_ANIMATIONS_WHEN_OPENING || iconState.useFullTransitionAmount || iconState.useLinearTransitionAmount) { @@ -452,6 +505,11 @@ public class NotificationShelf extends ActivatableNotificationView implements iconState.scaleX = newSize / icon.getHeight() / icon.getIconScale(); iconState.scaleY = iconState.scaleX; iconState.hidden = transitionAmount == 0.0f && !iconState.isAnimating(icon); + boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf(); + if (isAppearing) { + iconState.hidden = true; + iconState.iconAppearAmount = 0.0f; + } iconState.alpha = alpha; iconState.yTranslation = iconYTranslation; if (stayingInShelf) { @@ -548,8 +606,7 @@ public class NotificationShelf extends ActivatableNotificationView implements if (!hasOverflow) { // we have to ensure that adding the low priority notification won't lead to an // overflow - collapsedPadding -= (1.0f + NotificationIconContainer.OVERFLOW_EARLY_AMOUNT) - * mCollapsedIcons.getIconSize(); + collapsedPadding -= (1.0f + OVERFLOW_EARLY_AMOUNT) * mCollapsedIcons.getIconSize(); } float padding = NotificationUtils.interpolate(collapsedPadding, mShelfIcons.getPaddingEnd(), diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java index 720ca1499bf1..09ae521ceb2b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java @@ -19,9 +19,11 @@ import android.content.Context; import android.content.res.Configuration; import android.graphics.drawable.Icon; import android.util.AttributeSet; +import android.util.Log; import android.util.SparseArray; import android.view.Display; import android.view.Display.Mode; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -35,6 +37,7 @@ import com.android.systemui.R; import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.PluginManager; import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider; +import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseFrameLayout; import com.android.systemui.statusbar.policy.KeyButtonView; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; @@ -43,6 +46,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; + public class NavigationBarInflaterView extends FrameLayout implements Tunable, PluginListener<NavBarButtonProvider> { @@ -71,6 +76,8 @@ public class NavigationBarInflaterView extends FrameLayout public static final String KEY_CODE_START = "("; public static final String KEY_IMAGE_DELIM = ":"; public static final String KEY_CODE_END = ")"; + private static final String WEIGHT_SUFFIX = "W"; + private static final String WEIGHT_CENTERED_SUFFIX = "WC"; private final List<NavBarButtonProvider> mPlugins = new ArrayList<>(); @@ -219,26 +226,27 @@ public class NavigationBarInflaterView extends FrameLayout String[] center = sets[1].split(BUTTON_SEPARATOR); String[] end = sets[2].split(BUTTON_SEPARATOR); // Inflate these in start to end order or accessibility traversal will be messed up. - inflateButtons(start, (ViewGroup) mRot0.findViewById(R.id.ends_group), isRot0Landscape); - inflateButtons(start, (ViewGroup) mRot90.findViewById(R.id.ends_group), !isRot0Landscape); + inflateButtons(start, mRot0.findViewById(R.id.ends_group), isRot0Landscape, true); + inflateButtons(start, mRot90.findViewById(R.id.ends_group), !isRot0Landscape, true); - inflateButtons(center, (ViewGroup) mRot0.findViewById(R.id.center_group), isRot0Landscape); - inflateButtons(center, (ViewGroup) mRot90.findViewById(R.id.center_group), !isRot0Landscape); + inflateButtons(center, mRot0.findViewById(R.id.center_group), isRot0Landscape, false); + inflateButtons(center, mRot90.findViewById(R.id.center_group), !isRot0Landscape, false); - addGravitySpacer((LinearLayout) mRot0.findViewById(R.id.ends_group)); - addGravitySpacer((LinearLayout) mRot90.findViewById(R.id.ends_group)); + addGravitySpacer(mRot0.findViewById(R.id.ends_group)); + addGravitySpacer(mRot90.findViewById(R.id.ends_group)); - inflateButtons(end, (ViewGroup) mRot0.findViewById(R.id.ends_group), isRot0Landscape); - inflateButtons(end, (ViewGroup) mRot90.findViewById(R.id.ends_group), !isRot0Landscape); + inflateButtons(end, mRot0.findViewById(R.id.ends_group), isRot0Landscape, false); + inflateButtons(end, mRot90.findViewById(R.id.ends_group), !isRot0Landscape, false); } private void addGravitySpacer(LinearLayout layout) { layout.addView(new Space(mContext), new LinearLayout.LayoutParams(0, 0, 1)); } - private void inflateButtons(String[] buttons, ViewGroup parent, boolean landscape) { + private void inflateButtons(String[] buttons, ViewGroup parent, boolean landscape, + boolean start) { for (int i = 0; i < buttons.length; i++) { - inflateButton(buttons[i], parent, landscape); + inflateButton(buttons[i], parent, landscape, start); } } @@ -251,16 +259,13 @@ public class NavigationBarInflaterView extends FrameLayout } @Nullable - protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape) { + protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape, + boolean start) { LayoutInflater inflater = landscape ? mLandscapeInflater : mLayoutInflater; - float size = extractSize(buttonSpec); - View v = createView(buttonSpec, parent, inflater, landscape); + View v = createView(buttonSpec, parent, inflater); if (v == null) return null; - if (size != 0) { - ViewGroup.LayoutParams params = v.getLayoutParams(); - params.width = (int) (params.width * size); - } + v = applySize(v, buttonSpec, landscape, start); parent.addView(v); addToDispatchers(v); View lastView = landscape ? mLastLandscape : mLastPortrait; @@ -275,16 +280,41 @@ public class NavigationBarInflaterView extends FrameLayout return v; } - private View createView(String buttonSpec, ViewGroup parent, LayoutInflater inflater, - boolean landscape) { + private View applySize(View v, String buttonSpec, boolean landscape, boolean start) { + String sizeStr = extractSize(buttonSpec); + if (sizeStr == null) return v; + + if (sizeStr.contains(WEIGHT_SUFFIX)) { + float weight = Float.parseFloat(sizeStr.substring(0, sizeStr.indexOf(WEIGHT_SUFFIX))); + FrameLayout frame = new ReverseFrameLayout(mContext); + LayoutParams childParams = new LayoutParams(v.getLayoutParams()); + if (sizeStr.endsWith(WEIGHT_CENTERED_SUFFIX)) { + childParams.gravity = Gravity.CENTER; + } else { + childParams.gravity = landscape ? (start ? Gravity.BOTTOM : Gravity.TOP) + : (start ? Gravity.START : Gravity.END); + } + frame.addView(v, childParams); + frame.setLayoutParams(new LinearLayout.LayoutParams(0, MATCH_PARENT, weight)); + frame.setClipChildren(false); + frame.setClipToPadding(false); + return frame; + } + float size = Float.parseFloat(sizeStr); + ViewGroup.LayoutParams params = v.getLayoutParams(); + params.width = (int) (params.width * size); + return v; + } + + private View createView(String buttonSpec, ViewGroup parent, LayoutInflater inflater) { View v = null; String button = extractButton(buttonSpec); if (LEFT.equals(button)) { - buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT, NAVSPACE); - button = extractButton(buttonSpec); + String s = Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT, NAVSPACE); + button = extractButton(s); } else if (RIGHT.equals(button)) { - buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_RIGHT, MENU_IME); - button = extractButton(buttonSpec); + String s = Dependency.get(TunerService.class).getValue(NAV_BAR_RIGHT, MENU_IME); + button = extractButton(s); } // Let plugins go first so they can override a standard view if they want. for (NavBarButtonProvider provider : mPlugins) { @@ -340,13 +370,12 @@ public class NavigationBarInflaterView extends FrameLayout return Integer.parseInt(subStr); } - public static float extractSize(String buttonSpec) { + public static String extractSize(String buttonSpec) { if (!buttonSpec.contains(SIZE_MOD_START)) { - return 1; + return null; } final int sizeStart = buttonSpec.indexOf(SIZE_MOD_START); - String sizeStr = buttonSpec.substring(sizeStart + 1, buttonSpec.indexOf(SIZE_MOD_END)); - return Float.parseFloat(sizeStr); + return buttonSpec.substring(sizeStart + 1, buttonSpec.indexOf(SIZE_MOD_END)); } public static String extractButton(String buttonSpec) { @@ -379,8 +408,8 @@ public class NavigationBarInflaterView extends FrameLayout mButtonDispatchers.valueAt(i).clear(); } } - clearAllChildren((ViewGroup) mRot0.findViewById(R.id.nav_buttons)); - clearAllChildren((ViewGroup) mRot90.findViewById(R.id.nav_buttons)); + clearAllChildren(mRot0.findViewById(R.id.nav_buttons)); + clearAllChildren(mRot90.findViewById(R.id.nav_buttons)); } private void clearAllChildren(ViewGroup group) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index a6cd472f2686..426444158b11 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -575,15 +575,17 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mRotatedViews[Surface.ROTATION_270] = mRotatedViews[Surface.ROTATION_90] = findViewById(R.id.rot90); - updateCurrentView(); + mCurrentRotation = -1; + reorient(); } public boolean needsReorient(int rotation) { return mCurrentRotation != rotation; } - private void updateCurrentView() { + private boolean updateCurrentView() { final int rot = mDisplay.getRotation(); + if (rot == mCurrentRotation) return false; for (int i=0; i<4; i++) { mRotatedViews[i].setVisibility(View.GONE); } @@ -595,6 +597,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } updateLayoutTransitionsEnabled(); mCurrentRotation = rot; + return true; } private void updateRecentsIcon() { @@ -607,10 +610,14 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } public void reorient() { - updateCurrentView(); + if (!updateCurrentView()) { + return; + } mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone); - ((NavigationBarFrame) getRootView()).setDeadZone(mDeadZone); + if (getRootView() instanceof NavigationBarFrame) { + ((NavigationBarFrame) getRootView()).setDeadZone(mDeadZone); + } mDeadZone.setDisplayRotation(mCurrentRotation); // force the low profile & disabled states into compliance @@ -644,6 +651,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mVertical = newVertical; //Log.v(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w, mVertical?"y":"n")); reorient(); + getHomeButton().setVertical(mVertical); notifyVerticalChangedListener(newVertical); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java index 021e11acbcf5..6f5ad9614a26 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java @@ -526,6 +526,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { } public class IconState extends ViewState { + public static final int NO_VALUE = NotificationIconContainer.NO_VALUE; public float iconAppearAmount = 1.0f; public float clampedAppearAmount = 1.0f; public int visibleState; @@ -538,6 +539,8 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { public boolean justUndarkened; public int iconColor = StatusBarIconView.NO_COLOR; public boolean noAnimations; + public boolean isLastExpandIcon; + public int customTransformHeight = NO_VALUE; @Override public void applyToView(View view) { @@ -615,6 +618,10 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { justUndarkened = false; } + public boolean hasCustomTransformHeight() { + return isLastExpandIcon && customTransformHeight != NO_VALUE; + } + @Override public void initFrom(View view) { super.initFrom(view); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java index f45967a0a0a6..bcbc3457a2e2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java @@ -16,10 +16,10 @@ package com.android.systemui.statusbar.phone; import android.annotation.Nullable; import android.content.Context; -import android.content.res.Configuration; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; +import android.widget.FrameLayout; import android.widget.LinearLayout; import java.util.ArrayList; @@ -48,7 +48,7 @@ public class ReverseLinearLayout extends LinearLayout { @Override public void addView(View child) { - reversParams(child.getLayoutParams()); + reverseParams(child.getLayoutParams(), child); if (mIsLayoutReverse) { super.addView(child, 0); } else { @@ -58,7 +58,7 @@ public class ReverseLinearLayout extends LinearLayout { @Override public void addView(View child, ViewGroup.LayoutParams params) { - reversParams(params); + reverseParams(params, child); if (mIsLayoutReverse) { super.addView(child, 0, params); } else { @@ -100,7 +100,15 @@ public class ReverseLinearLayout extends LinearLayout { } } - private void reversParams(ViewGroup.LayoutParams params) { + private static void reverseParams(ViewGroup.LayoutParams params, View child) { + if (child instanceof Reversable) { + ((Reversable) child).reverse(); + } + if (child.getPaddingLeft() == child.getPaddingRight() + && child.getPaddingTop() == child.getPaddingBottom()) { + child.setPadding(child.getPaddingTop(), child.getPaddingLeft(), + child.getPaddingTop(), child.getPaddingLeft()); + } if (params == null) { return; } @@ -109,4 +117,23 @@ public class ReverseLinearLayout extends LinearLayout { params.height = width; } + public interface Reversable { + void reverse(); + } + + public static class ReverseFrameLayout extends FrameLayout implements Reversable { + + public ReverseFrameLayout(Context context) { + super(context); + } + + @Override + public void reverse() { + for (int i = 0; i < getChildCount(); i++) { + View child = getChildAt(i); + reverseParams(child.getLayoutParams(), child); + } + } + } + } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 419aefe3e9e9..754c34486954 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -61,11 +61,11 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, public static final float GRADIENT_SCRIM_ALPHA = 0.45f; // A scrim varies its opacity based on a busyness factor, for example // how many notifications are currently visible. - public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.90f; + public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.70f; protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = GRADIENT_SCRIM_ALPHA; protected static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f; - private static final float SCRIM_IN_FRONT_ALPHA = GRADIENT_SCRIM_ALPHA; - private static final float SCRIM_IN_FRONT_ALPHA_LOCKED = GRADIENT_SCRIM_ALPHA; + private static final float SCRIM_IN_FRONT_ALPHA = GRADIENT_SCRIM_ALPHA_BUSY; + private static final float SCRIM_IN_FRONT_ALPHA_LOCKED = GRADIENT_SCRIM_ALPHA_BUSY; private static final int TAG_KEY_ANIM = R.id.scrim; private static final int TAG_KEY_ANIM_TARGET = R.id.scrim_target; private static final int TAG_START_ALPHA = R.id.scrim_alpha_start; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java index deea521b7c2f..7a7efbdc6615 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java @@ -100,12 +100,8 @@ public class SignalDrawable extends Drawable { // How far the circle defining the corners is inset from the edges private final float mAppliedCornerInset; - // The easiest way to understand this is as if we set Style.STROKE and draw the triangle, - // but that is only theoretically right. Instead, draw the triangle and clip out a smaller - // one inset by this amount. - private final float mEmptyStrokeWidth; private static final float INV_TAN = 1f / (float) Math.tan(Math.PI / 8f); - private final float mEmptyDiagInset; // == mEmptyStrokeWidth * INV_TAN + private static final float CUT_WIDTH_DP = 1f / 12f; // Where the top and left points of the triangle would be if not for rounding private final PointF mVirtualTop = new PointF(); @@ -145,11 +141,6 @@ public class SignalDrawable extends Drawable { Utils.getDefaultColor(context, R.color.light_mode_icon_color_dual_tone_fill); mIntrinsicSize = context.getResources().getDimensionPixelSize(R.dimen.signal_icon_size); - // mCutPath parameters - mEmptyStrokeWidth = context.getResources() - .getDimensionPixelSize(R.dimen.mobile_signal_empty_strokewidth); - mEmptyDiagInset = mEmptyStrokeWidth * INV_TAN; - mHandler = new Handler(); setDarkIntensity(0); @@ -326,22 +317,20 @@ public class SignalDrawable extends Drawable { (padding + cornerRadius + mAppliedCornerInset) - (INV_TAN * cornerRadius), height - padding); + final float cutWidth = CUT_WIDTH_DP * height; + final float cutDiagInset = cutWidth * INV_TAN; + // Cut out a smaller triangle from the center of mFullPath mCutPath.reset(); mCutPath.setFillType(FillType.WINDING); - mCutPath.moveTo(width - padding - mEmptyStrokeWidth, - height - padding - mEmptyStrokeWidth); - mCutPath.lineTo(width - padding - mEmptyStrokeWidth, - mVirtualTop.y + mEmptyDiagInset); - mCutPath.lineTo(mVirtualLeft.x + mEmptyDiagInset, - height - padding - mEmptyStrokeWidth); - mCutPath.lineTo(width - padding - mEmptyStrokeWidth, - height - padding - mEmptyStrokeWidth); - - // In empty state, draw the full path as the foreground paint - mForegroundPath.set(mFullPath); - mFullPath.reset(); - mForegroundPath.op(mCutPath, Path.Op.DIFFERENCE); + mCutPath.moveTo(width - padding - cutWidth, height - padding - cutWidth); + mCutPath.lineTo(width - padding - cutWidth, mVirtualTop.y + cutDiagInset); + mCutPath.lineTo(mVirtualLeft.x + cutDiagInset, height - padding - cutWidth); + mCutPath.lineTo(width - padding - cutWidth, height - padding - cutWidth); + + // Draw empty state as only background + mForegroundPath.reset(); + mFullPath.op(mCutPath, Path.Op.DIFFERENCE); } else if (mState == STATE_AIRPLANE) { // Airplane mode is slashed, full-signal mForegroundPath.set(mFullPath); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 14d0b7ea86b9..33d92fc95105 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -309,7 +309,7 @@ public class StatusBar extends SystemUI implements DemoMode, public static final boolean DEBUG_GESTURES = false; public static final boolean DEBUG_MEDIA = false; public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false; - public static final boolean DEBUG_CAMERA_LIFT = true; // false once b/62623620 is fixed + public static final boolean DEBUG_CAMERA_LIFT = false; public static final boolean DEBUG_WINDOW_STATE = false; @@ -425,6 +425,7 @@ public class StatusBar extends SystemUI implements DemoMode, private boolean mWakeUpComingFromTouch; private PointF mWakeUpTouchLocation; private boolean mScreenTurningOn; + private boolean mScreenFullyOff; int mPixelFormat; Object mQueueLock = new Object(); @@ -2811,7 +2812,9 @@ public class StatusBar extends SystemUI implements DemoMode, } public void onScreenTurnedOff() { + mScreenFullyOff = true; mFalsingManager.onScreenOff(); + updateIsKeyguard(); } public NotificationStackScrollLayout getNotificationScrollLayout() { @@ -4188,8 +4191,11 @@ public class StatusBar extends SystemUI implements DemoMode, private boolean updateIsKeyguard() { // For dozing, keyguard needs to be shown whenever the device is non-interactive. Otherwise - // there's no surface we can show to the user. - boolean keyguardForDozing = mDozingRequested && !mDeviceInteractive; + // there's no surface we can show to the user. Note that the device goes fully interactive + // late in the transition, so we also allow the device to start dozing once the screen has + // turned off fully. + boolean keyguardForDozing = mDozingRequested && + (!mDeviceInteractive || mStartedGoingToSleep && (mScreenFullyOff || mIsKeyguard)); boolean shouldBeKeyguard = mKeyguardRequested || keyguardForDozing; if (keyguardForDozing) { updatePanelExpansionForKeyguard(); @@ -5130,6 +5136,7 @@ public class StatusBar extends SystemUI implements DemoMode, } public void onScreenTurningOn() { + mScreenFullyOff = false; mScreenTurningOn = true; mFalsingManager.onScreenTurningOn(); mNotificationPanel.onScreenTurningOn(); @@ -5297,7 +5304,7 @@ public class StatusBar extends SystemUI implements DemoMode, mDozingRequested = true; DozeLog.traceDozing(mContext, mDozing); updateDozing(); - + updateIsKeyguard(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 9b0307d6522e..2833ff1db27f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -152,7 +152,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb * {@link KeyguardBouncer#needsFullscreenBouncer()}. */ protected void showBouncerOrKeyguard(boolean hideBouncerWhenShowing) { - if (mBouncer.needsFullscreenBouncer()) { + if (mBouncer.needsFullscreenBouncer() && !mDozing) { // The keyguard might be showing (already). So we need to hide it. mStatusBar.hideKeyguard(); @@ -258,8 +258,11 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } public void setDozing(boolean dozing) { - mDozing = dozing; - updateStates(); + if (mDozing != dozing) { + mDozing = dozing; + reset(dozing /* hideBouncerWhenShowing */); + updateStates(); + } } public void onScreenTurnedOff() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java index 93dc6de1059a..6104befeb432 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java @@ -138,7 +138,7 @@ public class StatusBarWindowManager implements RemoteInputController.Callback, D } private void adjustScreenOrientation(State state) { - if (state.isKeyguardShowingAndNotOccluded()) { + if (state.isKeyguardShowingAndNotOccluded() || state.dozing) { if (mKeyguardScreenRotation) { mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER; } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java index d77796144282..2d3e0b6829ca 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java @@ -226,6 +226,9 @@ public class KeyButtonView extends ImageView implements ButtonInterface { case MotionEvent.ACTION_UP: final boolean doIt = isPressed() && !mLongClicked; setPressed(false); + // Always send a release ourselves because it doesn't seem to be sent elsewhere + // and it feels weird to sometimes get a release haptic and other times not. + performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE); if (mCode != 0) { if (doIt) { sendEvent(KeyEvent.ACTION_UP, 0); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index bd7fee0f7f52..b6c76551c48b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -341,6 +341,10 @@ public class MobileSignalController extends SignalController< } private boolean isRoaming() { + // During a carrier change, roaming indications need to be supressed. + if (isCarrierNetworkChangeActive()) { + return false; + } if (isCdma()) { final int iconMode = mServiceState.getCdmaEriIconMode(); return mServiceState.getCdmaEriIconIndex() != EriInfo.ROAMING_INDICATOR_OFF diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java index b7b991e36710..ba1e7c2d86c5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java @@ -62,6 +62,7 @@ public class AmbientState { private boolean mHasPulsingNotifications; private boolean mUnlockHintRunning; private boolean mQsCustomizerShowing; + private int mIntrinsicPadding; public AmbientState(Context context) { reload(context); @@ -323,4 +324,12 @@ public class AmbientState { public void setQsCustomizerShowing(boolean qsCustomizerShowing) { mQsCustomizerShowing = qsCustomizerShowing; } + + public void setIntrinsicPadding(int intrinsicPadding) { + mIntrinsicPadding = intrinsicPadding; + } + + public int getIntrinsicPadding() { + return mIntrinsicPadding; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index cbd315b940f3..41cde9c7dd5e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -2735,7 +2735,7 @@ public class NotificationStackScrollLayout extends ViewGroup return view.getHeight(); } - private int getPositionInLinearLayout(View requestedView) { + public int getPositionInLinearLayout(View requestedView) { ExpandableNotificationRow childInGroup = null; ExpandableNotificationRow requestedRow = null; if (isChildInGroup(requestedView)) { @@ -3650,6 +3650,7 @@ public class NotificationStackScrollLayout extends ViewGroup public void setIntrinsicPadding(int intrinsicPadding) { mIntrinsicPadding = intrinsicPadding; + mAmbientState.setIntrinsicPadding(intrinsicPadding); } public int getIntrinsicPadding() { diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java index 5d51a33c6307..eaad2f9bd457 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java @@ -43,6 +43,7 @@ import android.provider.Settings; import android.service.notification.Condition; import android.util.ArrayMap; import android.util.Log; +import android.view.accessibility.AccessibilityManager; import com.android.internal.annotations.GuardedBy; import com.android.systemui.Dumpable; @@ -122,6 +123,12 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa mReceiver.init(); mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); mHasVibrator = mVibrator != null && mVibrator.hasVibrator(); + + boolean accessibilityVolumeStreamActive = context.getSystemService( + AccessibilityManager.class).isAccessibilityVolumeStreamActive(); + mVolumeController.setA11yMode(accessibilityVolumeStreamActive ? + VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME : + VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME); } public AudioManager getAudioManager() { @@ -210,6 +217,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa public void addCallback(Callbacks callback, Handler handler) { mCallbacks.add(callback, handler); + callback.onAccessibilityModeChanged(mShowA11yStream); } public void setUserActivityListener(UserActivityListener listener) { diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml index b12fd1c9ba89..9bb21808e9bc 100644 --- a/packages/SystemUI/tests/AndroidManifest.xml +++ b/packages/SystemUI/tests/AndroidManifest.xml @@ -48,7 +48,7 @@ android:process=":killable" /> </application> - <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner" + <instrumentation android:name="android.testing.TestableInstrumentation" android:targetPackage="com.android.systemui.tests" android:label="Tests for SystemUI"> </instrumentation> diff --git a/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java b/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java index 945af34c1df1..2a447715fb6b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java @@ -21,7 +21,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -30,7 +29,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Fragment; -import android.support.test.filters.FlakyTest; import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; import android.view.Display; @@ -48,12 +46,10 @@ import com.android.systemui.tuner.TunablePadding.TunablePaddingService; import com.android.systemui.tuner.TunerService; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidTestingRunner.class) -@FlakyTest @SmallTest public class RoundedCornersTest extends SysuiTestCase { @@ -72,6 +68,7 @@ public class RoundedCornersTest extends SysuiTestCase { mWindowManager = mock(WindowManager.class); mView = spy(new StatusBarWindowView(mContext, null)); when(mStatusBar.getStatusBarWindow()).thenReturn(mView); + when(mStatusBar.getNavigationBarWindow()).thenReturn(mView); mContext.putComponent(StatusBar.class, mStatusBar); Display display = mContext.getSystemService(WindowManager.class).getDefaultDisplay(); @@ -94,6 +91,8 @@ public class RoundedCornersTest extends SysuiTestCase { @Test public void testNoRounding() { mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 0); + mContext.getOrCreateTestableResources() + .addOverride(dimen.rounded_corner_content_padding, 0); mRoundedCorners.start(); // No views added. @@ -107,13 +106,15 @@ public class RoundedCornersTest extends SysuiTestCase { @Test public void testRounding() { mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 20); + mContext.getOrCreateTestableResources() + .addOverride(dimen.rounded_corner_content_padding, 20); mRoundedCorners.start(); // Add 2 windows for rounded corners (top and bottom). verify(mWindowManager, times(2)).addView(any(), any()); - // Add 3 tag listeners for each of the fragments that are needed. - verify(mFragmentHostManager, times(3)).addTagListener(any(), any()); + // Add 2 tag listeners for each of the fragments that are needed. + verify(mFragmentHostManager, times(2)).addTagListener(any(), any()); // One tunable. verify(mTunerService, times(1)).addTunable(any(), any()); // One TunablePadding. diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java index 361a20fb7bdc..66d00dd6c5c6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java +++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java @@ -31,6 +31,8 @@ import android.util.Log; import org.junit.After; import org.junit.Before; import org.junit.Rule; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -56,10 +58,14 @@ public abstract class SysuiTestCase { mRealInstrumentation = InstrumentationRegistry.getInstrumentation(); Instrumentation inst = spy(mRealInstrumentation); - when(inst.getContext()).thenThrow(new RuntimeException( - "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext")); - when(inst.getTargetContext()).thenThrow(new RuntimeException( - "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext")); + when(inst.getContext()).thenAnswer(invocation -> { + throw new RuntimeException( + "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"); + }); + when(inst.getTargetContext()).thenAnswer(invocation -> { + throw new RuntimeException( + "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"); + }); InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java index 2363b2aadc10..8641faca5d6e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java @@ -27,7 +27,6 @@ import android.app.Instrumentation; import android.os.Handler; import android.os.Looper; import android.support.test.InstrumentationRegistry; -import android.support.test.filters.FlakyTest; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; diff --git a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java index b8e9fcd29096..bba982c3b060 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java @@ -26,8 +26,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; -import android.support.test.annotation.UiThreadTest; -import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -36,11 +34,10 @@ import android.testing.TestableLooper.RunWithLooper; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; -import com.android.systemui.plugins.annotations.ProvidesInterface; import com.android.systemui.plugins.PluginInstanceManager.PluginInfo; +import com.android.systemui.plugins.annotations.ProvidesInterface; import com.android.systemui.plugins.PluginManagerImpl.PluginInstanceManagerFactory; -import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java index 6a85511daca2..ed47fbb89077 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java @@ -23,10 +23,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import org.junit.After; -import org.junit.Ignore; import android.support.test.filters.SmallTest; -import android.support.test.filters.FlakyTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; @@ -41,6 +38,7 @@ import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.DetailAdapter; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java index f4fda065860e..d25bbe1e4904 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java @@ -21,7 +21,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.support.test.filters.SmallTest; -import android.support.test.filters.FlakyTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java index 637b2440af09..85cdfcc2ce09 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java @@ -20,7 +20,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.support.test.filters.SmallTest; -import android.support.test.filters.FlakyTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; @@ -31,7 +30,6 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.qs.customize.QSCustomizer; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @@ -40,7 +38,6 @@ import java.util.Collections; @RunWith(AndroidTestingRunner.class) @RunWithLooper @SmallTest -@FlakyTest public class QSPanelTest extends SysuiTestCase { private MetricsLogger mMetricsLogger; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java index 664ea710d61e..2f6511c8481e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java @@ -21,27 +21,21 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.annotation.UiThreadTest; -import android.support.test.filters.FlakyTest; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.view.View; +import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.notification.AboveShelfChangedListener; import com.android.systemui.statusbar.stack.NotificationChildrenContainer; -import com.android.systemui.SysuiTestCase; import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @SmallTest @RunWith(AndroidJUnit4.class) -@FlakyTest public class ExpandableNotificationRowTest extends SysuiTestCase { private ExpandableNotificationRow mGroup; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java index 4dce2f5f87ed..436849c9d700 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java @@ -16,30 +16,25 @@ package com.android.systemui.statusbar; -import android.content.Context; -import android.support.test.InstrumentationRegistry; +import static org.mockito.ArgumentMatchers.anyFloat; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; + import android.support.test.annotation.UiThreadTest; -import android.support.test.filters.FlakyTest; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.view.View; +import com.android.systemui.SysuiTestCase; + import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; -import static org.mockito.ArgumentMatchers.anyFloat; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; - -import com.android.systemui.SysuiTestCase; - @SmallTest @RunWith(AndroidJUnit4.class) -@FlakyTest public class NotificationContentViewTest extends SysuiTestCase { NotificationContentView mView; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java index d18e63bcc151..6e59d10aad3c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java @@ -16,10 +16,7 @@ package com.android.systemui.statusbar; -import android.content.Context; -import android.support.test.InstrumentationRegistry; import android.support.test.annotation.UiThreadTest; -import android.support.test.filters.FlakyTest; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.view.View; @@ -32,13 +29,11 @@ import com.android.systemui.statusbar.notification.NotificationViewWrapper; import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @SmallTest @RunWith(AndroidJUnit4.class) -@FlakyTest public class NotificationCustomViewWrapperTest extends SysuiTestCase { private ExpandableNotificationRow mRow; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java index 630da2e7eabc..2a2acabc8cee 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java @@ -57,4 +57,10 @@ public class NotificationMenuRowTest extends LeakCheckedTest { row.createMenu(null, null); assertTrue(row.getMenuView() != null); } + + @Test + public void testResetUncreatedMenu() { + NotificationMenuRowPlugin row = new NotificationMenuRow(mContext); + row.resetMenu(); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java index be3802bd68ed..cba9f77df2ff 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java @@ -494,6 +494,79 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { DEFAULT_ICON /* typeIcon */); } + @Test + public void testCarrierNetworkChange_roamingBeforeNetworkChange() { + int strength = SignalStrength.SIGNAL_STRENGTH_GREAT; + + setupDefaultSignal(); + setLevel(strength); + setGsmRoaming(true); + + // Verify baseline + verifyLastMobileDataIndicators(true /* visible */, + strength /* strengthIcon */, + DEFAULT_ICON /* typeIcon */, + true /* roaming */); + + // API call is made + setCarrierNetworkChange(true /* enabled */); + + // Carrier network change is true, show special indicator, no roaming. + verifyLastMobileDataIndicators(true /* visible */, + SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS), + 0 /* typeIcon */, + false /* roaming */); + + // Revert back + setCarrierNetworkChange(false /* enabled */); + + // Verify back in previous state + verifyLastMobileDataIndicators(true /* visible */, + strength /* strengthIcon */, + DEFAULT_ICON /* typeIcon */, + true /* roaming */); + } + + @Test + public void testCarrierNetworkChange_roamingAfterNetworkChange() { + int strength = SignalStrength.SIGNAL_STRENGTH_GREAT; + + setupDefaultSignal(); + setLevel(strength); + + // Verify baseline + verifyLastMobileDataIndicators(true /* visible */, + strength /* strengthIcon */, + DEFAULT_ICON /* typeIcon */, + false /* roaming */); + + // API call is made + setCarrierNetworkChange(true /* enabled */); + + // Carrier network change is true, show special indicator, no roaming. + verifyLastMobileDataIndicators(true /* visible */, + SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS), + 0 /* typeIcon */, + false /* roaming */); + + setGsmRoaming(true); + + // Roaming should not show. + verifyLastMobileDataIndicators(true /* visible */, + SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS), + 0 /* typeIcon */, + false /* roaming */); + + // Revert back + setCarrierNetworkChange(false /* enabled */); + + // Verify back in previous state + verifyLastMobileDataIndicators(true /* visible */, + strength /* strengthIcon */, + DEFAULT_ICON /* typeIcon */, + true /* roaming */); + } + private void verifyEmergencyOnly(boolean isEmergencyOnly) { ArgumentCaptor<Boolean> emergencyOnly = ArgumentCaptor.forClass(Boolean.class); Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setEmergencyCallsOnly( diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java index bc6833df1e30..5ac965cf4042 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java @@ -16,10 +16,6 @@ package com.android.systemui.statusbar.stack; -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.annotation.UiThreadTest; -import android.support.test.filters.FlakyTest; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.view.NotificationHeaderView; @@ -31,13 +27,11 @@ import com.android.systemui.statusbar.NotificationTestHelper; import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @SmallTest @RunWith(AndroidJUnit4.class) -@FlakyTest public class NotificationChildrenContainerTest extends SysuiTestCase { private ExpandableNotificationRow mGroup; diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java index 0a83a896dfaf..d1b1c5b9a066 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java +++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java @@ -14,7 +14,6 @@ package com.android.systemui.utils.leaks; -import android.content.Context; import android.testing.LeakCheck; import com.android.systemui.plugins.Plugin; diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 2edcd71721ca..9aa58f501602 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -4153,11 +4153,44 @@ message MetricsEvent { // OS: O DR FIELD_PLUG_BATTERY_PERCENTAGE = 1024; + // Device Headset battery level on Plug + // CATEGORY: OTHER + // FIELD - The battery percentage when the user decided to plug in + // Type: integer + // OS: O DR + FIELD_UNPLUG_BATTERY_PERCENTAGE = 1025; + // Device Headset Pose status // CATEGORY: OTHER // SUBTYPE: 1 is 6DOF, 2 is 3DOF // OS: O DR - ACTION_HEADSET_POSE_STATUS = 1025; + ACTION_HEADSET_POSE_STATUS = 1026; + + // Device Headset Usage session time + // CATEGORY: OTHER + // FIELD - The time the headset was used in a session + // OS: O DR + FIELD_SESSION_TIME_MS = 1027; + + // Device Headset Idle time + // CATEGORY: OTHER + // FIELD - The time in between each session + // OS: O DR + FIELD_TIME_ELAPSED_BETWEEN_SESSION_MS = 1028; + + // Device Headset charge session time + // CATEGORY: OTHER + // FIELD - The time taken for each charge + // OS: O DR + FIELD_TIME_OF_CHARGE_MS = 1029; + + // Device Headset time between charge + // CATEGORY: OTHER + // FIELD - The time in between each charge + // OS: O DR + FIELD_TIME_ELAPSED_BETWEEN_CHARGE_MS = 1030; + + // ---- End O-DR1 Constants, all O-DR1 constants go above this line ---- // Add new aosp constants above this line. // END OF AOSP CONSTANTS diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java index 9e4d89cbc9c5..0e42e6d6a83d 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java @@ -271,6 +271,7 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo private void processKeyEvent(EventStreamState state, KeyEvent event, int policyFlags) { if (!state.shouldProcessKeyEvent(event)) { + super.onInputEvent(event, policyFlags); return; } mEventHandler.onKeyEvent(event, policyFlags); diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index f1f875782416..e3da4eb1628f 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -5688,13 +5688,15 @@ public class BackupManagerService implements BackupManagerServiceInterface { PerformFullTransportBackupTask pftbt = null; synchronized (mQueueLock) { if (mRunningFullBackupTask != null) { - if (DEBUG_SCHEDULING) { - Slog.i(TAG, "Telling running backup to stop"); - } pftbt = mRunningFullBackupTask; } } - pftbt.handleCancel(true); + if (pftbt != null) { + if (DEBUG_SCHEDULING) { + Slog.i(TAG, "Telling running backup to stop"); + } + pftbt.handleCancel(true); + } } }; new Thread(endFullBackupRunnable, "end-full-backup").start(); diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index 4810f4fe8c82..f47b0d3c6e73 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -383,7 +383,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind findDeviceCallback, getServiceCallback()); } catch (RemoteException e) { - throw new RuntimeException(e); + Log.e(LOG_TAG, "Error while initiating device discovery", e); } } diff --git a/services/core/java/com/android/server/ContextHubSystemService.java b/services/core/java/com/android/server/ContextHubSystemService.java index 5d4317cbdae3..110847dd54c8 100644 --- a/services/core/java/com/android/server/ContextHubSystemService.java +++ b/services/core/java/com/android/server/ContextHubSystemService.java @@ -16,17 +16,25 @@ package com.android.server; +import com.android.internal.util.ConcurrentUtils; import com.android.server.location.ContextHubService; +import com.android.server.SystemServerInitThreadPool; import android.content.Context; import android.util.Log; +import java.util.concurrent.Future; + class ContextHubSystemService extends SystemService { private static final String TAG = "ContextHubSystemService"; - private final ContextHubService mContextHubService; + private ContextHubService mContextHubService; + + private Future<?> mInit; public ContextHubSystemService(Context context) { super(context); - mContextHubService = new ContextHubService(context); + mInit = SystemServerInitThreadPool.get().submit(() -> { + mContextHubService = new ContextHubService(context); + }, "Init ContextHubSystemService"); } @Override @@ -37,6 +45,9 @@ class ContextHubSystemService extends SystemService { public void onBootPhase(int phase) { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { Log.d(TAG, "onBootPhase: PHASE_SYSTEM_SERVICES_READY"); + ConcurrentUtils.waitForFutureNoInterrupt(mInit, + "Wait for ContextHubSystemService init"); + mInit = null; publishBinderService(Context.CONTEXTHUB_SERVICE, mContextHubService); } } diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java index 4c9495a786c3..a903f3dff0ae 100644 --- a/services/core/java/com/android/server/GestureLauncherService.java +++ b/services/core/java/com/android/server/GestureLauncherService.java @@ -57,7 +57,7 @@ import com.android.server.statusbar.StatusBarManagerInternal; */ public class GestureLauncherService extends SystemService { private static final boolean DBG = false; - private static final boolean DBG_CAMERA_LIFT = true; // false once b/62623620 is fixed + private static final boolean DBG_CAMERA_LIFT = false; private static final String TAG = "GestureLauncherService"; /** diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index fd4f672640c9..f106ca0b35cb 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -20,6 +20,7 @@ import static android.Manifest.permission.CHANGE_CONFIGURATION; import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; +import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; import static android.Manifest.permission.READ_FRAME_BUFFER; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; @@ -10297,7 +10298,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void moveStackToDisplay(int stackId, int displayId) { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()"); + enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()"); synchronized (this) { final long ident = Binder.clearCallingIdentity(); @@ -12573,7 +12574,6 @@ public class ActivityManagerService extends IActivityManager.Stub Binder.restoreCallingIdentity(ident); } } - closeSystemDialogs("setLockScreenShown"); } @Override diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 1ccac1b8dc8a..e0f2a751604a 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -16,6 +16,7 @@ package com.android.server.am; +import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; import static android.Manifest.permission.START_ANY_ACTIVITY; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; @@ -38,11 +39,13 @@ import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCRE import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.os.Process.SYSTEM_UID; import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.FLAG_PRIVATE; import static android.view.Display.INVALID_DISPLAY; import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT; +import static android.view.Display.TYPE_VIRTUAL; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; @@ -1694,6 +1697,24 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D return false; } + // Check if the caller can manage activity stacks. + final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid, + callingUid); + if (startAnyPerm == PERMISSION_GRANTED) { + if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" + + " allow launch any on display"); + return true; + } + + if (activityDisplay.mDisplay.getType() == TYPE_VIRTUAL + && activityDisplay.mDisplay.getOwnerUid() != SYSTEM_UID) { + // Limit launching on virtual displays, because their contents can be read from Surface + // by apps that created them. + if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" + + " disallow launch on virtual display for not-embedded activity"); + return false; + } + if (!activityDisplay.isPrivate()) { // Anyone can launch on a public display. if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" @@ -1715,15 +1736,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D return true; } - // Check if the caller can manage activity stacks. - final int startAnyPerm = mService.checkPermission(MANAGE_ACTIVITY_STACKS, callingPid, - callingUid); - if (startAnyPerm == PERMISSION_GRANTED) { - if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" - + " allow launch any on display"); - return true; - } - Slog.w(TAG, "Launch on display check: denied"); return false; } diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index a145435976fa..a31c33e4ab91 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -17,6 +17,7 @@ package com.android.server.am; import static android.app.Activity.RESULT_CANCELED; +import static android.app.ActivityManager.START_ABORTED; import static android.app.ActivityManager.START_CANCELED; import static android.app.ActivityManager.START_CLASS_NOT_FOUND; import static android.app.ActivityManager.START_DELIVERED_TO_TOP; @@ -279,7 +280,9 @@ class ActivityStarter { // mLastStartActivityRecord[0] is set in the call to startActivity above. outActivity[0] = mLastStartActivityRecord[0]; } - return mLastStartActivityResult; + + // Aborted results are treated as successes externally, but we must track them internally. + return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS; } /** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */ @@ -465,7 +468,7 @@ class ActivityStarter { // We pretend to the caller that it was really started, but // they will just get a cancel result. ActivityOptions.abort(options); - return START_SUCCESS; + return START_ABORTED; } // If permissions need a review before any of the app components can run, we diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java index 2e0ec0b361e2..a46c85170ba2 100644 --- a/services/core/java/com/android/server/am/KeyguardController.java +++ b/services/core/java/com/android/server/am/KeyguardController.java @@ -17,6 +17,7 @@ package com.android.server.am; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; +import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS; import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE; import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER; @@ -34,6 +35,7 @@ import static com.android.server.wm.AppTransition.TRANSIT_UNSET; import android.os.IBinder; import android.os.RemoteException; +import android.os.Trace; import android.util.Slog; import com.android.internal.policy.IKeyguardDismissCallback; @@ -111,22 +113,28 @@ class KeyguardController { * etc. */ void keyguardGoingAway(int flags) { - if (mKeyguardShowing) { - mWindowManager.deferSurfaceLayout(); - try { - setKeyguardGoingAway(true); - mWindowManager.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, - false /* alwaysKeepCurrent */, convertTransitFlags(flags), - false /* forceOverride */); - mService.updateSleepIfNeededLocked(); - - // Some stack visibility might change (e.g. docked stack) - mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); - mStackSupervisor.addStartingWindowsForVisibleActivities(true /* taskSwitch */); - mWindowManager.executeAppTransition(); - } finally { - mWindowManager.continueSurfaceLayout(); - } + if (!mKeyguardShowing) { + return; + } + Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "keyguardGoingAway"); + mWindowManager.deferSurfaceLayout(); + try { + setKeyguardGoingAway(true); + mWindowManager.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, + false /* alwaysKeepCurrent */, convertTransitFlags(flags), + false /* forceOverride */); + mService.updateSleepIfNeededLocked(); + + // Some stack visibility might change (e.g. docked stack) + mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); + mStackSupervisor.addStartingWindowsForVisibleActivities(true /* taskSwitch */); + mWindowManager.executeAppTransition(); + } finally { + Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "keyguardGoingAway: surfaceLayout"); + mWindowManager.continueSurfaceLayout(); + Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); + + Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); } } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index e5ab784df882..2199bba9bbac 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -239,6 +239,7 @@ public class AudioService extends IAudioService.Stub private static final int MSG_SET_A2DP_SRC_CONNECTION_STATE = 101; private static final int MSG_SET_A2DP_SINK_CONNECTION_STATE = 102; private static final int MSG_A2DP_DEVICE_CONFIG_CHANGE = 103; + private static final int MSG_DISABLE_AUDIO_FOR_UID = 104; // end of messages handled under wakelock private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000; @@ -4871,6 +4872,12 @@ public class AudioService extends IAudioService.Stub mAudioEventWakeLock.release(); break; + case MSG_DISABLE_AUDIO_FOR_UID: + mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */, + msg.arg2 /* uid */); + mAudioEventWakeLock.release(); + break; + case MSG_REPORT_NEW_ROUTES: { int N = mRoutesObservers.beginBroadcast(); if (N > 0) { @@ -6591,6 +6598,13 @@ public class AudioService extends IAudioService.Stub } } } + + @Override + public void disableAudioForUid(boolean disable, int uid) { + queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID, + disable ? 1 : 0 /* arg1 */, uid /* arg2 */, + null /* obj */, 0 /* delay */); + } } //========================================================================================== diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java index 702cbbed17de..663559f59eec 100644 --- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java +++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java @@ -29,6 +29,8 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Log; +import com.android.internal.util.ArrayUtils; + import java.io.PrintWriter; import java.text.DateFormat; import java.util.ArrayList; @@ -67,6 +69,12 @@ public final class PlaybackActivityMonitor .createIfNeeded() .build(); + // TODO support VolumeShaper on those players + private static final int[] UNDUCKABLE_PLAYER_TYPES = { + AudioPlaybackConfiguration.PLAYER_TYPE_AAUDIO, + AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL, + }; + // like a PLAY_CREATE_IF_NEEDED operation but with a skip to the end of the ramp private static final VolumeShaper.Operation PLAY_SKIP_RAMP = new VolumeShaper.Operation.Builder(PLAY_CREATE_IF_NEEDED).setXOffset(1.0f).build(); @@ -87,6 +95,43 @@ public final class PlaybackActivityMonitor } //================================================================= + private final ArrayList<Integer> mBannedUids = new ArrayList<Integer>(); + + // see AudioManagerInternal.disableAudioForUid(boolean disable, int uid) + public void disableAudioForUid(boolean disable, int uid) { + synchronized(mPlayerLock) { + final int index = mBannedUids.indexOf(new Integer(uid)); + if (index >= 0) { + if (!disable) { + mBannedUids.remove(index); + // nothing else to do, future playback requests from this uid are ok + } // no else to handle, uid already present, so disabling again is no-op + } else { + if (disable) { + for (AudioPlaybackConfiguration apc : mPlayers.values()) { + checkBanPlayer(apc, uid); + } + mBannedUids.add(new Integer(uid)); + } // no else to handle, uid already not in list, so enabling again is no-op + } + } + } + + private boolean checkBanPlayer(@NonNull AudioPlaybackConfiguration apc, int uid) { + final boolean toBan = (apc.getClientUid() == uid); + if (toBan) { + final int piid = apc.getPlayerInterfaceId(); + try { + Log.v(TAG, "banning player " + piid + " uid:" + uid); + apc.getPlayerProxy().pause(); + } catch (Exception e) { + Log.e(TAG, "error banning player " + piid + " uid:" + uid, e); + } + } + return toBan; + } + + //================================================================= // Track players and their states // methods playerAttributes, playerEvent, releasePlayer are all oneway calls // into AudioService. They trigger synchronous dispatchPlaybackChange() which updates @@ -129,6 +174,14 @@ public final class PlaybackActivityMonitor if (apc == null) { return; } + if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) { + for (Integer uidInteger: mBannedUids) { + if (checkBanPlayer(apc, uidInteger.intValue())) { + // player was banned, do not update its state + return; + } + } + } if (apc.getPlayerType() == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) { // FIXME SoundPool not ready for state reporting return; @@ -178,10 +231,17 @@ public final class PlaybackActivityMonitor pw.println("\n ducked players:"); mDuckingManager.dump(pw); // players muted due to the device ringing or being in a call - pw.println("\n muted player piids:"); + pw.print("\n muted player piids:"); for (int piid : mMutedPlayers) { - pw.println(" " + piid); + pw.print(" " + piid); + } + pw.println(); + // banned players: + pw.print("\n banned uids:"); + for (int uid : mBannedUids) { + pw.print(" " + uid); } + pw.println(); } } @@ -298,12 +358,12 @@ public final class PlaybackActivityMonitor + " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid() + " - SPEECH"); return false; - } else if (apc.getPlayerType() - == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) { - // TODO support ducking of SoundPool players + } else if (ArrayUtils.contains(UNDUCKABLE_PLAYER_TYPES, apc.getPlayerType())) { Log.v(TAG, "not ducking player " + apc.getPlayerInterfaceId() + " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid() - + " - SoundPool"); + + " due to type:" + + AudioPlaybackConfiguration.toLogFriendlyPlayerType( + apc.getPlayerType())); return false; } apcsToDuck.add(apc); diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java index 13054a643e52..ad74ff88e80f 100644 --- a/services/core/java/com/android/server/content/ContentService.java +++ b/services/core/java/com/android/server/content/ContentService.java @@ -60,6 +60,7 @@ import android.util.SparseArray; import android.util.SparseIntArray; import com.android.internal.annotations.GuardedBy; +import com.android.internal.util.ArrayUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.server.LocalServices; @@ -101,6 +102,22 @@ public final class ContentService extends IContentService.Stub { } } + + @Override + public void onStartUser(int userHandle) { + mService.onStartUser(userHandle); + } + + @Override + public void onUnlockUser(int userHandle) { + mService.onUnlockUser(userHandle); + } + + @Override + public void onStopUser(int userHandle) { + mService.onStopUser(userHandle); + } + @Override public void onCleanupUser(int userHandle) { synchronized (mService.mCache) { @@ -161,11 +178,25 @@ public final class ContentService extends IContentService.Stub { } } + void onStartUser(int userHandle) { + if (mSyncManager != null) mSyncManager.onStartUser(userHandle); + } + + void onUnlockUser(int userHandle) { + if (mSyncManager != null) mSyncManager.onUnlockUser(userHandle); + } + + void onStopUser(int userHandle) { + if (mSyncManager != null) mSyncManager.onStopUser(userHandle); + } + @Override protected synchronized void dump(FileDescriptor fd, PrintWriter pw_, String[] args) { if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw_)) return; final IndentingPrintWriter pw = new IndentingPrintWriter(pw_, " "); + final boolean dumpAll = ArrayUtils.contains(args, "-a"); + // This makes it so that future permission checks will be in the context of this // process rather than the caller's process. We will restore this before returning. final long identityToken = clearCallingIdentity(); @@ -173,7 +204,7 @@ public final class ContentService extends IContentService.Stub { if (mSyncManager == null) { pw.println("No SyncManager created! (Disk full?)"); } else { - mSyncManager.dump(fd, pw); + mSyncManager.dump(fd, pw, dumpAll); } pw.println(); pw.println("Observer tree:"); @@ -603,7 +634,7 @@ public final class ContentService extends IContentService.Stub { SyncStorageEngine.EndPoint info; info = new SyncStorageEngine.EndPoint(account, authority, userId); syncManager.clearScheduledSyncOperations(info); - syncManager.cancelActiveSync(info, null /* all syncs for this adapter */); + syncManager.cancelActiveSync(info, null /* all syncs for this adapter */, "API"); } } finally { restoreCallingIdentity(identityToken); @@ -631,7 +662,7 @@ public final class ContentService extends IContentService.Stub { } // Cancel active syncs and clear pending syncs from the queue. syncManager.cancelScheduledSyncOperation(info, extras); - syncManager.cancelActiveSync(info, extras); + syncManager.cancelActiveSync(info, extras, "API"); } finally { restoreCallingIdentity(identityToken); } diff --git a/services/core/java/com/android/server/content/SyncJobService.java b/services/core/java/com/android/server/content/SyncJobService.java index a621d7376b7f..1f02ebfc4972 100644 --- a/services/core/java/com/android/server/content/SyncJobService.java +++ b/services/core/java/com/android/server/content/SyncJobService.java @@ -34,6 +34,8 @@ public class SyncJobService extends JobService { private Messenger mMessenger; private SparseArray<JobParameters> jobParamsMap = new SparseArray<JobParameters>(); + private final SyncLogger mLogger = SyncLogger.getInstance(); + /** * This service is started by the SyncManager which passes a messenger object to * communicate back with it. It never stops while the device is running. @@ -63,6 +65,9 @@ public class SyncJobService extends JobService { @Override public boolean onStartJob(JobParameters params) { + + mLogger.purgeOldLogs(); + boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE); synchronized (jobParamsMap) { jobParamsMap.put(params.getJobId(), params); @@ -70,6 +75,9 @@ public class SyncJobService extends JobService { Message m = Message.obtain(); m.what = SyncManager.SyncHandler.MESSAGE_START_SYNC; SyncOperation op = SyncOperation.maybeCreateFromJobExtras(params.getExtras()); + + mLogger.log("onStopJob() jobid=", params.getJobId(), " op=", op); + if (op == null) { Slog.e(TAG, "Got invalid job " + params.getJobId()); return false; @@ -88,7 +96,7 @@ public class SyncJobService extends JobService { Slog.v(TAG, "onStopJob called " + params.getJobId() + ", reason: " + params.getStopReason()); } - + mLogger.log("onStopJob() ", mLogger.jobParametersToString(params)); synchronized (jobParamsMap) { jobParamsMap.remove(params.getJobId()); } @@ -108,9 +116,13 @@ public class SyncJobService extends JobService { return false; } - public void callJobFinished(int jobId, boolean needsReschedule) { + public void callJobFinished(int jobId, boolean needsReschedule, String why) { synchronized (jobParamsMap) { JobParameters params = jobParamsMap.get(jobId); + mLogger.log("callJobFinished()", + " needsReschedule=", needsReschedule, + " ", mLogger.jobParametersToString(params), + " why=", why); if (params != null) { jobFinished(params, needsReschedule); jobParamsMap.remove(jobId); diff --git a/services/core/java/com/android/server/content/SyncLogger.java b/services/core/java/com/android/server/content/SyncLogger.java new file mode 100644 index 000000000000..db794643b4df --- /dev/null +++ b/services/core/java/com/android/server/content/SyncLogger.java @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.server.content; + +import android.app.job.JobParameters; +import android.os.Build; +import android.os.Environment; +import android.os.FileUtils; +import android.os.SystemProperties; +import android.text.format.DateUtils; +import android.util.Slog; + +import com.android.internal.annotations.GuardedBy; + +import libcore.io.IoUtils; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Reader; +import java.io.Writer; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +/** + * Implements a rotating file logger for the sync manager, which is enabled only on userdebug/eng + * builds (unless debug.synclog is set to 1). + * + * Note this class could be used for other purposes too, but in general we don't want various + * system components to log to files, so it's put in a local package here. + */ +public class SyncLogger { + private static final String TAG = "SyncLogger"; + + private static SyncLogger sInstance; + + SyncLogger() { + } + + /** + * @return the singleton instance. + */ + public static synchronized SyncLogger getInstance() { + if (sInstance == null) { + final boolean enable = "1".equals(SystemProperties.get("debug.synclog", + Build.IS_DEBUGGABLE ? "1" : "0")); + if (enable) { + sInstance = new RotatingFileLogger(); + } else { + sInstance = new SyncLogger(); + } + } + return sInstance; + } + + /** + * Write strings to the log file. + */ + public void log(Object... message) { + } + + /** + * Remove old log files. + */ + public void purgeOldLogs() { + // The default implementation is no-op. + } + + public String jobParametersToString(JobParameters params) { + // The default implementation is no-op. + return ""; + } + + /** + * Dump all existing log files into a given writer. + */ + public void dumpAll(PrintWriter pw) { + } + + /** + * Actual implementation which is only used on userdebug/eng builds (by default). + */ + private static class RotatingFileLogger extends SyncLogger { + private final Object mLock = new Object(); + + private final long mKeepAgeMs = TimeUnit.DAYS.toMillis(7); + + private static final SimpleDateFormat sTimestampFormat + = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + + private static final SimpleDateFormat sFilenameDateFormat + = new SimpleDateFormat("yyyy-MM-dd"); + + @GuardedBy("mLock") + private final Date mCachedDate = new Date(); + + @GuardedBy("mLock") + private final StringBuilder mStringBuilder = new StringBuilder(); + + private final File mLogPath; + + @GuardedBy("mLock") + private long mCurrentLogFileDayTimestamp; + + @GuardedBy("mLock") + private Writer mLogWriter; + + @GuardedBy("mLock") + private boolean mErrorShown; + + RotatingFileLogger() { + mLogPath = new File(Environment.getDataSystemDirectory(), "syncmanager-log"); + } + + private void handleException(String message, Exception e) { + if (!mErrorShown) { + Slog.e(TAG, message, e); + mErrorShown = true; + } + } + + @Override + public void log(Object... message) { + if (message == null) { + return; + } + synchronized (mLock) { + final long now = System.currentTimeMillis(); + openLogLocked(now); + if (mLogWriter == null) { + return; // Couldn't open log file? + } + + mStringBuilder.setLength(0); + mCachedDate.setTime(now); + mStringBuilder.append(sTimestampFormat.format(mCachedDate)); + mStringBuilder.append(' '); + + mStringBuilder.append(android.os.Process.myTid()); + mStringBuilder.append(' '); + + for (Object o : message) { + mStringBuilder.append(o); + } + mStringBuilder.append('\n'); + + try { + mLogWriter.append(mStringBuilder); + mLogWriter.flush(); + } catch (IOException e) { + handleException("Failed to write log", e); + } + } + } + + private void openLogLocked(long now) { + // If we already have a log file opened and the date has't changed, just use it. + final long day = now % DateUtils.DAY_IN_MILLIS; + if ((mLogWriter != null) && (day == mCurrentLogFileDayTimestamp)) { + return; + } + + // Otherwise create a new log file. + closeCurrentLogLocked(); + + mCurrentLogFileDayTimestamp = day; + + mCachedDate.setTime(now); + final String filename = "synclog-" + sFilenameDateFormat.format(mCachedDate) + ".log"; + final File file = new File(mLogPath, filename); + + file.getParentFile().mkdirs(); + + try { + mLogWriter = new FileWriter(file, /* append= */ true); + } catch (IOException e) { + handleException("Failed to open log file: " + file, e); + } + } + + private void closeCurrentLogLocked() { + IoUtils.closeQuietly(mLogWriter); + mLogWriter = null; + } + + @Override + public void purgeOldLogs() { + synchronized (mLock) { + FileUtils.deleteOlderFiles(mLogPath, /* keepCount= */ 1, mKeepAgeMs); + } + } + + @Override + public String jobParametersToString(JobParameters params) { + if (params == null) { + return "job:null"; + } else { + return "job:#" + params.getJobId() + ":" + + SyncOperation.maybeCreateFromJobExtras(params.getExtras()); + } + } + + @Override + public void dumpAll(PrintWriter pw) { + synchronized (mLock) { + final String[] files = mLogPath.list(); + if (files == null || (files.length == 0)) { + return; + } + Arrays.sort(files); + + for (String file : files) { + dumpFile(pw, new File(mLogPath, file)); + } + } + } + + private void dumpFile(PrintWriter pw, File file) { + Slog.w(TAG, "Dumping " + file); + final char[] buffer = new char[32 * 1024]; + + try (Reader in = new BufferedReader(new FileReader(file))) { + int read; + while ((read = in.read(buffer)) >= 0) { + if (read > 0) { + pw.write(buffer, 0, read); + } + } + } catch (IOException e) { + } + } + } +} diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index e3e26583b686..c250005204ba 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -241,6 +241,8 @@ public class SyncManager { private final Random mRand; + private final SyncLogger mLogger; + private boolean isJobIdInUseLockedH(int jobId, List<JobInfo> pendingJobs) { for (JobInfo job: pendingJobs) { if (job.getId() == jobId) { @@ -289,13 +291,15 @@ public class SyncManager { mStorageIsLow = true; cancelActiveSync( SyncStorageEngine.EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL, - null /* any sync */); + null /* any sync */, + "storage low"); } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) { if (Log.isLoggable(TAG, Log.VERBOSE)) { Slog.v(TAG, "Internal storage is ok."); } mStorageIsLow = false; - rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL); + rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL, + "storage ok"); } } }; @@ -378,15 +382,16 @@ public class SyncManager { if (Log.isLoggable(TAG, Log.VERBOSE)) { Slog.v(TAG, "Reconnection detected: clearing all backoffs"); } + // Note the location of this code was wrong from nyc to oc; fixed in DR. + clearAllBackoffs("network reconnect"); } - clearAllBackoffs(); } } }; - private void clearAllBackoffs() { + private void clearAllBackoffs(String why) { mSyncStorageEngine.clearAllBackoffsLocked(); - rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL); + rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL, why); } private boolean readDataConnectionState() { @@ -400,6 +405,7 @@ public class SyncManager { public void onReceive(Context context, Intent intent) { Log.w(TAG, "Writing sync state before shutdown..."); getSyncStorageEngine().writeAllState(); + mLogger.log("Shutting down."); } }; @@ -502,6 +508,8 @@ public class SyncManager { // and creating threads and so on; it may fail if the disk is full. mContext = context; + mLogger = SyncLogger.getInstance(); + SyncStorageEngine.init(context); mSyncStorageEngine = SyncStorageEngine.getSingleton(); mSyncStorageEngine.setOnSyncRequestListener(new OnSyncRequestListener() { @@ -667,8 +675,23 @@ public class SyncManager { // before we started checking for account access because they already know // the account (they run before) which is the genie is out of the bottle. whiteListExistingSyncAdaptersIfNeeded(); + + mLogger.log("Sync manager initialized."); + } + + public void onStartUser(int userHandle) { + mLogger.log("onStartUser: user=", userHandle); + } + + public void onUnlockUser(int userHandle) { + mLogger.log("onUnlockUser: user=", userHandle); + } + + public void onStopUser(int userHandle) { + mLogger.log("onStopUser: user=", userHandle); } + private void whiteListExistingSyncAdaptersIfNeeded() { if (!mSyncStorageEngine.shouldGrantSyncAdaptersAccountAccess()) { return; @@ -1145,8 +1168,12 @@ public class SyncManager { mSyncHandler.sendMessage(msg); } - private void sendCancelSyncsMessage(final SyncStorageEngine.EndPoint info, Bundle extras) { + private void sendCancelSyncsMessage(final SyncStorageEngine.EndPoint info, Bundle extras, + String why) { if (Log.isLoggable(TAG, Log.VERBOSE)) Slog.v(TAG, "sending MESSAGE_CANCEL"); + + mLogger.log("sendCancelSyncsMessage() ep=", info, " why=", why); + Message msg = mSyncHandler.obtainMessage(); msg.what = SyncHandler.MESSAGE_CANCEL; msg.setData(extras); @@ -1227,7 +1254,7 @@ public class SyncManager { } } - private void clearBackoffSetting(EndPoint target) { + private void clearBackoffSetting(EndPoint target, String why) { Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(target); if (backoff != null && backoff.first == SyncStorageEngine.NOT_IN_BACKOFF_MODE && backoff.second == SyncStorageEngine.NOT_IN_BACKOFF_MODE) { @@ -1240,7 +1267,7 @@ public class SyncManager { SyncStorageEngine.NOT_IN_BACKOFF_MODE, SyncStorageEngine.NOT_IN_BACKOFF_MODE); - rescheduleSyncs(target); + rescheduleSyncs(target, why); } private void increaseBackoffSetting(EndPoint target) { @@ -1281,14 +1308,16 @@ public class SyncManager { Slog.v(TAG, "Backoff until: " + backoff + ", delayTime: " + newDelayInMs); } mSyncStorageEngine.setBackoff(target, backoff, newDelayInMs); - rescheduleSyncs(target); + rescheduleSyncs(target, "increaseBackoffSetting"); } /** * Reschedule all scheduled syncs for this EndPoint. The syncs will be scheduled according * to current backoff and delayUntil values of this EndPoint. */ - private void rescheduleSyncs(EndPoint target) { + private void rescheduleSyncs(EndPoint target, String why) { + mLogger.log("rescheduleSyncs() ep=", target, " why=", why); + List<SyncOperation> ops = getAllPendingSyncs(); int count = 0; for (SyncOperation op: ops) { @@ -1316,7 +1345,7 @@ public class SyncManager { if (Log.isLoggable(TAG, Log.VERBOSE)) { Slog.v(TAG, "Delay Until time set to " + newDelayUntilTime + " for " + target); } - rescheduleSyncs(target); + rescheduleSyncs(target, "delayUntil newDelayUntilTime: " + newDelayUntilTime); } private boolean isAdapterDelayed(EndPoint target) { @@ -1338,8 +1367,8 @@ public class SyncManager { * have null account/provider info to specify all accounts/providers. * @param extras if non-null, specifies the exact sync to remove. */ - public void cancelActiveSync(SyncStorageEngine.EndPoint info, Bundle extras) { - sendCancelSyncsMessage(info, extras); + public void cancelActiveSync(SyncStorageEngine.EndPoint info, Bundle extras, String why) { + sendCancelSyncsMessage(info, extras, why); } /** @@ -1599,7 +1628,8 @@ public class SyncManager { null /* any account */, null /* any authority */, userId), - null /* any sync. */ + null /* any sync. */, + "onUserStopped" ); } @@ -1759,10 +1789,15 @@ public class SyncManager { } } - protected void dump(FileDescriptor fd, PrintWriter pw) { + protected void dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll) { final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); dumpSyncState(ipw); dumpSyncAdapters(ipw); + + if (dumpAll) { + ipw.println("Detailed Sync History"); + mLogger.dumpAll(pw); + } } static String formatTime(long time) { @@ -2644,7 +2679,7 @@ public class SyncManager { Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_CANCEL: " + endpoint + " bundle: " + extras); } - cancelActiveSyncH(endpoint, extras); + cancelActiveSyncH(endpoint, extras, "MESSAGE_CANCEL"); break; case SyncHandler.MESSAGE_SYNC_FINISHED: @@ -2660,7 +2695,8 @@ public class SyncManager { Slog.v(TAG, "syncFinished" + payload.activeSyncContext.mSyncOperation); } mSyncJobService.callJobFinished( - payload.activeSyncContext.mSyncOperation.jobId, false); + payload.activeSyncContext.mSyncOperation.jobId, false, + "sync finished"); runSyncFinishedOrCanceledH(payload.syncResult, payload.activeSyncContext); break; @@ -2704,7 +2740,8 @@ public class SyncManager { SyncResult syncResult = new SyncResult(); syncResult.stats.numIoExceptions++; mSyncJobService.callJobFinished( - currentSyncContext.mSyncOperation.jobId, false); + currentSyncContext.mSyncOperation.jobId, false, + "service disconnected"); runSyncFinishedOrCanceledH(syncResult, currentSyncContext); } break; @@ -2722,7 +2759,8 @@ public class SyncManager { "Detected sync making no progress for %s. cancelling.", monitoredSyncContext)); mSyncJobService.callJobFinished( - monitoredSyncContext.mSyncOperation.jobId, false); + monitoredSyncContext.mSyncOperation.jobId, false, + "no network activity"); runSyncFinishedOrCanceledH( null /* cancel => no result */, monitoredSyncContext); } else { @@ -2754,8 +2792,10 @@ public class SyncManager { * delay. This is equivalent to a failure. If this is a periodic sync, a delayed one-off * sync will be scheduled. */ - private void deferSyncH(SyncOperation op, long delay) { - mSyncJobService.callJobFinished(op.jobId, false); + private void deferSyncH(SyncOperation op, long delay, String why) { + mLogger.log("deferSyncH() ", (op.isPeriodic ? "periodic " : ""), + "sync. op=", op, " delay=", delay, " why=", why); + mSyncJobService.callJobFinished(op.jobId, false, why); if (op.isPeriodic) { scheduleSyncOperationH(op.createOneTimeSyncOperation(), delay); } else { @@ -2779,10 +2819,10 @@ public class SyncManager { /** * Cancel an active sync and reschedule it on the JobScheduler with some delay. */ - private void deferActiveSyncH(ActiveSyncContext asc) { + private void deferActiveSyncH(ActiveSyncContext asc, String why) { SyncOperation op = asc.mSyncOperation; runSyncFinishedOrCanceledH(null, asc); - deferSyncH(op, SYNC_DELAY_ON_CONFLICT); + deferSyncH(op, SYNC_DELAY_ON_CONFLICT, why); } private void startSyncH(SyncOperation op) { @@ -2790,7 +2830,7 @@ public class SyncManager { if (isLoggable) Slog.v(TAG, op.toString()); if (mStorageIsLow) { - deferSyncH(op, SYNC_DELAY_ON_LOW_STORAGE); + deferSyncH(op, SYNC_DELAY_ON_LOW_STORAGE, "storage low"); return; } @@ -2800,7 +2840,8 @@ public class SyncManager { List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation syncOperation: ops) { if (syncOperation.sourcePeriodicId == op.jobId) { - mSyncJobService.callJobFinished(op.jobId, false); + mSyncJobService.callJobFinished(op.jobId, false, + "periodic sync, pending"); return; } } @@ -2808,13 +2849,14 @@ public class SyncManager { // executing according to some backoff criteria. for (ActiveSyncContext asc: mActiveSyncContexts) { if (asc.mSyncOperation.sourcePeriodicId == op.jobId) { - mSyncJobService.callJobFinished(op.jobId, false); + mSyncJobService.callJobFinished(op.jobId, false, + "periodic sync, already running"); return; } } // Check for adapter delays. if (isAdapterDelayed(op.target)) { - deferSyncH(op, 0 /* No minimum delay */); + deferSyncH(op, 0 /* No minimum delay */, "backing off"); return; } } @@ -2828,13 +2870,13 @@ public class SyncManager { if (isLoggable) { Slog.v(TAG, "Rescheduling sync due to conflict " + op.toString()); } - deferSyncH(op, SYNC_DELAY_ON_CONFLICT); + deferSyncH(op, SYNC_DELAY_ON_CONFLICT, "delay on conflict"); return; } else { if (isLoggable) { Slog.v(TAG, "Pushing back running sync due to a higher priority sync"); } - deferActiveSyncH(asc); + deferActiveSyncH(asc, "preempted"); break; } } @@ -2844,12 +2886,13 @@ public class SyncManager { switch (syncOpState) { case SYNC_OP_STATE_INVALID_NO_ACCOUNT_ACCESS: case SYNC_OP_STATE_INVALID: { - mSyncJobService.callJobFinished(op.jobId, false); + mSyncJobService.callJobFinished(op.jobId, false, + "invalid op state: " + syncOpState); } return; } if (!dispatchSyncOperation(op)) { - mSyncJobService.callJobFinished(op.jobId, false); + mSyncJobService.callJobFinished(op.jobId, false, "dispatchSyncOperation() failed"); } setAuthorityPendingState(op.target); @@ -3019,7 +3062,8 @@ public class SyncManager { if (op.sourcePeriodicId == syncOperation.jobId || op.jobId == syncOperation.jobId) { ActiveSyncContext asc = findActiveSyncContextH(syncOperation.jobId); if (asc != null) { - mSyncJobService.callJobFinished(syncOperation.jobId, false); + mSyncJobService.callJobFinished(syncOperation.jobId, false, + "removePeriodicSyncInternalH"); runSyncFinishedOrCanceledH(null, asc); } getJobScheduler().cancel(op.jobId); @@ -3131,6 +3175,8 @@ public class SyncManager { final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo; syncAdapterInfo = mSyncAdapters.getServiceInfo(syncAdapterType, info.userId); if (syncAdapterInfo == null) { + mLogger.log("dispatchSyncOperation() failed: no sync adapter info for ", + syncAdapterType); Log.d(TAG, "can't find a sync adapter for " + syncAdapterType + ", removing settings for it"); mSyncStorageEngine.removeAuthority(info); @@ -3151,6 +3197,8 @@ public class SyncManager { postMonitorSyncProgressMessage(activeSyncContext); if (!activeSyncContext.bindToSyncAdapter(targetComponent, info.userId)) { + mLogger.log("dispatchSyncOperation() failed: bind failed. target: ", + targetComponent); Slog.e(TAG, "Bind attempt failed - target: " + targetComponent); closeActiveSyncContext(activeSyncContext); return false; @@ -3166,16 +3214,25 @@ public class SyncManager { activeSyncContext.mIsLinkedToDeath = true; syncAdapter.linkToDeath(activeSyncContext, 0); + mLogger.log("Sync start: account=" + syncOperation.target.account, + " authority=", syncOperation.target.provider, + " reason=", SyncOperation.reasonToString(null, syncOperation.reason), + " extras=", SyncOperation.extrasToString(syncOperation.extras)); + activeSyncContext.mSyncAdapter = ISyncAdapter.Stub.asInterface(syncAdapter); activeSyncContext.mSyncAdapter .startSync(activeSyncContext, syncOperation.target.provider, syncOperation.target.account, syncOperation.extras); + + mLogger.log("Sync finish"); } catch (RemoteException remoteExc) { + mLogger.log("Sync failed with RemoteException: ", remoteExc.toString()); Log.d(TAG, "maybeStartNextSync: caught a RemoteException, rescheduling", remoteExc); closeActiveSyncContext(activeSyncContext); increaseBackoffSetting(syncOperation.target); scheduleSyncOperationH(syncOperation); } catch (RuntimeException exc) { + mLogger.log("Sync failed with RuntimeException: ", exc.toString()); closeActiveSyncContext(activeSyncContext); Slog.e(TAG, "Caught RuntimeException while starting the sync " + syncOperation, exc); } @@ -3186,7 +3243,8 @@ public class SyncManager { * @param info Can have null fields to indicate all the active syncs for that field. * @param extras Can be null to indicate <strong>all</strong> syncs for the given endpoint. */ - private void cancelActiveSyncH(SyncStorageEngine.EndPoint info, Bundle extras) { + private void cancelActiveSyncH(SyncStorageEngine.EndPoint info, Bundle extras, + String why) { ArrayList<ActiveSyncContext> activeSyncs = new ArrayList<ActiveSyncContext>(mActiveSyncContexts); for (ActiveSyncContext activeSyncContext : activeSyncs) { @@ -3202,7 +3260,8 @@ public class SyncManager { false /* no config settings */)) { continue; } - mSyncJobService.callJobFinished(activeSyncContext.mSyncOperation.jobId, false); + mSyncJobService.callJobFinished(activeSyncContext.mSyncOperation.jobId, false, + why); runSyncFinishedOrCanceledH(null /* cancel => no result */, activeSyncContext); } } @@ -3250,6 +3309,7 @@ public class SyncManager { // potentially rescheduling all pending jobs to respect new backoff values. getJobScheduler().cancel(syncOperation.jobId); } + mLogger.log("runSyncFinishedOrCanceledH() op=", syncOperation, " result=", syncResult); if (syncResult != null) { if (isLoggable) { @@ -3262,7 +3322,7 @@ public class SyncManager { // TODO: set these correctly when the SyncResult is extended to include it downstreamActivity = 0; upstreamActivity = 0; - clearBackoffSetting(syncOperation.target); + clearBackoffSetting(syncOperation.target, "sync success"); // If the operation completes successfully and it was scheduled due to // a periodic operation failing, we reschedule the periodic operation to diff --git a/services/core/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java index b46426cc4a05..7d2cc0035847 100644 --- a/services/core/java/com/android/server/content/SyncOperation.java +++ b/services/core/java/com/android/server/content/SyncOperation.java @@ -237,6 +237,9 @@ public class SyncOperation { * contain a valid sync operation. */ static SyncOperation maybeCreateFromJobExtras(PersistableBundle jobExtras) { + if (jobExtras == null) { + return null; + } String accountName, accountType; String provider; int userId, owningUid; @@ -445,6 +448,10 @@ public class SyncOperation { } static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) { + if (bundle == null) { + sb.append("null"); + return; + } sb.append("["); for (String key : bundle.keySet()) { sb.append(key).append("=").append(bundle.get(key)).append(" "); @@ -452,6 +459,12 @@ public class SyncOperation { sb.append("]"); } + static String extrasToString(Bundle bundle) { + final StringBuilder sb = new StringBuilder(); + extrasToStringBuilder(bundle, sb); + return sb.toString(); + } + String wakeLockName() { if (wakeLockName != null) { return wakeLockName; diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 8129f450a85b..8269042da24a 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -132,7 +132,7 @@ public final class DisplayManagerService extends SystemService { private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000; - private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER = 1; + private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1; private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2; private static final int MSG_DELIVER_DISPLAY_EVENT = 3; private static final int MSG_REQUEST_TRAVERSAL = 4; @@ -266,7 +266,6 @@ public final class DisplayManagerService extends SystemService { PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting(); - } public void setupSchedulerPolicies() { @@ -284,9 +283,9 @@ public final class DisplayManagerService extends SystemService { // We need to pre-load the persistent data store so it's ready before the default display // adapter is up so that we have it's configuration. We could load it lazily, but since // we're going to have to read it in eventually we may as well do it here rather than after - // we've waited for the diplay to register itself with us. + // we've waited for the display to register itself with us. mPersistentDataStore.loadIfNeeded(); - mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER); + mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); publishBinderService(Context.DISPLAY_SERVICE, new BinderService(), true /*allowIsolated*/); @@ -298,12 +297,16 @@ public final class DisplayManagerService extends SystemService { public void onBootPhase(int phase) { if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) { synchronized (mSyncRoot) { - long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT; - while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) { + long timeout = SystemClock.uptimeMillis() + + mInjector.getDefaultDisplayDelayTimeout(); + while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null || + mVirtualDisplayAdapter == null) { long delay = timeout - SystemClock.uptimeMillis(); if (delay <= 0) { throw new RuntimeException("Timeout waiting for default display " - + "to be initialized."); + + "to be initialized. DefaultDisplay=" + + mLogicalDisplays.get(Display.DEFAULT_DISPLAY) + + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter); } if (DEBUG) { Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay); @@ -685,11 +688,23 @@ public final class DisplayManagerService extends SystemService { } } - private void registerDefaultDisplayAdapter() { - // Register default display adapter. + private void registerDefaultDisplayAdapters() { + // Register default display adapters. synchronized (mSyncRoot) { + // main display adapter registerDisplayAdapterLocked(new LocalDisplayAdapter( mSyncRoot, mContext, mHandler, mDisplayAdapterListener)); + + // Standalone VR devices rely on a virtual display as their primary display for + // 2D UI. We register virtual display adapter along side the main display adapter + // here so that it is ready by the time the system sends the home Intent for + // early apps like SetupWizard/Launcher. In particular, SUW is displayed using + // the virtual display inside VR before any VR-specific apps even run. + mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext, + mHandler, mDisplayAdapterListener); + if (mVirtualDisplayAdapter != null) { + registerDisplayAdapterLocked(mVirtualDisplayAdapter); + } } } @@ -698,7 +713,6 @@ public final class DisplayManagerService extends SystemService { if (shouldRegisterNonEssentialDisplayAdaptersLocked()) { registerOverlayDisplayAdapterLocked(); registerWifiDisplayAdapterLocked(); - registerVirtualDisplayAdapterLocked(); } } } @@ -719,12 +733,6 @@ public final class DisplayManagerService extends SystemService { } } - private void registerVirtualDisplayAdapterLocked() { - mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext, mHandler, - mDisplayAdapterListener); - registerDisplayAdapterLocked(mVirtualDisplayAdapter); - } - private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() { // In safe mode, we disable non-essential display adapters to give the user // an opportunity to fix broken settings or other problems that might affect @@ -1219,6 +1227,22 @@ public final class DisplayManagerService extends SystemService { Handler handler, DisplayAdapter.Listener displayAdapterListener) { return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener); } + + long getDefaultDisplayDelayTimeout() { + return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT; + } + } + + @VisibleForTesting + DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) { + synchronized (mSyncRoot) { + LogicalDisplay display = mLogicalDisplays.get(displayId); + if (display != null) { + DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked(); + return displayDevice.getDisplayDeviceInfoLocked(); + } + return null; + } } private final class DisplayManagerHandler extends Handler { @@ -1229,8 +1253,8 @@ public final class DisplayManagerService extends SystemService { @Override public void handleMessage(Message msg) { switch (msg.what) { - case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER: - registerDefaultDisplayAdapter(); + case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS: + registerDefaultDisplayAdapters(); break; case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS: diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index 9d3021af1ac2..d6ab88813f4d 100644 --- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -23,6 +23,7 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESE import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH; +import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT; import android.content.Context; import android.hardware.display.IVirtualDisplayCallback; @@ -359,6 +360,10 @@ public class VirtualDisplayAdapter extends DisplayAdapter { if ((mFlags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) { mInfo.flags |= DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD; } + if ((mFlags & VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT) != 0) { + mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT; + } + mInfo.type = Display.TYPE_VIRTUAL; mInfo.touch = ((mFlags & VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH) == 0) ? DisplayDeviceInfo.TOUCH_NONE : DisplayDeviceInfo.TOUCH_VIRTUAL; diff --git a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java index 5339bac8b030..370e569f2598 100644 --- a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java +++ b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java @@ -79,7 +79,7 @@ public abstract class AuthenticationClient extends ClientMonitor { } if (!authenticated) { if (receiver != null) { - FingerprintUtils.vibrateFingerprintError(getContext()); + vibrateError(); } // allow system-defined limit of number of attempts before giving up int lockoutMode = handleFailedAttempt(); @@ -99,7 +99,7 @@ public abstract class AuthenticationClient extends ClientMonitor { result |= lockoutMode != LOCKOUT_NONE; // in a lockout mode } else { if (receiver != null) { - FingerprintUtils.vibrateFingerprintSuccess(getContext()); + vibrateSuccess(); } result |= true; // we have a valid fingerprint, done resetFailedAttempts(); diff --git a/services/core/java/com/android/server/fingerprint/ClientMonitor.java b/services/core/java/com/android/server/fingerprint/ClientMonitor.java index 1a2e1443d329..3eae157c53aa 100644 --- a/services/core/java/com/android/server/fingerprint/ClientMonitor.java +++ b/services/core/java/com/android/server/fingerprint/ClientMonitor.java @@ -23,6 +23,8 @@ import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.os.IBinder; import android.os.RemoteException; +import android.os.VibrationEffect; +import android.os.Vibrator; import android.util.Slog; import java.util.NoSuchElementException; @@ -36,14 +38,18 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient { protected static final String TAG = FingerprintService.TAG; // TODO: get specific name protected static final int ERROR_ESRCH = 3; // Likely fingerprint HAL is dead. See errno.h. protected static final boolean DEBUG = FingerprintService.DEBUG; + private static final long[] DEFAULT_SUCCESS_VIBRATION_PATTERN = new long[] {0, 30}; + private final Context mContext; + private final long mHalDeviceId; + private final int mTargetUserId; + private final int mGroupId; + // True if client does not have MANAGE_FINGERPRINT permission + private final boolean mIsRestricted; + private final String mOwner; + private final VibrationEffect mSuccessVibrationEffect; + private final VibrationEffect mErrorVibrationEffect; private IBinder mToken; private IFingerprintServiceReceiver mReceiver; - private int mTargetUserId; - private int mGroupId; - private boolean mIsRestricted; // True if client does not have MANAGE_FINGERPRINT permission - private String mOwner; - private Context mContext; - private long mHalDeviceId; protected boolean mAlreadyCancelled; /** @@ -68,6 +74,8 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient { mGroupId = groupId; mIsRestricted = restricted; mOwner = owner; + mSuccessVibrationEffect = getSuccessVibrationEffect(context); + mErrorVibrationEffect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK); try { if (token != null) { token.linkToDeath(this, 0); @@ -79,7 +87,7 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient { /** * Contacts fingerprint HAL to start the client. - * @return 0 on succes, errno from driver on failure + * @return 0 on success, errno from driver on failure */ public abstract int start(); @@ -211,4 +219,39 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient { public final IBinder getToken() { return mToken; } + + public final void vibrateSuccess() { + Vibrator vibrator = mContext.getSystemService(Vibrator.class); + if (vibrator != null) { + vibrator.vibrate(mSuccessVibrationEffect); + } + } + + public final void vibrateError() { + Vibrator vibrator = mContext.getSystemService(Vibrator.class); + if (vibrator != null) { + vibrator.vibrate(mErrorVibrationEffect); + } + } + + private static VibrationEffect getSuccessVibrationEffect(Context ctx) { + int[] arr = ctx.getResources().getIntArray( + com.android.internal.R.array.config_longPressVibePattern); + final long[] vibePattern; + if (arr == null || arr.length == 0) { + vibePattern = DEFAULT_SUCCESS_VIBRATION_PATTERN; + } else { + vibePattern = new long[arr.length]; + for (int i = 0; i < arr.length; i++) { + vibePattern[i] = arr[i]; + } + } + if (vibePattern.length == 1) { + return VibrationEffect.createOneShot( + vibePattern[0], VibrationEffect.DEFAULT_AMPLITUDE); + } else { + return VibrationEffect.createWaveform(vibePattern, -1); + } + } + } diff --git a/services/core/java/com/android/server/fingerprint/EnrollClient.java b/services/core/java/com/android/server/fingerprint/EnrollClient.java index 61708946f806..c9efcf2fd687 100644 --- a/services/core/java/com/android/server/fingerprint/EnrollClient.java +++ b/services/core/java/com/android/server/fingerprint/EnrollClient.java @@ -65,7 +65,7 @@ public abstract class EnrollClient extends ClientMonitor { if (receiver == null) return true; // client not listening - FingerprintUtils.vibrateFingerprintSuccess(getContext()); + vibrateSuccess(); MetricsLogger.action(getContext(), MetricsEvent.ACTION_FINGERPRINT_ENROLL); try { receiver.onEnrollResult(getHalDeviceId(), fpId, groupId, remaining); diff --git a/services/core/java/com/android/server/fingerprint/FingerprintUtils.java b/services/core/java/com/android/server/fingerprint/FingerprintUtils.java index 49dc8e4dac71..5fbd735d4ac5 100644 --- a/services/core/java/com/android/server/fingerprint/FingerprintUtils.java +++ b/services/core/java/com/android/server/fingerprint/FingerprintUtils.java @@ -18,7 +18,6 @@ package com.android.server.fingerprint; import android.content.Context; import android.hardware.fingerprint.Fingerprint; -import android.os.Vibrator; import android.text.TextUtils; import android.util.SparseArray; @@ -31,9 +30,6 @@ import java.util.List; */ public class FingerprintUtils { - private static final long[] FP_ERROR_VIBRATE_PATTERN = new long[] {0, 30, 100, 30}; - private static final long[] FP_SUCCESS_VIBRATE_PATTERN = new long[] {0, 30}; - private static final Object sInstanceLock = new Object(); private static FingerprintUtils sInstance; @@ -72,20 +68,6 @@ public class FingerprintUtils { getStateForUser(ctx, userId).renameFingerprint(fingerId, name); } - public static void vibrateFingerprintError(Context context) { - Vibrator vibrator = context.getSystemService(Vibrator.class); - if (vibrator != null) { - vibrator.vibrate(FP_ERROR_VIBRATE_PATTERN, -1); - } - } - - public static void vibrateFingerprintSuccess(Context context) { - Vibrator vibrator = context.getSystemService(Vibrator.class); - if (vibrator != null) { - vibrator.vibrate(FP_SUCCESS_VIBRATE_PATTERN, -1); - } - } - private FingerprintsUserState getStateForUser(Context ctx, int userId) { synchronized (this) { FingerprintsUserState state = mUsers.get(userId); diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index fe2c5bd87df4..c1e820c9b787 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -142,6 +142,7 @@ public class LockSettingsService extends ILockSettings.Stub { private static final int SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT = 1; // Order of holding lock: mSeparateChallengeLock -> mSpManager -> this + // Do not call into ActivityManager while holding mSpManager lock. private final Object mSeparateChallengeLock = new Object(); private final DeviceProvisionedObserver mDeviceProvisionedObserver = @@ -1434,16 +1435,14 @@ public class LockSettingsService extends ILockSettings.Stub { Slog.e(TAG, "FRP credential can only be verified prior to provisioning."); return VerifyCredentialResponse.ERROR; } - synchronized (mSpManager) { - if (isSyntheticPasswordBasedCredentialLocked(userId)) { - VerifyCredentialResponse response = spBasedDoVerifyCredentialLocked(credential, - credentialType, hasChallenge, challenge, userId, progressCallback); - if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { - mStrongAuth.reportSuccessfulStrongAuthUnlock(userId); - } - return response; - } + VerifyCredentialResponse response = null; + response = spBasedDoVerifyCredential(credential, credentialType, hasChallenge, challenge, + userId, progressCallback); + // The user employs synthetic password based credential. + if (response != null) { + return response; } + final CredentialHash storedHash; if (userId == USER_FRP) { PersistentData data = mStorage.readPersistentDataBlock(); @@ -1472,7 +1471,7 @@ public class LockSettingsService extends ILockSettings.Stub { credentialToVerify = credential; } - VerifyCredentialResponse response = verifyCredential(userId, storedHash, credentialToVerify, + response = verifyCredential(userId, storedHash, credentialToVerify, hasChallenge, challenge, progressCallback); if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { @@ -1995,33 +1994,46 @@ public class LockSettingsService extends ILockSettings.Stub { setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM); } - private VerifyCredentialResponse spBasedDoVerifyCredentialLocked(String userCredential, int + private VerifyCredentialResponse spBasedDoVerifyCredential(String userCredential, int credentialType, boolean hasChallenge, long challenge, int userId, ICheckCredentialProgressCallback progressCallback) throws RemoteException { - if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredentialLocked: user=" + userId); + if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredential: user=" + userId); if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) { userCredential = null; } - if (userId == USER_FRP) { - return mSpManager.verifyFrpCredential(getGateKeeperService(), - userCredential, credentialType, progressCallback); - } - long handle = getSyntheticPasswordHandleLocked(userId); - AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword( - getGateKeeperService(), handle, userCredential, userId); + final AuthenticationResult authResult; + VerifyCredentialResponse response; + synchronized (mSpManager) { + if (!isSyntheticPasswordBasedCredentialLocked(userId)) { + return null; + } + if (userId == USER_FRP) { + return mSpManager.verifyFrpCredential(getGateKeeperService(), + userCredential, credentialType, progressCallback); + } - VerifyCredentialResponse response = authResult.gkResponse; - if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { + long handle = getSyntheticPasswordHandleLocked(userId); + authResult = mSpManager.unwrapPasswordBasedSyntheticPassword( + getGateKeeperService(), handle, userCredential, userId); + + response = authResult.gkResponse; // credential has matched - // perform verifyChallenge with synthetic password which generates the real auth - // token for the current user - response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken, - challenge, userId); - if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) { - Slog.wtf(TAG, "verifyChallenge with SP failed."); - return VerifyCredentialResponse.ERROR; + if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { + // perform verifyChallenge with synthetic password which generates the real GK auth + // token and response for the current user + response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken, + challenge, userId); + if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) { + // This shouldn't really happen: the unwrapping of SP succeeds, but SP doesn't + // match the recorded GK password handle. + Slog.wtf(TAG, "verifyChallenge with SP failed."); + return VerifyCredentialResponse.ERROR; + } } + } + + if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { if (progressCallback != null) { progressCallback.onCredentialVerified(); } @@ -2032,12 +2044,14 @@ public class LockSettingsService extends ILockSettings.Stub { Slog.i(TAG, "Unlocking user " + userId + " with secret only, length " + secret.length); unlockUser(userId, null, secret); + activateEscrowTokens(authResult.authToken, userId); + if (isManagedProfileWithSeparatedLock(userId)) { TrustManager trustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE); trustManager.setDeviceLockedForUser(userId, false); } - activateEscrowTokens(authResult.authToken, userId); + mStrongAuth.reportSuccessfulStrongAuthUnlock(userId); } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) { if (response.getTimeout() > 0) { requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId); @@ -2184,8 +2198,8 @@ public class LockSettingsService extends ILockSettings.Stub { private void activateEscrowTokens(AuthenticationToken auth, int userId) throws RemoteException { if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId); - disableEscrowTokenOnNonManagedDevicesIfNeeded(userId); synchronized (mSpManager) { + disableEscrowTokenOnNonManagedDevicesIfNeeded(userId); for (long handle : mSpManager.getPendingTokensForUser(userId)) { Slog.i(TAG, String.format("activateEscrowTokens: %x %d ", handle, userId)); mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 5ee7ac4d16d1..038e47e4dada 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -4004,16 +4004,19 @@ public class NotificationManagerService extends SystemService { } int indexBefore = findNotificationRecordIndexLocked(record); boolean interceptBefore = record.isIntercepted(); + float contactAffinityBefore = record.getContactAffinity(); int visibilityBefore = record.getPackageVisibilityOverride(); recon.applyChangesLocked(record); applyZenModeLocked(record); mRankingHelper.sort(mNotificationList); int indexAfter = findNotificationRecordIndexLocked(record); boolean interceptAfter = record.isIntercepted(); + float contactAffinityAfter = record.getContactAffinity(); int visibilityAfter = record.getPackageVisibilityOverride(); changed = indexBefore != indexAfter || interceptBefore != interceptAfter || visibilityBefore != visibilityAfter; - if (interceptBefore && !interceptAfter) { + if (interceptBefore && !interceptAfter + && Float.compare(contactAffinityBefore, contactAffinityAfter) != 0) { buzzBeepBlinkLocked(record); } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 5501ef110b09..1242daa48bee 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -7205,12 +7205,15 @@ public class PackageManagerService extends IPackageManager.Stub // load resources from the correct package installerInfo.resolvePackageName = info.getComponentInfo().packageName; resolveInfos.set(i, installerInfo); + continue; } - continue; } // caller is a full app, don't need to apply any other filtering if (ephemeralPkgName == null) { continue; + } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) { + // caller is same app; don't need to apply any other filtering + continue; } // allow activities that have been explicitly exposed to ephemeral apps if (!isEphemeralApp @@ -20029,7 +20032,7 @@ public class PackageManagerService extends IPackageManager.Stub // Queue up an async operation since the package deletion may take a little while. mHandler.post(new Runnable() { public void run() { - final PackageSetting ps = (PackageSetting) pkg.mExtras; + final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras; boolean doClearData = true; if (ps != null) { final boolean targetIsInstantApp = diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index f3a292b7e1e0..20d7b28c55e1 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -1018,7 +1018,7 @@ class PackageManagerShellCommand extends ShellCommand { throw new RuntimeException(e.getMessage(), e); } try { - ResolveInfo ri = mInterface.resolveIntent(intent, null, 0, mTargetUser); + ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), 0, mTargetUser); PrintWriter pw = getOutPrintWriter(); if (ri == null) { pw.println("No activity found"); @@ -1040,7 +1040,7 @@ class PackageManagerShellCommand extends ShellCommand { throw new RuntimeException(e.getMessage(), e); } try { - List<ResolveInfo> result = mInterface.queryIntentActivities(intent, null, 0, + List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(), 0, mTargetUser).getList(); PrintWriter pw = getOutPrintWriter(); if (result == null || result.size() <= 0) { @@ -1074,7 +1074,7 @@ class PackageManagerShellCommand extends ShellCommand { throw new RuntimeException(e.getMessage(), e); } try { - List<ResolveInfo> result = mInterface.queryIntentServices(intent, null, 0, + List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(), 0, mTargetUser).getList(); PrintWriter pw = getOutPrintWriter(); if (result == null || result.size() <= 0) { @@ -1108,7 +1108,7 @@ class PackageManagerShellCommand extends ShellCommand { throw new RuntimeException(e.getMessage(), e); } try { - List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, null, 0, + List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(), 0, mTargetUser).getList(); PrintWriter pw = getOutPrintWriter(); if (result == null || result.size() <= 0) { diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 89dbc2a1c1c4..5d2d4b6d6090 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -1677,8 +1677,17 @@ public class PhoneWindowManager implements WindowManagerPolicy { } boolean isUserSetupComplete() { - return Settings.Secure.getIntForUser(mContext.getContentResolver(), + boolean isSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0; + if (mHasFeatureLeanback) { + isSetupComplete &= isTvUserSetupComplete(); + } + return isSetupComplete; + } + + private boolean isTvUserSetupComplete() { + return Settings.Secure.getIntForUser(mContext.getContentResolver(), + Settings.Secure.TV_USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0; } private void handleShortPressOnHome() { diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 32871bb0ba2c..984b40f806bb 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -783,7 +783,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub { mHandler.post(() -> { // ShutdownThread displays UI, so give it a UI context. if (safeMode) { - ShutdownThread.rebootSafeMode(getUiContext(), false); + ShutdownThread.rebootSafeMode(getUiContext(), true); } else { ShutdownThread.reboot(getUiContext(), PowerManager.SHUTDOWN_USER_REQUESTED, false); diff --git a/services/core/java/com/android/server/vr/Vr2dDisplay.java b/services/core/java/com/android/server/vr/Vr2dDisplay.java index 4a1297f8af71..b1c1df14feeb 100644 --- a/services/core/java/com/android/server/vr/Vr2dDisplay.java +++ b/services/core/java/com/android/server/vr/Vr2dDisplay.java @@ -35,7 +35,6 @@ class Vr2dDisplay { private final static String TAG = "Vr2dDisplay"; private final static boolean DEBUG = false; - // TODO: Go over these values and figure out what is best private int mVirtualDisplayHeight; private int mVirtualDisplayWidth; private int mVirtualDisplayDpi; @@ -55,17 +54,17 @@ class Vr2dDisplay { /** * The default width of the VR virtual display */ - public static final int DEFAULT_VR_DISPLAY_WIDTH = 1400; + public static final int DEFAULT_VIRTUAL_DISPLAY_WIDTH = 1400; /** * The default height of the VR virtual display */ - public static final int DEFAULT_VR_DISPLAY_HEIGHT = 1800; + public static final int DEFAULT_VIRTUAL_DISPLAY_HEIGHT = 1400; /** * The default height of the VR virtual dpi. */ - public static final int DEFAULT_VR_DISPLAY_DPI = 320; + public static final int DEFAULT_VIRTUAL_DISPLAY_DPI = 320; /** * The minimum height, width and dpi of VR virtual display. @@ -87,8 +86,8 @@ class Vr2dDisplay { new IPersistentVrStateCallbacks.Stub() { @Override public void onPersistentVrStateChanged(boolean enabled) { - if (enabled != mIsVrModeEnabled) { - mIsVrModeEnabled = enabled; + if (enabled != mIsPersistentVrModeEnabled) { + mIsPersistentVrModeEnabled = enabled; updateVirtualDisplay(); } } @@ -98,25 +97,33 @@ class Vr2dDisplay { private Surface mSurface; private ImageReader mImageReader; private Runnable mStopVDRunnable; - private boolean mIsVrModeOverrideEnabled; - private boolean mIsVrModeEnabled; + private boolean mIsVrModeOverrideEnabled; // debug override to set vr mode. + private boolean mIsVirtualDisplayAllowed = true; // Virtual-display feature toggle + private boolean mIsPersistentVrModeEnabled; // indicates we are in vr persistent mode. + private boolean mBootsToVr = false; // The device boots into VR (standalone VR device) public Vr2dDisplay(DisplayManager displayManager, ActivityManagerInternal activityManagerInternal, IVrManager vrManager) { mDisplayManager = displayManager; mActivityManagerInternal = activityManagerInternal; mVrManager = vrManager; - mVirtualDisplayWidth = DEFAULT_VR_DISPLAY_WIDTH; - mVirtualDisplayHeight = DEFAULT_VR_DISPLAY_HEIGHT; - mVirtualDisplayDpi = DEFAULT_VR_DISPLAY_DPI; + mVirtualDisplayWidth = DEFAULT_VIRTUAL_DISPLAY_WIDTH; + mVirtualDisplayHeight = DEFAULT_VIRTUAL_DISPLAY_HEIGHT; + mVirtualDisplayDpi = DEFAULT_VIRTUAL_DISPLAY_DPI; } /** * Initializes the compabilitiy display by listening to VR mode changes. */ - public void init(Context context) { + public void init(Context context, boolean bootsToVr) { startVrModeListener(); startDebugOnlyBroadcastReceiver(context); + mBootsToVr = bootsToVr; + if (mBootsToVr) { + // If we are booting into VR, we need to start the virtual display immediately. This + // ensures that the virtual display is up by the time Setup Wizard is started. + updateVirtualDisplay(); + } } /** @@ -124,10 +131,13 @@ class Vr2dDisplay { */ private void updateVirtualDisplay() { if (DEBUG) { - Log.i(TAG, "isVrMode: " + mIsVrModeEnabled + ", override: " + mIsVrModeOverrideEnabled); + Log.i(TAG, "isVrMode: " + mIsPersistentVrModeEnabled + ", override: " + + mIsVrModeOverrideEnabled + ", isAllowed: " + mIsVirtualDisplayAllowed + + ", bootsToVr: " + mBootsToVr); } - if (mIsVrModeEnabled || mIsVrModeOverrideEnabled) { + if (shouldRunVirtualDisplay()) { + Log.i(TAG, "Attempting to start virtual display"); // TODO: Consider not creating the display until ActivityManager needs one on // which to display a 2D application. startVirtualDisplay(); @@ -190,33 +200,43 @@ class Vr2dDisplay { * * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p> * - * @param compatDisplayProperties Properties of the virtual display for 2D applications + * @param displayProperties Properties of the virtual display for 2D applications * in VR mode. */ - public void setVirtualDisplayProperties(Vr2dDisplayProperties compatDisplayProperties) { + public void setVirtualDisplayProperties(Vr2dDisplayProperties displayProperties) { synchronized(mVdLock) { if (DEBUG) { - Log.i(TAG, "VD setVirtualDisplayProperties: res = " - + compatDisplayProperties.getWidth() + "X" - + compatDisplayProperties.getHeight() + ", dpi = " - + compatDisplayProperties.getDpi()); + Log.i(TAG, "VD setVirtualDisplayProperties: " + + displayProperties.toString()); } - if (compatDisplayProperties.getWidth() < MIN_VR_DISPLAY_WIDTH || - compatDisplayProperties.getHeight() < MIN_VR_DISPLAY_HEIGHT || - compatDisplayProperties.getDpi() < MIN_VR_DISPLAY_DPI) { - throw new IllegalArgumentException ( - "Illegal argument: height, width, dpi cannot be negative. res = " - + compatDisplayProperties.getWidth() + "X" - + compatDisplayProperties.getHeight() - + ", dpi = " + compatDisplayProperties.getDpi()); + int width = displayProperties.getWidth(); + int height = displayProperties.getHeight(); + int dpi = displayProperties.getDpi(); + boolean resized = false; + + if (width < MIN_VR_DISPLAY_WIDTH || height < MIN_VR_DISPLAY_HEIGHT || + dpi < MIN_VR_DISPLAY_DPI) { + Log.i(TAG, "Ignoring Width/Height/Dpi values of " + width + "," + height + "," + + dpi); + } else { + Log.i(TAG, "Setting width/height/dpi to " + width + "," + height + "," + dpi); + mVirtualDisplayWidth = width; + mVirtualDisplayHeight = height; + mVirtualDisplayDpi = dpi; + resized = true; } - mVirtualDisplayWidth = compatDisplayProperties.getWidth(); - mVirtualDisplayHeight = compatDisplayProperties.getHeight(); - mVirtualDisplayDpi = compatDisplayProperties.getDpi(); + if ((displayProperties.getFlags() & Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED) + == Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED) { + mIsVirtualDisplayAllowed = true; + } else if ((displayProperties.getRemovedFlags() & + Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED) + == Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED) { + mIsVirtualDisplayAllowed = false; + } - if (mVirtualDisplay != null) { + if (mVirtualDisplay != null && resized && mIsVirtualDisplayAllowed) { mVirtualDisplay.resize(mVirtualDisplayWidth, mVirtualDisplayHeight, mVirtualDisplayDpi); ImageReader oldImageReader = mImageReader; @@ -224,6 +244,9 @@ class Vr2dDisplay { startImageReader(); oldImageReader.close(); } + + // Start/Stop the virtual display in case the updates indicated that we should. + updateVirtualDisplay(); } } @@ -266,6 +289,7 @@ class Vr2dDisplay { } int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH; + flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT; mVirtualDisplay = mDisplayManager.createVirtualDisplay(null /* projection */, DISPLAY_NAME, mVirtualDisplayWidth, mVirtualDisplayHeight, mVirtualDisplayDpi, null /* surface */, flags, null /* callback */, null /* handler */, @@ -296,7 +320,7 @@ class Vr2dDisplay { mStopVDRunnable = new Runnable() { @Override public void run() { - if (mIsVrModeEnabled) { + if (shouldRunVirtualDisplay()) { Log.i(TAG, "Virtual Display destruction stopped: VrMode is back on."); } else { Log.i(TAG, "Stopping Virtual Display"); @@ -365,4 +389,14 @@ class Vr2dDisplay { mImageReader = null; } } + + private boolean shouldRunVirtualDisplay() { + // Virtual Display should run whenever: + // * Virtual Display is allowed/enabled AND + // (1) BootsToVr is set indicating the device never leaves VR + // (2) VR (persistent) mode is enabled + // (3) VR mode is overridden to be enabled. + return mIsVirtualDisplayAllowed && + (mBootsToVr || mIsPersistentVrModeEnabled || mIsVrModeOverrideEnabled); + } } diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java index 55d471919099..f13cc76577c8 100644 --- a/services/core/java/com/android/server/vr/VrManagerService.java +++ b/services/core/java/com/android/server/vr/VrManagerService.java @@ -619,7 +619,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE); ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class); mVr2dDisplay = new Vr2dDisplay(dm, ami, mVrManager); - mVr2dDisplay.init(getContext()); + mVr2dDisplay.init(getContext(), mBootsToVr); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_UNLOCKED); diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java index fe7494728ac3..4e4398ee9d91 100644 --- a/services/core/java/com/android/server/wm/AppWindowContainerController.java +++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java @@ -614,8 +614,8 @@ public class AppWindowContainerController return STARTING_WINDOW_TYPE_SPLASH_SCREEN; } else if (taskSwitch && allowTaskSnapshot) { return snapshot == null ? STARTING_WINDOW_TYPE_NONE - : snapshotFillsWidth(snapshot) || fromRecents ? STARTING_WINDOW_TYPE_SNAPSHOT - : STARTING_WINDOW_TYPE_SPLASH_SCREEN; + : snapshotOrientationSameAsTask(snapshot) || fromRecents + ? STARTING_WINDOW_TYPE_SNAPSHOT : STARTING_WINDOW_TYPE_SPLASH_SCREEN; } else { return STARTING_WINDOW_TYPE_NONE; } @@ -640,22 +640,11 @@ public class AppWindowContainerController return true; } - private boolean snapshotFillsWidth(TaskSnapshot snapshot) { + private boolean snapshotOrientationSameAsTask(TaskSnapshot snapshot) { if (snapshot == null) { return false; } - final Rect rect = new Rect(0, 0, snapshot.getSnapshot().getWidth(), - snapshot.getSnapshot().getHeight()); - rect.inset(snapshot.getContentInsets()); - final Rect taskBoundsWithoutInsets = new Rect(); - mContainer.getTask().getBounds(taskBoundsWithoutInsets); - final DisplayInfo di = mContainer.getDisplayContent().getDisplayInfo(); - final Rect displayBounds = new Rect(0, 0, di.logicalWidth, di.logicalHeight); - final Rect stableInsets = new Rect(); - mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, - stableInsets); - displayBounds.inset(stableInsets); - return rect.width() >= displayBounds.width(); + return mContainer.getTask().getConfiguration().orientation == snapshot.getOrientation(); } public void removeStartingWindow() { diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index bd379344e18b..8afc4fd6a8df 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -937,8 +937,6 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree // Update keyguard flags upon finishing relaunch. checkKeyguardFlagsChanged(); } - - updateAllDrawn(); } void clearRelaunching() { @@ -1344,6 +1342,10 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } } + /** + * Determines if the token has finished drawing. This should only be called from + * {@link DisplayContent#applySurfaceChangesTransaction} + */ void updateAllDrawn() { if (!allDrawn) { // Number of drawn windows can be less when a window is being relaunched, wait for diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index c98d60dcad93..9fe73815b380 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1183,6 +1183,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo final int dh = displayInfo.logicalHeight; config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE; + config.setRotation(displayInfo.rotation); + config.screenWidthDp = (int)(mService.mPolicy.getConfigDisplayWidth(dw, dh, displayInfo.rotation, config.uiMode, mDisplayId) / mDisplayMetrics.density); diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java index 297e2880a455..b628869c54e5 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java @@ -25,6 +25,7 @@ import android.app.ActivityManager.TaskSnapshot; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.Bitmap.Config; +import android.graphics.GraphicBuffer; import android.os.Process; import android.os.SystemClock; import android.util.ArraySet; @@ -325,6 +326,15 @@ class TaskSnapshotPersister { final File file = getBitmapFile(mTaskId, mUserId); final File reducedFile = getReducedResolutionBitmapFile(mTaskId, mUserId); final Bitmap bitmap = Bitmap.createHardwareBitmap(mSnapshot.getSnapshot()); + if (bitmap == null) { + Slog.e(TAG, "Invalid task snapshot"); + return false; + } else if (bitmap.getWidth() == 0 || bitmap.getHeight() == 0) { + Slog.e(TAG, "Invalid task snapshot dimensions " + bitmap.getWidth() + "x" + + bitmap.getHeight()); + return false; + } + final Bitmap swBitmap = bitmap.copy(Config.ARGB_8888, false /* isMutable */); final Bitmap reduced = Bitmap.createScaledBitmap(swBitmap, (int) (bitmap.getWidth() * REDUCED_SCALE), diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f9d7c3704341..613c830f31f2 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -19,16 +19,17 @@ package com.android.server.wm; import static android.Manifest.permission.MANAGE_APP_TOKENS; import static android.Manifest.permission.READ_FRAME_BUFFER; import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS; +import static android.Manifest.permission.RESTRICTED_VR_ACCESS; import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW; import static android.app.StatusBarManager.DISABLE_MASK; import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED; import static android.content.Intent.ACTION_USER_REMOVED; import static android.content.Intent.EXTRA_USER_HANDLE; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Process.ROOT_UID; import static android.os.Process.SHELL_UID; import static android.os.Process.SYSTEM_UID; -import static android.os.Process.THREAD_PRIORITY_DISPLAY; import static android.os.Process.myPid; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.os.UserHandle.USER_NULL; @@ -48,7 +49,6 @@ import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHA import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; -import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TASK_SNAPSHOT; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; @@ -231,7 +231,6 @@ import com.android.server.DisplayThread; import com.android.server.EventLogTags; import com.android.server.FgThread; import com.android.server.LocalServices; -import com.android.server.ThreadPriorityBooster; import com.android.server.UiThread; import com.android.server.Watchdog; import com.android.server.input.InputManagerService; @@ -2018,8 +2017,7 @@ public class WindowManagerService extends IWindowManager.Stub win.setDisplayLayoutNeeded(); mWindowPlacerLocked.performSurfacePlacement(true); } - result = win.relayoutVisibleWindow(mergedConfiguration, result, attrChanges, - oldVisibility); + result = win.relayoutVisibleWindow(result, attrChanges, oldVisibility); try { result = createSurfaceControl(outSurface, result, win, winAnimator); @@ -2157,6 +2155,15 @@ public class WindowManagerService extends IWindowManager.Stub if (!win.isGoneForLayoutLw()) { win.mResizedWhileGone = false; } + + // We must always send the latest {@link MergedConfiguration}, regardless of whether we + // have already reported it. The client might not have processed the previous value yet + // and needs process it before handling the corresponding window frame. the variable + // {@code mergedConfiguration} is an out parameter that will be passed back to the + // client over IPC and checked there. + win.getMergedConfiguration(mergedConfiguration); + win.setReportedConfiguration(mergedConfiguration); + outFrame.set(win.mCompatFrame); outOverscanInsets.set(win.mOverscanInsets); outContentInsets.set(win.mContentInsets); @@ -2948,9 +2955,10 @@ public class WindowManagerService extends IWindowManager.Stub } public void setKeyguardGoingAway(boolean keyguardGoingAway) { - synchronized (mWindowMap) { - mKeyguardGoingAway = keyguardGoingAway; - } +// TODO: Use of this can be removed. Revert ag/I8369723d6a77f2c602f1ef080371fa7cd9ee094e +// synchronized (mWindowMap) { +// mKeyguardGoingAway = keyguardGoingAway; +// } } // ------------------------------------------------------------- @@ -6304,6 +6312,9 @@ public class WindowManagerService extends IWindowManager.Stub @Override public Region getCurrentImeTouchRegion() { + if (mContext.checkCallingOrSelfPermission(RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) { + throw new SecurityException("getCurrentImeTouchRegion is restricted to VR services"); + } synchronized (mWindowMap) { final Region r = new Region(); if (mInputMethodWindow != null) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index f74948f8e7f0..d1fbf900ef70 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2207,8 +2207,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } - void prepareWindowToDisplayDuringRelayout(MergedConfiguration mergedConfiguration, - boolean wasVisible) { + void prepareWindowToDisplayDuringRelayout(boolean wasVisible) { // We need to turn on screen regardless of visibility. if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) { if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this); @@ -2230,16 +2229,16 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (isDrawnLw() && mService.okToDisplay()) { mWinAnimator.applyEnterAnimationLocked(); } + } - if (isConfigChanged()) { - final Configuration globalConfig = mService.mRoot.getConfiguration(); - final Configuration overrideConfig = getMergedOverrideConfiguration(); - mergedConfiguration.setConfiguration(globalConfig, overrideConfig); - if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this - + " visible with new global config: " + globalConfig - + " merged override config: " + overrideConfig); - mLastReportedConfiguration.setTo(getConfiguration()); - } + void getMergedConfiguration(MergedConfiguration outConfiguration) { + final Configuration globalConfig = mService.mRoot.getConfiguration(); + final Configuration overrideConfig = getMergedOverrideConfiguration(); + outConfiguration.setConfiguration(globalConfig, overrideConfig); + } + + void setReportedConfiguration(MergedConfiguration config) { + mLastReportedConfiguration.setTo(config.getMergedConfiguration()); } void adjustStartingWindowFlags() { @@ -3005,14 +3004,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP try { if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this + ": " + mCompatFrame); - final MergedConfiguration mergedConfiguration; - if (isConfigChanged()) { - mergedConfiguration = new MergedConfiguration(mService.mRoot.getConfiguration(), - getMergedOverrideConfiguration()); - mLastReportedConfiguration.setTo(mergedConfiguration.getMergedConfiguration()); - } else { - mergedConfiguration = null; - } + final MergedConfiguration mergedConfiguration = + new MergedConfiguration(mService.mRoot.getConfiguration(), + getMergedOverrideConfiguration()); + + setReportedConfiguration(mergedConfiguration); + if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == DRAW_PENDING) Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING"); @@ -4342,8 +4339,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return !mLastSurfaceInsets.equals(mAttrs.surfaceInsets); } - int relayoutVisibleWindow(MergedConfiguration mergedConfiguration, int result, int attrChanges, - int oldVisibility) { + int relayoutVisibleWindow(int result, int attrChanges, int oldVisibility) { final boolean wasVisible = isVisibleLw(); result |= (!wasVisible || !isDrawnLw()) ? RELAYOUT_RES_FIRST_TIME : 0; @@ -4366,7 +4362,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mWinAnimator.mEnteringAnimation = true; - prepareWindowToDisplayDuringRelayout(mergedConfiguration, wasVisible); + prepareWindowToDisplayDuringRelayout(wasVisible); if ((attrChanges & FORMAT_CHANGED) != 0) { // If the format can't be changed in place, preserve the old surface until the app draws diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk index a3d28bbd3754..e2a82b74e283 100644 --- a/services/core/jni/Android.mk +++ b/services/core/jni/Android.mk @@ -33,6 +33,7 @@ LOCAL_SRC_FILES += \ $(LOCAL_REL_DIR)/com_android_server_tv_TvInputHal.cpp \ $(LOCAL_REL_DIR)/com_android_server_vr_VrManagerService.cpp \ $(LOCAL_REL_DIR)/com_android_server_UsbDeviceManager.cpp \ + $(LOCAL_REL_DIR)/com_android_server_UsbDescriptorParser.cpp \ $(LOCAL_REL_DIR)/com_android_server_UsbMidiDevice.cpp \ $(LOCAL_REL_DIR)/com_android_server_UsbHostManager.cpp \ $(LOCAL_REL_DIR)/com_android_server_VibratorService.cpp \ diff --git a/services/core/jni/com_android_server_UsbDescriptorParser.cpp b/services/core/jni/com_android_server_UsbDescriptorParser.cpp new file mode 100644 index 000000000000..98c5ec1bd4d5 --- /dev/null +++ b/services/core/jni/com_android_server_UsbDescriptorParser.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "UsbHostManagerJNI" +#include "utils/Log.h" + +#include "jni.h" +#include "JNIHelp.h" + +#include <usbhost/usbhost.h> + +#define MAX_DESCRIPTORS_LENGTH 16384 + +// com.android.server.usb.descriptors +extern "C" { +jbyteArray JNICALL Java_com_android_server_usb_descriptors_UsbDescriptorParser_getRawDescriptors( + JNIEnv* env, jobject thiz, jstring deviceAddr) { + const char *deviceAddrStr = env->GetStringUTFChars(deviceAddr, NULL); + struct usb_device* device = usb_device_open(deviceAddrStr); + env->ReleaseStringUTFChars(deviceAddr, deviceAddrStr); + + if (!device) { + ALOGE("usb_device_open failed"); + return NULL; + } + + int fd = usb_device_get_fd(device); + if (fd < 0) { + return NULL; + } + + // from android_hardware_UsbDeviceConnection_get_desc() + jbyte buffer[MAX_DESCRIPTORS_LENGTH]; + lseek(fd, 0, SEEK_SET); + int numBytes = read(fd, buffer, sizeof(buffer)); + + usb_device_close(device); + + jbyteArray ret = NULL; + if (numBytes != 0) { + ret = env->NewByteArray(numBytes); + env->SetByteArrayRegion(ret, 0, numBytes, buffer); + } + return ret; +} + +} // extern "C" + + diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp index 804cd17fc27c..cb8416b36be5 100644 --- a/services/core/jni/com_android_server_VibratorService.cpp +++ b/services/core/jni/com_android_server_VibratorService.cpp @@ -42,107 +42,121 @@ using IVibrator_1_1 = android::hardware::vibrator::V1_1::IVibrator; namespace android { -static sp<IVibrator> mHal; +static constexpr int NUM_TRIES = 2; + +// Creates a Return<R> with STATUS::EX_NULL_POINTER. +template<class R> +inline Return<R> NullptrStatus() { + using ::android::hardware::Status; + return Return<R>{Status::fromExceptionCode(Status::EX_NULL_POINTER)}; +} + +// Helper used to transparently deal with the vibrator HAL becoming unavailable. +template<class R, class I, class... Args0, class... Args1> +Return<R> halCall(Return<R> (I::* fn)(Args0...), Args1&&... args1) { + // Assume that if getService returns a nullptr, HAL is not available on the + // device. + static sp<I> sHal = I::getService(); + static bool sAvailable = sHal != nullptr; + + if (!sAvailable) { + return NullptrStatus<R>(); + } + + // Return<R> doesn't have a default constructor, so make a Return<R> with + // STATUS::EX_NONE. + using ::android::hardware::Status; + Return<R> ret{Status::fromExceptionCode(Status::EX_NONE)}; + + // Note that ret is guaranteed to be changed after this loop. + for (int i = 0; i < NUM_TRIES; ++i) { + ret = (sHal == nullptr) ? NullptrStatus<R>() + : (*sHal.*fn)(std::forward<Args1>(args1)...); + + if (!ret.isOk()) { + ALOGE("Failed to issue command to vibrator HAL. Retrying."); + // Restoring connection to the HAL. + sHal = I::tryGetService(); + } + } + return ret; +} static void vibratorInit(JNIEnv /* env */, jobject /* clazz */) { - /* TODO(b/31632518) */ - if (mHal != nullptr) { - return; - } - mHal = IVibrator::getService(); + halCall(&IVibrator::ping).isOk(); } static jboolean vibratorExists(JNIEnv* /* env */, jobject /* clazz */) { - if (mHal != nullptr) { - return JNI_TRUE; - } else { - return JNI_FALSE; - } + return halCall(&IVibrator::ping).isOk() ? JNI_TRUE : JNI_FALSE; } static void vibratorOn(JNIEnv* /* env */, jobject /* clazz */, jlong timeout_ms) { - if (mHal != nullptr) { - Status retStatus = mHal->on(timeout_ms); - if (retStatus != Status::OK) { - ALOGE("vibratorOn command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus)); - } - } else { - ALOGW("Tried to vibrate but there is no vibrator device."); + Status retStatus = halCall(&IVibrator::on, timeout_ms).withDefault(Status::UNKNOWN_ERROR); + if (retStatus != Status::OK) { + ALOGE("vibratorOn command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus)); } } static void vibratorOff(JNIEnv* /* env */, jobject /* clazz */) { - if (mHal != nullptr) { - Status retStatus = mHal->off(); - if (retStatus != Status::OK) { - ALOGE("vibratorOff command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus)); - } - } else { - ALOGW("Tried to stop vibrating but there is no vibrator device."); + Status retStatus = halCall(&IVibrator::off).withDefault(Status::UNKNOWN_ERROR); + if (retStatus != Status::OK) { + ALOGE("vibratorOff command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus)); } } static jlong vibratorSupportsAmplitudeControl(JNIEnv*, jobject) { - if (mHal != nullptr) { - return mHal->supportsAmplitudeControl(); - } else { - ALOGW("Unable to get max vibration amplitude, there is no vibrator device."); - } - return false; + return halCall(&IVibrator::supportsAmplitudeControl).withDefault(false); } static void vibratorSetAmplitude(JNIEnv*, jobject, jint amplitude) { - if (mHal != nullptr) { - Status status = mHal->setAmplitude(static_cast<uint32_t>(amplitude)); - if (status != Status::OK) { - ALOGE("Failed to set vibrator amplitude (%" PRIu32 ").", - static_cast<uint32_t>(status)); - } - } else { - ALOGW("Unable to set vibration amplitude, there is no vibrator device."); + Status status = halCall(&IVibrator::setAmplitude, static_cast<uint32_t>(amplitude)) + .withDefault(Status::UNKNOWN_ERROR); + if (status != Status::OK) { + ALOGE("Failed to set vibrator amplitude (%" PRIu32 ").", + static_cast<uint32_t>(status)); } } static jlong vibratorPerformEffect(JNIEnv*, jobject, jlong effect, jint strength) { - if (mHal != nullptr) { - Status status; - uint32_t lengthMs; - auto callback = [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) { - status = retStatus; - lengthMs = retLengthMs; - }; - EffectStrength effectStrength(static_cast<EffectStrength>(strength)); - - if (effect < 0 || effect > static_cast<uint32_t>(Effect_1_1::TICK)) { - ALOGW("Unable to perform haptic effect, invalid effect ID (%" PRId32 ")", + Status status; + uint32_t lengthMs; + auto callback = [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) { + status = retStatus; + lengthMs = retLengthMs; + }; + EffectStrength effectStrength(static_cast<EffectStrength>(strength)); + + if (effect < 0 || effect > static_cast<uint32_t>(Effect_1_1::TICK)) { + ALOGW("Unable to perform haptic effect, invalid effect ID (%" PRId32 ")", + static_cast<int32_t>(effect)); + } else if (effect == static_cast<uint32_t>(Effect_1_1::TICK)) { + auto ret = halCall(&IVibrator_1_1::perform_1_1, static_cast<Effect_1_1>(effect), + effectStrength, callback); + if (!ret.isOk()) { + ALOGW("Failed to perform effect (%" PRId32 "), insufficient HAL version", static_cast<int32_t>(effect)); - } else if (effect == static_cast<uint32_t>(Effect_1_1::TICK)) { - sp<IVibrator_1_1> hal_1_1 = IVibrator_1_1::castFrom(mHal); - if (hal_1_1 != nullptr) { - hal_1_1->perform_1_1(static_cast<Effect_1_1>(effect), effectStrength, callback); - } else { - ALOGW("Failed to perform effect (%" PRId32 "), insufficient HAL version", - static_cast<int32_t>(effect)); - } - } else { - mHal->perform(static_cast<Effect>(effect), effectStrength, callback); - } - if (status == Status::OK) { - return lengthMs; - } else if (status != Status::UNSUPPORTED_OPERATION) { - // Don't warn on UNSUPPORTED_OPERATION, that's a normal even and just means the motor - // doesn't have a pre-defined waveform to perform for it, so we should just fall back - // to the framework waveforms. - ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32 - ", error=%" PRIu32 ").", static_cast<int64_t>(effect), - static_cast<int32_t>(strength), static_cast<uint32_t>(status)); } } else { - ALOGW("Unable to perform haptic effect, there is no vibrator device."); + auto ret = halCall(&IVibrator::perform, static_cast<Effect>(effect), effectStrength, + callback); + if (!ret.isOk()) { + ALOGW("Failed to perform effect (%" PRId32 ")", static_cast<int32_t>(effect)); + } + } + + if (status == Status::OK) { + return lengthMs; + } else if (status != Status::UNSUPPORTED_OPERATION) { + // Don't warn on UNSUPPORTED_OPERATION, that's a normal even and just means the motor + // doesn't have a pre-defined waveform to perform for it, so we should just fall back + // to the framework waveforms. + ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32 + ", error=%" PRIu32 ").", static_cast<int64_t>(effect), + static_cast<int32_t>(strength), static_cast<uint32_t>(status)); } return -1; } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 136d335cf473..8cac6e051e6b 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -43,6 +43,7 @@ import static android.app.admin.DevicePolicyManager.DELEGATION_PACKAGE_ACCESS; import static android.app.admin.DevicePolicyManager.DELEGATION_PERMISSION_GRANT; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; import static android.app.admin.DevicePolicyManager.PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER; +import static android.app.admin.DevicePolicyManager.WIPE_EUICC; import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE; import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA; import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; @@ -1691,9 +1692,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mContext.getSystemService(PowerManager.class).reboot(reason); } - void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force) - throws IOException { - RecoverySystem.rebootWipeUserData(mContext, shutdown, reason, force); + void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force, + boolean wipeEuicc) throws IOException { + RecoverySystem.rebootWipeUserData(mContext, shutdown, reason, force, wipeEuicc); } boolean systemPropertiesGetBoolean(String key, boolean def) { @@ -5302,7 +5303,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } - private void forceWipeDeviceNoLock(boolean wipeExtRequested, String reason) { + private void forceWipeDeviceNoLock(boolean wipeExtRequested, String reason, boolean wipeEuicc) { wtfIfInLock(); if (wipeExtRequested) { @@ -5312,7 +5313,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } try { mInjector.recoverySystemRebootWipeUserData( - /*shutdown=*/ false, reason, /*force=*/ true); + /*shutdown=*/ false, reason, /*force=*/ true, /*wipeEuicc=*/ wipeEuicc); } catch (IOException | SecurityException e) { Slog.w(LOG_TAG, "Failed requesting data wipe", e); } @@ -5389,7 +5390,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // removes that user (but still clears FRP...) if (userId == UserHandle.USER_SYSTEM) { forceWipeDeviceNoLock(/*wipeExtRequested=*/ (flags & WIPE_EXTERNAL_STORAGE) != 0, - reason); + reason, /*wipeEuicc=*/ (flags & WIPE_EUICC) != 0); } else { forceWipeUser(userId); } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java index 70c7e586d3fe..608635491849 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java @@ -25,8 +25,8 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.SystemClock; -import android.util.Log; import android.util.LongSparseArray; +import android.util.Slog; import com.android.internal.annotations.GuardedBy; @@ -60,16 +60,21 @@ final class NetworkLoggingHandler extends Handler { /** Delay after which older batches get discarded after a retrieval. */ private static final long RETRIEVED_BATCH_DISCARD_DELAY_MS = 5 * 60 * 1000; // 5m + /** Do not call into mDpm with locks held */ private final DevicePolicyManagerService mDpm; private final AlarmManager mAlarmManager; private final OnAlarmListener mBatchTimeoutAlarmListener = new OnAlarmListener() { @Override public void onAlarm() { - Log.d(TAG, "Received a batch finalization timeout alarm, finalizing " + Slog.d(TAG, "Received a batch finalization timeout alarm, finalizing " + mNetworkEvents.size() + " pending events."); + Bundle notificationExtras = null; synchronized (NetworkLoggingHandler.this) { - finalizeBatchAndNotifyDeviceOwnerLocked(); + notificationExtras = finalizeBatchAndBuildDeviceOwnerMessageLocked(); + } + if (notificationExtras != null) { + notifyDeviceOwner(notificationExtras); } } }; @@ -110,17 +115,21 @@ final class NetworkLoggingHandler extends Handler { case LOG_NETWORK_EVENT_MSG: { final NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY); if (networkEvent != null) { + Bundle notificationExtras = null; synchronized (NetworkLoggingHandler.this) { mNetworkEvents.add(networkEvent); if (mNetworkEvents.size() >= MAX_EVENTS_PER_BATCH) { - finalizeBatchAndNotifyDeviceOwnerLocked(); + notificationExtras = finalizeBatchAndBuildDeviceOwnerMessageLocked(); } } + if (notificationExtras != null) { + notifyDeviceOwner(notificationExtras); + } } break; } default: { - Log.d(TAG, "NetworkLoggingHandler received an unknown of message."); + Slog.d(TAG, "NetworkLoggingHandler received an unknown of message."); break; } } @@ -133,40 +142,48 @@ final class NetworkLoggingHandler extends Handler { mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS, NETWORK_LOGGING_TIMEOUT_ALARM_TAG, mBatchTimeoutAlarmListener, this); - Log.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS + Slog.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS + "ms from now."); } synchronized void pause() { - Log.d(TAG, "Paused network logging"); + Slog.d(TAG, "Paused network logging"); mPaused = true; } - synchronized void resume() { - if (!mPaused) { - Log.d(TAG, "Attempted to resume network logging, but logging is not paused."); - return; - } + void resume() { + Bundle notificationExtras = null; + synchronized (this) { + if (!mPaused) { + Slog.d(TAG, "Attempted to resume network logging, but logging is not paused."); + return; + } - Log.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken - + ", LastRetrievedBatch=" + mLastRetrievedBatchToken); - mPaused = false; + Slog.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken + + ", LastRetrievedBatch=" + mLastRetrievedBatchToken); + mPaused = false; - // If there is a batch ready that the device owner hasn't been notified about, do it now. - if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) { - scheduleBatchFinalization(); - notifyDeviceOwnerLocked(); + // If there is a batch ready that the device owner hasn't been notified about, do it now. + if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) { + scheduleBatchFinalization(); + notificationExtras = buildDeviceOwnerMessageLocked(); + } + } + if (notificationExtras != null) { + notifyDeviceOwner(notificationExtras); } } synchronized void discardLogs() { mBatches.clear(); mNetworkEvents = new ArrayList<>(); - Log.d(TAG, "Discarded all network logs"); + Slog.d(TAG, "Discarded all network logs"); } @GuardedBy("this") - private void finalizeBatchAndNotifyDeviceOwnerLocked() { + /** @returns extras if a message should be sent to the device owner */ + private Bundle finalizeBatchAndBuildDeviceOwnerMessageLocked() { + Bundle notificationExtras = null; if (mNetworkEvents.size() > 0) { // Finalize the batch and start a new one from scratch. if (mBatches.size() >= MAX_BATCHES) { @@ -177,27 +194,39 @@ final class NetworkLoggingHandler extends Handler { mBatches.append(mCurrentBatchToken, mNetworkEvents); mNetworkEvents = new ArrayList<>(); if (!mPaused) { - notifyDeviceOwnerLocked(); + notificationExtras = buildDeviceOwnerMessageLocked(); } } else { // Don't notify the DO, since there are no events; DPC can still retrieve // the last full batch if not paused. - Log.d(TAG, "Was about to finalize the batch, but there were no events to send to" + Slog.d(TAG, "Was about to finalize the batch, but there were no events to send to" + " the DPC, the batchToken of last available batch: " + mCurrentBatchToken); } // Regardless of whether the batch was non-empty schedule a new finalization after timeout. scheduleBatchFinalization(); + return notificationExtras; } - /** Sends a notification to the DO. Should only be called when there is a batch available. */ @GuardedBy("this") - private void notifyDeviceOwnerLocked() { + /** Build extras notification to the DO. Should only be called when there + is a batch available. */ + private Bundle buildDeviceOwnerMessageLocked() { final Bundle extras = new Bundle(); final int lastBatchSize = mBatches.valueAt(mBatches.size() - 1).size(); extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentBatchToken); extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, lastBatchSize); - Log.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: " - + mCurrentBatchToken); + return extras; + } + + /** Sends a notification to the DO. Should not hold locks as DevicePolicyManagerService may + call into NetworkLoggingHandler. */ + private void notifyDeviceOwner(Bundle extras) { + Slog.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: " + + extras.getLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, -1)); + if (Thread.holdsLock(this)) { + Slog.wtfStack(TAG, "Shouldn't be called with NetworkLoggingHandler lock held"); + return; + } mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras); } diff --git a/services/tests/notification/AndroidManifest.xml b/services/tests/notification/AndroidManifest.xml index 99d9c7b87301..c20020abb85c 100644 --- a/services/tests/notification/AndroidManifest.xml +++ b/services/tests/notification/AndroidManifest.xml @@ -31,7 +31,7 @@ </application> <instrumentation - android:name="android.support.test.runner.AndroidJUnitRunner" + android:name="android.testing.TestableInstrumentation" android:targetPackage="com.android.frameworks.tests.notification" android:label="Notification Tests" /> </manifest> diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java index a33153e07496..54717157d069 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java @@ -269,9 +269,9 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi } @Override - void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force) - throws IOException { - services.recoverySystem.rebootWipeUserData(shutdown, reason, force); + void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force, + boolean wipeEuicc) throws IOException { + services.recoverySystem.rebootWipeUserData(shutdown, reason, force, wipeEuicc); } @Override diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 6393b0b4018e..c58b733b8b54 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -17,6 +17,7 @@ package com.android.server.devicepolicy; import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS; import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL; +import static android.app.admin.DevicePolicyManager.WIPE_EUICC; import static android.os.UserManagerInternal.CAMERA_DISABLED_GLOBALLY; import static android.os.UserManagerInternal.CAMERA_DISABLED_LOCALLY; import static android.os.UserManagerInternal.CAMERA_NOT_DISABLED; @@ -3451,7 +3452,21 @@ public class DevicePolicyManagerTest extends DpmTestBase { dpm.wipeData(0); verify(getServices().recoverySystem).rebootWipeUserData( - /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true)); + /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true), + /*wipeEuicc=*/ eq(false)); + } + + public void testWipeEuiccDataEnabled() throws Exception { + setDeviceOwner(); + when(getServices().userManager.getUserRestrictionSource( + UserManager.DISALLOW_FACTORY_RESET, + UserHandle.SYSTEM)) + .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER); + + dpm.wipeData(WIPE_EUICC); + verify(getServices().recoverySystem).rebootWipeUserData( + /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true), + /*wipeEuicc=*/ eq(true)); } public void testWipeDataDeviceOwnerDisallowed() throws Exception { @@ -3549,7 +3564,8 @@ public class DevicePolicyManagerTest extends DpmTestBase { // The device should be wiped even if DISALLOW_FACTORY_RESET is enabled, because both the // user restriction and the policy were set by the DO. verify(getServices().recoverySystem).rebootWipeUserData( - /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true)); + /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true), + /*wipeEuicc=*/ eq(false)); } public void testMaximumFailedPasswordAttemptsReachedDeviceOwnerDisallowed() throws Exception { diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java index ed8de0517631..8121bcf16c60 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java @@ -314,8 +314,8 @@ public class MockSystemServices { } public static class RecoverySystemForMock { - public void rebootWipeUserData( - boolean shutdown, String reason, boolean force) throws IOException { + public void rebootWipeUserData(boolean shutdown, String reason, boolean force, + boolean wipeEuicc) throws IOException { } } diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java index c399a5de46dd..61df22ecda9c 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -29,8 +29,11 @@ import android.view.SurfaceControl; import android.view.WindowManagerInternal; import com.android.server.LocalServices; +import com.android.server.SystemService; +import com.android.server.display.DisplayDeviceInfo; import com.android.server.display.DisplayManagerService.SyncRoot; import com.android.server.display.VirtualDisplayAdapter.SurfaceControlDisplayFactory; +import com.android.server.lights.LightsManager; import org.mockito.ArgumentCaptor; import org.mockito.Mock; @@ -44,35 +47,51 @@ import static org.mockito.Mockito.when; @SmallTest public class DisplayManagerServiceTest extends AndroidTestCase { - private Handler mHandler; - private DisplayManagerService mDisplayManager; + private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1; + private static final long SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS = 10; + + private final DisplayManagerService.Injector mShortMockedInjector = + new DisplayManagerService.Injector() { + @Override + VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, + Context context, Handler handler, DisplayAdapter.Listener listener) { + return mMockVirtualDisplayAdapter; + } + + @Override + long getDefaultDisplayDelayTimeout() { + return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS; + } + }; + private final DisplayManagerService.Injector mBasicInjector = + new DisplayManagerService.Injector() { + @Override + VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, + Context context, Handler handler, + DisplayAdapter.Listener displayAdapterListener) { + return new VirtualDisplayAdapter(syncRoot, context, handler, + displayAdapterListener, + (String name, boolean secure) -> mMockDisplayToken); + } + }; + @Mock InputManagerInternal mMockInputManagerInternal; @Mock IVirtualDisplayCallback.Stub mMockAppToken; @Mock WindowManagerInternal mMockWindowManagerInternal; + @Mock LightsManager mMockLightsManager; @Mock VirtualDisplayAdapter mMockVirtualDisplayAdapter; @Mock IBinder mMockDisplayToken; @Override protected void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mDisplayManager = new DisplayManagerService(mContext, - new DisplayManagerService.Injector() { - @Override - VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, - Handler handler, DisplayAdapter.Listener displayAdapterListener) { - return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener, - (String name, boolean secure) -> mMockDisplayToken); - } - }); - mHandler = mDisplayManager.getDisplayHandler(); LocalServices.removeServiceForTest(InputManagerInternal.class); LocalServices.addService(InputManagerInternal.class, mMockInputManagerInternal); LocalServices.removeServiceForTest(WindowManagerInternal.class); LocalServices.addService(WindowManagerInternal.class, mMockWindowManagerInternal); - - mDisplayManager.systemReady(false /* safeMode */, false /* onlyCore */); - mDisplayManager.windowManagerAndInputReady(); + LocalServices.removeServiceForTest(LightsManager.class); + LocalServices.addService(LightsManager.class, mMockLightsManager); super.setUp(); } @@ -82,8 +101,14 @@ public class DisplayManagerServiceTest extends AndroidTestCase { } public void testCreateVirtualDisplay_sentToInputManager() throws Exception { + DisplayManagerService displayManager = + new DisplayManagerService(mContext, mBasicInjector); + registerDefaultDisplays(displayManager); + displayManager.systemReady(false /* safeMode */, true /* onlyCore */); + displayManager.windowManagerAndInputReady(); + // This is effectively the DisplayManager service published to ServiceManager. - DisplayManagerService.BinderService bs = mDisplayManager.new BinderService(); + DisplayManagerService.BinderService bs = displayManager.new BinderService(); String uniqueId = "uniqueId --- Test"; String uniqueIdPrefix = "virtual:" + mContext.getPackageName() + ":"; @@ -98,10 +123,10 @@ public class DisplayManagerServiceTest extends AndroidTestCase { "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */, uniqueId); - mDisplayManager.performTraversalInTransactionFromWindowManagerInternal(); + displayManager.performTraversalInTransactionFromWindowManagerInternal(); // flush the handler - mHandler.runWithScissors(() -> {}, 0 /* now */); + displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); ArgumentCaptor<List<DisplayViewport>> virtualViewportCaptor = ArgumentCaptor.forClass(List.class); @@ -115,4 +140,97 @@ public class DisplayManagerServiceTest extends AndroidTestCase { assertEquals(uniqueIdPrefix + uniqueId, dv.uniqueId); assertEquals(displayId, dv.displayId); } + + public void testCreateVirtualDisplayRotatesWithContent() throws Exception { + DisplayManagerService displayManager = + new DisplayManagerService(mContext, mBasicInjector); + registerDefaultDisplays(displayManager); + + // This is effectively the DisplayManager service published to ServiceManager. + DisplayManagerService.BinderService bs = displayManager.new BinderService(); + + String uniqueId = "uniqueId --- Rotates With Content Test"; + int width = 600; + int height = 800; + int dpi = 320; + int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT; + + when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); + int displayId = bs.createVirtualDisplay(mMockAppToken /* callback */, + null /* projection */, "com.android.frameworks.servicestests", + "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */, + uniqueId); + + displayManager.performTraversalInTransactionFromWindowManagerInternal(); + + // flush the handler + displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); + + DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId); + assertNotNull(ddi); + assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0); + } + + /** + * Tests that the virtual display is created along-side the default display. + */ + public void testStartVirtualDisplayWithDefaultDisplay_Succeeds() throws Exception { + DisplayManagerService displayManager = + new DisplayManagerService(mContext, mShortMockedInjector); + registerDefaultDisplays(displayManager); + displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); + } + + /** + * Tests that we get a Runtime exception when we cannot initialize the default display. + */ + public void testStartVirtualDisplayWithDefDisplay_NoDefaultDisplay() throws Exception { + DisplayManagerService displayManager = + new DisplayManagerService(mContext, mShortMockedInjector); + Handler handler = displayManager.getDisplayHandler(); + handler.runWithScissors(() -> {}, 0 /* now */); + + try { + displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); + } catch (RuntimeException e) { + return; + } + fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the" + + " default display"); + } + + /** + * Tests that we get a Runtime exception when we cannot initialize the virtual display. + */ + public void testStartVirtualDisplayWithDefDisplay_NoVirtualDisplayAdapter() throws Exception { + DisplayManagerService displayManager = new DisplayManagerService(mContext, + new DisplayManagerService.Injector() { + @Override + VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, + Context context, Handler handler, DisplayAdapter.Listener listener) { + return null; // return null for the adapter. This should cause a failure. + } + + @Override + long getDefaultDisplayDelayTimeout() { + return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS; + } + }); + try { + displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); + } catch (RuntimeException e) { + return; + } + fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the" + + " virtual display adapter"); + } + + private void registerDefaultDisplays(DisplayManagerService displayManager) { + Handler handler = displayManager.getDisplayHandler(); + // Would prefer to call displayManager.onStart() directly here but it performs binderService + // registration which triggers security exceptions when running from a test. + handler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); + // flush the handler + handler.runWithScissors(() -> {}, 0 /* now */); + } } diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java index c809c325726f..67db5f4d12dd 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java @@ -218,8 +218,7 @@ public class WindowStateTests extends WindowTestsBase { root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON; root.mTurnOnScreen = false; - root.prepareWindowToDisplayDuringRelayout(new MergedConfiguration(), - wasVisible /*wasVisible*/); + root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/); assertTrue(root.mTurnOnScreen); } } diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java index d315b181c357..68c1d5f6ec7f 100644 --- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java +++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java @@ -65,6 +65,9 @@ public final class UsbAlsaManager { private final HashMap<UsbDevice,UsbAudioDevice> mAudioDevices = new HashMap<UsbDevice,UsbAudioDevice>(); + private boolean mIsInputHeadset; // as reported by UsbDescriptorParser + private boolean mIsOutputHeadset; // as reported by UsbDescriptorParser + private final HashMap<UsbDevice,UsbMidiDevice> mMidiDevices = new HashMap<UsbDevice,UsbMidiDevice>(); @@ -184,9 +187,14 @@ public final class UsbAlsaManager { try { // Playback Device if (audioDevice.mHasPlayback) { - int device = (audioDevice == mAccessoryAudioDevice ? - AudioSystem.DEVICE_OUT_USB_ACCESSORY : - AudioSystem.DEVICE_OUT_USB_DEVICE); + int device; + if (mIsOutputHeadset) { + device = AudioSystem.DEVICE_OUT_USB_HEADSET; + } else { + device = (audioDevice == mAccessoryAudioDevice + ? AudioSystem.DEVICE_OUT_USB_ACCESSORY + : AudioSystem.DEVICE_OUT_USB_DEVICE); + } if (DEBUG) { Slog.i(TAG, "pre-call device:0x" + Integer.toHexString(device) + " addr:" + address + " name:" + audioDevice.getDeviceName()); @@ -197,9 +205,14 @@ public final class UsbAlsaManager { // Capture Device if (audioDevice.mHasCapture) { - int device = (audioDevice == mAccessoryAudioDevice ? - AudioSystem.DEVICE_IN_USB_ACCESSORY : - AudioSystem.DEVICE_IN_USB_DEVICE); + int device; + if (mIsInputHeadset) { + device = AudioSystem.DEVICE_IN_USB_HEADSET; + } else { + device = (audioDevice == mAccessoryAudioDevice + ? AudioSystem.DEVICE_IN_USB_ACCESSORY + : AudioSystem.DEVICE_IN_USB_DEVICE); + } mAudioService.setWiredDeviceConnectionState( device, state, address, audioDevice.getDeviceName(), TAG); } @@ -343,12 +356,16 @@ public final class UsbAlsaManager { return selectAudioCard(mCardsParser.getDefaultCard()); } - /* package */ void usbDeviceAdded(UsbDevice usbDevice) { - if (DEBUG) { - Slog.d(TAG, "deviceAdded(): " + usbDevice.getManufacturerName() + - " nm:" + usbDevice.getProductName()); + /* package */ void usbDeviceAdded(UsbDevice usbDevice, + boolean isInputHeadset, boolean isOutputHeadset) { + if (DEBUG) { + Slog.d(TAG, "deviceAdded(): " + usbDevice.getManufacturerName() + + " nm:" + usbDevice.getProductName()); } + mIsInputHeadset = isInputHeadset; + mIsOutputHeadset = isOutputHeadset; + // Is there an audio interface in there? boolean isAudioDevice = false; diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java index af78c05ae399..40aadbbcc457 100644 --- a/services/usb/java/com/android/server/usb/UsbHostManager.java +++ b/services/usb/java/com/android/server/usb/UsbHostManager.java @@ -16,7 +16,6 @@ package com.android.server.usb; -import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; @@ -32,6 +31,7 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; +import com.android.server.usb.descriptors.UsbDescriptorParser; import java.util.ArrayList; import java.util.HashMap; @@ -259,7 +259,14 @@ public class UsbHostManager { getCurrentUserSettings().deviceAttachedForFixedHandler(mNewDevice, usbDeviceConnectionHandler); } - mUsbAlsaManager.usbDeviceAdded(mNewDevice); + // deviceName is something like: "/dev/bus/usb/001/001" + UsbDescriptorParser parser = new UsbDescriptorParser(); + if (parser.parseDevice(mNewDevice.getDeviceName())) { + Slog.i(TAG, "---- isHeadset[in:" + parser.isInputHeadset() + + " , out:" + parser.isOutputHeadset() + "]"); + mUsbAlsaManager.usbDeviceAdded(mNewDevice, + parser.isInputHeadset(), parser.isOutputHeadset()); + } } else { Slog.e(TAG, "mNewDevice is null in endUsbDeviceAdded"); } diff --git a/services/usb/java/com/android/server/usb/descriptors/ByteStream.java b/services/usb/java/com/android/server/usb/descriptors/ByteStream.java new file mode 100644 index 000000000000..d678931fd01a --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/ByteStream.java @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +import android.annotation.NonNull; + +/** + * @hide + * A stream interface wrapping a byte array. Very much like a java.io.ByteArrayInputStream + * but with the capability to "back up" in situations where the parser discovers that a + * UsbDescriptor has overrun its length. + */ +public class ByteStream { + private static final String TAG = "ByteStream"; + + /** The byte array being wrapped */ + @NonNull + private final byte[] mBytes; // this is never null. + + /** + * The index into the byte array to be read next. + * This value is altered by reading data out of the stream + * (using either the getByte() or unpack*() methods), or alternatively + * by explicitly offseting the stream position with either + * advance() or reverse(). + */ + private int mIndex; + + /* + * This member used with resetReadCount() & getReadCount() can be used to determine how many + * bytes a UsbDescriptor subclass ACTUALLY reads (as opposed to what its length field says). + * using this info, the parser can mark a descriptor as valid or invalid and correct the stream + * position with advance() & reverse() to keep from "getting lost" in the descriptor stream. + */ + private int mReadCount; + + /** + * Create a ByteStream object wrapping the specified byte array. + * + * @param bytes The byte array containing the raw descriptor information retrieved from + * the USB device. + * @throws IllegalArgumentException + */ + public ByteStream(@NonNull byte[] bytes) { + if (bytes == null) { + throw new IllegalArgumentException(); + } + mBytes = bytes; + } + + /** + * Resets the running count of bytes read so that later we can see how much more has been read. + */ + public void resetReadCount() { + mReadCount = 0; + } + + /** + * Retrieves the running count of bytes read from the stream. + */ + public int getReadCount() { + return mReadCount; + } + + /** + * @return The value of the next byte in the stream without advancing the stream. + * Does not affect the running count as the byte hasn't been "consumed". + * @throws IndexOutOfBoundsException + */ + public byte peekByte() { + if (available() > 0) { + return mBytes[mIndex + 1]; + } else { + throw new IndexOutOfBoundsException(); + } + } + + /** + * @return the next byte from the stream and advances the stream and the read count. Note + * that this is a signed byte (as is the case of byte in Java). The user may need to understand + * from context if it should be interpreted as an unsigned value. + * @throws IndexOutOfBoundsException + */ + public byte getByte() { + if (available() > 0) { + mReadCount++; + return mBytes[mIndex++]; + } else { + throw new IndexOutOfBoundsException(); + } + } + + /** + * Reads 2 bytes in *little endian format* from the stream and composes a 16-bit integer. + * As we are storing the 2-byte value in a 4-byte integer, the upper 2 bytes are always + * 0, essentially making the returned value *unsigned*. + * @return The 16-bit integer (packed into the lower 2 bytes of an int) encoded by the + * next 2 bytes in the stream. + * @throws IndexOutOfBoundsException + */ + public int unpackUsbWord() { + if (available() >= 2) { + int b0 = getByte(); + int b1 = getByte(); + return ((b1 << 8) & 0x0000FF00) | (b0 & 0x000000FF); + } else { + throw new IndexOutOfBoundsException(); + } + } + + /** + * Reads 3 bytes in *little endian format* from the stream and composes a 24-bit integer. + * As we are storing the 3-byte value in a 4-byte integer, the upper byte is always + * 0, essentially making the returned value *unsigned*. + * @return The 24-bit integer (packed into the lower 3 bytes of an int) encoded by the + * next 3 bytes in the stream. + * @throws IndexOutOfBoundsException + */ + public int unpackUsbTriple() { + if (available() >= 3) { + int b0 = getByte(); + int b1 = getByte(); + int b2 = getByte(); + return ((b2 << 16) & 0x00FF0000) | ((b1 << 8) & 0x0000FF00) | (b0 & 0x000000FF); + } else { + throw new IndexOutOfBoundsException(); + } + } + + /** + * Advances the logical position in the stream. Affects the running count also. + * @param numBytes The number of bytes to advance. + * @throws IndexOutOfBoundsException + * @throws IllegalArgumentException + */ + public void advance(int numBytes) { + if (numBytes < 0) { + // Positive offsets only + throw new IllegalArgumentException(); + } + // do arithmetic and comparison in long to ovoid potention integer overflow + long longNewIndex = (long) mIndex + (long) numBytes; + if (longNewIndex < (long) mBytes.length) { + mReadCount += numBytes; + mIndex += numBytes; + } else { + throw new IndexOutOfBoundsException(); + } + } + + /** + * Reverse the logical position in the stream. Affects the running count also. + * @param numBytes The (positive) number of bytes to reverse. + * @throws IndexOutOfBoundsException + * @throws IllegalArgumentException + */ + public void reverse(int numBytes) { + if (numBytes < 0) { + // Positive (reverse) offsets only + throw new IllegalArgumentException(); + } + if (mIndex >= numBytes) { + mReadCount -= numBytes; + mIndex -= numBytes; + } else { + throw new IndexOutOfBoundsException(); + } + } + + /** + * @return The number of bytes available to be read in the stream. + */ + public int available() { + return mBytes.length - mIndex; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACAudioControlEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioControlEndpoint.java new file mode 100644 index 000000000000..96fcc6a0b8db --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioControlEndpoint.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific Audio Control Endpoint. + * audio10.pdf section 4.4.2.1 + */ +public class UsbACAudioControlEndpoint extends UsbACEndpoint { + private static final String TAG = "ACAudioControlEndpoint"; + + private byte mAddress; // 2:1 The address of the endpoint on the USB device. + // D7: Direction. 1 = IN endpoint + // D6..4: Reserved, reset to zero + // D3..0: The endpoint number. + private byte mAttribs; // 3:1 (see ATTRIBSMASK_* below + private int mMaxPacketSize; // 4:2 Maximum packet size this endpoint is capable of sending + // or receiving when this configuration is selected. + private byte mInterval; // 6:1 + + static final byte ADDRESSMASK_DIRECTION = (byte) 0x80; + static final byte ADDRESSMASK_ENDPOINT = 0x0F; + + static final byte ATTRIBSMASK_SYNC = 0x0C; + static final byte ATTRIBMASK_TRANS = 0x03; + + public UsbACAudioControlEndpoint(int length, byte type, byte subclass) { + super(length, type, subclass); + } + + public byte getAddress() { + return mAddress; + } + + public byte getAttribs() { + return mAttribs; + } + + public int getMaxPacketSize() { + return mMaxPacketSize; + } + + public byte getInterval() { + return mInterval; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + super.parseRawDescriptors(stream); + + mAddress = stream.getByte(); + mAttribs = stream.getByte(); + mMaxPacketSize = stream.unpackUsbWord(); + mInterval = stream.getByte(); + + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACAudioStreamEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioStreamEndpoint.java new file mode 100644 index 000000000000..d387883d3049 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioStreamEndpoint.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific Streaming Endpoint + * see audio10.pdf section 3.7.2 + */ +public class UsbACAudioStreamEndpoint extends UsbACEndpoint { + private static final String TAG = "ACAudioStreamEndpoint"; + + //TODO data fields... + public UsbACAudioStreamEndpoint(int length, byte type, byte subclass) { + super(length, type, subclass); + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + super.parseRawDescriptors(stream); + + //TODO Read fields + stream.advance(mLength - stream.getReadCount()); + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java new file mode 100644 index 000000000000..223496ab016e --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +import android.util.Log; + +/** + * @hide + * An audio class-specific Endpoint + * see audio10.pdf section 4.4.1.2 + */ +abstract class UsbACEndpoint extends UsbDescriptor { + private static final String TAG = "ACEndpoint"; + + protected final byte mSubclass; // from the mSubclass member of the "enclosing" + // Interface Descriptor, not the stream. + protected byte mSubtype; // 2:1 HEADER descriptor subtype + + UsbACEndpoint(int length, byte type, byte subclass) { + super(length, type); + mSubclass = subclass; + } + + public byte getSubclass() { + return mSubclass; + } + + public byte getSubtype() { + return mSubtype; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + mSubtype = stream.getByte(); + + return mLength; + } + + public static UsbDescriptor allocDescriptor(UsbDescriptorParser parser, + int length, byte type) { + UsbInterfaceDescriptor interfaceDesc = parser.getCurInterface(); + byte subClass = interfaceDesc.getUsbSubclass(); + switch (subClass) { + case AUDIO_AUDIOCONTROL: + return new UsbACAudioControlEndpoint(length, type, subClass); + + case AUDIO_AUDIOSTREAMING: + return new UsbACAudioStreamEndpoint(length, type, subClass); + + case AUDIO_MIDISTREAMING: + return new UsbACMidiEndpoint(length, type, subClass); + + default: + Log.w(TAG, "Unknown Audio Class Endpoint id:0x" + Integer.toHexString(subClass)); + return null; + } + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACFeatureUnit.java b/services/usb/java/com/android/server/usb/descriptors/UsbACFeatureUnit.java new file mode 100644 index 000000000000..739fe5503a1d --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbACFeatureUnit.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific Feature Unit Interface + * see audio10.pdf section 3.5.5 + */ +public class UsbACFeatureUnit extends UsbACInterface { + private static final String TAG = "ACFeatureUnit"; + + // audio10.pdf section 4.3.2.5 + public static final int CONTROL_MASK_MUTE = 0x0001; + public static final int CONTROL_MASK_VOL = 0x0002; + public static final int CONTROL_MASK_BASS = 0x0004; + public static final int CONTROL_MASK_MID = 0x0008; + public static final int CONTROL_MASK_TREB = 0x0010; + public static final int CONTROL_MASK_EQ = 0x0020; + public static final int CONTROL_MASK_AGC = 0x0040; + public static final int CONTROL_MASK_DELAY = 0x0080; + public static final int CONTROL_MASK_BOOST = 0x0100; // BASS boost + public static final int CONTROL_MASK_LOUD = 0x0200; // LOUDNESS + + private int mNumChannels; + + private byte mUnitID; // 3:1 Constant uniquely identifying the Unit within the audio function. + // This value is used in all requests to address this Unit + private byte mSourceID; // 4:1 ID of the Unit or Terminal to which this Feature Unit + // is connected. + private byte mControlSize; // 5:1 Size in bytes of an element of the mControls array: n + private int[] mControls; // 6:? bitmask (see above) of supported controls in a given + // logical channel + private byte mUnitName; // ?:1 Index of a string descriptor, describing this Feature Unit. + + public UsbACFeatureUnit(int length, byte type, byte subtype, byte subClass) { + super(length, type, subtype, subClass); + } + + public int getNumChannels() { + return mNumChannels; + } + + public byte getUnitID() { + return mUnitID; + } + + public byte getSourceID() { + return mSourceID; + } + + public byte getControlSize() { + return mControlSize; + } + + public int[] getControls() { + return mControls; + } + + public byte getUnitName() { + return mUnitName; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACHeader.java b/services/usb/java/com/android/server/usb/descriptors/UsbACHeader.java new file mode 100644 index 000000000000..e31438c58e06 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbACHeader.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific Interface Header. + * see audio10.pdf section 4.3.2 + */ +public class UsbACHeader extends UsbACInterface { + private static final String TAG = "ACHeader"; + + private int mADCRelease; // 3:2 Audio Device Class Specification Release (BCD). + private int mTotalLength; // 5:2 Total number of bytes returned for the class-specific + // AudioControl interface descriptor. Includes the combined length + // of this descriptor header and all Unit and Terminal descriptors. + private byte mNumInterfaces = 0; // 7:1 The number of AudioStreaming and MIDIStreaming + // interfaces in the Audio Interface Collection to which this + // AudioControl interface belongs: n + private byte[] mInterfaceNums = null; // 8:n List of Audio/MIDI streaming interface + // numbers associate with this endpoint + private byte mControls; // Vers 2.0 thing + + public UsbACHeader(int length, byte type, byte subtype, byte subclass) { + super(length, type, subtype, subclass); + } + + public int getADCRelease() { + return mADCRelease; + } + + public int getTotalLength() { + return mTotalLength; + } + + public byte getNumInterfaces() { + return mNumInterfaces; + } + + public byte[] getInterfaceNums() { + return mInterfaceNums; + } + + public byte getControls() { + return mControls; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + mADCRelease = stream.unpackUsbWord(); + + mTotalLength = stream.unpackUsbWord(); + if (mADCRelease >= 0x200) { + mControls = stream.getByte(); + } else { + mNumInterfaces = stream.getByte(); + mInterfaceNums = new byte[mNumInterfaces]; + for (int index = 0; index < mNumInterfaces; index++) { + mInterfaceNums[index] = stream.getByte(); + } + } + + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACInputTerminal.java b/services/usb/java/com/android/server/usb/descriptors/UsbACInputTerminal.java new file mode 100644 index 000000000000..653a7de5457e --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbACInputTerminal.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific Input Terminal interface. + * see audio10.pdf section 4.3.2.1 + */ +public class UsbACInputTerminal extends UsbACTerminal { + private static final String TAG = "ACInputTerminal"; + + private byte mNrChannels; // 7:1 1 Channel (0x01) + // Number of logical output channels in the + // Terminal’s output audio channel cluster + private int mChannelConfig; // 8:2 Mono (0x0000) + private byte mChannelNames; // 10:1 Unused (0x00) + private byte mTerminal; // 11:1 Unused (0x00) + + public UsbACInputTerminal(int length, byte type, byte subtype, byte subclass) { + super(length, type, subtype, subclass); + } + + public byte getNrChannels() { + return mNrChannels; + } + + public int getChannelConfig() { + return mChannelConfig; + } + + public byte getChannelNames() { + return mChannelNames; + } + + public byte getTerminal() { + return mTerminal; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + super.parseRawDescriptors(stream); + + mNrChannels = stream.getByte(); + mChannelConfig = stream.unpackUsbWord(); + mChannelNames = stream.getByte(); + mTerminal = stream.getByte(); + + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java b/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java new file mode 100644 index 000000000000..0ab7fccd2c3b --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +import android.util.Log; + +/** + * @hide + * An audio class-specific Interface. + * see audio10.pdf section 4.3.2 + */ +public abstract class UsbACInterface extends UsbDescriptor { + private static final String TAG = "ACInterface"; + + // Audio Control Subtypes + public static final byte ACI_UNDEFINED = 0; + public static final byte ACI_HEADER = 1; + public static final byte ACI_INPUT_TERMINAL = 2; + public static final byte ACI_OUTPUT_TERMINAL = 3; + public static final byte ACI_MIXER_UNIT = 4; + public static final byte ACI_SELECTOR_UNIT = 5; + public static final byte ACI_FEATURE_UNIT = 6; + public static final byte ACI_PROCESSING_UNIT = 7; + public static final byte ACI_EXTENSION_UNIT = 8; + + // Audio Streaming Subtypes + public static final byte ASI_UNDEFINED = 0; + public static final byte ASI_GENERAL = 1; + public static final byte ASI_FORMAT_TYPE = 2; + public static final byte ASI_FORMAT_SPECIFIC = 3; + + // MIDI Streaming Subtypes + public static final byte MSI_UNDEFINED = 0; + public static final byte MSI_HEADER = 1; + public static final byte MSI_IN_JACK = 2; + public static final byte MSI_OUT_JACK = 3; + public static final byte MSI_ELEMENT = 4; + + // Sample format IDs (encodings) + // FORMAT_I + public static final int FORMAT_I_UNDEFINED = 0x0000; + public static final int FORMAT_I_PCM = 0x0001; + public static final int FORMAT_I_PCM8 = 0x0002; + public static final int FORMAT_I_IEEE_FLOAT = 0x0003; + public static final int FORMAT_I_ALAW = 0x0004; + public static final int FORMAT_I_MULAW = 0x0005; + // FORMAT_II + public static final int FORMAT_II_UNDEFINED = 0x1000; + public static final int FORMAT_II_MPEG = 0x1001; + public static final int FORMAT_II_AC3 = 0x1002; + // FORMAT_III + public static final int FORMAT_III_UNDEFINED = 0x2000; + public static final int FORMAT_III_IEC1937AC3 = 0x2001; + public static final int FORMAT_III_IEC1937_MPEG1_Layer1 = 0x2002; + public static final int FORMAT_III_IEC1937_MPEG1_Layer2 = 0x2003; + public static final int FORMAT_III_IEC1937_MPEG2_EXT = 0x2004; + public static final int FORMAT_III_IEC1937_MPEG2_Layer1LS = 0x2005; + + protected final byte mSubtype; // 2:1 HEADER descriptor subtype + protected final byte mSubclass; // from the mSubclass member of the + // "enclosing" Interface Descriptor + + public UsbACInterface(int length, byte type, byte subtype, byte subclass) { + super(length, type); + mSubtype = subtype; + mSubclass = subclass; + } + + public byte getSubtype() { + return mSubtype; + } + + public byte getSubclass() { + return mSubclass; + } + + private static UsbDescriptor allocAudioControlDescriptor(ByteStream stream, + int length, byte type, byte subtype, byte subClass) { + switch (subtype) { + case ACI_HEADER: + return new UsbACHeader(length, type, subtype, subClass); + + case ACI_INPUT_TERMINAL: + return new UsbACInputTerminal(length, type, subtype, subClass); + + case ACI_OUTPUT_TERMINAL: + return new UsbACOutputTerminal(length, type, subtype, subClass); + + case ACI_SELECTOR_UNIT: + return new UsbACSelectorUnit(length, type, subtype, subClass); + + case ACI_FEATURE_UNIT: + return new UsbACFeatureUnit(length, type, subtype, subClass); + + case ACI_MIXER_UNIT: + return new UsbACMixerUnit(length, type, subtype, subClass); + + case ACI_PROCESSING_UNIT: + case ACI_EXTENSION_UNIT: + case ACI_UNDEFINED: + // break; Fall through until we implement this descriptor + default: + Log.w(TAG, "Unknown Audio Class Interface subtype:0x" + + Integer.toHexString(subtype)); + return null; + } + } + + private static UsbDescriptor allocAudioStreamingDescriptor(ByteStream stream, + int length, byte type, byte subtype, byte subClass) { + switch (subtype) { + case ASI_GENERAL: + return new UsbASGeneral(length, type, subtype, subClass); + + case ASI_FORMAT_TYPE: + return UsbASFormat.allocDescriptor(stream, length, type, subtype, subClass); + + case ASI_FORMAT_SPECIFIC: + case ASI_UNDEFINED: + // break; Fall through until we implement this descriptor + default: + Log.w(TAG, "Unknown Audio Streaming Interface subtype:0x" + + Integer.toHexString(subtype)); + return null; + } + } + + private static UsbDescriptor allocMidiStreamingDescriptor(int length, byte type, + byte subtype, byte subClass) { + switch (subtype) { + case MSI_HEADER: + return new UsbMSMidiHeader(length, type, subtype, subClass); + + case MSI_IN_JACK: + return new UsbMSMidiInputJack(length, type, subtype, subClass); + + case MSI_OUT_JACK: + return new UsbMSMidiOutputJack(length, type, subtype, subClass); + + case MSI_ELEMENT: + // break; + // Fall through until we implement that descriptor + + case MSI_UNDEFINED: + // break; Fall through until we implement this descriptor + default: + Log.w(TAG, "Unknown MIDI Streaming Interface subtype:0x" + + Integer.toHexString(subtype)); + return null; + } + } + + /** + * Allocates an audio class interface subtype based on subtype and subclass. + */ + public static UsbDescriptor allocDescriptor(UsbDescriptorParser parser, ByteStream stream, + int length, byte type) { + byte subtype = stream.getByte(); + UsbInterfaceDescriptor interfaceDesc = parser.getCurInterface(); + byte subClass = interfaceDesc.getUsbSubclass(); + switch (subClass) { + case AUDIO_AUDIOCONTROL: + return allocAudioControlDescriptor(stream, length, type, subtype, subClass); + + case AUDIO_AUDIOSTREAMING: + return allocAudioStreamingDescriptor(stream, length, type, subtype, subClass); + + case AUDIO_MIDISTREAMING: + return allocMidiStreamingDescriptor(length, type, subtype, subClass); + + default: + Log.w(TAG, "Unknown Audio Class Interface Subclass: 0x" + + Integer.toHexString(subClass)); + return null; + } + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACMidiEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACMidiEndpoint.java new file mode 100644 index 000000000000..9c072426cc49 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbACMidiEndpoint.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific Midi Endpoint. + * see midi10.pdf section 6.2.2 + */ +public class UsbACMidiEndpoint extends UsbACEndpoint { + private static final String TAG = "ACMidiEndpoint"; + + private byte mNumJacks; + private byte[] mJackIds; + + public UsbACMidiEndpoint(int length, byte type, byte subclass) { + super(length, type, subclass); + } + + public byte getNumJacks() { + return mNumJacks; + } + + public byte[] getJackIds() { + return mJackIds; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + super.parseRawDescriptors(stream); + + mNumJacks = stream.getByte(); + mJackIds = new byte[mNumJacks]; + for (int jack = 0; jack < mNumJacks; jack++) { + mJackIds[jack] = stream.getByte(); + } + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACMixerUnit.java b/services/usb/java/com/android/server/usb/descriptors/UsbACMixerUnit.java new file mode 100644 index 000000000000..552b5ae308d6 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbACMixerUnit.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific Mixer Interface. + * see audio10.pdf section 4.3.2.3 + */ +public class UsbACMixerUnit extends UsbACInterface { + private static final String TAG = "ACMixerUnit"; + + private byte mUnitID; // 3:1 + private byte mNumInputs; // 4:1 Number of Input Pins of this Unit. + private byte[] mInputIDs; // 5...:1 ID of the Unit or Terminal to which the Input Pins + // are connected. + private byte mNumOutputs; // The number of output channels + private int mChannelConfig; // Spacial location of output channels + private byte mChanNameID; // First channel name string descriptor ID + private byte[] mControls; // bitmasks of which controls are present for each channel + private byte mNameID; // string descriptor ID of mixer name + + public UsbACMixerUnit(int length, byte type, byte subtype, byte subClass) { + super(length, type, subtype, subClass); + } + + public byte getUnitID() { + return mUnitID; + } + + public byte getNumInputs() { + return mNumInputs; + } + + public byte[] getInputIDs() { + return mInputIDs; + } + + public byte getNumOutputs() { + return mNumOutputs; + } + + public int getChannelConfig() { + return mChannelConfig; + } + + public byte getChanNameID() { + return mChanNameID; + } + + public byte[] getControls() { + return mControls; + } + + public byte getNameID() { + return mNameID; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + mUnitID = stream.getByte(); + mNumInputs = stream.getByte(); + mInputIDs = new byte[mNumInputs]; + for (int input = 0; input < mNumInputs; input++) { + mInputIDs[input] = stream.getByte(); + } + mNumOutputs = stream.getByte(); + mChannelConfig = stream.unpackUsbWord(); + mChanNameID = stream.getByte(); + + int controlArraySize; + int totalChannels = mNumInputs * mNumOutputs; + if (totalChannels % 8 == 0) { + controlArraySize = totalChannels / 8; + } else { + controlArraySize = totalChannels / 8 + 1; + } + mControls = new byte[controlArraySize]; + for (int index = 0; index < controlArraySize; index++) { + mControls[index] = stream.getByte(); + } + + mNameID = stream.getByte(); + + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACOutputTerminal.java b/services/usb/java/com/android/server/usb/descriptors/UsbACOutputTerminal.java new file mode 100644 index 000000000000..f957e3dbe217 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbACOutputTerminal.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific Output Terminal Interface. + * see audio10.pdf section 4.3.2.2 + */ +public class UsbACOutputTerminal extends UsbACTerminal { + private static final String TAG = "ACOutputTerminal"; + + private byte mSourceID; // 7:1 From Input Terminal. (0x01) + private byte mTerminal; // 8:1 Unused. + + public UsbACOutputTerminal(int length, byte type, byte subtype, byte subClass) { + super(length, type, subtype, subClass); + } + + public byte getSourceID() { + return mSourceID; + } + + public byte getTerminal() { + return mTerminal; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + super.parseRawDescriptors(stream); + + mSourceID = stream.getByte(); + mTerminal = stream.getByte(); + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACSelectorUnit.java b/services/usb/java/com/android/server/usb/descriptors/UsbACSelectorUnit.java new file mode 100644 index 000000000000..b1f60bdcf6ed --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbACSelectorUnit.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific Selector Unit Interface. + * see audio10.pdf section 4.3.2.4 + */ +public class UsbACSelectorUnit extends UsbACInterface { + private static final String TAG = "ACSelectorUnit"; + + private byte mUnitID; // 3:1 Constant uniquely identifying the Unit within the audio function. + // This value is used in all requests to address this Unit. + private byte mNumPins; // 4:1 Number of input pins in this unit + private byte[] mSourceIDs; // 5+mNumPins:1 ID of the Unit or Terminal to which the first + // Input Pin of this Selector Unit is connected. + private byte mNameIndex; // Index of a string descriptor, describing the Selector Unit. + + public UsbACSelectorUnit(int length, byte type, byte subtype, byte subClass) { + super(length, type, subtype, subClass); + } + + public byte getUnitID() { + return mUnitID; + } + + public byte getNumPins() { + return mNumPins; + } + + public byte[] getSourceIDs() { + return mSourceIDs; + } + + public byte getNameIndex() { + return mNameIndex; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + mUnitID = stream.getByte(); + mNumPins = stream.getByte(); + mSourceIDs = new byte[mNumPins]; + for (int index = 0; index < mNumPins; index++) { + mSourceIDs[index] = stream.getByte(); + } + mNameIndex = stream.getByte(); + + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java b/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java new file mode 100644 index 000000000000..ea80208ee3f3 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + */ +public abstract class UsbACTerminal extends UsbACInterface { + // Note that these fields are the same for both the + // audio class-specific Output Terminal Interface.(audio10.pdf section 4.3.2.2) + // and audio class-specific Input Terminal interface.(audio10.pdf section 4.3.2.1) + // so we may as well unify the parsing here. + protected byte mTerminalID; // 3:1 ID of this Output Terminal. (0x02) + protected int mTerminalType; // 4:2 USB Streaming. (0x0101) + protected byte mAssocTerminal; // 6:1 Unused (0x00) + + public UsbACTerminal(int length, byte type, byte subtype, byte subclass) { + super(length, type, subtype, subclass); + } + + public byte getTerminalID() { + return mTerminalID; + } + + public int getTerminalType() { + return mTerminalType; + } + + public byte getAssocTerminal() { + return mAssocTerminal; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + mTerminalID = stream.getByte(); + mTerminalType = stream.unpackUsbWord(); + mAssocTerminal = stream.getByte(); + + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASFormat.java b/services/usb/java/com/android/server/usb/descriptors/UsbASFormat.java new file mode 100644 index 000000000000..d7c84c6a0965 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbASFormat.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific Format Interface. + * Subclasses: UsbACFormatI and UsbACFormatII. + * see audio10.pdf section 4.5.3 & & Frmts10.pdf + */ +public abstract class UsbASFormat extends UsbACInterface { + private static final String TAG = "ASFormat"; + + private final byte mFormatType; // 3:1 FORMAT_TYPE_* + + public static final byte FORMAT_TYPE_I = 1; + public static final byte FORMAT_TYPE_II = 2; + + public UsbASFormat(int length, byte type, byte subtype, byte formatType, byte mSubclass) { + super(length, type, subtype, mSubclass); + mFormatType = formatType; + } + + public byte getFormatType() { + return mFormatType; + } + + /** + * Allocates the audio-class format subtype associated with the format type read from the + * stream. + */ + public static UsbDescriptor allocDescriptor(ByteStream stream, int length, byte type, + byte subtype, byte subclass) { + + byte formatType = stream.getByte(); + //TODO + // There is an issue parsing format descriptors on (some) USB 2.0 pro-audio interfaces + // Since we don't need this info for headset detection, just skip these descriptors + // for now to avoid the (low) possibility of an IndexOutOfBounds exception. + switch (formatType) { +// case FORMAT_TYPE_I: +// return new UsbASFormatI(length, type, subtype, formatType, subclass); +// +// case FORMAT_TYPE_II: +// return new UsbASFormatII(length, type, subtype, formatType, subclass); + + default: + return null; + } + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASFormatI.java b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatI.java new file mode 100644 index 000000000000..347a6cffb525 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatI.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific Format I interface. + * see Frmts10.pdf section 2.2 + */ +public class UsbASFormatI extends UsbASFormat { + private static final String TAG = "ASFormatI"; + + private byte mNumChannels; // 4:1 + private byte mSubframeSize; // 5:1 frame size in bytes + private byte mBitResolution; // 6:1 sample size in bits + private byte mSampleFreqType; // 7:1 + private int[] mSampleRates; // if mSamFreqType == 0, there will be 2 values: the + // min & max rates otherwise mSamFreqType rates. + // All 3-byte values. All rates in Hz + + public UsbASFormatI(int length, byte type, byte subtype, byte formatType, byte subclass) { + super(length, type, subtype, formatType, subclass); + } + + public byte getNumChannels() { + return mNumChannels; + } + + public byte getSubframeSize() { + return mSubframeSize; + } + + public byte getBitResolution() { + return mBitResolution; + } + + public byte getSampleFreqType() { + return mSampleFreqType; + } + + public int[] getSampleRates() { + return mSampleRates; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + mNumChannels = stream.getByte(); + mSubframeSize = stream.getByte(); + mBitResolution = stream.getByte(); + mSampleFreqType = stream.getByte(); + if (mSampleFreqType == 0) { + mSampleRates = new int[2]; + mSampleRates[0] = stream.unpackUsbTriple(); + mSampleRates[1] = stream.unpackUsbTriple(); + } else { + mSampleRates = new int[mSampleFreqType]; + for (int index = 0; index < mSampleFreqType; index++) { + mSampleRates[index] = stream.unpackUsbTriple(); + } + } + + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASFormatII.java b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatII.java new file mode 100644 index 000000000000..abdc62145aa2 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatII.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific Format II interface. + * see Frmts10.pdf section 2.3 + */ +public class UsbASFormatII extends UsbASFormat { + private static final String TAG = "ASFormatII"; + + private int mMaxBitRate; // 4:2 Indicates the maximum number of bits per second this + // interface can handle. Expressed in kbits/s. + private int mSamplesPerFrame; // 6:2 Indicates the number of PCM audio samples contained + // in one encoded audio frame. + private byte mSamFreqType; // Indicates how the sampling frequency can be programmed: + // 0: Continuous sampling frequency + // 1..255: The number of discrete sampling frequencies supported + // by the isochronous data endpoint of the AudioStreaming + // interface (ns) + private int[] mSampleRates; // if mSamFreqType == 0, there will be 2 values: + // the min & max rates. otherwise mSamFreqType rates. + // All 3-byte values. All rates in Hz + + public UsbASFormatII(int length, byte type, byte subtype, byte formatType, byte subclass) { + super(length, type, subtype, formatType, subclass); + } + + public int getMaxBitRate() { + return mMaxBitRate; + } + + public int getSamplesPerFrame() { + return mSamplesPerFrame; + } + + public byte getSamFreqType() { + return mSamFreqType; + } + + public int[] getSampleRates() { + return mSampleRates; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + mMaxBitRate = stream.unpackUsbWord(); + mSamplesPerFrame = stream.unpackUsbWord(); + mSamFreqType = stream.getByte(); + int numFreqs = mSamFreqType == 0 ? 2 : mSamFreqType; + mSampleRates = new int[numFreqs]; + for (int index = 0; index < numFreqs; index++) { + mSampleRates[index] = stream.unpackUsbTriple(); + } + + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASGeneral.java b/services/usb/java/com/android/server/usb/descriptors/UsbASGeneral.java new file mode 100644 index 000000000000..c4f42d318213 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbASGeneral.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific General interface. + * see audio10.pdf section 4.5.2 + */ +public class UsbASGeneral extends UsbACInterface { + private static final String TAG = "ACGeneral"; + + // audio10.pdf - section 4.5.2 + private byte mTerminalLink; // 3:1 The Terminal ID of the Terminal to which the endpoint + // of this interface is connected. + private byte mDelay; // 4:1 Delay introduced by the data path (see Section 3.4, + // “Inter Channel Synchronization”). Expressed in number of frames. + private int mFormatTag; // 5:2 The Audio Data Format that has to be used to communicate + // with this interface. + + public UsbASGeneral(int length, byte type, byte subtype, byte subclass) { + super(length, type, subtype, subclass); + } + + public byte getTerminalLink() { + return mTerminalLink; + } + + public byte getDelay() { + return mDelay; + } + + public int getFormatTag() { + return mFormatTag; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + mTerminalLink = stream.getByte(); + mDelay = stream.getByte(); + mFormatTag = stream.unpackUsbWord(); + + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbBinaryParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbBinaryParser.java new file mode 100644 index 000000000000..185cee20b090 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbBinaryParser.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +import android.hardware.usb.UsbDeviceConnection; +import android.util.Log; + +import com.android.server.usb.descriptors.report.UsbStrings; + +/** + * @hide + * A class that just walks the descriptors and does a hex dump of the contained values. + * Usefull as a debugging tool. + */ +public class UsbBinaryParser { + private static final String TAG = "UsbBinaryParser"; + private static final boolean LOGGING = false; + + private void dumpDescriptor(ByteStream stream, int length, byte type, StringBuilder builder) { + + // Log + if (LOGGING) { + Log.i(TAG, "l:" + length + " t:" + Integer.toHexString(type) + " " + + UsbStrings.getDescriptorName(type)); + StringBuilder sb = new StringBuilder(); + for (int index = 2; index < length; index++) { + sb.append("0x" + Integer.toHexString(stream.getByte() & 0xFF) + " "); + } + Log.i(TAG, sb.toString()); + } else { + // Screen Dump + builder.append("<p>"); + builder.append("<b> l:" + length + + " t:0x" + Integer.toHexString(type) + " " + + UsbStrings.getDescriptorName(type) + "</b><br>"); + for (int index = 2; index < length; index++) { + builder.append("0x" + Integer.toHexString(stream.getByte() & 0xFF) + " "); + } + builder.append("</p>"); + } + } + + /** + * Walk through descriptor stream and generate an HTML text report of the contents. + * TODO: This should be done in the model of UsbDescriptorsParser/Reporter model. + */ + public void parseDescriptors(UsbDeviceConnection connection, byte[] descriptors, + StringBuilder builder) { + + builder.append("<tt>"); + ByteStream stream = new ByteStream(descriptors); + while (stream.available() > 0) { + int length = (int) stream.getByte() & 0x000000FF; + byte type = stream.getByte(); + dumpDescriptor(stream, length, type, builder); + } + builder.append("</tt>"); + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java new file mode 100644 index 000000000000..8ae6d0f1ee7e --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An USB Config Descriptor. + * see usb11.pdf section 9.6.2 + */ +public class UsbConfigDescriptor extends UsbDescriptor { + private static final String TAG = "Config"; + + private int mTotalLength; // 2:2 Total length in bytes of data returned + private byte mNumInterfaces; // 4:1 Number of Interfaces + private byte mConfigValue; // 5:1 Value to use as an argument to select this configuration + private byte mConfigIndex; // 6:1 Index of String Descriptor describing this configuration + private byte mAttribs; // 7:1 D7 Reserved, set to 1. (USB 1.0 Bus Powered) + // D6 Self Powered + // D5 Remote Wakeup + // D4..0 Reserved, set to 0. + private byte mMaxPower; // 8:1 Maximum Power Consumption in 2mA units + + UsbConfigDescriptor(int length, byte type) { + super(length, type); + } + + public int getTotalLength() { + return mTotalLength; + } + + public byte getNumInterfaces() { + return mNumInterfaces; + } + + public byte getConfigValue() { + return mConfigValue; + } + + public byte getConfigIndex() { + return mConfigIndex; + } + + public byte getAttribs() { + return mAttribs; + } + + public byte getMaxPower() { + return mMaxPower; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + mTotalLength = stream.unpackUsbWord(); + mNumInterfaces = stream.getByte(); + mConfigValue = stream.getByte(); + mConfigIndex = stream.getByte(); + mAttribs = stream.getByte(); + mMaxPower = stream.getByte(); + + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java new file mode 100644 index 000000000000..63b2d7f6aed7 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +import android.hardware.usb.UsbConstants; +import android.hardware.usb.UsbDeviceConnection; +import android.util.Log; + +/* + * Some notes about UsbDescriptor and its subclasses. + * + * It is assumed that the user of the UsbDescriptorParser knows what they are doing + * so NO PROTECTION is implemented against "improper" use. Such uses are specifically: + * allocating a UsbDescriptor (subclass) object outside of the context of parsing/reading + * a rawdescriptor stream and perhaps accessing fields which have not been inialized (by + * parsing/reading or course). + */ + +/** + * @hide + * Common superclass for all USB Descriptors. + */ +public abstract class UsbDescriptor { + private static final String TAG = "Descriptor"; + + protected final int mLength; // 0:1 bLength Number Size of the Descriptor in Bytes (18 bytes) + // we store this as an int because Java bytes are SIGNED. + protected final byte mType; // 1:1 bDescriptorType Constant Device Descriptor (0x01) + + private byte[] mRawData; + + private static final int SIZE_STRINGBUFFER = 256; + private static byte[] sStringBuffer = new byte[SIZE_STRINGBUFFER]; + + // Status + public static final int STATUS_UNPARSED = 0; + public static final int STATUS_PARSED_OK = 1; + public static final int STATUS_PARSED_UNDERRUN = 2; + public static final int STATUS_PARSED_OVERRUN = 3; + private int mStatus = STATUS_UNPARSED; + + private static String[] sStatusStrings = { + "UNPARSED", "PARSED - OK", "PARSED - UNDERRUN", "PARSED - OVERRUN"}; + + // Descriptor Type IDs + public static final byte DESCRIPTORTYPE_DEVICE = 0x01; // 1 + public static final byte DESCRIPTORTYPE_CONFIG = 0x02; // 2 + public static final byte DESCRIPTORTYPE_STRING = 0x03; // 3 + public static final byte DESCRIPTORTYPE_INTERFACE = 0x04; // 4 + public static final byte DESCRIPTORTYPE_ENDPOINT = 0x05; // 5 + public static final byte DESCRIPTORTYPE_INTERFACEASSOC = 0x0B; // 11 + public static final byte DESCRIPTORTYPE_BOS = 0x0F; // 15 + public static final byte DESCRIPTORTYPE_CAPABILITY = 0x10; // 16 + + public static final byte DESCRIPTORTYPE_HID = 0x21; // 33 + public static final byte DESCRIPTORTYPE_REPORT = 0x22; // 34 + public static final byte DESCRIPTORTYPE_PHYSICAL = 0x23; // 35 + public static final byte DESCRIPTORTYPE_AUDIO_INTERFACE = 0x24; // 36 + public static final byte DESCRIPTORTYPE_AUDIO_ENDPOINT = 0x25; // 37 + public static final byte DESCRIPTORTYPE_HUB = 0x29; // 41 + public static final byte DESCRIPTORTYPE_SUPERSPEED_HUB = 0x2A; // 42 + public static final byte DESCRIPTORTYPE_ENDPOINT_COMPANION = 0x30; // 48 + + // Class IDs + public static final byte CLASSID_DEVICE = 0x00; + public static final byte CLASSID_AUDIO = 0x01; + public static final byte CLASSID_COM = 0x02; + public static final byte CLASSID_HID = 0x03; + // public static final byte CLASSID_??? = 0x04; + public static final byte CLASSID_PHYSICAL = 0x05; + public static final byte CLASSID_IMAGE = 0x06; + public static final byte CLASSID_PRINTER = 0x07; + public static final byte CLASSID_STORAGE = 0x08; + public static final byte CLASSID_HUB = 0x09; + public static final byte CLASSID_CDC_CONTROL = 0x0A; + public static final byte CLASSID_SMART_CARD = 0x0B; + //public static final byte CLASSID_??? = 0x0C; + public static final byte CLASSID_SECURITY = 0x0D; + public static final byte CLASSID_VIDEO = 0x0E; + public static final byte CLASSID_HEALTHCARE = 0x0F; + public static final byte CLASSID_AUDIOVIDEO = 0x10; + public static final byte CLASSID_BILLBOARD = 0x11; + public static final byte CLASSID_TYPECBRIDGE = 0x12; + public static final byte CLASSID_DIAGNOSTIC = (byte) 0xDC; + public static final byte CLASSID_WIRELESS = (byte) 0xE0; + public static final byte CLASSID_MISC = (byte) 0xEF; + public static final byte CLASSID_APPSPECIFIC = (byte) 0xFE; + public static final byte CLASSID_VENDSPECIFIC = (byte) 0xFF; + + // Audio Subclass codes + public static final byte AUDIO_SUBCLASS_UNDEFINED = 0x00; + public static final byte AUDIO_AUDIOCONTROL = 0x01; + public static final byte AUDIO_AUDIOSTREAMING = 0x02; + public static final byte AUDIO_MIDISTREAMING = 0x03; + + // Request IDs + public static final int REQUEST_GET_STATUS = 0x00; + public static final int REQUEST_CLEAR_FEATURE = 0x01; + public static final int REQUEST_SET_FEATURE = 0x03; + public static final int REQUEST_GET_ADDRESS = 0x05; + public static final int REQUEST_GET_DESCRIPTOR = 0x06; + public static final int REQUEST_SET_DESCRIPTOR = 0x07; + public static final int REQUEST_GET_CONFIGURATION = 0x08; + public static final int REQUEST_SET_CONFIGURATION = 0x09; + + /** + * @throws IllegalArgumentException + */ + UsbDescriptor(int length, byte type) { + // a descriptor has at least a length byte and type byte + // one could imagine an empty one otherwise + if (length < 2) { + // huh? + throw new IllegalArgumentException(); + } + + mLength = length; + mType = type; + } + + public int getLength() { + return mLength; + } + + public byte getType() { + return mType; + } + + public int getStatus() { + return mStatus; + } + + public void setStatus(int status) { + mStatus = status; + } + + public String getStatusString() { + return sStatusStrings[mStatus]; + } + + public byte[] getRawData() { + return mRawData; + } + + /** + * Called by the parser for any necessary cleanup. + */ + public void postParse(ByteStream stream) { + // Status + int bytesRead = stream.getReadCount(); + if (bytesRead < mLength) { + // Too cold... + stream.advance(mLength - bytesRead); + mStatus = STATUS_PARSED_UNDERRUN; + Log.w(TAG, "UNDERRUN t:0x" + Integer.toHexString(mType) + + " r:" + bytesRead + " < l:" + mLength); + } else if (bytesRead > mLength) { + // Too hot... + stream.reverse(bytesRead - mLength); + mStatus = STATUS_PARSED_OVERRUN; + Log.w(TAG, "OVERRRUN t:0x" + Integer.toHexString(mType) + + " r:" + bytesRead + " > l:" + mLength); + } else { + // Just right! + mStatus = STATUS_PARSED_OK; + } + } + + /** + * Reads data fields from specified raw-data stream. + */ + public int parseRawDescriptors(ByteStream stream) { + int numRead = stream.getReadCount(); + int dataLen = mLength - numRead; + if (dataLen > 0) { + mRawData = new byte[dataLen]; + for (int index = 0; index < dataLen; index++) { + mRawData[index] = stream.getByte(); + } + } + return mLength; + } + + /** + * Gets a string for the specified index from the USB Device's string descriptors. + */ + public static String getUsbDescriptorString(UsbDeviceConnection connection, byte strIndex) { + String usbStr = ""; + if (strIndex != 0) { + try { + int rdo = connection.controlTransfer( + UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_STANDARD, + REQUEST_GET_DESCRIPTOR, + (DESCRIPTORTYPE_STRING << 8) | strIndex, + 0, + sStringBuffer, + 0xFF, + 0); + if (rdo >= 0) { + usbStr = new String(sStringBuffer, 2, rdo - 2, "UTF-16LE"); + } else { + usbStr = "?"; + } + } catch (Exception e) { + Log.e(TAG, "Can not communicate with USB device", e); + } + } + return usbStr; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java new file mode 100644 index 000000000000..7c074dadadf9 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +import android.util.Log; + +import java.util.ArrayList; + +/** + * @hide + * Class for parsing a binary stream of USB Descriptors. + */ +public class UsbDescriptorParser { + private static final String TAG = "DescriptorParser"; + + // Descriptor Objects + private ArrayList<UsbDescriptor> mDescriptors = new ArrayList<UsbDescriptor>(); + + private UsbDeviceDescriptor mDeviceDescriptor; + private UsbInterfaceDescriptor mCurInterfaceDescriptor; + + public UsbDescriptorParser() {} + + /** + * The probability (as returned by getHeadsetProbability() at which we conclude + * the peripheral is a headset. + */ + private static final float IN_HEADSET_TRIGGER = 0.75f; + private static final float OUT_HEADSET_TRIGGER = 0.75f; + + private UsbDescriptor allocDescriptor(ByteStream stream) { + stream.resetReadCount(); + + int length = (int) stream.getByte() & 0x000000FF; + byte type = stream.getByte(); + + UsbDescriptor descriptor = null; + switch (type) { + /* + * Standard + */ + case UsbDescriptor.DESCRIPTORTYPE_DEVICE: + descriptor = mDeviceDescriptor = new UsbDeviceDescriptor(length, type); + break; + + case UsbDescriptor.DESCRIPTORTYPE_CONFIG: + descriptor = new UsbConfigDescriptor(length, type); + break; + + case UsbDescriptor.DESCRIPTORTYPE_INTERFACE: + descriptor = mCurInterfaceDescriptor = new UsbInterfaceDescriptor(length, type); + break; + + case UsbDescriptor.DESCRIPTORTYPE_ENDPOINT: + descriptor = new UsbEndpointDescriptor(length, type); + break; + + /* + * HID + */ + case UsbDescriptor.DESCRIPTORTYPE_HID: + descriptor = new UsbHIDDescriptor(length, type); + break; + + /* + * Other + */ + case UsbDescriptor.DESCRIPTORTYPE_INTERFACEASSOC: + descriptor = new UsbInterfaceAssoc(length, type); + break; + + /* + * Audio Class Specific + */ + case UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE: + descriptor = UsbACInterface.allocDescriptor(this, stream, length, type); + break; + + case UsbDescriptor.DESCRIPTORTYPE_AUDIO_ENDPOINT: + descriptor = UsbACEndpoint.allocDescriptor(this, length, type); + break; + + default: + break; + } + + if (descriptor == null) { + // Unknown Descriptor + Log.i(TAG, "Unknown Descriptor len:" + length + " type:0x" + + Integer.toHexString(type)); + descriptor = new UsbUnknown(length, type); + } + + return descriptor; + } + + public UsbDeviceDescriptor getDeviceDescriptor() { + return mDeviceDescriptor; + } + + public UsbInterfaceDescriptor getCurInterface() { + return mCurInterfaceDescriptor; + } + + /** + * @hide + */ + public boolean parseDescriptors(byte[] descriptors) { + try { + mDescriptors.clear(); + + ByteStream stream = new ByteStream(descriptors); + while (stream.available() > 0) { + UsbDescriptor descriptor = allocDescriptor(stream); + if (descriptor != null) { + // Parse + descriptor.parseRawDescriptors(stream); + mDescriptors.add(descriptor); + + // Clean up + descriptor.postParse(stream); + } + } + return true; + } catch (Exception ex) { + Log.e(TAG, "Exception parsing USB descriptors.", ex); + } + return false; + } + + /** + * @hide + */ + public boolean parseDevice(String deviceAddr) { + byte[] rawDescriptors = getRawDescriptors(deviceAddr); + return rawDescriptors != null && parseDescriptors(rawDescriptors); + } + + private native byte[] getRawDescriptors(String deviceAddr); + + public int getParsingSpec() { + return mDeviceDescriptor != null ? mDeviceDescriptor.getSpec() : 0; + } + + public ArrayList<UsbDescriptor> getDescriptors() { + return mDescriptors; + } + + /** + * @hide + */ + public ArrayList<UsbDescriptor> getDescriptors(byte type) { + ArrayList<UsbDescriptor> list = new ArrayList<UsbDescriptor>(); + for (UsbDescriptor descriptor : mDescriptors) { + if (descriptor.getType() == type) { + list.add(descriptor); + } + } + return list; + } + + /** + * @hide + */ + public ArrayList<UsbDescriptor> getInterfaceDescriptorsForClass(byte usbClass) { + ArrayList<UsbDescriptor> list = new ArrayList<UsbDescriptor>(); + for (UsbDescriptor descriptor : mDescriptors) { + // ensure that this isn't an unrecognized DESCRIPTORTYPE_INTERFACE + if (descriptor.getType() == UsbDescriptor.DESCRIPTORTYPE_INTERFACE) { + if (descriptor instanceof UsbInterfaceDescriptor) { + UsbInterfaceDescriptor intrDesc = (UsbInterfaceDescriptor) descriptor; + if (intrDesc.getUsbClass() == usbClass) { + list.add(descriptor); + } + } else { + Log.w(TAG, "Unrecognized Interface l:" + descriptor.getLength() + + " t:0x" + Integer.toHexString(descriptor.getType())); + } + } + } + return list; + } + + /** + * @hide + */ + public ArrayList<UsbDescriptor> getACInterfaceDescriptors(byte subtype, byte subclass) { + ArrayList<UsbDescriptor> list = new ArrayList<UsbDescriptor>(); + for (UsbDescriptor descriptor : mDescriptors) { + if (descriptor.getType() == UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE) { + // ensure that this isn't an unrecognized DESCRIPTORTYPE_AUDIO_INTERFACE + if (descriptor instanceof UsbACInterface) { + UsbACInterface acDescriptor = (UsbACInterface) descriptor; + if (acDescriptor.getSubtype() == subtype + && acDescriptor.getSubclass() == subclass) { + list.add(descriptor); + } + } else { + Log.w(TAG, "Unrecognized Audio Interface l:" + descriptor.getLength() + + " t:0x" + Integer.toHexString(descriptor.getType())); + } + } + } + return list; + } + + /** + * @hide + */ + public boolean hasHIDDescriptor() { + ArrayList<UsbDescriptor> descriptors = + getInterfaceDescriptorsForClass(UsbDescriptor.CLASSID_HID); + return !descriptors.isEmpty(); + } + + /** + * @hide + */ + public boolean hasMIDIInterface() { + ArrayList<UsbDescriptor> descriptors = + getInterfaceDescriptorsForClass(UsbDescriptor.CLASSID_AUDIO); + for (UsbDescriptor descriptor : descriptors) { + // enusure that this isn't an unrecognized interface descriptor + if (descriptor instanceof UsbInterfaceDescriptor) { + UsbInterfaceDescriptor interfaceDescr = (UsbInterfaceDescriptor) descriptor; + if (interfaceDescr.getUsbSubclass() == UsbDescriptor.AUDIO_MIDISTREAMING) { + return true; + } + } else { + Log.w(TAG, "Undefined Audio Class Interface l:" + descriptor.getLength() + + " t:0x" + Integer.toHexString(descriptor.getType())); + } + } + return false; + } + + /** + * @hide + */ + public float getInputHeadsetProbability() { + if (hasMIDIInterface()) { + return 0.0f; + } + + float probability = 0.0f; + ArrayList<UsbDescriptor> acDescriptors; + + // Look for a microphone + boolean hasMic = false; + acDescriptors = getACInterfaceDescriptors(UsbACInterface.ACI_INPUT_TERMINAL, + UsbACInterface.AUDIO_AUDIOCONTROL); + for (UsbDescriptor descriptor : acDescriptors) { + if (descriptor instanceof UsbACInputTerminal) { + UsbACInputTerminal inDescr = (UsbACInputTerminal) descriptor; + if (inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_IN_MIC + || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET + || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_UNDEFINED + || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_EXTERN_LINE) { + hasMic = true; + break; + } + } else { + Log.w(TAG, "Undefined Audio Input terminal l:" + descriptor.getLength() + + " t:0x" + Integer.toHexString(descriptor.getType())); + } + } + + // Look for a "speaker" + boolean hasSpeaker = false; + acDescriptors = + getACInterfaceDescriptors(UsbACInterface.ACI_OUTPUT_TERMINAL, + UsbACInterface.AUDIO_AUDIOCONTROL); + for (UsbDescriptor descriptor : acDescriptors) { + if (descriptor instanceof UsbACOutputTerminal) { + UsbACOutputTerminal outDescr = (UsbACOutputTerminal) descriptor; + if (outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_OUT_SPEAKER + || outDescr.getTerminalType() + == UsbTerminalTypes.TERMINAL_OUT_HEADPHONES + || outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET) { + hasSpeaker = true; + break; + } + } else { + Log.w(TAG, "Undefined Audio Output terminal l:" + descriptor.getLength() + + " t:0x" + Integer.toHexString(descriptor.getType())); + } + } + + if (hasMic && hasSpeaker) { + probability += 0.75f; + } + + if (hasMic && hasHIDDescriptor()) { + probability += 0.25f; + } + + return probability; + } + + /** + * getInputHeadsetProbability() reports a probability of a USB Input peripheral being a + * headset. The probability range is between 0.0f (definitely NOT a headset) and + * 1.0f (definitely IS a headset). A probability of 0.75f seems sufficient + * to count on the peripheral being a headset. + */ + public boolean isInputHeadset() { + return getInputHeadsetProbability() >= IN_HEADSET_TRIGGER; + } + + /** + * @hide + */ + public float getOutputHeadsetProbability() { + if (hasMIDIInterface()) { + return 0.0f; + } + + float probability = 0.0f; + ArrayList<UsbDescriptor> acDescriptors; + + // Look for a "speaker" + boolean hasSpeaker = false; + acDescriptors = + getACInterfaceDescriptors(UsbACInterface.ACI_OUTPUT_TERMINAL, + UsbACInterface.AUDIO_AUDIOCONTROL); + for (UsbDescriptor descriptor : acDescriptors) { + if (descriptor instanceof UsbACOutputTerminal) { + UsbACOutputTerminal outDescr = (UsbACOutputTerminal) descriptor; + if (outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_OUT_SPEAKER + || outDescr.getTerminalType() + == UsbTerminalTypes.TERMINAL_OUT_HEADPHONES + || outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET) { + hasSpeaker = true; + break; + } + } else { + Log.w(TAG, "Undefined Audio Output terminal l:" + descriptor.getLength() + + " t:0x" + Integer.toHexString(descriptor.getType())); + } + } + + if (hasSpeaker) { + probability += 0.75f; + } + + if (hasSpeaker && hasHIDDescriptor()) { + probability += 0.25f; + } + + return probability; + } + + /** + * getOutputHeadsetProbability() reports a probability of a USB Output peripheral being a + * headset. The probability range is between 0.0f (definitely NOT a headset) and + * 1.0f (definitely IS a headset). A probability of 0.75f seems sufficient + * to count on the peripheral being a headset. + */ + public boolean isOutputHeadset() { + return getOutputHeadsetProbability() >= OUT_HEADSET_TRIGGER; + } + +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java new file mode 100644 index 000000000000..90848caba852 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * A USB Device Descriptor. + * see usb11.pdf section 9.6.1 + */ +/* public */ public class UsbDeviceDescriptor extends UsbDescriptor { + private static final String TAG = "Device"; + + private int mSpec; // 2:2 bcdUSB 2 BCD USB Specification Number - BCD + private byte mDevClass; // 4:1 class code + private byte mDevSubClass; // 5:1 subclass code + private byte mProtocol; // 6:1 protocol + private byte mPacketSize; // 7:1 Maximum Packet Size for Zero Endpoint. + // Valid Sizes are 8, 16, 32, 64 + private int mVendorID; // 8:2 vendor ID + private int mProductID; // 10:2 product ID + private int mDeviceRelease; // 12:2 Device Release number - BCD + private byte mMfgIndex; // 14:1 Index of Manufacturer String Descriptor + private byte mProductIndex; // 15:1 Index of Product String Descriptor + private byte mSerialNum; // 16:1 Index of Serial Number String Descriptor + private byte mNumConfigs; // 17:1 Number of Possible Configurations + + UsbDeviceDescriptor(int length, byte type) { + super(length, type); + } + + public int getSpec() { + return mSpec; + } + + public byte getDevClass() { + return mDevClass; + } + + public byte getDevSubClass() { + return mDevSubClass; + } + + public byte getProtocol() { + return mProtocol; + } + + public byte getPacketSize() { + return mPacketSize; + } + + public int getVendorID() { + return mVendorID; + } + + public int getProductID() { + return mProductID; + } + + public int getDeviceRelease() { + return mDeviceRelease; + } + + public byte getMfgIndex() { + return mMfgIndex; + } + + public byte getProductIndex() { + return mProductIndex; + } + + public byte getSerialNum() { + return mSerialNum; + } + + public byte getNumConfigs() { + return mNumConfigs; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + mSpec = stream.unpackUsbWord(); + mDevClass = stream.getByte(); + mDevSubClass = stream.getByte(); + mProtocol = stream.getByte(); + mPacketSize = stream.getByte(); + mVendorID = stream.unpackUsbWord(); + mProductID = stream.unpackUsbWord(); + mDeviceRelease = stream.unpackUsbWord(); + mMfgIndex = stream.getByte(); + mProductIndex = stream.getByte(); + mSerialNum = stream.getByte(); + mNumConfigs = stream.getByte(); + + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java new file mode 100644 index 000000000000..def670093e6e --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * A Usb Endpoint Descriptor. + * see usb11.pdf section 9.6.4 + */ +public class UsbEndpointDescriptor extends UsbDescriptor { + private static final String TAG = "EndPoint"; + + public static final byte MASK_ENDPOINT_ADDRESS = 0b0001111; + public static final byte MASK_ENDPOINT_DIRECTION = (byte) 0b10000000; + public static final byte DIRECTION_OUTPUT = 0x00; + public static final byte DIRECTION_INPUT = (byte) 0x80; + + public static final byte MASK_ATTRIBS_TRANSTYPE = 0b00000011; + public static final byte TRANSTYPE_CONTROL = 0x00; + public static final byte TRANSTYPE_ISO = 0x01; + public static final byte TRANSTYPE_BULK = 0x02; + public static final byte TRANSTYPE_INTERRUPT = 0x03; + + public static final byte MASK_ATTRIBS_SYNCTYPE = 0b00001100; + public static final byte SYNCTYPE_NONE = 0b00000000; + public static final byte SYNCTYPE_ASYNC = 0b00000100; + public static final byte SYNCTYPE_ADAPTSYNC = 0b00001000; + public static final byte SYNCTYPE_RESERVED = 0b00001100; + + public static final byte MASK_ATTRIBS_USEAGE = 0b00110000; + public static final byte USEAGE_DATA = 0b00000000; + public static final byte USEAGE_FEEDBACK = 0b00010000; + public static final byte USEAGE_EXPLICIT = 0b00100000; + public static final byte USEAGE_RESERVED = 0b00110000; + + private byte mEndpointAddress; // 2:1 Endpoint Address + // Bits 0..3b Endpoint Number. + // Bits 4..6b Reserved. Set to Zero + // Bits 7 Direction 0 = Out, 1 = In + // (Ignored for Control Endpoints) + private byte mAttributes; // 3:1 Various flags + // Bits 0..1 Transfer Type: + // 00 = Control, 01 = Isochronous, 10 = Bulk, 11 = Interrupt + // Bits 2..7 are reserved. If Isochronous endpoint, + // Bits 3..2 = Synchronisation Type (Iso Mode) + // 00 = No Synchonisation + // 01 = Asynchronous + // 10 = Adaptive + // 11 = Synchronous + // Bits 5..4 = Usage Type (Iso Mode) + // 00: Data Endpoint + // 01:Feedback Endpoint 10 + // Explicit Feedback Data Endpoint + // 11: Reserved + private int mPacketSize; // 4:2 Maximum Packet Size this endpoint is capable of + // sending or receiving + private byte mInterval; // 6:1 Interval for polling endpoint data transfers. Value in + // frame counts. + // Ignored for Bulk & Control Endpoints. Isochronous must equal + // 1 and field may range from 1 to 255 for interrupt endpoints. + private byte mRefresh; + private byte mSyncAddress; + + public UsbEndpointDescriptor(int length, byte type) { + super(length, type); + } + + public byte getEndpointAddress() { + return mEndpointAddress; + } + + public byte getAttributes() { + return mAttributes; + } + + public int getPacketSize() { + return mPacketSize; + } + + public byte getInterval() { + return mInterval; + } + + public byte getRefresh() { + return mRefresh; + } + + public byte getSyncAddress() { + return mSyncAddress; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + mEndpointAddress = stream.getByte(); + mAttributes = stream.getByte(); + mPacketSize = stream.unpackUsbWord(); + mInterval = stream.getByte(); + if (mLength == 9) { + mRefresh = stream.getByte(); + mSyncAddress = stream.getByte(); + } + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbHIDDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbHIDDescriptor.java new file mode 100644 index 000000000000..56c07ec9a071 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbHIDDescriptor.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * A USB HID (Human Interface Descriptor). + * see HID1_11.pdf - 6.2.1 + */ +public class UsbHIDDescriptor extends UsbDescriptor { + private static final String TAG = "HID"; + + private int mRelease; // 2:2 the HID Class Specification release. + private byte mCountryCode; // 4:1 country code of the localized hardware. + private byte mNumDescriptors; // number of descriptors (always at least one + // i.e. Report descriptor.) + private byte mDescriptorType; // 6:1 type of class descriptor. + // See Section 7.1.2: Set_Descriptor + // Request for a table of class descriptor constants. + private int mDescriptorLen; // 7:2 Numeric expression that is the total size of + // the Report descriptor. + + public UsbHIDDescriptor(int length, byte type) { + super(length, type); + } + + public int getRelease() { + return mRelease; + } + + public byte getCountryCode() { + return mCountryCode; + } + + public byte getNumDescriptors() { + return mNumDescriptors; + } + + public byte getDescriptorType() { + return mDescriptorType; + } + + public int getDescriptorLen() { + return mDescriptorLen; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + mRelease = stream.unpackUsbWord(); + mCountryCode = stream.getByte(); + mNumDescriptors = stream.getByte(); + mDescriptorType = stream.getByte(); + mDescriptorLen = stream.unpackUsbWord(); + + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceAssoc.java b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceAssoc.java new file mode 100644 index 000000000000..4b18a01b1c8b --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceAssoc.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * A USB Interface Association Descriptor. + * found this one here: http://www.usb.org/developers/docs/whitepapers/iadclasscode_r10.pdf + * also: https://msdn.microsoft.com/en-us/library/windows/hardware/ff540054(v=vs.85).aspx + */ +public class UsbInterfaceAssoc extends UsbDescriptor { + private static final String TAG = "InterfaceAssoc"; + + private byte mFirstInterface; + private byte mInterfaceCount; + private byte mFunctionClass; + private byte mFunctionSubClass; + private byte mFunctionProtocol; + private byte mFunction; + + public UsbInterfaceAssoc(int length, byte type) { + super(length, type); + } + + public byte getFirstInterface() { + return mFirstInterface; + } + + public byte getInterfaceCount() { + return mInterfaceCount; + } + + public byte getFunctionClass() { + return mFunctionClass; + } + + public byte getFunctionSubClass() { + return mFunctionSubClass; + } + + public byte getFunctionProtocol() { + return mFunctionProtocol; + } + + public byte getFunction() { + return mFunction; + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + mFirstInterface = stream.getByte(); + mInterfaceCount = stream.getByte(); + mFunctionClass = stream.getByte(); + mFunctionSubClass = stream.getByte(); + mFunctionProtocol = stream.getByte(); + mFunction = stream.getByte(); + + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java new file mode 100644 index 000000000000..21b5e0cbaa1b --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * A common super-class for all USB Interface Descritor subtypes. + * see usb11.pdf section 9.6.3 + */ +public class UsbInterfaceDescriptor extends UsbDescriptor { + private static final String TAG = "Interface"; + + protected byte mInterfaceNumber; // 2:1 Number of Interface + protected byte mAlternateSetting; // 3:1 Value used to select alternative setting + protected byte mNumEndpoints; // 4:1 Number of Endpoints used for this interface + protected byte mUsbClass; // 5:1 Class Code + protected byte mUsbSubclass; // 6:1 Subclass Code + protected byte mProtocol; // 7:1 Protocol Code + protected byte mDescrIndex; // 8:1 Index of String Descriptor Describing this interface + + UsbInterfaceDescriptor(int length, byte type) { + super(length, type); + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + mInterfaceNumber = stream.getByte(); + mAlternateSetting = stream.getByte(); + mNumEndpoints = stream.getByte(); + mUsbClass = stream.getByte(); + mUsbSubclass = stream.getByte(); + mProtocol = stream.getByte(); + mDescrIndex = stream.getByte(); + + return mLength; + } + + public byte getInterfaceNumber() { + return mInterfaceNumber; + } + + public byte getAlternateSetting() { + return mAlternateSetting; + } + + public byte getNumEndpoints() { + return mNumEndpoints; + } + + public byte getUsbClass() { + return mUsbClass; + } + + public byte getUsbSubclass() { + return mUsbSubclass; + } + + public byte getProtocol() { + return mProtocol; + } + + public byte getDescrIndex() { + return mDescrIndex; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiHeader.java b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiHeader.java new file mode 100644 index 000000000000..4452b23cb6ae --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiHeader.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific Midi Streaming Interface. + * see midi10.pdf section 6.1.2.1 + */ +public class UsbMSMidiHeader extends UsbACInterface { + private static final String TAG = "MSMidiHeader"; + + public UsbMSMidiHeader(int length, byte type, byte subtype, byte subclass) { + super(length, type, subtype, subclass); + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + // TODO - read data memebers + stream.advance(mLength - stream.getReadCount()); + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiInputJack.java b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiInputJack.java new file mode 100644 index 000000000000..2d33ba7727dd --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiInputJack.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific Midi Input Jack Interface. + * see midi10.pdf section B.4.3 + */ +public class UsbMSMidiInputJack extends UsbACInterface { + private static final String TAG = "MSMidiInputJack"; + + UsbMSMidiInputJack(int length, byte type, byte subtype, byte subclass) { + super(length, type, subtype, subclass); + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + // TODO - read data memebers + stream.advance(mLength - stream.getReadCount()); + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiOutputJack.java b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiOutputJack.java new file mode 100644 index 000000000000..bd2dc11d57df --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiOutputJack.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * An audio class-specific Midi Output Jack Interface. + * see midi10.pdf section B.4.4 + */ +public class UsbMSMidiOutputJack extends UsbACInterface { + private static final String TAG = "MSMidiOutputJack"; + + public UsbMSMidiOutputJack(int length, byte type, byte subtype, byte subclass) { + super(length, type, subtype, subclass); + } + + @Override + public int parseRawDescriptors(ByteStream stream) { + // TODO - read data memebers + stream.advance(mLength - stream.getReadCount()); + return mLength; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java b/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java new file mode 100644 index 000000000000..b5214625126a --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * A class for decoding information in Terminal Descriptors. + * see termt10.pdf + */ +public class UsbTerminalTypes { + private static final String TAG = "TerminalTypes"; + + // USB + public static final int TERMINAL_USB_STREAMING = 0x0101; + + // Inputs + public static final int TERMINAL_IN_UNDEFINED = 0x0200; + public static final int TERMINAL_IN_MIC = 0x0201; + public static final int TERMINAL_IN_DESKTOP_MIC = 0x0202; + public static final int TERMINAL_IN_PERSONAL_MIC = 0x0203; + public static final int TERMINAL_IN_OMNI_MIC = 0x0204; + public static final int TERMINAL_IN_MIC_ARRAY = 0x0205; + public static final int TERMINAL_IN_PROC_MIC_ARRAY = 0x0206; + + // Outputs + public static final int TERMINAL_OUT_UNDEFINED = 0x0300; + public static final int TERMINAL_OUT_SPEAKER = 0x0301; + public static final int TERMINAL_OUT_HEADPHONES = 0x0302; + public static final int TERMINAL_OUT_HEADMOUNTED = 0x0303; + public static final int TERMINAL_OUT_DESKTOPSPEAKER = 0x0304; + public static final int TERMINAL_OUT_ROOMSPEAKER = 0x0305; + public static final int TERMINAL_OUT_COMSPEAKER = 0x0306; + public static final int TERMINAL_OUT_LFSPEAKER = 0x0307; + + // Bi-directional + public static final int TERMINAL_BIDIR_UNDEFINED = 0x0400; + public static final int TERMINAL_BIDIR_HANDSET = 0x0401; + public static final int TERMINAL_BIDIR_HEADSET = 0x0402; + public static final int TERMINAL_BIDIR_SKRPHONE = 0x0403; + public static final int TERMINAL_BIDIR_SKRPHONE_SUPRESS = 0x0404; + public static final int TERMINAL_BIDIR_SKRPHONE_CANCEL = 0x0405; + + // Telephony + public static final int TERMINAL_TELE_UNDEFINED = 0x0500; + public static final int TERMINAL_TELE_PHONELINE = 0x0501; + public static final int TERMINAL_TELE_PHONE = 0x0502; + public static final int TERMINAL_TELE_DOWNLINEPHONE = 0x0503; + + // External + public static final int TERMINAL_EXTERN_UNDEFINED = 0x0600; + public static final int TERMINAL_EXTERN_ANALOG = 0x0601; + public static final int TERMINAL_EXTERN_DIGITAL = 0x0602; + public static final int TERMINAL_EXTERN_LINE = 0x0603; + public static final int TERMINAL_EXTERN_LEGACY = 0x0604; + public static final int TERMINAL_EXTERN_SPIDF = 0x0605; + public static final int TERMINAL_EXTERN_1394DA = 0x0606; + public static final int TERMINAL_EXTERN_1394DV = 0x0607; + + public static final int TERMINAL_EMBED_UNDEFINED = 0x0700; + public static final int TERMINAL_EMBED_CALNOISE = 0x0701; + public static final int TERMINAL_EMBED_EQNOISE = 0x0702; + public static final int TERMINAL_EMBED_CDPLAYER = 0x0703; + public static final int TERMINAL_EMBED_DAT = 0x0704; + public static final int TERMINAL_EMBED_DCC = 0x0705; + public static final int TERMINAL_EMBED_MINIDISK = 0x0706; + public static final int TERMINAL_EMBED_ANALOGTAPE = 0x0707; + public static final int TERMINAL_EMBED_PHONOGRAPH = 0x0708; + public static final int TERMINAL_EMBED_VCRAUDIO = 0x0709; + public static final int TERMINAL_EMBED_VIDDISKAUDIO = 0x070A; + public static final int TERMINAL_EMBED_DVDAUDIO = 0x070B; + public static final int TERMINAL_EMBED_TVAUDIO = 0x070C; + public static final int TERMINAL_EMBED_SATELLITEAUDIO = 0x070D; + public static final int TERMINAL_EMBED_CABLEAUDIO = 0x070E; + public static final int TERMINAL_EMBED_DSSAUDIO = 0x070F; + public static final int TERMINAL_EMBED_RADIOAUDIO = 0x0710; + public static final int TERMINAL_EMBED_RADIOTRANSMITTER = 0x0711; + public static final int TERMINAL_EMBED_MULTITRACK = 0x0712; + public static final int TERMINAL_EMBED_SYNTHESIZER = 0x0713; + +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbUnknown.java b/services/usb/java/com/android/server/usb/descriptors/UsbUnknown.java new file mode 100644 index 000000000000..a6fe8bba3508 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/UsbUnknown.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors; + +/** + * @hide + * A holder for any unrecognized descriptor encountered in the descriptor stream. + */ +public class UsbUnknown extends UsbDescriptor { + static final String TAG = "Unknown"; + + public UsbUnknown(int length, byte type) { + super(length, type); + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/report/HTMLReporter.java b/services/usb/java/com/android/server/usb/descriptors/report/HTMLReporter.java new file mode 100644 index 000000000000..c98789d880a0 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/report/HTMLReporter.java @@ -0,0 +1,572 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors.report; + +import android.hardware.usb.UsbDeviceConnection; + +import com.android.server.usb.descriptors.UsbACAudioControlEndpoint; +import com.android.server.usb.descriptors.UsbACAudioStreamEndpoint; +import com.android.server.usb.descriptors.UsbACFeatureUnit; +import com.android.server.usb.descriptors.UsbACHeader; +import com.android.server.usb.descriptors.UsbACInputTerminal; +import com.android.server.usb.descriptors.UsbACInterface; +import com.android.server.usb.descriptors.UsbACMidiEndpoint; +import com.android.server.usb.descriptors.UsbACMixerUnit; +import com.android.server.usb.descriptors.UsbACOutputTerminal; +import com.android.server.usb.descriptors.UsbACSelectorUnit; +import com.android.server.usb.descriptors.UsbACTerminal; +import com.android.server.usb.descriptors.UsbASFormat; +import com.android.server.usb.descriptors.UsbASFormatI; +import com.android.server.usb.descriptors.UsbASFormatII; +import com.android.server.usb.descriptors.UsbASGeneral; +import com.android.server.usb.descriptors.UsbConfigDescriptor; +import com.android.server.usb.descriptors.UsbDescriptor; +import com.android.server.usb.descriptors.UsbDeviceDescriptor; +import com.android.server.usb.descriptors.UsbEndpointDescriptor; +import com.android.server.usb.descriptors.UsbHIDDescriptor; +import com.android.server.usb.descriptors.UsbInterfaceAssoc; +import com.android.server.usb.descriptors.UsbInterfaceDescriptor; +import com.android.server.usb.descriptors.UsbMSMidiHeader; +import com.android.server.usb.descriptors.UsbMSMidiInputJack; +import com.android.server.usb.descriptors.UsbMSMidiOutputJack; +import com.android.server.usb.descriptors.UsbUnknown; + +/** + * Implements the Reporter inteface to provide HTML reporting for UsbDescriptor subclasses. + */ +public class HTMLReporter implements Reporter { + private final StringBuilder mStringBuilder; + private final UsbDeviceConnection mConnection; + + public HTMLReporter(StringBuilder stringBuilder, UsbDeviceConnection connection) { + mStringBuilder = stringBuilder; + mConnection = connection; + } + + /* + * HTML Helpers + */ + private void writeHeader(int level, String text) { + mStringBuilder + .append("<h").append(level).append('>') + .append(text) + .append("</h").append(level).append('>'); + } + + private void openParagraph() { + mStringBuilder.append("<p>"); + } + + private void closeParagraph() { + mStringBuilder.append("</p>"); + } + + private void writeParagraph(String text) { + openParagraph(); + mStringBuilder.append(text); + closeParagraph(); + } + + private void openList() { + mStringBuilder.append("<ul>"); + } + + private void closeList() { + mStringBuilder.append("</ul>"); + } + + private void openListItem() { + mStringBuilder.append("<li>"); + } + + private void closeListItem() { + mStringBuilder.append("</li>"); + } + + private void writeListItem(String text) { + openListItem(); + mStringBuilder.append(text); + closeListItem(); + } + + /* + * Data Formating Helpers + */ + private static String getHexString(byte value) { + return "0x" + Integer.toHexString(((int) value) & 0xFF).toUpperCase(); + } + + private static String getBCDString(int value) { + int major = value >> 8; + int minor = (value >> 4) & 0x0F; + int subminor = value & 0x0F; + + return "" + major + "." + minor + subminor; + } + + private static String getHexString(int value) { + int intValue = value & 0xFFFF; + return "0x" + Integer.toHexString(intValue).toUpperCase(); + } + + private void dumpHexArray(byte[] rawData, StringBuilder builder) { + if (rawData != null) { + // Assume the type and Length and perhaps sub-type have been displayed + openParagraph(); + for (int index = 0; index < rawData.length; index++) { + builder.append(getHexString(rawData[index]) + " "); + } + closeParagraph(); + } + } + + /** + * Decode ACTUAL UsbDescriptor sub classes and call type-specific report methods. + */ + @Override + public void report(UsbDescriptor descriptor) { + if (descriptor instanceof UsbDeviceDescriptor) { + tsReport((UsbDeviceDescriptor) descriptor); + } else if (descriptor instanceof UsbConfigDescriptor) { + tsReport((UsbConfigDescriptor) descriptor); + } else if (descriptor instanceof UsbInterfaceDescriptor) { + tsReport((UsbInterfaceDescriptor) descriptor); + } else if (descriptor instanceof UsbEndpointDescriptor) { + tsReport((UsbEndpointDescriptor) descriptor); + } else if (descriptor instanceof UsbHIDDescriptor) { + tsReport((UsbHIDDescriptor) descriptor); + } else if (descriptor instanceof UsbACAudioControlEndpoint) { + tsReport((UsbACAudioControlEndpoint) descriptor); + } else if (descriptor instanceof UsbACAudioStreamEndpoint) { + tsReport((UsbACAudioStreamEndpoint) descriptor); + } else if (descriptor instanceof UsbACHeader) { + tsReport((UsbACHeader) descriptor); + } else if (descriptor instanceof UsbACFeatureUnit) { + tsReport((UsbACFeatureUnit) descriptor); + } else if (descriptor instanceof UsbACInputTerminal) { + tsReport((UsbACInputTerminal) descriptor); + } else if (descriptor instanceof UsbACOutputTerminal) { + tsReport((UsbACOutputTerminal) descriptor); + } else if (descriptor instanceof UsbACMidiEndpoint) { + tsReport((UsbACMidiEndpoint) descriptor); + } else if (descriptor instanceof UsbACMixerUnit) { + tsReport((UsbACMixerUnit) descriptor); + } else if (descriptor instanceof UsbACSelectorUnit) { + tsReport((UsbACSelectorUnit) descriptor); + } else if (descriptor instanceof UsbASFormatI) { + tsReport((UsbASFormatI) descriptor); + } else if (descriptor instanceof UsbASFormatII) { + tsReport((UsbASFormatII) descriptor); + } else if (descriptor instanceof UsbASFormat) { + tsReport((UsbASFormat) descriptor); + } else if (descriptor instanceof UsbASGeneral) { + tsReport((UsbASGeneral) descriptor); + } else if (descriptor instanceof UsbInterfaceAssoc) { + tsReport((UsbInterfaceAssoc) descriptor); + } else if (descriptor instanceof UsbMSMidiHeader) { + tsReport((UsbMSMidiHeader) descriptor); + } else if (descriptor instanceof UsbMSMidiInputJack) { + tsReport((UsbMSMidiInputJack) descriptor); + } else if (descriptor instanceof UsbMSMidiOutputJack) { + tsReport((UsbMSMidiOutputJack) descriptor); + } else if (descriptor instanceof UsbUnknown) { + tsReport((UsbUnknown) descriptor); + } else if (descriptor instanceof UsbACInterface) { + tsReport((UsbACInterface) descriptor); + } else if (descriptor instanceof UsbDescriptor) { + tsReport((UsbDescriptor) descriptor); + } + } + + // + // Type-specific report() implementations + // + private void tsReport(UsbDescriptor descriptor) { + int length = descriptor.getLength(); + byte type = descriptor.getType(); + int status = descriptor.getStatus(); + + String descTypeStr = UsbStrings.getDescriptorName(type); + writeParagraph(descTypeStr + ":" + type + " l:" + length + " s:" + status); + } + + private void tsReport(UsbDeviceDescriptor descriptor) { + writeHeader(1, "Device len:" + descriptor.getLength()); + openList(); + + int spec = descriptor.getSpec(); + writeListItem("spec:" + getBCDString(spec)); + + byte devClass = descriptor.getDevClass(); + String classStr = UsbStrings.getClassName(devClass); + byte devSubClass = descriptor.getDevSubClass(); + String subClasStr = UsbStrings.getClassName(devSubClass); + writeListItem("class " + devClass + ":" + classStr + " subclass" + + devSubClass + ":" + subClasStr); + writeListItem("vendorID:" + descriptor.getVendorID() + + " prodID:" + descriptor.getProductID() + + " prodRel:" + getBCDString(descriptor.getDeviceRelease())); + + byte mfgIndex = descriptor.getMfgIndex(); + String manufacturer = UsbDescriptor.getUsbDescriptorString(mConnection, mfgIndex); + byte productIndex = descriptor.getProductIndex(); + String product = UsbDescriptor.getUsbDescriptorString(mConnection, productIndex); + + writeListItem("mfg " + mfgIndex + ":" + manufacturer + + " prod " + productIndex + ":" + product); + closeList(); + } + + private void tsReport(UsbConfigDescriptor descriptor) { + writeHeader(2, "Config #" + descriptor.getConfigValue() + + " len:" + descriptor.getLength()); + + openList(); + writeListItem(descriptor.getNumInterfaces() + " interfaces."); + writeListItem("attribs:" + getHexString(descriptor.getAttribs())); + closeList(); + } + + private void tsReport(UsbInterfaceDescriptor descriptor) { + byte usbClass = descriptor.getUsbClass(); + byte usbSubclass = descriptor.getUsbSubclass(); + String descr = UsbStrings.getDescriptorName(descriptor.getType()); + String className = UsbStrings.getClassName(usbClass); + String subclassName = ""; + if (usbClass == UsbDescriptor.CLASSID_AUDIO) { + subclassName = UsbStrings.getAudioSubclassName(usbSubclass); + } + + writeHeader(2, descr + " #" + descriptor.getInterfaceNumber() + + " len:" + descriptor.getLength()); + String descrStr = + UsbDescriptor.getUsbDescriptorString(mConnection, descriptor.getDescrIndex()); + if (descrStr.length() > 0) { + mStringBuilder.append("<br>" + descrStr); + } + openList(); + writeListItem("class " + getHexString(usbClass) + ":" + className + + " subclass " + getHexString(usbSubclass) + ":" + subclassName); + writeListItem("" + descriptor.getNumEndpoints() + " endpoints"); + closeList(); + } + + private void tsReport(UsbEndpointDescriptor descriptor) { + writeHeader(3, "Endpoint " + getHexString(descriptor.getType()) + + " len:" + descriptor.getLength()); + openList(); + + byte address = descriptor.getEndpointAddress(); + writeListItem("address:" + + getHexString(address & UsbEndpointDescriptor.MASK_ENDPOINT_ADDRESS) + + ((address & UsbEndpointDescriptor.MASK_ENDPOINT_DIRECTION) + == UsbEndpointDescriptor.DIRECTION_OUTPUT ? " [out]" : " [in]")); + + byte attributes = descriptor.getAttributes(); + openListItem(); + mStringBuilder.append("attribs:" + getHexString(attributes) + " "); + switch (attributes & UsbEndpointDescriptor.MASK_ATTRIBS_TRANSTYPE) { + case UsbEndpointDescriptor.TRANSTYPE_CONTROL: + mStringBuilder.append("Control"); + break; + case UsbEndpointDescriptor.TRANSTYPE_ISO: + mStringBuilder.append("Iso"); + break; + case UsbEndpointDescriptor.TRANSTYPE_BULK: + mStringBuilder.append("Bulk"); + break; + case UsbEndpointDescriptor.TRANSTYPE_INTERRUPT: + mStringBuilder.append("Interrupt"); + break; + } + closeListItem(); + + // These flags are only relevant for ISO transfer type + if ((attributes & UsbEndpointDescriptor.MASK_ATTRIBS_TRANSTYPE) + == UsbEndpointDescriptor.TRANSTYPE_ISO) { + openListItem(); + mStringBuilder.append("sync:"); + switch (attributes & UsbEndpointDescriptor.MASK_ATTRIBS_SYNCTYPE) { + case UsbEndpointDescriptor.SYNCTYPE_NONE: + mStringBuilder.append("NONE"); + break; + case UsbEndpointDescriptor.SYNCTYPE_ASYNC: + mStringBuilder.append("ASYNC"); + break; + case UsbEndpointDescriptor.SYNCTYPE_ADAPTSYNC: + mStringBuilder.append("ADAPTIVE ASYNC"); + break; + } + closeListItem(); + + openListItem(); + mStringBuilder.append("useage:"); + switch (attributes & UsbEndpointDescriptor.MASK_ATTRIBS_USEAGE) { + case UsbEndpointDescriptor.USEAGE_DATA: + mStringBuilder.append("DATA"); + break; + case UsbEndpointDescriptor.USEAGE_FEEDBACK: + mStringBuilder.append("FEEDBACK"); + break; + case UsbEndpointDescriptor.USEAGE_EXPLICIT: + mStringBuilder.append("EXPLICIT FEEDBACK"); + break; + case UsbEndpointDescriptor.USEAGE_RESERVED: + mStringBuilder.append("RESERVED"); + break; + } + closeListItem(); + } + writeListItem("package size:" + descriptor.getPacketSize()); + writeListItem("interval:" + descriptor.getInterval()); + closeList(); + } + + private void tsReport(UsbHIDDescriptor descriptor) { + String descr = UsbStrings.getDescriptorName(descriptor.getType()); + writeHeader(2, descr + " len:" + descriptor.getLength()); + openList(); + writeListItem("spec:" + getBCDString(descriptor.getRelease())); + writeListItem("type:" + getBCDString(descriptor.getDescriptorType())); + writeListItem("descriptor.getNumDescriptors() descriptors len:" + + descriptor.getDescriptorLen()); + closeList(); + } + + private void tsReport(UsbACAudioControlEndpoint descriptor) { + writeHeader(3, "AC Audio Control Endpoint:" + getHexString(descriptor.getType()) + + " length:" + descriptor.getLength()); + } + + private void tsReport(UsbACAudioStreamEndpoint descriptor) { + writeHeader(3, "AC Audio Streaming Endpoint:" + + getHexString(descriptor.getType()) + + " length:" + descriptor.getLength()); + } + + private void tsReport(UsbACHeader descriptor) { + tsReport((UsbACInterface) descriptor); + + openList(); + writeListItem("spec:" + getBCDString(descriptor.getADCRelease())); + int numInterfaces = descriptor.getNumInterfaces(); + writeListItem("" + numInterfaces + " interfaces"); + if (numInterfaces > 0) { + openListItem(); + mStringBuilder.append("["); + byte[] interfaceNums = descriptor.getInterfaceNums(); + if (numInterfaces != 0 && interfaceNums != null) { + for (int index = 0; index < numInterfaces; index++) { + mStringBuilder.append("" + interfaceNums[index]); + if (index < numInterfaces - 1) { + mStringBuilder.append(" "); + } + } + } + mStringBuilder.append("]"); + closeListItem(); + } + writeListItem("controls:" + getHexString(descriptor.getControls())); + closeList(); + } + + private void tsReport(UsbACFeatureUnit descriptor) { + tsReport((UsbACInterface) descriptor); + } + + private void tsReport(UsbACInterface descriptor) { + String subClassName = + descriptor.getSubclass() == UsbDescriptor.AUDIO_AUDIOCONTROL + ? "AC Control" + : "AC Streaming"; + byte subtype = descriptor.getSubtype(); + String subTypeStr = UsbStrings.getACControlInterfaceName(subtype); + writeHeader(4, subClassName + " - " + getHexString(subtype) + + ":" + subTypeStr + " len:" + descriptor.getLength()); + } + + private void tsReport(UsbACTerminal descriptor) { + tsReport((UsbACInterface) descriptor); + } + + private void tsReport(UsbACInputTerminal descriptor) { + tsReport((UsbACTerminal) descriptor); + + openList(); + writeListItem("ID:" + getHexString(descriptor.getTerminalID())); + int terminalType = descriptor.getTerminalType(); + writeListItem("Type:<b>" + getHexString(terminalType) + ":" + + UsbStrings.getTerminalName(terminalType) + "</b>"); + writeListItem("AssocTerminal:" + getHexString(descriptor.getAssocTerminal())); + writeListItem("" + descriptor.getNrChannels() + " chans. config:" + + getHexString(descriptor.getChannelConfig())); + closeList(); + } + + private void tsReport(UsbACOutputTerminal descriptor) { + tsReport((UsbACTerminal) descriptor); + + openList(); + writeListItem("ID:" + getHexString(descriptor.getTerminalID())); + int terminalType = descriptor.getTerminalType(); + writeListItem("Type:<b>" + getHexString(terminalType) + ":" + + UsbStrings.getTerminalName(terminalType) + "</b>"); + writeListItem("AssocTerminal:" + getHexString(descriptor.getAssocTerminal())); + writeListItem("Source:" + getHexString(descriptor.getSourceID())); + closeList(); + } + + private void tsReport(UsbACMidiEndpoint descriptor) { + writeHeader(3, "AC Midi Endpoint:" + getHexString(descriptor.getType()) + + " length:" + descriptor.getLength()); + openList(); + writeListItem("" + descriptor.getNumJacks() + " jacks."); + closeList(); + } + + private void tsReport(UsbACMixerUnit descriptor) { + tsReport((UsbACInterface) descriptor); + openList(); + + writeListItem("Unit ID:" + getHexString(descriptor.getUnitID())); + byte numInputs = descriptor.getNumInputs(); + byte[] inputIDs = descriptor.getInputIDs(); + openListItem(); + mStringBuilder.append("Num Inputs:" + numInputs + " ["); + for (int input = 0; input < numInputs; input++) { + mStringBuilder.append("" + getHexString(inputIDs[input])); + if (input < numInputs - 1) { + mStringBuilder.append(" "); + } + } + mStringBuilder.append("]"); + closeListItem(); + + writeListItem("Num Outputs:" + descriptor.getNumOutputs()); + writeListItem("Chan Config:" + getHexString(descriptor.getChannelConfig())); + + byte[] controls = descriptor.getControls(); + openListItem(); + mStringBuilder.append("controls:" + controls.length + " ["); + for (int ctrl = 0; ctrl < controls.length; ctrl++) { + mStringBuilder.append("" + controls[ctrl]); + if (ctrl < controls.length - 1) { + mStringBuilder.append(" "); + } + } + mStringBuilder.append("]"); + closeListItem(); + closeList(); + // byte mChanNameID; // First channel name string descriptor ID + // byte mNameID; // string descriptor ID of mixer name + } + + private void tsReport(UsbACSelectorUnit descriptor) { + tsReport((UsbACInterface) descriptor); + } + + private void tsReport(UsbASFormat descriptor) { + writeHeader(4, "AC Streaming Format " + + (descriptor.getFormatType() == UsbASFormat.FORMAT_TYPE_I ? "I" : "II") + + " - " + getHexString(descriptor.getSubtype()) + ":" + + " len:" + descriptor.getLength()); + } + + private void tsReport(UsbASFormatI descriptor) { + tsReport((UsbASFormat) descriptor); + openList(); + writeListItem("chans:" + descriptor.getNumChannels()); + writeListItem("subframe size:" + descriptor.getSubframeSize()); + writeListItem("bit resolution:" + descriptor.getBitResolution()); + byte sampleFreqType = descriptor.getSampleFreqType(); + int[] sampleRates = descriptor.getSampleRates(); + writeListItem("sample freq type:" + sampleFreqType); + if (sampleFreqType == 0) { + openList(); + writeListItem("min:" + sampleRates[0]); + writeListItem("max:" + sampleRates[1]); + closeList(); + } else { + openList(); + for (int index = 0; index < sampleFreqType; index++) { + writeListItem("" + sampleRates[index]); + } + closeList(); + } + closeList(); + } + + private void tsReport(UsbASFormatII descriptor) { + tsReport((UsbASFormat) descriptor); + openList(); + writeListItem("max bit rate:" + descriptor.getMaxBitRate()); + writeListItem("samples per frame:" + descriptor.getMaxBitRate()); + byte sampleFreqType = descriptor.getSamFreqType(); + int[] sampleRates = descriptor.getSampleRates(); + writeListItem("sample freq type:" + sampleFreqType); + if (sampleFreqType == 0) { + openList(); + writeListItem("min:" + sampleRates[0]); + writeListItem("max:" + sampleRates[1]); + closeList(); + } else { + openList(); + for (int index = 0; index < sampleFreqType; index++) { + writeListItem("" + sampleRates[index]); + } + closeList(); + } + + closeList(); + } + + private void tsReport(UsbASGeneral descriptor) { + tsReport((UsbACInterface) descriptor); + openList(); + int formatTag = descriptor.getFormatTag(); + writeListItem("fmt:" + UsbStrings.getAudioFormatName(formatTag) + " - " + + getHexString(formatTag)); + closeList(); + } + + private void tsReport(UsbInterfaceAssoc descriptor) { + tsReport((UsbDescriptor) descriptor); + } + + private void tsReport(UsbMSMidiHeader descriptor) { + writeHeader(3, "MS Midi Header:" + getHexString(descriptor.getType()) + + " subType:" + getHexString(descriptor.getSubclass()) + + " length:" + descriptor.getSubclass()); + } + + private void tsReport(UsbMSMidiInputJack descriptor) { + writeHeader(3, "MS Midi Input Jack:" + getHexString(descriptor.getType()) + + " subType:" + getHexString(descriptor.getSubclass()) + + " length:" + descriptor.getSubclass()); + } + + private void tsReport(UsbMSMidiOutputJack descriptor) { + writeHeader(3, "MS Midi Output Jack:" + getHexString(descriptor.getType()) + + " subType:" + getHexString(descriptor.getSubclass()) + + " length:" + descriptor.getSubclass()); + } + + private void tsReport(UsbUnknown descriptor) { + writeParagraph("<i><b>Unknown Descriptor " + getHexString(descriptor.getType()) + + " len:" + descriptor.getLength() + "</b></i>"); + dumpHexArray(descriptor.getRawData(), mStringBuilder); + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/report/Reporter.java b/services/usb/java/com/android/server/usb/descriptors/report/Reporter.java new file mode 100644 index 000000000000..2944c10796f6 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/report/Reporter.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors.report; + +import com.android.server.usb.descriptors.UsbDescriptor; + +/** + * Declares the Reporter interface to provide HTML reporting for UsbDescriptor (sub)classes. + * + * NOTE: It is the responsibility of the implementor of this interface to correctly + * interpret/decode the SPECIFIC UsbDescriptor subclass (perhaps with 'instanceof') that is + * passed and handle that in the appropriate manner. This appears to be a + * not very object-oriented approach, and that is true. This approach DOES however move the + * complexity and 'plumbing' of reporting into the Reporter implementation and avoids needing + * a (trivial) type-specific call to 'report()' in each UsbDescriptor (sub)class, instead + * having just one in the top-level UsbDescriptor class. It also removes the need to add new + * type-specific 'report()' methods to be added to Reporter interface whenever a + * new UsbDescriptor subclass is defined. This seems like a pretty good trade-off. + * + * See HTMLReporter.java in this package for an example of type decoding. + */ +public interface Reporter { + /** + * Generate report for this UsbDescriptor descriptor + */ + void report(UsbDescriptor descriptor); +} diff --git a/services/usb/java/com/android/server/usb/descriptors/report/Reporting.java b/services/usb/java/com/android/server/usb/descriptors/report/Reporting.java new file mode 100644 index 000000000000..c13111b3e81c --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/report/Reporting.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors.report; + +/** + * Declares the interface for classes that provide reporting functionality. + * (This is the double-indirection aspect of the "Visitor" pattern. + */ +public interface Reporting { + /** + * Declares the report method that UsbDescriptor subclasses call. + */ + void report(Reporter reporter); +} diff --git a/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java b/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java new file mode 100644 index 000000000000..0461150abd27 --- /dev/null +++ b/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.descriptors.report; + +import com.android.server.usb.descriptors.UsbACInterface; +import com.android.server.usb.descriptors.UsbDescriptor; +import com.android.server.usb.descriptors.UsbTerminalTypes; + +import java.util.HashMap; + +/** + * @hide + * A class to provide human-readable strings for various USB constants. + */ +public class UsbStrings { + private static final String TAG = "UsbStrings"; + + private static HashMap<Byte, String> sDescriptorNames; + private static HashMap<Byte, String> sACControlInterfaceNames; + private static HashMap<Byte, String> sACStreamingInterfaceNames; + private static HashMap<Byte, String> sClassNames; + private static HashMap<Byte, String> sAudioSubclassNames; + private static HashMap<Integer, String> sAudioEncodingNames; + private static HashMap<Integer, String> sTerminalNames; + + private static void initDescriptorNames() { + sDescriptorNames = new HashMap<Byte, String>(); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_DEVICE, "Device"); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_CONFIG, "Config"); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_STRING, "String"); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_INTERFACE, "Interface"); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_ENDPOINT, "Endpoint"); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_BOS, "BOS (whatever that means)"); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_INTERFACEASSOC, + "Interface Association"); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_CAPABILITY, "Capability"); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_HID, "HID"); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_REPORT, "Report"); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_PHYSICAL, "Physical"); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE, + "Audio Class Interface"); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_AUDIO_ENDPOINT, "Audio Class Endpoint"); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_HUB, "Hub"); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_SUPERSPEED_HUB, "Superspeed Hub"); + sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_ENDPOINT_COMPANION, + "Endpoint Companion"); + } + + private static void initACControlInterfaceNames() { + sACControlInterfaceNames = new HashMap<Byte, String>(); + sACControlInterfaceNames.put(UsbACInterface.ACI_UNDEFINED, "Undefined"); + sACControlInterfaceNames.put(UsbACInterface.ACI_HEADER, "Header"); + sACControlInterfaceNames.put(UsbACInterface.ACI_INPUT_TERMINAL, "Input Terminal"); + sACControlInterfaceNames.put(UsbACInterface.ACI_OUTPUT_TERMINAL, "Output Terminal"); + sACControlInterfaceNames.put(UsbACInterface.ACI_MIXER_UNIT, "Mixer Unit"); + sACControlInterfaceNames.put(UsbACInterface.ACI_SELECTOR_UNIT, "Selector Unit"); + sACControlInterfaceNames.put(UsbACInterface.ACI_FEATURE_UNIT, "Feature Unit"); + sACControlInterfaceNames.put(UsbACInterface.ACI_PROCESSING_UNIT, "Processing Unit"); + sACControlInterfaceNames.put(UsbACInterface.ACI_EXTENSION_UNIT, "Extension Unit"); + } + + private static void initACStreamingInterfaceNames() { + sACStreamingInterfaceNames = new HashMap<Byte, String>(); + sACStreamingInterfaceNames.put(UsbACInterface.ASI_UNDEFINED, "Undefined"); + sACStreamingInterfaceNames.put(UsbACInterface.ASI_GENERAL, "General"); + sACStreamingInterfaceNames.put(UsbACInterface.ASI_FORMAT_TYPE, "Format Type"); + sACStreamingInterfaceNames.put(UsbACInterface.ASI_FORMAT_SPECIFIC, "Format Specific"); + } + + private static void initClassNames() { + sClassNames = new HashMap<Byte, String>(); + sClassNames.put(UsbDescriptor.CLASSID_DEVICE, "Device"); + sClassNames.put(UsbDescriptor.CLASSID_AUDIO, "Audio"); + sClassNames.put(UsbDescriptor.CLASSID_COM, "Communications"); + sClassNames.put(UsbDescriptor.CLASSID_HID, "HID"); + sClassNames.put(UsbDescriptor.CLASSID_PHYSICAL, "Physical"); + sClassNames.put(UsbDescriptor.CLASSID_IMAGE, "Image"); + sClassNames.put(UsbDescriptor.CLASSID_PRINTER, "Printer"); + sClassNames.put(UsbDescriptor.CLASSID_STORAGE, "Storage"); + sClassNames.put(UsbDescriptor.CLASSID_HUB, "Hub"); + sClassNames.put(UsbDescriptor.CLASSID_CDC_CONTROL, "CDC Control"); + sClassNames.put(UsbDescriptor.CLASSID_SMART_CARD, "Smart Card"); + sClassNames.put(UsbDescriptor.CLASSID_SECURITY, "Security"); + sClassNames.put(UsbDescriptor.CLASSID_VIDEO, "Video"); + sClassNames.put(UsbDescriptor.CLASSID_HEALTHCARE, "Healthcare"); + sClassNames.put(UsbDescriptor.CLASSID_AUDIOVIDEO, "Audio/Video"); + sClassNames.put(UsbDescriptor.CLASSID_BILLBOARD, "Billboard"); + sClassNames.put(UsbDescriptor.CLASSID_TYPECBRIDGE, "Type C Bridge"); + sClassNames.put(UsbDescriptor.CLASSID_DIAGNOSTIC, "Diagnostic"); + sClassNames.put(UsbDescriptor.CLASSID_WIRELESS, "Wireless"); + sClassNames.put(UsbDescriptor.CLASSID_MISC, "Misc"); + sClassNames.put(UsbDescriptor.CLASSID_APPSPECIFIC, "Application Specific"); + sClassNames.put(UsbDescriptor.CLASSID_VENDSPECIFIC, "Vendor Specific"); + } + + private static void initAudioSubclassNames() { + sAudioSubclassNames = new HashMap<Byte, String>(); + sAudioSubclassNames.put(UsbDescriptor.AUDIO_SUBCLASS_UNDEFINED, "Undefinded"); + sAudioSubclassNames.put(UsbDescriptor.AUDIO_AUDIOCONTROL, "Audio Control"); + sAudioSubclassNames.put(UsbDescriptor.AUDIO_AUDIOSTREAMING, "Audio Streaming"); + sAudioSubclassNames.put(UsbDescriptor.AUDIO_MIDISTREAMING, "MIDI Streaming"); + } + + private static void initAudioEncodingNames() { + sAudioEncodingNames = new HashMap<Integer, String>(); + sAudioEncodingNames.put(UsbACInterface.FORMAT_I_UNDEFINED, "Format I Undefined"); + sAudioEncodingNames.put(UsbACInterface.FORMAT_I_PCM, "Format I PCM"); + sAudioEncodingNames.put(UsbACInterface.FORMAT_I_PCM8, "Format I PCM8"); + sAudioEncodingNames.put(UsbACInterface.FORMAT_I_IEEE_FLOAT, "Format I FLOAT"); + sAudioEncodingNames.put(UsbACInterface.FORMAT_I_ALAW, "Format I ALAW"); + sAudioEncodingNames.put(UsbACInterface.FORMAT_I_MULAW, "Format I MuLAW"); + sAudioEncodingNames.put(UsbACInterface.FORMAT_II_UNDEFINED, "FORMAT_II Undefined"); + sAudioEncodingNames.put(UsbACInterface.FORMAT_II_MPEG, "FORMAT_II MPEG"); + sAudioEncodingNames.put(UsbACInterface.FORMAT_II_AC3, "FORMAT_II AC3"); + sAudioEncodingNames.put(UsbACInterface.FORMAT_III_UNDEFINED, "FORMAT_III Undefined"); + sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937AC3, "FORMAT_III IEC1937 AC3"); + sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG1_Layer1, + "FORMAT_III MPEG1 Layer 1"); + sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG1_Layer2, + "FORMAT_III MPEG1 Layer 2"); + sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG2_EXT, + "FORMAT_III MPEG2 EXT"); + sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG2_Layer1LS, + "FORMAT_III MPEG2 Layer1LS"); + } + + private static void initTerminalNames() { + sTerminalNames = new HashMap<Integer, String>(); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_USB_STREAMING, "USB Streaming"); + + sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_UNDEFINED, "Undefined"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_MIC, "Microphone"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_DESKTOP_MIC, "Desktop Microphone"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_PERSONAL_MIC, + "Personal (headset) Microphone"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_OMNI_MIC, "Omni Microphone"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_MIC_ARRAY, "Microphone Array"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_PROC_MIC_ARRAY, + "Proecessing Microphone Array"); + + sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_UNDEFINED, "Undefined"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_SPEAKER, "Speaker"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_HEADPHONES, "Headphones"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_HEADMOUNTED, "Head Mounted Speaker"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_DESKTOPSPEAKER, "Desktop Speaker"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_ROOMSPEAKER, "Room Speaker"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_COMSPEAKER, "Communications Speaker"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_LFSPEAKER, "Low Frequency Speaker"); + + sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_UNDEFINED, "Undefined"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_HANDSET, "Handset"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_HEADSET, "Headset"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_SKRPHONE, "Speaker Phone"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_SKRPHONE_SUPRESS, + "Speaker Phone (echo supressing)"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_SKRPHONE_CANCEL, + "Speaker Phone (echo canceling)"); + + sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_UNDEFINED, "Undefined"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_PHONELINE, "Phone Line"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_PHONE, "Telephone"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_DOWNLINEPHONE, "Down Line Phone"); + + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_UNDEFINED, "Undefined"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_ANALOG, "Analog Connector"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_DIGITAL, "Digital Connector"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_LINE, "Line Connector"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_LEGACY, "Legacy Audio Connector"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_SPIDF, "S/PIDF Interface"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_1394DA, "1394 Audio"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_1394DV, "1394 Audio/Video"); + + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_UNDEFINED, "Undefined"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_CALNOISE, "Calibration Nose"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_EQNOISE, "EQ Noise"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_CDPLAYER, "CD Player"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DAT, "DAT"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DCC, "DCC"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_MINIDISK, "Mini Disk"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_ANALOGTAPE, "Analog Tap"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_PHONOGRAPH, "Phonograph"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_VCRAUDIO, "VCR Audio"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_VIDDISKAUDIO, "Video Disk Audio"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DVDAUDIO, "DVD Audio"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_TVAUDIO, "TV Audio"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_SATELLITEAUDIO, "Satellite Audio"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_CABLEAUDIO, "Cable Tuner Audio"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DSSAUDIO, "DSS Audio"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_RADIOTRANSMITTER, "Radio Transmitter"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_MULTITRACK, "Multitrack Recorder"); + sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_SYNTHESIZER, "Synthesizer"); + } + + /** + * Retrieves the terminal name for the specified terminal type ID. + */ + public static String getTerminalName(int terminalType) { + String name = sTerminalNames.get(terminalType); + return name != null + ? name + : "Unknown Terminal Type 0x" + Integer.toHexString(terminalType); + } + /** + * Initializes string tables. + */ + public static void allocUsbStrings() { + initDescriptorNames(); + initACControlInterfaceNames(); + initACStreamingInterfaceNames(); + initClassNames(); + initAudioSubclassNames(); + initAudioEncodingNames(); + initTerminalNames(); + } + + /** + * Initializes string tables. + */ + public static void releaseUsbStrings() { + sDescriptorNames = null; + sACControlInterfaceNames = null; + sACStreamingInterfaceNames = null; + sClassNames = null; + sAudioSubclassNames = null; + sAudioEncodingNames = null; + sTerminalNames = null; + } + + /** + * Retrieves the name for the specified descriptor ID. + */ + public static String getDescriptorName(byte descriptorID) { + String name = sDescriptorNames.get(descriptorID); + int iDescriptorID = descriptorID & 0xFF; + return name != null + ? name + : "Unknown Descriptor [0x" + Integer.toHexString(iDescriptorID) + + ":" + iDescriptorID + "]"; + } + + /** + * Retrieves the audio-class control interface name for the specified audio-class subtype. + */ + public static String getACControlInterfaceName(byte subtype) { + String name = sACControlInterfaceNames.get(subtype); + int iSubType = subtype & 0xFF; + return name != null + ? name + : "Unknown subtype [0x" + Integer.toHexString(iSubType) + + ":" + iSubType + "]"; + } + + /** + * Retrieves the audio-class streaming interface name for the specified audio-class subtype. + */ + public static String getACStreamingInterfaceName(byte subtype) { + String name = sACStreamingInterfaceNames.get(subtype); + int iSubType = subtype & 0xFF; + return name != null + ? name + : "Unknown Subtype [0x" + Integer.toHexString(iSubType) + ":" + + iSubType + "]"; + } + + /** + * Retrieves the name for the specified USB class ID. + */ + public static String getClassName(byte classID) { + String name = sClassNames.get(classID); + int iClassID = classID & 0xFF; + return name != null + ? name + : "Unknown Class ID [0x" + Integer.toHexString(iClassID) + ":" + + iClassID + "]"; + } + + /** + * Retrieves the name for the specified USB audio subclass ID. + */ + public static String getAudioSubclassName(byte subClassID) { + String name = sAudioSubclassNames.get(subClassID); + int iSubclassID = subClassID & 0xFF; + return name != null + ? name + : "Unknown Audio Subclass [0x" + Integer.toHexString(iSubclassID) + ":" + + iSubclassID + "]"; + } + + /** + * Retrieves the name for the specified USB audio format ID. + */ + public static String getAudioFormatName(int formatID) { + String name = sAudioEncodingNames.get(formatID); + return name != null + ? name + : "Unknown Format (encoding) ID [0x" + Integer.toHexString(formatID) + ":" + + formatID + "]"; + } +} diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index a6bfbad8e053..e8e06808e189 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -189,6 +189,19 @@ public final class Call { */ public static final String EVENT_HANDOVER_COMPLETE = "android.telecom.event.HANDOVER_COMPLETE"; + + /** + * Call event sent from Telecom to the handover destination {@link ConnectionService} via + * {@link Connection#onCallEvent(String, Bundle)} to inform the handover destination that the + * source connection has disconnected. The {@link Bundle} parameter for the call event will be + * {@code null}. + * <p> + * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event. + * @hide + */ + public static final String EVENT_HANDOVER_SOURCE_DISCONNECTED = + "android.telecom.event.HANDOVER_SOURCE_DISCONNECTED"; + /** * Call event sent from Telecom to the handover {@link ConnectionService} via * {@link Connection#onCallEvent(String, Bundle)} to inform a {@link Connection} that a handover diff --git a/telephony/java/android/telephony/ImsiEncryptionInfo.java b/telephony/java/android/telephony/ImsiEncryptionInfo.java index ecb9d25f2745..d2680ad66ed1 100644 --- a/telephony/java/android/telephony/ImsiEncryptionInfo.java +++ b/telephony/java/android/telephony/ImsiEncryptionInfo.java @@ -17,6 +17,7 @@ package android.telephony; import android.os.Parcel; import android.os.Parcelable; +import java.util.Date; import android.util.Log; import java.security.KeyFactory; @@ -34,7 +35,6 @@ import java.security.spec.X509EncodedKeySpec; public final class ImsiEncryptionInfo implements Parcelable { private static final String LOG_TAG = "ImsiEncryptionInfo"; - private static final boolean DBG = false; private final String mcc; @@ -42,14 +42,25 @@ public final class ImsiEncryptionInfo implements Parcelable { private final PublicKey publicKey; private final String keyIdentifier; private final int keyType; + //Date-Time in UTC when the key will expire. + private final Date expirationTime; public ImsiEncryptionInfo(String mcc, String mnc, int keyType, String keyIdentifier, - PublicKey publicKey) { + byte[] key, Date expirationTime) { + this(mcc, mnc, keyType, keyIdentifier, makeKeyObject(key), expirationTime); + } + + public ImsiEncryptionInfo(String mcc, String mnc, int keyType, String keyIdentifier, + PublicKey publicKey, Date expirationTime) { + // todo need to validate that ImsiEncryptionInfo is being created with the correct params. + // Including validating that the public key is in "X.509" format. This will be done in + // a subsequent CL. this.mcc = mcc; this.mnc = mnc; this.keyType = keyType; this.publicKey = publicKey; this.keyIdentifier = keyIdentifier; + this.expirationTime = expirationTime; } public ImsiEncryptionInfo(Parcel in) { @@ -61,7 +72,7 @@ public final class ImsiEncryptionInfo implements Parcelable { mnc = in.readString(); keyIdentifier = in.readString(); keyType = in.readInt(); - + expirationTime = new Date(in.readLong()); } public String getMnc() { @@ -84,6 +95,10 @@ public final class ImsiEncryptionInfo implements Parcelable { return this.publicKey; } + public Date getExpirationTime() { + return this.expirationTime; + } + private static PublicKey makeKeyObject(byte[] publicKeyBytes) { try { X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(publicKeyBytes); @@ -91,7 +106,7 @@ public final class ImsiEncryptionInfo implements Parcelable { } catch (InvalidKeySpecException | NoSuchAlgorithmException ex) { Log.e(LOG_TAG, "Error makeKeyObject: unable to convert into PublicKey", ex); } - return null; + throw new IllegalArgumentException(); } /** Implement the Parcelable interface */ @@ -122,6 +137,7 @@ public final class ImsiEncryptionInfo implements Parcelable { dest.writeString(mnc); dest.writeString(keyIdentifier); dest.writeInt(keyType); + dest.writeLong(expirationTime.getTime()); } @Override @@ -132,6 +148,7 @@ public final class ImsiEncryptionInfo implements Parcelable { + "publicKey=" + publicKey + ", keyIdentifier=" + keyIdentifier + ", keyType=" + keyType + + ", expirationTime=" + expirationTime + "]"; } } diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java index c905d3a433f3..92a21b6fb85f 100644 --- a/telephony/java/android/telephony/TelephonyScanManager.java +++ b/telephony/java/android/telephony/TelephonyScanManager.java @@ -20,15 +20,18 @@ import static com.android.internal.util.Preconditions.checkNotNull; import android.content.Context; import android.os.Binder; +import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.Messenger; +import android.os.Parcelable; import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; import android.util.SparseArray; +import java.util.Arrays; import java.util.List; import com.android.internal.telephony.ITelephony; @@ -42,6 +45,9 @@ public final class TelephonyScanManager { private static final String TAG = "TelephonyScanManager"; /** @hide */ + public static final String SCAN_RESULT_KEY = "scanResult"; + + /** @hide */ public static final int CALLBACK_SCAN_RESULTS = 1; /** @hide */ public static final int CALLBACK_SCAN_ERROR = 2; @@ -112,7 +118,13 @@ public final class TelephonyScanManager { switch (message.what) { case CALLBACK_SCAN_RESULTS: try { - callback.onResults((List<CellInfo>) message.obj); + final Bundle b = message.getData(); + final Parcelable[] parcelables = b.getParcelableArray(SCAN_RESULT_KEY); + CellInfo[] ci = new CellInfo[parcelables.length]; + for (int i = 0; i < parcelables.length; i++) { + ci[i] = (CellInfo) parcelables[i]; + } + callback.onResults((List<CellInfo>) Arrays.asList(ci)); } catch (Exception e) { Rlog.e(TAG, "Exception in networkscan callback onResults", e); } diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java index 11770fb06c95..8304d84d8a2b 100644 --- a/telephony/java/android/telephony/euicc/EuiccManager.java +++ b/telephony/java/android/telephony/euicc/EuiccManager.java @@ -320,7 +320,8 @@ public class EuiccManager { return; } try { - mController.getDownloadableSubscriptionMetadata(subscription, callbackIntent); + mController.getDownloadableSubscriptionMetadata( + subscription, mContext.getOpPackageName(), callbackIntent); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -349,7 +350,8 @@ public class EuiccManager { return; } try { - mController.getDefaultDownloadableSubscriptionList(callbackIntent); + mController.getDefaultDownloadableSubscriptionList( + mContext.getOpPackageName(), callbackIntent); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -473,6 +475,36 @@ public class EuiccManager { } } + /** + * Ensure that subscriptions will be retained on the next factory reset. + * + * <p>By default, all subscriptions on the eUICC are erased the first time a device boots (ever + * and after factory resets). This ensures that the data is wiped after a factory reset is + * performed via fastboot or recovery mode, as these modes do not support the necessary radio + * communication needed to wipe the eSIM. + * + * <p>However, this method may be called right before a factory reset issued via settings when + * the user elects to retain subscriptions. Doing so will mark them for retention so that they + * are not cleared after the ensuing reset. + * + * <p>Requires that the calling app has the {@link android.Manifest.permission#MASTER_CLEAR} + * permission. This is for internal system use only. + * + * @param callbackIntent a PendingIntent to launch when the operation completes. + * @hide + */ + public void retainSubscriptionsForFactoryReset(PendingIntent callbackIntent) { + if (!isEnabled()) { + sendUnavailableError(callbackIntent); + return; + } + try { + mController.retainSubscriptionsForFactoryReset(callbackIntent); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + private static void sendUnavailableError(PendingIntent callbackIntent) { try { callbackIntent.send(EMBEDDED_SUBSCRIPTION_RESULT_ERROR); diff --git a/telephony/java/android/telephony/ims/ImsServiceProxy.java b/telephony/java/android/telephony/ims/ImsServiceProxy.java index a75cd86dcf07..038e295d8822 100644 --- a/telephony/java/android/telephony/ims/ImsServiceProxy.java +++ b/telephony/java/android/telephony/ims/ImsServiceProxy.java @@ -90,11 +90,11 @@ public class ImsServiceProxy extends ImsServiceProxyCompat implements IRcsFeatur " status: " + status); if (mSlotId == slotId && feature == mSupportedFeature) { mFeatureStatusCached = status; + if (mStatusCallback != null) { + mStatusCallback.notifyStatusChanged(); + } } } - if (mStatusCallback != null) { - mStatusCallback.notifyStatusChanged(); - } } }; @@ -129,7 +129,9 @@ public class ImsServiceProxy extends ImsServiceProxyCompat implements IRcsFeatur @Override public void endSession(int sessionId) throws RemoteException { synchronized (mLock) { - checkServiceIsReady(); + // Only check to make sure the binder connection still exists. This method should + // still be able to be called when the state is STATE_NOT_AVAILABLE. + checkBinderConnection(); getServiceInterface(mBinder).endSession(mSlotId, mSupportedFeature, sessionId); } } diff --git a/telephony/java/com/android/internal/telephony/NetworkScanResult.java b/telephony/java/com/android/internal/telephony/NetworkScanResult.java index 7a7c17467dae..95f39d7f878a 100644 --- a/telephony/java/com/android/internal/telephony/NetworkScanResult.java +++ b/telephony/java/com/android/internal/telephony/NetworkScanResult.java @@ -35,10 +35,10 @@ import java.util.Objects; public final class NetworkScanResult implements Parcelable { // Contains only part of the scan result and more are coming. - public static final int SCAN_STATUS_PARTIAL = 0; + public static final int SCAN_STATUS_PARTIAL = 1; // Contains the last part of the scan result and the scan is now complete. - public static final int SCAN_STATUS_COMPLETE = 1; + public static final int SCAN_STATUS_COMPLETE = 2; // The status of the scan, only valid when scanError = SUCCESS. public int scanStatus; diff --git a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl index 725b89bcf351..b3fc90db75d3 100644 --- a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl +++ b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl @@ -26,8 +26,9 @@ import android.telephony.euicc.EuiccInfo; interface IEuiccController { oneway void continueOperation(in Intent resolutionIntent, in Bundle resolutionExtras); oneway void getDownloadableSubscriptionMetadata(in DownloadableSubscription subscription, - in PendingIntent callbackIntent); - oneway void getDefaultDownloadableSubscriptionList(in PendingIntent callbackIntent); + String callingPackage, in PendingIntent callbackIntent); + oneway void getDefaultDownloadableSubscriptionList( + String callingPackage, in PendingIntent callbackIntent); String getEid(); oneway void downloadSubscription(in DownloadableSubscription subscription, boolean switchAfterDownload, String callingPackage, in PendingIntent callbackIntent); @@ -39,4 +40,5 @@ interface IEuiccController { oneway void updateSubscriptionNickname(int subscriptionId, String nickname, in PendingIntent callbackIntent); oneway void eraseSubscriptions(in PendingIntent callbackIntent); + oneway void retainSubscriptionsForFactoryReset(in PendingIntent callbackIntent); }
\ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java index f28d1263d13a..0fabc2ff6b86 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java @@ -30,10 +30,6 @@ public class SmsCbConstants { /** Private constructor for utility class. */ private SmsCbConstants() { } - /** Channel 50 required by Brazil. ID 0~999 is allocated by GSMA */ - public static final int MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_50 - = 0x0032; - /** Start of PWS Message Identifier range (includes ETWS and CMAS). */ public static final int MESSAGE_ID_PWS_FIRST_IDENTIFIER = 0x1100; // 4352 diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java index 582506a367d0..d4098d94ba6c 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java @@ -278,6 +278,10 @@ public class SmsMessage extends SmsMessageBase { scAddress, destinationAddress, mtiByte, statusReportRequested, ret); + // Skip encoding pdu if error occurs when create pdu head and the error will be handled + // properly later on encodedMessage sanity check. + if (bo == null) return ret; + // User Data (and length) byte[] userData; try { @@ -420,6 +424,9 @@ public class SmsMessage extends SmsMessageBase { scAddress, destinationAddress, (byte) 0x41, // MTI = SMS-SUBMIT, // TP-UDHI = true statusReportRequested, ret); + // Skip encoding pdu if error occurs when create pdu head and the error will be handled + // properly later on encodedMessage sanity check. + if (bo == null) return ret; // TP-Data-Coding-Scheme // No class, 8 bit data @@ -451,7 +458,7 @@ public class SmsMessage extends SmsMessageBase { * @param destinationAddress the address of the destination for the message * @param mtiByte * @param ret <code>SubmitPdu</code> containing the encoded SC - * address, if applicable, and the encoded message + * address, if applicable, and the encoded message. Returns null on encode error. */ private static ByteArrayOutputStream getSubmitPduHead( String scAddress, String destinationAddress, byte mtiByte, @@ -482,6 +489,9 @@ public class SmsMessage extends SmsMessageBase { daBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(destinationAddress); + // return empty pduHead for invalid destination address + if (daBytes == null) return null; + // destination address length in BCD digits, ignoring TON byte and pad // TODO Should be better. bo.write((daBytes.length - 1) * 2 diff --git a/tests/StatusBar/AndroidManifest.xml b/tests/StatusBar/AndroidManifest.xml index 81442bfc60a4..6a082e990dab 100644 --- a/tests/StatusBar/AndroidManifest.xml +++ b/tests/StatusBar/AndroidManifest.xml @@ -6,6 +6,7 @@ <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" /> + <uses-permission android:name="android.permission.MANAGE_NOTIFICATIONS" /> <application> <activity android:name="StatusBarTest" android:label="_StatusBar"> diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java index 5dd42dd21c90..fc68183b5970 100644 --- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java +++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java @@ -129,6 +129,42 @@ public class NotificationTestList extends TestActivity mNM.notify(7001, n); } }, + new Test("with zen") { + public void run() + { + mNM.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALARMS); + Notification n = new Notification.Builder(NotificationTestList.this, + "default") + .setSmallIcon(R.drawable.icon2) + .setContentTitle("Default priority") + .build(); + mNM.notify("default", 7004, n); + try { + Thread.sleep(8000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + mNM.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); + } + }, + new Test("repeated") { + public void run() + { + for (int i = 0; i < 50; i++) { + Notification n = new Notification.Builder(NotificationTestList.this, + "default") + .setSmallIcon(R.drawable.icon2) + .setContentTitle("Default priority") + .build(); + mNM.notify("default", 7004, n); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }, new Test("Post a group") { public void run() { diff --git a/tests/testables/src/android/testing/TestableInstrumentation.java b/tests/testables/src/android/testing/TestableInstrumentation.java new file mode 100644 index 000000000000..93fed859cf39 --- /dev/null +++ b/tests/testables/src/android/testing/TestableInstrumentation.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package android.testing; + +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.os.TestLooperManager; +import android.support.test.runner.AndroidJUnitRunner; +import android.util.Log; + +import java.util.ArrayList; + +/** + * Wrapper around instrumentation that spins up a TestLooperManager around + * the main looper whenever a test is not using it to attempt to stop crashes + * from stopping other tests from running. + */ +public class TestableInstrumentation extends AndroidJUnitRunner { + + private static final String TAG = "TestableInstrumentation"; + + private static final int MAX_CRASHES = 5; + private static MainLooperManager sManager; + + @Override + public void onCreate(Bundle arguments) { + sManager = new MainLooperManager(); + Log.setWtfHandler((tag, what, system) -> { + if (system) { + Log.e(TAG, "WTF!!", what); + } else { + // These normally kill the app, but we don't want that in a test, instead we want + // it to throw. + throw new RuntimeException(what); + } + }); + super.onCreate(arguments); + } + + @Override + public void finish(int resultCode, Bundle results) { + sManager.destroy(); + super.finish(resultCode, results); + } + + public static void acquireMain() { + if (sManager != null) { + sManager.acquireMain(); + } + } + + public static void releaseMain() { + if (sManager != null) { + sManager.releaseMain(); + } + } + + public class MainLooperManager implements Runnable { + + private final ArrayList<Throwable> mExceptions = new ArrayList<>(); + private Message mStopMessage; + private final Handler mMainHandler; + private TestLooperManager mManager; + + public MainLooperManager() { + mMainHandler = new Handler(Looper.getMainLooper()); + startManaging(); + } + + @Override + public void run() { + try { + synchronized (this) { + // Let the thing starting us know we are up and ready to run. + notify(); + } + while (true) { + Message m = mManager.next(); + if (m == mStopMessage) { + mManager.recycle(m); + return; + } + try { + mManager.execute(m); + } catch (Throwable t) { + if (!checkStack(t) || (mExceptions.size() == MAX_CRASHES)) { + throw t; + } + mExceptions.add(t); + Log.d(TAG, "Ignoring exception to run more tests", t); + } + mManager.recycle(m); + } + } finally { + mManager.release(); + synchronized (this) { + // Let the caller know we are done managing the main thread. + notify(); + } + } + } + + private boolean checkStack(Throwable t) { + StackTraceElement topStack = t.getStackTrace()[0]; + String className = topStack.getClassName(); + if (className.equals(TestLooperManager.class.getName())) { + topStack = t.getCause().getStackTrace()[0]; + className = topStack.getClassName(); + } + // Only interested in blocking exceptions from the app itself, not from android + // framework. + return !className.startsWith("android.") + && !className.startsWith("com.android.internal"); + } + + public void destroy() { + mStopMessage.sendToTarget(); + if (mExceptions.size() != 0) { + throw new RuntimeException("Exception caught during tests", mExceptions.get(0)); + } + } + + public void acquireMain() { + synchronized (this) { + mStopMessage.sendToTarget(); + try { + wait(); + } catch (InterruptedException e) { + } + } + } + + public void releaseMain() { + startManaging(); + } + + private void startManaging() { + mStopMessage = mMainHandler.obtainMessage(); + synchronized (this) { + mManager = acquireLooperManager(Looper.getMainLooper()); + // This bit needs to happen on a background thread or it will hang if called + // from the same thread we are looking to block. + new Thread(() -> { + // Post a message to the main handler that will manage executing all future + // messages. + mMainHandler.post(this); + while (!mManager.hasMessages(mMainHandler, null, this)); + // Lastly run the message that executes this so it can manage the main thread. + Message next = mManager.next(); + // Run through messages until we reach ours. + while (next.getCallback() != this) { + mManager.execute(next); + mManager.recycle(next); + next = mManager.next(); + } + mManager.execute(next); + }).start(); + if (Looper.myLooper() != Looper.getMainLooper()) { + try { + wait(); + } catch (InterruptedException e) { + } + } + } + } + } +} diff --git a/tests/testables/src/android/testing/TestableLooper.java b/tests/testables/src/android/testing/TestableLooper.java index f6c3cb3ec498..f1a70921a469 100644 --- a/tests/testables/src/android/testing/TestableLooper.java +++ b/tests/testables/src/android/testing/TestableLooper.java @@ -29,7 +29,6 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.lang.reflect.Field; import java.util.Map; /** @@ -49,7 +48,7 @@ public class TestableLooper { private TestLooperManager mQueueWrapper; public TestableLooper(Looper l) throws Exception { - this(InstrumentationRegistry.getInstrumentation().acquireLooperManager(l), l); + this(acquireLooperManager(l), l); } private TestableLooper(TestLooperManager wrapper, Looper l) throws Exception { @@ -78,6 +77,9 @@ public class TestableLooper { */ public void destroy() throws NoSuchFieldException, IllegalAccessException { mQueueWrapper.release(); + if (mLooper == Looper.getMainLooper()) { + TestableInstrumentation.releaseMain(); + } } /** @@ -196,6 +198,13 @@ public class TestableLooper { } } + private static TestLooperManager acquireLooperManager(Looper l) { + if (l == Looper.getMainLooper()) { + TestableInstrumentation.acquireMain(); + } + return InstrumentationRegistry.getInstrumentation().acquireLooperManager(l); + } + private static final Map<Object, TestableLooper> sLoopers = new ArrayMap<>(); /** @@ -247,8 +256,7 @@ public class TestableLooper { } boolean set = mTestableLooper.mQueueWrapper == null; if (set) { - mTestableLooper.mQueueWrapper = InstrumentationRegistry.getInstrumentation() - .acquireLooperManager(mLooper); + mTestableLooper.mQueueWrapper = acquireLooperManager(mLooper); } try { Object[] ret = new Object[1]; @@ -283,6 +291,9 @@ public class TestableLooper { if (set) { mTestableLooper.mQueueWrapper.release(); mTestableLooper.mQueueWrapper = null; + if (mLooper == Looper.getMainLooper()) { + TestableInstrumentation.releaseMain(); + } } } } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index f596eef1bf21..0d4359e878d2 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -291,7 +291,6 @@ public class WifiP2pManager { "android.net.wifi.p2p.CALLING_PACKAGE"; IWifiP2pManager mService; - private final Map<Channel, Binder> mBinders = new HashMap<>(); private static final int BASE = Protocol.BASE_WIFI_P2P_MANAGER; @@ -670,11 +669,12 @@ public class WifiP2pManager { * by doing a call on {@link #initialize} */ public static class Channel { - Channel(Context context, Looper looper, ChannelListener l) { + Channel(Context context, Looper looper, ChannelListener l, Binder binder) { mAsyncChannel = new AsyncChannel(); mHandler = new P2pHandler(looper); mChannelListener = l; mContext = context; + mBinder = binder; } private final static int INVALID_LISTENER_KEY = 0; private ChannelListener mChannelListener; @@ -686,6 +686,8 @@ public class WifiP2pManager { private final Object mListenerMapLock = new Object(); private int mListenerKey = 0; + /* package */ final Binder mBinder; + private AsyncChannel mAsyncChannel; private P2pHandler mHandler; Context mContext; @@ -892,8 +894,8 @@ public class WifiP2pManager { */ public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) { Binder binder = new Binder(); - Channel channel = initalizeChannel(srcContext, srcLooper, listener, getMessenger(binder)); - mBinders.put(channel, binder); + Channel channel = initalizeChannel(srcContext, srcLooper, listener, getMessenger(binder), + binder); return channel; } @@ -903,14 +905,15 @@ public class WifiP2pManager { */ public Channel initializeInternal(Context srcContext, Looper srcLooper, ChannelListener listener) { - return initalizeChannel(srcContext, srcLooper, listener, getP2pStateMachineMessenger()); + return initalizeChannel(srcContext, srcLooper, listener, getP2pStateMachineMessenger(), + null); } private Channel initalizeChannel(Context srcContext, Looper srcLooper, ChannelListener listener, - Messenger messenger) { + Messenger messenger, Binder binder) { if (messenger == null) return null; - Channel c = new Channel(srcContext, srcLooper, listener); + Channel c = new Channel(srcContext, srcLooper, listener, binder); if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger) == AsyncChannel.STATUS_SUCCESSFUL) { return c; @@ -1428,8 +1431,9 @@ public class WifiP2pManager { */ public void close(Channel c) { try { - mService.close(mBinders.get(c)); - mBinders.remove(c); + if (c != null) { + mService.close(c.mBinder); + } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } |