Merge "Start using bcinfo components within librs."
diff --git a/Android.mk b/Android.mk
index b61936f..752a5f8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -116,15 +116,10 @@
core/java/android/net/INetworkPolicyListener.aidl \
core/java/android/net/INetworkPolicyManager.aidl \
core/java/android/net/INetworkStatsService.aidl \
- core/java/android/nfc/ILlcpConnectionlessSocket.aidl \
- core/java/android/nfc/ILlcpServiceSocket.aidl \
- core/java/android/nfc/ILlcpSocket.aidl \
core/java/android/nfc/INdefPushCallback.aidl \
core/java/android/nfc/INfcAdapter.aidl \
core/java/android/nfc/INfcAdapterExtras.aidl \
core/java/android/nfc/INfcTag.aidl \
- core/java/android/nfc/IP2pInitiator.aidl \
- core/java/android/nfc/IP2pTarget.aidl \
core/java/android/os/IHardwareService.aidl \
core/java/android/os/IMessenger.aidl \
core/java/android/os/INetworkManagementService.aidl \
@@ -188,6 +183,7 @@
media/java/android/media/IAudioFocusDispatcher.aidl \
media/java/android/media/IMediaScannerListener.aidl \
media/java/android/media/IMediaScannerService.aidl \
+ media/java/android/media/IRemoteControlClient.aidl \
telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl \
telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
telephony/java/com/android/internal/telephony/ITelephony.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index f3eaeeb..a87293d 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -101,6 +101,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os)
$(call add-clean-step, rm -rf $(OUT_DIR)target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/keystore/java/android/security/IKeyChainAliasResponse.java)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/vpn)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/api/14.txt b/api/14.txt
index 895c44d..3d96c11 100644
--- a/api/14.txt
+++ b/api/14.txt
@@ -20979,45 +20979,17 @@
public class Surface implements android.os.Parcelable {
method public int describeContents();
- method public void freeze();
- method public void hide();
method public boolean isValid();
method public android.graphics.Canvas lockCanvas(android.graphics.Rect) throws java.lang.IllegalArgumentException, android.view.Surface.OutOfResourcesException;
method public void readFromParcel(android.os.Parcel);
- method public void setAlpha(float);
- method public void setFlags(int, int);
- method public void setFreezeTint(int);
- method public void setLayer(int);
- method public void setMatrix(float, float, float, float);
- method public static void setOrientation(int, int);
- method public void setPosition(int, int);
- method public void setSize(int, int);
- method public void setTransparentRegionHint(android.graphics.Region);
- method public void show();
- method public void unfreeze();
method public void unlockCanvas(android.graphics.Canvas);
method public void unlockCanvasAndPost(android.graphics.Canvas);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
- field public static final int FX_SURFACE_BLUR = 65536; // 0x10000
- field public static final int FX_SURFACE_DIM = 131072; // 0x20000
- field public static final int FX_SURFACE_MASK = 983040; // 0xf0000
- field public static final int FX_SURFACE_NORMAL = 0; // 0x0
- field public static final deprecated int GPU = 40; // 0x28
- field public static final deprecated int HARDWARE = 16; // 0x10
- field public static final int HIDDEN = 4; // 0x4
- field public static final int NON_PREMULTIPLIED = 256; // 0x100
- field public static final deprecated int PUSH_BUFFERS = 512; // 0x200
field public static final int ROTATION_0 = 0; // 0x0
field public static final int ROTATION_180 = 2; // 0x2
field public static final int ROTATION_270 = 3; // 0x3
field public static final int ROTATION_90 = 1; // 0x1
- field public static final int SECURE = 128; // 0x80
- field public static final deprecated int SURACE_FROZEN = 2; // 0x2
- field public static final int SURFACE_BLUR_FREEZE = 16; // 0x10
- field public static final int SURFACE_DITHER = 4; // 0x4
- field public static final int SURFACE_FROZEN = 2; // 0x2
- field public static final int SURFACE_HIDDEN = 1; // 0x1
}
public static class Surface.OutOfResourcesException extends java.lang.Exception {
diff --git a/api/current.txt b/api/current.txt
index 44fbc81..035da89 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -15,6 +15,7 @@
field public static final java.lang.String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER";
field public static final java.lang.String ACCESS_WIFI_STATE = "android.permission.ACCESS_WIFI_STATE";
field public static final java.lang.String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER";
+ field public static final java.lang.String ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL";
field public static final java.lang.String AUTHENTICATE_ACCOUNTS = "android.permission.AUTHENTICATE_ACCOUNTS";
field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
@@ -83,7 +84,6 @@
field public static final java.lang.String READ_SMS = "android.permission.READ_SMS";
field public static final java.lang.String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS";
field public static final java.lang.String READ_SYNC_STATS = "android.permission.READ_SYNC_STATS";
- field public static final java.lang.String READ_WRITE_OWN_VOICEMAIL = "com.android.voicemail.permission.READ_WRITE_OWN_VOICEMAIL";
field public static final java.lang.String REBOOT = "android.permission.REBOOT";
field public static final java.lang.String RECEIVE_BOOT_COMPLETED = "android.permission.RECEIVE_BOOT_COMPLETED";
field public static final java.lang.String RECEIVE_MMS = "android.permission.RECEIVE_MMS";
@@ -183,19 +183,19 @@
public static final class R.attr {
ctor public R.attr();
field public static final int absListViewStyle = 16842858; // 0x101006a
- field public static final int accessibilityEventTypes = 16843646; // 0x101037e
- field public static final int accessibilityFeedbackType = 16843648; // 0x1010380
- field public static final int accessibilityFlags = 16843650; // 0x1010382
+ field public static final int accessibilityEventTypes = 16843644; // 0x101037c
+ field public static final int accessibilityFeedbackType = 16843646; // 0x101037e
+ field public static final int accessibilityFlags = 16843648; // 0x1010380
field public static final int accountPreferences = 16843423; // 0x101029f
field public static final int accountType = 16843407; // 0x101028f
field public static final int action = 16842797; // 0x101002d
field public static final int actionBarSize = 16843499; // 0x10102eb
- field public static final int actionBarSplitStyle = 16843668; // 0x1010394
+ field public static final int actionBarSplitStyle = 16843666; // 0x1010392
field public static final int actionBarStyle = 16843470; // 0x10102ce
field public static final int actionBarTabBarStyle = 16843508; // 0x10102f4
field public static final int actionBarTabStyle = 16843507; // 0x10102f3
field public static final int actionBarTabTextStyle = 16843509; // 0x10102f5
- field public static final int actionBarWidgetTheme = 16843683; // 0x10103a3
+ field public static final int actionBarWidgetTheme = 16843681; // 0x10103a1
field public static final int actionButtonStyle = 16843480; // 0x10102d8
field public static final int actionDropDownStyle = 16843479; // 0x10102d7
field public static final int actionLayout = 16843515; // 0x10102fb
@@ -207,10 +207,10 @@
field public static final int actionModeCopyDrawable = 16843538; // 0x1010312
field public static final int actionModeCutDrawable = 16843537; // 0x1010311
field public static final int actionModePasteDrawable = 16843539; // 0x1010313
- field public static final int actionModeSelectAllDrawable = 16843644; // 0x101037c
- field public static final int actionModeStyle = 16843680; // 0x10103a0
+ field public static final int actionModeSelectAllDrawable = 16843642; // 0x101037a
+ field public static final int actionModeStyle = 16843678; // 0x101039e
field public static final int actionOverflowButtonStyle = 16843510; // 0x10102f6
- field public static final int actionProviderClass = 16843669; // 0x1010395
+ field public static final int actionProviderClass = 16843667; // 0x1010393
field public static final int actionViewClass = 16843516; // 0x10102fc
field public static final int activatedBackgroundIndicator = 16843517; // 0x10102fd
field public static final int activityCloseEnterAnimation = 16842938; // 0x10100ba
@@ -256,8 +256,8 @@
field public static final int background = 16842964; // 0x10100d4
field public static final int backgroundDimAmount = 16842802; // 0x1010032
field public static final int backgroundDimEnabled = 16843295; // 0x101021f
- field public static final int backgroundSplit = 16843671; // 0x1010397
- field public static final int backgroundStacked = 16843670; // 0x1010396
+ field public static final int backgroundSplit = 16843669; // 0x1010395
+ field public static final int backgroundStacked = 16843668; // 0x1010394
field public static final int backupAgent = 16843391; // 0x101027f
field public static final int baseline = 16843548; // 0x101031c
field public static final int baselineAlignBottom = 16843042; // 0x1010122
@@ -266,7 +266,7 @@
field public static final int borderlessButtonStyle = 16843563; // 0x101032b
field public static final int bottom = 16843184; // 0x10101b0
field public static final int bottomBright = 16842957; // 0x10100cd
- field public static final int bottomChevronDrawable = 16843657; // 0x1010389
+ field public static final int bottomChevronDrawable = 16843655; // 0x1010387
field public static final int bottomDark = 16842953; // 0x10100c9
field public static final int bottomLeftRadius = 16843179; // 0x10101ab
field public static final int bottomMedium = 16842958; // 0x10100ce
@@ -285,7 +285,7 @@
field public static final int cacheColorHint = 16843009; // 0x1010101
field public static final int calendarViewShown = 16843596; // 0x101034c
field public static final int calendarViewStyle = 16843613; // 0x101035d
- field public static final int canRetrieveWindowContent = 16843651; // 0x1010383
+ field public static final int canRetrieveWindowContent = 16843649; // 0x1010381
field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230
field public static final deprecated int capitalize = 16843113; // 0x1010169
field public static final int centerBright = 16842956; // 0x10100cc
@@ -314,15 +314,15 @@
field public static final int codes = 16843330; // 0x1010242
field public static final int collapseColumns = 16843083; // 0x101014b
field public static final int color = 16843173; // 0x10101a5
- field public static final int colorActivatedHighlight = 16843676; // 0x101039c
+ field public static final int colorActivatedHighlight = 16843674; // 0x101039a
field public static final int colorBackground = 16842801; // 0x1010031
field public static final int colorBackgroundCacheHint = 16843435; // 0x10102ab
- field public static final int colorFocusedHighlight = 16843675; // 0x101039b
+ field public static final int colorFocusedHighlight = 16843673; // 0x1010399
field public static final int colorForeground = 16842800; // 0x1010030
field public static final int colorForegroundInverse = 16843270; // 0x1010206
- field public static final int colorLongPressedHighlight = 16843674; // 0x101039a
- field public static final int colorMultiSelectHighlight = 16843677; // 0x101039d
- field public static final int colorPressedHighlight = 16843673; // 0x1010399
+ field public static final int colorLongPressedHighlight = 16843672; // 0x1010398
+ field public static final int colorMultiSelectHighlight = 16843675; // 0x101039b
+ field public static final int colorPressedHighlight = 16843671; // 0x1010397
field public static final int columnCount = 16843635; // 0x1010373
field public static final int columnDelay = 16843215; // 0x10101cf
field public static final int columnOrderPreserved = 16843636; // 0x1010374
@@ -379,11 +379,11 @@
field public static final int drawSelectorOnTop = 16843004; // 0x10100fc
field public static final int drawable = 16843161; // 0x1010199
field public static final int drawableBottom = 16843118; // 0x101016e
- field public static final int drawableEnd = 16843679; // 0x101039f
+ field public static final int drawableEnd = 16843677; // 0x101039d
field public static final int drawableLeft = 16843119; // 0x101016f
field public static final int drawablePadding = 16843121; // 0x1010171
field public static final int drawableRight = 16843120; // 0x1010170
- field public static final int drawableStart = 16843678; // 0x101039e
+ field public static final int drawableStart = 16843676; // 0x101039c
field public static final int drawableTop = 16843117; // 0x101016d
field public static final int drawingCacheQuality = 16842984; // 0x10100e8
field public static final int dropDownAnchor = 16843363; // 0x1010263
@@ -440,7 +440,7 @@
field public static final int fastScrollTextColor = 16843609; // 0x1010359
field public static final int fastScrollThumbDrawable = 16843574; // 0x1010336
field public static final int fastScrollTrackDrawable = 16843577; // 0x1010339
- field public static final int feedbackCount = 16843663; // 0x101038f
+ field public static final int feedbackCount = 16843661; // 0x101038d
field public static final int fillAfter = 16843197; // 0x10101bd
field public static final int fillBefore = 16843196; // 0x10101bc
field public static final int fillEnabled = 16843343; // 0x101024f
@@ -493,7 +493,7 @@
field public static final int hand_hour = 16843011; // 0x1010103
field public static final int hand_minute = 16843012; // 0x1010104
field public static final int handle = 16843354; // 0x101025a
- field public static final int handleDrawable = 16843653; // 0x1010385
+ field public static final int handleDrawable = 16843651; // 0x1010383
field public static final int handleProfiling = 16842786; // 0x1010022
field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e
field public static final int hardwareAccelerated = 16843475; // 0x10102d3
@@ -502,12 +502,12 @@
field public static final int headerDividersEnabled = 16843310; // 0x101022e
field public static final int height = 16843093; // 0x1010155
field public static final int hint = 16843088; // 0x1010150
- field public static final int hitRadius = 16843660; // 0x101038c
+ field public static final int hitRadius = 16843658; // 0x101038a
field public static final int homeAsUpIndicator = 16843531; // 0x101030b
field public static final int homeLayout = 16843549; // 0x101031d
field public static final int horizontalDivider = 16843053; // 0x101012d
field public static final int horizontalGap = 16843327; // 0x101023f
- field public static final int horizontalOffset = 16843665; // 0x1010391
+ field public static final int horizontalOffset = 16843663; // 0x101038f
field public static final int horizontalScrollViewStyle = 16843603; // 0x1010353
field public static final int horizontalSpacing = 16843028; // 0x1010114
field public static final int host = 16842792; // 0x1010028
@@ -553,7 +553,7 @@
field public static final int installLocation = 16843447; // 0x10102b7
field public static final int interpolator = 16843073; // 0x1010141
field public static final int isAlwaysSyncable = 16843571; // 0x1010333
- field public static final int isAuxiliary = 16843645; // 0x101037d
+ field public static final int isAuxiliary = 16843643; // 0x101037b
field public static final int isDefault = 16843297; // 0x1010221
field public static final int isIndicator = 16843079; // 0x1010147
field public static final int isModifier = 16843334; // 0x1010246
@@ -606,8 +606,7 @@
field public static final int layout_centerInParent = 16843151; // 0x101018f
field public static final int layout_centerVertical = 16843153; // 0x1010191
field public static final int layout_column = 16843084; // 0x101014c
- field public static final deprecated int layout_columnFlexibility = 16843643; // 0x101037b
- field public static final int layout_columnSpan = 16843642; // 0x101037a
+ field public static final int layout_columnSpan = 16843641; // 0x1010379
field public static final int layout_gravity = 16842931; // 0x10100b3
field public static final int layout_height = 16842997; // 0x10100f5
field public static final int layout_margin = 16842998; // 0x10100f6
@@ -616,7 +615,6 @@
field public static final int layout_marginRight = 16843001; // 0x10100f9
field public static final int layout_marginTop = 16843000; // 0x10100f8
field public static final int layout_row = 16843639; // 0x1010377
- field public static final deprecated int layout_rowFlexibility = 16843641; // 0x1010379
field public static final int layout_rowSpan = 16843640; // 0x1010378
field public static final int layout_scale = 16843155; // 0x1010193
field public static final int layout_span = 16843085; // 0x101014d
@@ -627,7 +625,7 @@
field public static final int layout_x = 16843135; // 0x101017f
field public static final int layout_y = 16843136; // 0x1010180
field public static final int left = 16843181; // 0x10101ad
- field public static final int leftChevronDrawable = 16843654; // 0x1010386
+ field public static final int leftChevronDrawable = 16843652; // 0x1010384
field public static final int lineSpacingExtra = 16843287; // 0x1010217
field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
field public static final int lines = 16843092; // 0x1010154
@@ -639,8 +637,8 @@
field public static final int listDividerAlertDialog = 16843525; // 0x1010305
field public static final int listPopupWindowStyle = 16843519; // 0x10102ff
field public static final int listPreferredItemHeight = 16842829; // 0x101004d
- field public static final int listPreferredItemHeightLarge = 16843666; // 0x1010392
- field public static final int listPreferredItemHeightSmall = 16843667; // 0x1010393
+ field public static final int listPreferredItemHeightLarge = 16843664; // 0x1010390
+ field public static final int listPreferredItemHeightSmall = 16843665; // 0x1010391
field public static final int listSelector = 16843003; // 0x10100fb
field public static final int listSeparatorTextViewStyle = 16843272; // 0x1010208
field public static final int listViewStyle = 16842868; // 0x1010074
@@ -671,8 +669,8 @@
field public static final int minHeight = 16843072; // 0x1010140
field public static final int minLevel = 16843185; // 0x10101b1
field public static final int minLines = 16843094; // 0x1010156
- field public static final int minResizeHeight = 16843682; // 0x10103a2
- field public static final int minResizeWidth = 16843681; // 0x10103a1
+ field public static final int minResizeHeight = 16843680; // 0x10103a0
+ field public static final int minResizeWidth = 16843679; // 0x101039f
field public static final int minSdkVersion = 16843276; // 0x101020c
field public static final int minWidth = 16843071; // 0x101013f
field public static final int mode = 16843134; // 0x101017e
@@ -688,7 +686,7 @@
field public static final int nextFocusUp = 16842979; // 0x10100e3
field public static final int noHistory = 16843309; // 0x101022d
field public static final int normalScreens = 16843397; // 0x1010285
- field public static final int notificationTimeout = 16843649; // 0x1010381
+ field public static final int notificationTimeout = 16843647; // 0x101037f
field public static final int numColumns = 16843032; // 0x1010118
field public static final int numStars = 16843076; // 0x1010144
field public static final deprecated int numeric = 16843109; // 0x1010165
@@ -702,11 +700,11 @@
field public static final int orderingFromXml = 16843239; // 0x10101e7
field public static final int orientation = 16842948; // 0x10100c4
field public static final int outAnimation = 16843128; // 0x1010178
- field public static final int outerRadius = 16843659; // 0x101038b
+ field public static final int outerRadius = 16843657; // 0x1010389
field public static final int overScrollFooter = 16843459; // 0x10102c3
field public static final int overScrollHeader = 16843458; // 0x10102c2
field public static final int overScrollMode = 16843457; // 0x10102c1
- field public static final int packageNames = 16843647; // 0x101037f
+ field public static final int packageNames = 16843645; // 0x101037d
field public static final int padding = 16842965; // 0x10100d5
field public static final int paddingBottom = 16842969; // 0x10100d9
field public static final int paddingLeft = 16842966; // 0x10100d6
@@ -791,7 +789,7 @@
field public static final int restoreAnyVersion = 16843450; // 0x10102ba
field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d
field public static final int right = 16843183; // 0x10101af
- field public static final int rightChevronDrawable = 16843655; // 0x1010387
+ field public static final int rightChevronDrawable = 16843653; // 0x1010385
field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
field public static final int ringtoneType = 16843257; // 0x10101f9
field public static final int rotation = 16843558; // 0x1010326
@@ -867,7 +865,7 @@
field public static final int smallIcon = 16843422; // 0x101029e
field public static final int smallScreens = 16843396; // 0x1010284
field public static final int smoothScrollbar = 16843313; // 0x1010231
- field public static final int snapMargin = 16843662; // 0x101038e
+ field public static final int snapMargin = 16843660; // 0x101038c
field public static final int soundEffectsEnabled = 16843285; // 0x1010215
field public static final int spacing = 16843027; // 0x1010113
field public static final int spinnerDropDownItemStyle = 16842887; // 0x1010087
@@ -932,7 +930,7 @@
field public static final int tag = 16842961; // 0x10100d1
field public static final int targetActivity = 16843266; // 0x1010202
field public static final int targetClass = 16842799; // 0x101002f
- field public static final int targetDrawables = 16843652; // 0x1010384
+ field public static final int targetDrawables = 16843650; // 0x1010382
field public static final int targetPackage = 16842785; // 0x1010021
field public static final int targetSdkVersion = 16843376; // 0x1010270
field public static final int taskAffinity = 16842770; // 0x1010012
@@ -947,7 +945,7 @@
field public static final int tension = 16843370; // 0x101026a
field public static final int testOnly = 16843378; // 0x1010272
field public static final int text = 16843087; // 0x101014f
- field public static final int textAllCaps = 16843672; // 0x1010398
+ field public static final int textAllCaps = 16843670; // 0x1010396
field public static final int textAppearance = 16842804; // 0x1010034
field public static final int textAppearanceButton = 16843271; // 0x1010207
field public static final int textAppearanceInverse = 16842805; // 0x1010035
@@ -1021,7 +1019,7 @@
field public static final int toYScale = 16843205; // 0x10101c5
field public static final int top = 16843182; // 0x10101ae
field public static final int topBright = 16842955; // 0x10100cb
- field public static final int topChevronDrawable = 16843656; // 0x1010388
+ field public static final int topChevronDrawable = 16843654; // 0x1010386
field public static final int topDark = 16842951; // 0x10100c7
field public static final int topLeftRadius = 16843177; // 0x10101a9
field public static final int topOffset = 16843352; // 0x1010258
@@ -1033,6 +1031,7 @@
field public static final int translationY = 16843555; // 0x1010323
field public static final int type = 16843169; // 0x10101a1
field public static final int typeface = 16842902; // 0x1010096
+ field public static final int uiOptions = 16843682; // 0x10103a2
field public static final int uncertainGestureColor = 16843382; // 0x1010276
field public static final int unfocusedMonthDateColor = 16843588; // 0x1010344
field public static final int unselectedAlpha = 16843278; // 0x101020e
@@ -1051,10 +1050,10 @@
field public static final int verticalCorrection = 16843322; // 0x101023a
field public static final int verticalDivider = 16843054; // 0x101012e
field public static final int verticalGap = 16843328; // 0x1010240
- field public static final int verticalOffset = 16843664; // 0x1010390
+ field public static final int verticalOffset = 16843662; // 0x101038e
field public static final int verticalScrollbarPosition = 16843572; // 0x1010334
field public static final int verticalSpacing = 16843029; // 0x1010115
- field public static final int vibrationDuration = 16843661; // 0x101038d
+ field public static final int vibrationDuration = 16843659; // 0x101038b
field public static final int visibility = 16842972; // 0x10100dc
field public static final int visible = 16843156; // 0x1010194
field public static final int vmSafeMode = 16843448; // 0x10102b8
@@ -1071,7 +1070,7 @@
field public static final int wallpaperIntraOpenExitAnimation = 16843416; // 0x1010298
field public static final int wallpaperOpenEnterAnimation = 16843411; // 0x1010293
field public static final int wallpaperOpenExitAnimation = 16843412; // 0x1010294
- field public static final int waveDrawable = 16843658; // 0x101038a
+ field public static final int waveDrawable = 16843656; // 0x1010388
field public static final int webTextViewStyle = 16843449; // 0x10102b9
field public static final int webViewStyle = 16842885; // 0x1010085
field public static final int weekDayTextAppearance = 16843592; // 0x1010348
@@ -1499,6 +1498,12 @@
field public static final int Animation_InputMethod = 16973910; // 0x1030056
field public static final int Animation_Toast = 16973828; // 0x1030004
field public static final int Animation_Translucent = 16973827; // 0x1030003
+ field public static final int DeviceDefault_ButtonBar = 16974287; // 0x10301cf
+ field public static final int DeviceDefault_ButtonBar_AlertDialog = 16974288; // 0x10301d0
+ field public static final int DeviceDefault_Light_ButtonBar = 16974290; // 0x10301d2
+ field public static final int DeviceDefault_Light_ButtonBar_AlertDialog = 16974291; // 0x10301d3
+ field public static final int DeviceDefault_Light_SegmentedButton = 16974292; // 0x10301d4
+ field public static final int DeviceDefault_SegmentedButton = 16974289; // 0x10301d1
field public static final int Holo_ButtonBar = 16974053; // 0x10300e5
field public static final int Holo_ButtonBar_AlertDialog = 16974055; // 0x10300e7
field public static final int Holo_Light_ButtonBar = 16974054; // 0x10300e6
@@ -1513,6 +1518,40 @@
field public static final int MediaButton_Previous = 16973880; // 0x1030038
field public static final int MediaButton_Rew = 16973884; // 0x103003c
field public static final int TextAppearance = 16973886; // 0x103003e
+ field public static final int TextAppearance_DeviceDefault = 16974253; // 0x10301ad
+ field public static final int TextAppearance_DeviceDefault_DialogWindowTitle = 16974264; // 0x10301b8
+ field public static final int TextAppearance_DeviceDefault_Inverse = 16974254; // 0x10301ae
+ field public static final int TextAppearance_DeviceDefault_Large = 16974255; // 0x10301af
+ field public static final int TextAppearance_DeviceDefault_Large_Inverse = 16974256; // 0x10301b0
+ field public static final int TextAppearance_DeviceDefault_Medium = 16974257; // 0x10301b1
+ field public static final int TextAppearance_DeviceDefault_Medium_Inverse = 16974258; // 0x10301b2
+ field public static final int TextAppearance_DeviceDefault_SearchResult_Subtitle = 16974262; // 0x10301b6
+ field public static final int TextAppearance_DeviceDefault_SearchResult_Title = 16974261; // 0x10301b5
+ field public static final int TextAppearance_DeviceDefault_Small = 16974259; // 0x10301b3
+ field public static final int TextAppearance_DeviceDefault_Small_Inverse = 16974260; // 0x10301b4
+ field public static final int TextAppearance_DeviceDefault_Widget = 16974265; // 0x10301b9
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionBar_Menu = 16974286; // 0x10301ce
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionBar_Subtitle = 16974279; // 0x10301c7
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionBar_Subtitle_Inverse = 16974283; // 0x10301cb
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionBar_Title = 16974278; // 0x10301c6
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionBar_Title_Inverse = 16974282; // 0x10301ca
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionMode_Subtitle = 16974281; // 0x10301c9
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionMode_Subtitle_Inverse = 16974285; // 0x10301cd
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionMode_Title = 16974280; // 0x10301c8
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionMode_Title_Inverse = 16974284; // 0x10301cc
+ field public static final int TextAppearance_DeviceDefault_Widget_Button = 16974266; // 0x10301ba
+ field public static final int TextAppearance_DeviceDefault_Widget_DropDownHint = 16974271; // 0x10301bf
+ field public static final int TextAppearance_DeviceDefault_Widget_DropDownItem = 16974272; // 0x10301c0
+ field public static final int TextAppearance_DeviceDefault_Widget_EditText = 16974274; // 0x10301c2
+ field public static final int TextAppearance_DeviceDefault_Widget_IconMenu_Item = 16974267; // 0x10301bb
+ field public static final int TextAppearance_DeviceDefault_Widget_PopupMenu = 16974275; // 0x10301c3
+ field public static final int TextAppearance_DeviceDefault_Widget_PopupMenu_Large = 16974276; // 0x10301c4
+ field public static final int TextAppearance_DeviceDefault_Widget_PopupMenu_Small = 16974277; // 0x10301c5
+ field public static final int TextAppearance_DeviceDefault_Widget_TabWidget = 16974268; // 0x10301bc
+ field public static final int TextAppearance_DeviceDefault_Widget_TextView = 16974269; // 0x10301bd
+ field public static final int TextAppearance_DeviceDefault_Widget_TextView_PopupMenu = 16974270; // 0x10301be
+ field public static final int TextAppearance_DeviceDefault_Widget_TextView_SpinnerItem = 16974273; // 0x10301c1
+ field public static final int TextAppearance_DeviceDefault_WindowTitle = 16974263; // 0x10301b7
field public static final int TextAppearance_DialogWindowTitle = 16973889; // 0x1030041
field public static final int TextAppearance_Holo = 16974075; // 0x10300fb
field public static final int TextAppearance_Holo_DialogWindowTitle = 16974103; // 0x1030117
@@ -1526,15 +1565,15 @@
field public static final int TextAppearance_Holo_Small = 16974081; // 0x1030101
field public static final int TextAppearance_Holo_Small_Inverse = 16974082; // 0x1030102
field public static final int TextAppearance_Holo_Widget = 16974085; // 0x1030105
- field public static final int TextAppearance_Holo_Widget_ActionBar_Menu = 16974113; // 0x1030121
+ field public static final int TextAppearance_Holo_Widget_ActionBar_Menu = 16974112; // 0x1030120
field public static final int TextAppearance_Holo_Widget_ActionBar_Subtitle = 16974099; // 0x1030113
- field public static final int TextAppearance_Holo_Widget_ActionBar_Subtitle_Inverse = 16974110; // 0x103011e
+ field public static final int TextAppearance_Holo_Widget_ActionBar_Subtitle_Inverse = 16974109; // 0x103011d
field public static final int TextAppearance_Holo_Widget_ActionBar_Title = 16974098; // 0x1030112
- field public static final int TextAppearance_Holo_Widget_ActionBar_Title_Inverse = 16974109; // 0x103011d
+ field public static final int TextAppearance_Holo_Widget_ActionBar_Title_Inverse = 16974108; // 0x103011c
field public static final int TextAppearance_Holo_Widget_ActionMode_Subtitle = 16974101; // 0x1030115
- field public static final int TextAppearance_Holo_Widget_ActionMode_Subtitle_Inverse = 16974112; // 0x1030120
+ field public static final int TextAppearance_Holo_Widget_ActionMode_Subtitle_Inverse = 16974111; // 0x103011f
field public static final int TextAppearance_Holo_Widget_ActionMode_Title = 16974100; // 0x1030114
- field public static final int TextAppearance_Holo_Widget_ActionMode_Title_Inverse = 16974111; // 0x103011f
+ field public static final int TextAppearance_Holo_Widget_ActionMode_Title_Inverse = 16974110; // 0x103011e
field public static final int TextAppearance_Holo_Widget_Button = 16974086; // 0x1030106
field public static final int TextAppearance_Holo_Widget_DropDownHint = 16974091; // 0x103010b
field public static final int TextAppearance_Holo_Widget_DropDownItem = 16974092; // 0x103010c
@@ -1578,6 +1617,30 @@
field public static final int Theme_Black = 16973832; // 0x1030008
field public static final int Theme_Black_NoTitleBar = 16973833; // 0x1030009
field public static final int Theme_Black_NoTitleBar_Fullscreen = 16973834; // 0x103000a
+ field public static final int Theme_DeviceDefault = 16974120; // 0x1030128
+ field public static final int Theme_DeviceDefault_Dialog = 16974126; // 0x103012e
+ field public static final int Theme_DeviceDefault_DialogWhenLarge = 16974134; // 0x1030136
+ field public static final int Theme_DeviceDefault_DialogWhenLarge_NoActionBar = 16974135; // 0x1030137
+ field public static final int Theme_DeviceDefault_Dialog_MinWidth = 16974127; // 0x103012f
+ field public static final int Theme_DeviceDefault_Dialog_NoActionBar = 16974128; // 0x1030130
+ field public static final int Theme_DeviceDefault_Dialog_NoActionBar_MinWidth = 16974129; // 0x1030131
+ field public static final int Theme_DeviceDefault_InputMethod = 16974142; // 0x103013e
+ field public static final int Theme_DeviceDefault_Light = 16974123; // 0x103012b
+ field public static final int Theme_DeviceDefault_Light_DarkActionBar = 16974143; // 0x103013f
+ field public static final int Theme_DeviceDefault_Light_Dialog = 16974130; // 0x1030132
+ field public static final int Theme_DeviceDefault_Light_DialogWhenLarge = 16974136; // 0x1030138
+ field public static final int Theme_DeviceDefault_Light_DialogWhenLarge_NoActionBar = 16974137; // 0x1030139
+ field public static final int Theme_DeviceDefault_Light_Dialog_MinWidth = 16974131; // 0x1030133
+ field public static final int Theme_DeviceDefault_Light_Dialog_NoActionBar = 16974132; // 0x1030134
+ field public static final int Theme_DeviceDefault_Light_Dialog_NoActionBar_MinWidth = 16974133; // 0x1030135
+ field public static final int Theme_DeviceDefault_Light_NoActionBar = 16974124; // 0x103012c
+ field public static final int Theme_DeviceDefault_Light_NoActionBar_Fullscreen = 16974125; // 0x103012d
+ field public static final int Theme_DeviceDefault_Light_Panel = 16974139; // 0x103013b
+ field public static final int Theme_DeviceDefault_NoActionBar = 16974121; // 0x1030129
+ field public static final int Theme_DeviceDefault_NoActionBar_Fullscreen = 16974122; // 0x103012a
+ field public static final int Theme_DeviceDefault_Panel = 16974138; // 0x103013a
+ field public static final int Theme_DeviceDefault_Wallpaper = 16974140; // 0x103013c
+ field public static final int Theme_DeviceDefault_Wallpaper_NoTitleBar = 16974141; // 0x103013d
field public static final int Theme_Dialog = 16973835; // 0x103000b
field public static final int Theme_Holo = 16973931; // 0x103006b
field public static final int Theme_Holo_Dialog = 16973935; // 0x103006f
@@ -1588,6 +1651,7 @@
field public static final int Theme_Holo_Dialog_NoActionBar_MinWidth = 16973938; // 0x1030072
field public static final int Theme_Holo_InputMethod = 16973951; // 0x103007f
field public static final int Theme_Holo_Light = 16973934; // 0x103006e
+ field public static final int Theme_Holo_Light_DarkActionBar = 16974105; // 0x1030119
field public static final int Theme_Holo_Light_Dialog = 16973939; // 0x1030073
field public static final int Theme_Holo_Light_DialogWhenLarge = 16973945; // 0x1030079
field public static final int Theme_Holo_Light_DialogWhenLarge_NoActionBar = 16973946; // 0x103007a
@@ -1597,17 +1661,9 @@
field public static final int Theme_Holo_Light_NoActionBar = 16974064; // 0x10300f0
field public static final int Theme_Holo_Light_NoActionBar_Fullscreen = 16974065; // 0x10300f1
field public static final int Theme_Holo_Light_Panel = 16973948; // 0x103007c
- field public static final int Theme_Holo_Light_SolidActionBar = 16974122; // 0x103012a
- field public static final int Theme_Holo_Light_SolidActionBar_Inverse = 16974123; // 0x103012b
- field public static final int Theme_Holo_Light_SolidActionBar_Inverse_SplitActionBarWhenNarrow = 16974126; // 0x103012e
- field public static final int Theme_Holo_Light_SolidActionBar_SplitActionBarWhenNarrow = 16974125; // 0x103012d
- field public static final int Theme_Holo_Light_SplitActionBarWhenNarrow = 16974106; // 0x103011a
field public static final int Theme_Holo_NoActionBar = 16973932; // 0x103006c
field public static final int Theme_Holo_NoActionBar_Fullscreen = 16973933; // 0x103006d
field public static final int Theme_Holo_Panel = 16973947; // 0x103007b
- field public static final int Theme_Holo_SolidActionBar = 16974121; // 0x1030129
- field public static final int Theme_Holo_SolidActionBar_SplitActionBarWhenNarrow = 16974124; // 0x103012c
- field public static final int Theme_Holo_SplitActionBarWhenNarrow = 16974105; // 0x1030119
field public static final int Theme_Holo_Wallpaper = 16973949; // 0x103007d
field public static final int Theme_Holo_Wallpaper_NoTitleBar = 16973950; // 0x103007e
field public static final int Theme_InputMethod = 16973908; // 0x1030054
@@ -1649,6 +1705,115 @@
field public static final int Widget_CompoundButton_RadioButton = 16973850; // 0x103001a
field public static final int Widget_CompoundButton_Star = 16973851; // 0x103001b
field public static final int Widget_DatePicker = 16974062; // 0x10300ee
+ field public static final int Widget_DeviceDefault = 16974144; // 0x1030140
+ field public static final int Widget_DeviceDefault_ActionBar = 16974187; // 0x103016b
+ field public static final int Widget_DeviceDefault_ActionBar_Solid = 16974195; // 0x1030173
+ field public static final int Widget_DeviceDefault_ActionBar_TabBar = 16974194; // 0x1030172
+ field public static final int Widget_DeviceDefault_ActionBar_TabText = 16974193; // 0x1030171
+ field public static final int Widget_DeviceDefault_ActionBar_TabView = 16974192; // 0x1030170
+ field public static final int Widget_DeviceDefault_ActionButton = 16974182; // 0x1030166
+ field public static final int Widget_DeviceDefault_ActionButton_CloseMode = 16974186; // 0x103016a
+ field public static final int Widget_DeviceDefault_ActionButton_Overflow = 16974183; // 0x1030167
+ field public static final int Widget_DeviceDefault_ActionButton_TextButton = 16974184; // 0x1030168
+ field public static final int Widget_DeviceDefault_ActionMode = 16974185; // 0x1030169
+ field public static final int Widget_DeviceDefault_AutoCompleteTextView = 16974151; // 0x1030147
+ field public static final int Widget_DeviceDefault_Button = 16974145; // 0x1030141
+ field public static final int Widget_DeviceDefault_Button_Borderless = 16974188; // 0x103016c
+ field public static final int Widget_DeviceDefault_Button_Borderless_Small = 16974149; // 0x1030145
+ field public static final int Widget_DeviceDefault_Button_Inset = 16974147; // 0x1030143
+ field public static final int Widget_DeviceDefault_Button_Small = 16974146; // 0x1030142
+ field public static final int Widget_DeviceDefault_Button_Toggle = 16974148; // 0x1030144
+ field public static final int Widget_DeviceDefault_CalendarView = 16974190; // 0x103016e
+ field public static final int Widget_DeviceDefault_CompoundButton_CheckBox = 16974152; // 0x1030148
+ field public static final int Widget_DeviceDefault_CompoundButton_RadioButton = 16974169; // 0x1030159
+ field public static final int Widget_DeviceDefault_CompoundButton_Star = 16974173; // 0x103015d
+ field public static final int Widget_DeviceDefault_DatePicker = 16974191; // 0x103016f
+ field public static final int Widget_DeviceDefault_DropDownItem = 16974177; // 0x1030161
+ field public static final int Widget_DeviceDefault_DropDownItem_Spinner = 16974178; // 0x1030162
+ field public static final int Widget_DeviceDefault_EditText = 16974154; // 0x103014a
+ field public static final int Widget_DeviceDefault_ExpandableListView = 16974155; // 0x103014b
+ field public static final int Widget_DeviceDefault_GridView = 16974156; // 0x103014c
+ field public static final int Widget_DeviceDefault_HorizontalScrollView = 16974171; // 0x103015b
+ field public static final int Widget_DeviceDefault_ImageButton = 16974157; // 0x103014d
+ field public static final int Widget_DeviceDefault_Light = 16974196; // 0x1030174
+ field public static final int Widget_DeviceDefault_Light_ActionBar = 16974243; // 0x10301a3
+ field public static final int Widget_DeviceDefault_Light_ActionBar_Solid = 16974247; // 0x10301a7
+ field public static final int Widget_DeviceDefault_Light_ActionBar_Solid_Inverse = 16974248; // 0x10301a8
+ field public static final int Widget_DeviceDefault_Light_ActionBar_TabBar = 16974246; // 0x10301a6
+ field public static final int Widget_DeviceDefault_Light_ActionBar_TabBar_Inverse = 16974249; // 0x10301a9
+ field public static final int Widget_DeviceDefault_Light_ActionBar_TabText = 16974245; // 0x10301a5
+ field public static final int Widget_DeviceDefault_Light_ActionBar_TabText_Inverse = 16974251; // 0x10301ab
+ field public static final int Widget_DeviceDefault_Light_ActionBar_TabView = 16974244; // 0x10301a4
+ field public static final int Widget_DeviceDefault_Light_ActionBar_TabView_Inverse = 16974250; // 0x10301aa
+ field public static final int Widget_DeviceDefault_Light_ActionButton = 16974239; // 0x103019f
+ field public static final int Widget_DeviceDefault_Light_ActionButton_CloseMode = 16974242; // 0x10301a2
+ field public static final int Widget_DeviceDefault_Light_ActionButton_Overflow = 16974240; // 0x10301a0
+ field public static final int Widget_DeviceDefault_Light_ActionMode = 16974241; // 0x10301a1
+ field public static final int Widget_DeviceDefault_Light_ActionMode_Inverse = 16974252; // 0x10301ac
+ field public static final int Widget_DeviceDefault_Light_AutoCompleteTextView = 16974203; // 0x103017b
+ field public static final int Widget_DeviceDefault_Light_Button = 16974197; // 0x1030175
+ field public static final int Widget_DeviceDefault_Light_Button_Borderless_Small = 16974201; // 0x1030179
+ field public static final int Widget_DeviceDefault_Light_Button_Inset = 16974199; // 0x1030177
+ field public static final int Widget_DeviceDefault_Light_Button_Small = 16974198; // 0x1030176
+ field public static final int Widget_DeviceDefault_Light_Button_Toggle = 16974200; // 0x1030178
+ field public static final int Widget_DeviceDefault_Light_CalendarView = 16974238; // 0x103019e
+ field public static final int Widget_DeviceDefault_Light_CompoundButton_CheckBox = 16974204; // 0x103017c
+ field public static final int Widget_DeviceDefault_Light_CompoundButton_RadioButton = 16974224; // 0x1030190
+ field public static final int Widget_DeviceDefault_Light_CompoundButton_Star = 16974228; // 0x1030194
+ field public static final int Widget_DeviceDefault_Light_DropDownItem = 16974232; // 0x1030198
+ field public static final int Widget_DeviceDefault_Light_DropDownItem_Spinner = 16974233; // 0x1030199
+ field public static final int Widget_DeviceDefault_Light_EditText = 16974206; // 0x103017e
+ field public static final int Widget_DeviceDefault_Light_ExpandableListView = 16974207; // 0x103017f
+ field public static final int Widget_DeviceDefault_Light_GridView = 16974208; // 0x1030180
+ field public static final int Widget_DeviceDefault_Light_HorizontalScrollView = 16974226; // 0x1030192
+ field public static final int Widget_DeviceDefault_Light_ImageButton = 16974209; // 0x1030181
+ field public static final int Widget_DeviceDefault_Light_ListPopupWindow = 16974235; // 0x103019b
+ field public static final int Widget_DeviceDefault_Light_ListView = 16974210; // 0x1030182
+ field public static final int Widget_DeviceDefault_Light_ListView_DropDown = 16974205; // 0x103017d
+ field public static final int Widget_DeviceDefault_Light_PopupMenu = 16974236; // 0x103019c
+ field public static final int Widget_DeviceDefault_Light_PopupWindow = 16974211; // 0x1030183
+ field public static final int Widget_DeviceDefault_Light_ProgressBar = 16974212; // 0x1030184
+ field public static final int Widget_DeviceDefault_Light_ProgressBar_Horizontal = 16974213; // 0x1030185
+ field public static final int Widget_DeviceDefault_Light_ProgressBar_Inverse = 16974217; // 0x1030189
+ field public static final int Widget_DeviceDefault_Light_ProgressBar_Large = 16974216; // 0x1030188
+ field public static final int Widget_DeviceDefault_Light_ProgressBar_Large_Inverse = 16974219; // 0x103018b
+ field public static final int Widget_DeviceDefault_Light_ProgressBar_Small = 16974214; // 0x1030186
+ field public static final int Widget_DeviceDefault_Light_ProgressBar_Small_Inverse = 16974218; // 0x103018a
+ field public static final int Widget_DeviceDefault_Light_ProgressBar_Small_Title = 16974215; // 0x1030187
+ field public static final int Widget_DeviceDefault_Light_RatingBar = 16974221; // 0x103018d
+ field public static final int Widget_DeviceDefault_Light_RatingBar_Indicator = 16974222; // 0x103018e
+ field public static final int Widget_DeviceDefault_Light_RatingBar_Small = 16974223; // 0x103018f
+ field public static final int Widget_DeviceDefault_Light_ScrollView = 16974225; // 0x1030191
+ field public static final int Widget_DeviceDefault_Light_SeekBar = 16974220; // 0x103018c
+ field public static final int Widget_DeviceDefault_Light_Spinner = 16974227; // 0x1030193
+ field public static final int Widget_DeviceDefault_Light_Tab = 16974237; // 0x103019d
+ field public static final int Widget_DeviceDefault_Light_TabWidget = 16974229; // 0x1030195
+ field public static final int Widget_DeviceDefault_Light_TextView = 16974202; // 0x103017a
+ field public static final int Widget_DeviceDefault_Light_TextView_SpinnerItem = 16974234; // 0x103019a
+ field public static final int Widget_DeviceDefault_Light_WebTextView = 16974230; // 0x1030196
+ field public static final int Widget_DeviceDefault_Light_WebView = 16974231; // 0x1030197
+ field public static final int Widget_DeviceDefault_ListPopupWindow = 16974180; // 0x1030164
+ field public static final int Widget_DeviceDefault_ListView = 16974158; // 0x103014e
+ field public static final int Widget_DeviceDefault_ListView_DropDown = 16974153; // 0x1030149
+ field public static final int Widget_DeviceDefault_PopupMenu = 16974181; // 0x1030165
+ field public static final int Widget_DeviceDefault_PopupWindow = 16974159; // 0x103014f
+ field public static final int Widget_DeviceDefault_ProgressBar = 16974160; // 0x1030150
+ field public static final int Widget_DeviceDefault_ProgressBar_Horizontal = 16974161; // 0x1030151
+ field public static final int Widget_DeviceDefault_ProgressBar_Large = 16974164; // 0x1030154
+ field public static final int Widget_DeviceDefault_ProgressBar_Small = 16974162; // 0x1030152
+ field public static final int Widget_DeviceDefault_ProgressBar_Small_Title = 16974163; // 0x1030153
+ field public static final int Widget_DeviceDefault_RatingBar = 16974166; // 0x1030156
+ field public static final int Widget_DeviceDefault_RatingBar_Indicator = 16974167; // 0x1030157
+ field public static final int Widget_DeviceDefault_RatingBar_Small = 16974168; // 0x1030158
+ field public static final int Widget_DeviceDefault_ScrollView = 16974170; // 0x103015a
+ field public static final int Widget_DeviceDefault_SeekBar = 16974165; // 0x1030155
+ field public static final int Widget_DeviceDefault_Spinner = 16974172; // 0x103015c
+ field public static final int Widget_DeviceDefault_Tab = 16974189; // 0x103016d
+ field public static final int Widget_DeviceDefault_TabWidget = 16974174; // 0x103015e
+ field public static final int Widget_DeviceDefault_TextView = 16974150; // 0x1030146
+ field public static final int Widget_DeviceDefault_TextView_SpinnerItem = 16974179; // 0x1030163
+ field public static final int Widget_DeviceDefault_WebTextView = 16974175; // 0x103015f
+ field public static final int Widget_DeviceDefault_WebView = 16974176; // 0x1030160
field public static final int Widget_DropDownItem = 16973867; // 0x103002b
field public static final int Widget_DropDownItem_Spinner = 16973868; // 0x103002c
field public static final int Widget_EditText = 16973859; // 0x1030023
@@ -1658,7 +1823,7 @@
field public static final int Widget_GridView = 16973874; // 0x1030032
field public static final int Widget_Holo = 16973962; // 0x103008a
field public static final int Widget_Holo_ActionBar = 16974004; // 0x10300b4
- field public static final int Widget_Holo_ActionBar_Solid = 16974114; // 0x1030122
+ field public static final int Widget_Holo_ActionBar_Solid = 16974113; // 0x1030121
field public static final int Widget_Holo_ActionBar_TabBar = 16974071; // 0x10300f7
field public static final int Widget_Holo_ActionBar_TabText = 16974070; // 0x10300f6
field public static final int Widget_Holo_ActionBar_TabView = 16974069; // 0x10300f5
@@ -1670,7 +1835,7 @@
field public static final int Widget_Holo_AutoCompleteTextView = 16973968; // 0x1030090
field public static final int Widget_Holo_Button = 16973963; // 0x103008b
field public static final int Widget_Holo_Button_Borderless = 16974050; // 0x10300e2
- field public static final int Widget_Holo_Button_Borderless_Small = 16974107; // 0x103011b
+ field public static final int Widget_Holo_Button_Borderless_Small = 16974106; // 0x103011a
field public static final int Widget_Holo_Button_Inset = 16973965; // 0x103008d
field public static final int Widget_Holo_Button_Small = 16973964; // 0x103008c
field public static final int Widget_Holo_Button_Toggle = 16973966; // 0x103008e
@@ -1688,22 +1853,22 @@
field public static final int Widget_Holo_ImageButton = 16973974; // 0x1030096
field public static final int Widget_Holo_Light = 16974005; // 0x10300b5
field public static final int Widget_Holo_Light_ActionBar = 16974049; // 0x10300e1
- field public static final int Widget_Holo_Light_ActionBar_Solid = 16974115; // 0x1030123
- field public static final int Widget_Holo_Light_ActionBar_Solid_Inverse = 16974116; // 0x1030124
+ field public static final int Widget_Holo_Light_ActionBar_Solid = 16974114; // 0x1030122
+ field public static final int Widget_Holo_Light_ActionBar_Solid_Inverse = 16974115; // 0x1030123
field public static final int Widget_Holo_Light_ActionBar_TabBar = 16974074; // 0x10300fa
- field public static final int Widget_Holo_Light_ActionBar_TabBar_Inverse = 16974117; // 0x1030125
+ field public static final int Widget_Holo_Light_ActionBar_TabBar_Inverse = 16974116; // 0x1030124
field public static final int Widget_Holo_Light_ActionBar_TabText = 16974073; // 0x10300f9
- field public static final int Widget_Holo_Light_ActionBar_TabText_Inverse = 16974119; // 0x1030127
+ field public static final int Widget_Holo_Light_ActionBar_TabText_Inverse = 16974118; // 0x1030126
field public static final int Widget_Holo_Light_ActionBar_TabView = 16974072; // 0x10300f8
- field public static final int Widget_Holo_Light_ActionBar_TabView_Inverse = 16974118; // 0x1030126
+ field public static final int Widget_Holo_Light_ActionBar_TabView_Inverse = 16974117; // 0x1030125
field public static final int Widget_Holo_Light_ActionButton = 16974045; // 0x10300dd
field public static final int Widget_Holo_Light_ActionButton_CloseMode = 16974048; // 0x10300e0
field public static final int Widget_Holo_Light_ActionButton_Overflow = 16974046; // 0x10300de
field public static final int Widget_Holo_Light_ActionMode = 16974047; // 0x10300df
- field public static final int Widget_Holo_Light_ActionMode_Inverse = 16974120; // 0x1030128
+ field public static final int Widget_Holo_Light_ActionMode_Inverse = 16974119; // 0x1030127
field public static final int Widget_Holo_Light_AutoCompleteTextView = 16974011; // 0x10300bb
field public static final int Widget_Holo_Light_Button = 16974006; // 0x10300b6
- field public static final int Widget_Holo_Light_Button_Borderless_Small = 16974108; // 0x103011c
+ field public static final int Widget_Holo_Light_Button_Borderless_Small = 16974107; // 0x103011b
field public static final int Widget_Holo_Light_Button_Inset = 16974008; // 0x10300b8
field public static final int Widget_Holo_Light_Button_Small = 16974007; // 0x10300b7
field public static final int Widget_Holo_Light_Button_Toggle = 16974009; // 0x10300b9
@@ -3072,6 +3237,7 @@
method public abstract android.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
method public abstract int getBackStackEntryCount();
method public abstract android.app.Fragment getFragment(android.os.Bundle, java.lang.String);
+ method public void invalidateOptionsMenu();
method public abstract void popBackStack();
method public abstract void popBackStack(java.lang.String, int);
method public abstract void popBackStack(int, int);
@@ -3644,6 +3810,7 @@
public class WallpaperManager {
method public void clear() throws java.io.IOException;
method public void clearWallpaperOffsets(android.os.IBinder);
+ method public void forgetLoadedWallpaper();
method public int getDesiredMinimumHeight();
method public int getDesiredMinimumWidth();
method public android.graphics.drawable.Drawable getDrawable();
@@ -5637,6 +5804,7 @@
field public static final int SCREEN_ORIENTATION_SENSOR_PORTRAIT = 7; // 0x7
field public static final int SCREEN_ORIENTATION_UNSPECIFIED = -1; // 0xffffffff
field public static final int SCREEN_ORIENTATION_USER = 2; // 0x2
+ field public static final int UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW = 1; // 0x1
field public int configChanges;
field public int flags;
field public int launchMode;
@@ -5646,6 +5814,7 @@
field public java.lang.String targetActivity;
field public java.lang.String taskAffinity;
field public int theme;
+ field public int uiOptions;
}
public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
@@ -5696,6 +5865,7 @@
field public int targetSdkVersion;
field public java.lang.String taskAffinity;
field public int theme;
+ field public int uiOptions;
field public int uid;
}
@@ -8456,6 +8626,7 @@
ctor public SurfaceTexture(int, boolean);
method public long getTimestamp();
method public void getTransformMatrix(float[]);
+ method public void release();
method public void setOnFrameAvailableListener(android.graphics.SurfaceTexture.OnFrameAvailableListener);
method public void updateTexImage();
}
@@ -11118,6 +11289,7 @@
public class ConnectivityManager {
method public android.net.NetworkInfo getActiveNetworkInfo();
+ method public android.net.NetworkQuotaInfo getActiveNetworkQuotaInfo();
method public android.net.NetworkInfo[] getAllNetworkInfo();
method public boolean getBackgroundDataSetting();
method public android.net.NetworkInfo getNetworkInfo(int);
@@ -11132,7 +11304,7 @@
field public static final int DEFAULT_NETWORK_PREFERENCE = 1; // 0x1
field public static final java.lang.String EXTRA_EXTRA_INFO = "extraInfo";
field public static final java.lang.String EXTRA_IS_FAILOVER = "isFailover";
- field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
+ field public static final deprecated java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
field public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity";
field public static final java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
field public static final java.lang.String EXTRA_REASON = "reason";
@@ -11277,6 +11449,16 @@
enum_constant public static final android.net.NetworkInfo.State UNKNOWN;
}
+ public class NetworkQuotaInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public long getEstimatedBytes();
+ method public long getHardLimitBytes();
+ method public long getSoftLimitBytes();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
+ field public static final long NO_LIMIT = -1L; // 0xffffffffffffffffL
+ }
+
public class ParseException extends java.lang.RuntimeException {
field public java.lang.String response;
}
@@ -11336,6 +11518,7 @@
method public static long getUidUdpRxPackets(int);
method public static long getUidUdpTxBytes(int);
method public static long getUidUdpTxPackets(int);
+ method public static void incrementOperationCount(int, int);
method public static void setThreadStatsTag(int);
method public static deprecated void setThreadStatsTag(java.lang.String);
method public static void tagSocket(java.net.Socket) throws java.net.SocketException;
@@ -16985,7 +17168,7 @@
field public static final java.lang.String VOICEMAIL_ACCESS_URI = "voicemail_access_uri";
}
- public static final class VoicemailContract.Voicemails implements android.provider.BaseColumns {
+ public static final class VoicemailContract.Voicemails implements android.provider.BaseColumns android.provider.OpenableColumns {
method public static android.net.Uri buildSourceUri(java.lang.String);
field public static final android.net.Uri CONTENT_URI;
field public static final java.lang.String DATE = "date";
@@ -18002,23 +18185,19 @@
public abstract class SpellCheckerService extends android.app.Service {
ctor public SpellCheckerService();
- method public void cancel();
- method public abstract android.view.textservice.SuggestionsInfo getSuggestions(android.view.textservice.TextInfo, int, java.lang.String);
- method public android.view.textservice.SuggestionsInfo[] getSuggestionsMultiple(android.view.textservice.TextInfo[], java.lang.String, int, boolean);
+ method public abstract android.service.textservice.SpellCheckerService.Session createSession();
method public final android.os.IBinder onBind(android.content.Intent);
field public static final java.lang.String SERVICE_INTERFACE = "android.service.textservice.SpellCheckerService";
}
- public class SpellCheckerSession {
- method public void close();
- method public android.view.textservice.SpellCheckerInfo getSpellChecker();
- method public void getSuggestions(android.view.textservice.TextInfo, int);
- method public void getSuggestions(android.view.textservice.TextInfo[], int, boolean);
- method public boolean isSessionDisconnected();
- }
-
- public static abstract interface SpellCheckerSession.SpellCheckerSessionListener {
- method public abstract void onGetSuggestions(android.view.textservice.SuggestionsInfo[]);
+ public abstract class SpellCheckerService.Session {
+ ctor public SpellCheckerService.Session();
+ method public android.os.Bundle getBundle();
+ method public java.lang.String getLocale();
+ method public void onCancel();
+ method public abstract void onCreate();
+ method public abstract android.view.textservice.SuggestionsInfo onGetSuggestions(android.view.textservice.TextInfo, int);
+ method public android.view.textservice.SuggestionsInfo[] onGetSuggestionsMultiple(android.view.textservice.TextInfo[], int, boolean);
}
}
@@ -22081,45 +22260,18 @@
public class Surface implements android.os.Parcelable {
method public int describeContents();
- method public void freeze();
- method public void hide();
method public boolean isValid();
method public android.graphics.Canvas lockCanvas(android.graphics.Rect) throws java.lang.IllegalArgumentException, android.view.Surface.OutOfResourcesException;
method public void readFromParcel(android.os.Parcel);
- method public void setAlpha(float);
- method public void setFlags(int, int);
- method public void setFreezeTint(int);
- method public void setLayer(int);
- method public void setMatrix(float, float, float, float);
- method public static void setOrientation(int, int);
- method public void setPosition(int, int);
- method public void setSize(int, int);
- method public void setTransparentRegionHint(android.graphics.Region);
- method public void show();
- method public void unfreeze();
+ method public void release();
method public void unlockCanvas(android.graphics.Canvas);
method public void unlockCanvasAndPost(android.graphics.Canvas);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
- field public static final int FX_SURFACE_BLUR = 65536; // 0x10000
- field public static final int FX_SURFACE_DIM = 131072; // 0x20000
- field public static final int FX_SURFACE_MASK = 983040; // 0xf0000
- field public static final int FX_SURFACE_NORMAL = 0; // 0x0
- field public static final deprecated int GPU = 40; // 0x28
- field public static final deprecated int HARDWARE = 16; // 0x10
- field public static final int HIDDEN = 4; // 0x4
- field public static final int NON_PREMULTIPLIED = 256; // 0x100
- field public static final deprecated int PUSH_BUFFERS = 512; // 0x200
field public static final int ROTATION_0 = 0; // 0x0
field public static final int ROTATION_180 = 2; // 0x2
field public static final int ROTATION_270 = 3; // 0x3
field public static final int ROTATION_90 = 1; // 0x1
- field public static final int SECURE = 128; // 0x80
- field public static final deprecated int SURACE_FROZEN = 2; // 0x2
- field public static final int SURFACE_BLUR_FREEZE = 16; // 0x10
- field public static final int SURFACE_DITHER = 4; // 0x4
- field public static final int SURFACE_FROZEN = 2; // 0x2
- field public static final int SURFACE_HIDDEN = 1; // 0x1
}
public static class Surface.OutOfResourcesException extends java.lang.Exception {
@@ -23173,6 +23325,7 @@
method public abstract void setTitle(java.lang.CharSequence);
method public abstract void setTitleColor(int);
method public void setType(int);
+ method public void setUiOptions(int);
method public abstract void setVolumeControlStream(int);
method public void setWindowAnimations(int);
method public void setWindowManager(android.view.WindowManager, android.os.IBinder, java.lang.String);
@@ -24120,6 +24273,19 @@
field public static final android.os.Parcelable.Creator CREATOR;
}
+ public class SpellCheckerSession {
+ method public void close();
+ method public android.view.textservice.SpellCheckerInfo getSpellChecker();
+ method public void getSuggestions(android.view.textservice.TextInfo, int);
+ method public void getSuggestions(android.view.textservice.TextInfo[], int, boolean);
+ method public boolean isSessionDisconnected();
+ field public static final java.lang.String SERVICE_META_DATA = "android.view.textservice.scs";
+ }
+
+ public static abstract interface SpellCheckerSession.SpellCheckerSessionListener {
+ method public abstract void onGetSuggestions(android.view.textservice.SuggestionsInfo[]);
+ }
+
public final class SuggestionsInfo implements android.os.Parcelable {
ctor public SuggestionsInfo(int, java.lang.String[]);
ctor public SuggestionsInfo(int, java.lang.String[], int, int);
@@ -24134,7 +24300,7 @@
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
field public static final int RESULT_ATTR_IN_THE_DICTIONARY = 1; // 0x1
- field public static final int RESULT_ATTR_LOOKS_TYPO = 2; // 0x2
+ field public static final int RESULT_ATTR_LOOKS_LIKE_TYPO = 2; // 0x2
}
public final class TextInfo implements android.os.Parcelable {
@@ -24150,7 +24316,7 @@
}
public final class TextServicesManager {
- method public android.service.textservice.SpellCheckerSession newSpellCheckerSession(java.util.Locale, android.service.textservice.SpellCheckerSession.SpellCheckerSessionListener, boolean);
+ method public android.view.textservice.SpellCheckerSession newSpellCheckerSession(android.os.Bundle, java.util.Locale, android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener, boolean);
}
}
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 5fe3644..57e0583 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -32,10 +32,9 @@
/**
* Starts this animation. If the animation has a nonzero startDelay, the animation will start
- * running after that delay elapses. Note that the animation does not start synchronously with
- * this call, because all animation events are posted to a central timing loop so that animation
- * times are all synchronized on a single timing pulse on the UI thread. So the animation will
- * start the next time that event handler processes events.
+ * running after that delay elapses. A non-delayed animation will have its initial
+ * value(s) set immediately, followed by calls to
+ * {@link AnimatorListener#onAnimationStart(Animator)} for any listeners of this animator.
*
* <p>The animation started by calling this method will be run on the thread that called
* this method. This thread should have a Looper on it (a runtime exception will be thrown if
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index e6c2a0f..ce3dd13 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -349,7 +349,8 @@
return true;
}
}
- return false;
+ // Also return true if we're currently running the startDelay animator
+ return (mDelayAnim != null && mDelayAnim.isRunning());
}
/**
@@ -445,7 +446,10 @@
// First, clear out the old listeners
ArrayList<AnimatorListener> oldListeners = node.animation.getListeners();
if (oldListeners != null && oldListeners.size() > 0) {
- for (AnimatorListener listener : oldListeners) {
+ final ArrayList<AnimatorListener> clonedListeners = new
+ ArrayList<AnimatorListener>(oldListeners);
+
+ for (AnimatorListener listener : clonedListeners) {
if (listener instanceof DependencyListener ||
listener instanceof AnimatorSetListener) {
node.animation.removeListener(listener);
@@ -484,7 +488,6 @@
mPlayingSet.add(node.animation);
}
} else {
- // TODO: Need to cancel out of the delay appropriately
mDelayAnim = ValueAnimator.ofFloat(0f, 1f);
mDelayAnim.setDuration(mStartDelay);
mDelayAnim.addListener(new AnimatorListenerAdapter() {
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 90d676e..c22306a 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -186,6 +186,16 @@
int mPlayingState = STOPPED;
/**
+ * Additional playing state to indicate whether an animator has been start()'d. There is
+ * some lag between a call to start() and the first animation frame. We should still note
+ * that the animation has been started, even if it's first animation frame has not yet
+ * happened, and reflect that state in isRunning().
+ * Note that delayed animations are different: they are not started until their first
+ * animation frame, which occurs after their delay elapses.
+ */
+ private boolean mStarted = false;
+
+ /**
* Flag that denotes whether the animation is set up and ready to go. Used to
* set up animation that has not yet been started.
*/
@@ -618,6 +628,7 @@
for (int i = 0; i < numReadyAnims; ++i) {
ValueAnimator anim = readyAnims.get(i);
anim.startAnimation();
+ anim.mStarted = true;
delayedAnims.remove(anim);
}
readyAnims.clear();
@@ -908,6 +919,7 @@
// This sets the initial value of the animation, prior to actually starting it running
setCurrentPlayTime(getCurrentPlayTime());
mPlayingState = STOPPED;
+ mStarted = true;
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
@@ -937,7 +949,8 @@
// to run
if (mPlayingState != STOPPED || sPendingAnimations.get().contains(this) ||
sDelayedAnims.get().contains(this)) {
- if (mListeners != null) {
+ // Only notify listeners if the animator has actually started
+ if (mStarted && mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
for (AnimatorListener listener : tmpListeners) {
@@ -969,7 +982,7 @@
@Override
public boolean isRunning() {
- return (mPlayingState == RUNNING);
+ return (mPlayingState == RUNNING || mStarted);
}
/**
@@ -1000,7 +1013,7 @@
sPendingAnimations.get().remove(this);
sDelayedAnims.get().remove(this);
mPlayingState = STOPPED;
- if (mListeners != null) {
+ if (mStarted && mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
int numListeners = tmpListeners.size();
@@ -1008,6 +1021,7 @@
tmpListeners.get(i).onAnimationEnd(this);
}
}
+ mStarted = false;
}
/**
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index d5b669e..98b867d 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -4399,6 +4399,9 @@
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);
}
+ if (info.uiOptions != 0) {
+ mWindow.setUiOptions(info.uiOptions);
+ }
mUiThread = Thread.currentThread();
mMainThread = aThread;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 8931675..c566104 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2503,6 +2503,7 @@
mAvailThumbnailBitmap = thumbnail;
thumbnail = null;
}
+ cv.setBitmap(null);
}
} catch (Exception e) {
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 371e7ad..a8621f8 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -30,14 +30,14 @@
import android.util.DebugUtils;
import android.util.SparseArray;
import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
-import android.view.ViewGroup;
-import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
+import android.view.ViewGroup;
import android.widget.AdapterView;
import java.io.FileDescriptor;
@@ -883,8 +883,8 @@
public void setHasOptionsMenu(boolean hasMenu) {
if (mHasMenu != hasMenu) {
mHasMenu = hasMenu;
- if (isAdded() && !isHidden() && isResumed()) {
- mActivity.invalidateOptionsMenu();
+ if (isAdded() && !isHidden()) {
+ mFragmentManager.invalidateOptionsMenu();
}
}
}
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index c33ab2c..712b55f 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -315,6 +315,12 @@
public static void enableDebugLogging(boolean enabled) {
FragmentManagerImpl.DEBUG = enabled;
}
+
+ /**
+ * Invalidate the attached activity's options menu as necessary.
+ * This may end up being deferred until we move to the resumed state.
+ */
+ public void invalidateOptionsMenu() { }
}
final class FragmentManagerState implements Parcelable {
@@ -1816,7 +1822,16 @@
}
}
}
-
+
+ @Override
+ public void invalidateOptionsMenu() {
+ if (mActivity != null && mCurState == Fragment.RESUMED) {
+ mActivity.invalidateOptionsMenu();
+ } else {
+ mNeedMenuInvalidate = true;
+ }
+ }
+
public static int reverseTransit(int transit) {
int rev = 0;
switch (transit) {
diff --git a/core/java/android/app/LauncherActivity.java b/core/java/android/app/LauncherActivity.java
index 7b9bd60..8eb9ba4 100644
--- a/core/java/android/app/LauncherActivity.java
+++ b/core/java/android/app/LauncherActivity.java
@@ -314,6 +314,7 @@
icon.draw(canvas);
icon.setBounds(mOldBounds);
icon = new BitmapDrawable(getResources(), thumb);
+ canvas.setBitmap(null);
} else if (iconWidth < width && iconHeight < height) {
final Bitmap.Config c = Bitmap.Config.ARGB_8888;
final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c);
@@ -326,6 +327,7 @@
icon.draw(canvas);
icon.setBounds(mOldBounds);
icon = new BitmapDrawable(getResources(), thumb);
+ canvas.setBitmap(null);
}
}
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 8472b31..ff04757 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -234,14 +234,25 @@
} catch (OutOfMemoryError e) {
Log.w(TAG, "No memory load current wallpaper", e);
}
- if (mWallpaper == null && returnDefault) {
- mDefaultWallpaper = getDefaultWallpaperLocked(context);
- return mDefaultWallpaper;
+ if (returnDefault) {
+ if (mWallpaper == null) {
+ mDefaultWallpaper = getDefaultWallpaperLocked(context);
+ return mDefaultWallpaper;
+ } else {
+ mDefaultWallpaper = null;
+ }
}
return mWallpaper;
}
}
-
+
+ public void forgetLoadedWallpaper() {
+ synchronized (this) {
+ mWallpaper = null;
+ mDefaultWallpaper = null;
+ }
+ }
+
private Bitmap getCurrentWallpaperLocked(Context context) {
try {
Bundle params = new Bundle();
@@ -402,6 +413,16 @@
}
/**
+ * Remove all internal references to the last loaded wallpaper. Useful
+ * for apps that want to reduce memory usage when they only temporarily
+ * need to have the wallpaper. After calling, the next request for the
+ * wallpaper will require reloading it again from disk.
+ */
+ public void forgetLoadedWallpaper() {
+ sGlobals.forgetLoadedWallpaper();
+ }
+
+ /**
* If the current wallpaper is a live wallpaper component, return the
* information about that wallpaper. Otherwise, if it is a static image,
* simply return null.
@@ -716,6 +737,7 @@
c.drawBitmap(bm, null, targetRect, paint);
bm.recycle();
+ c.setBitmap(null);
return newbm;
} catch (OutOfMemoryError e) {
Log.w(TAG, "Can't generate default bitmap", e);
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index ca6f085..28bc424 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1163,7 +1163,10 @@
* <p> If this API returns true, it means the callback will be called.
* The callback will be called with the current state of Bluetooth.
* If the state is not what was requested, an internal error would be the
- * reason.
+ * reason. If Bluetooth is already on and if this function is called to turn
+ * it on, the api will return true and a callback will be called.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
*
* @param on True for on, false for off.
* @param callback The callback to notify changes to the state.
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index 095cd11..316c474 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -1048,12 +1048,12 @@
break;
case CONNECT_HID_INCOMING:
if (!accept) {
- ret = mService.allowIncomingHidConnect(mDevice, false);
+ ret = mService.allowIncomingProfileConnect(mDevice, false);
sendMessage(TRANSITION_TO_STABLE);
updateIncomingAllowedTimer();
} else {
writeTimerValue(0);
- ret = mService.allowIncomingHidConnect(mDevice, true);
+ ret = mService.allowIncomingProfileConnect(mDevice, true);
}
break;
default:
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index f6757d9..282b70a 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -308,28 +308,6 @@
return BluetoothProfile.PRIORITY_OFF;
}
- /**
- * Allow or disallow incoming connection
- * @param device Input device
- * @param allow true / false
- * @return Success or Failure of the operation
- * @hide
- */
- public boolean allowIncomingConnect(BluetoothDevice device, boolean allow) {
- if (DBG) log("allowIncomingConnect(" + device + ", " + allow + ")");
-
- if (mService == null || !isEnabled() || !isValidDevice(device)) {
- return false;
- }
- try {
- mService.allowIncomingHidConnect(device, allow);
- } catch (RemoteException e) {
- Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
- return false;
- }
- return true;
- }
-
private boolean isEnabled() {
if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
return false;
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index ddede9c..48dfed8 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -85,6 +85,7 @@
int addRfcommServiceRecord(in String serviceName, in ParcelUuid uuid, int channel, IBinder b);
void removeServiceRecord(int handle);
+ boolean allowIncomingProfileConnect(in BluetoothDevice device, boolean value);
boolean connectHeadset(String address);
boolean disconnectHeadset(String address);
@@ -98,7 +99,6 @@
int getInputDeviceConnectionState(in BluetoothDevice device);
boolean setInputDevicePriority(in BluetoothDevice device, int priority);
int getInputDevicePriority(in BluetoothDevice device);
- boolean allowIncomingHidConnect(in BluetoothDevice device, boolean value);
boolean isTetheringOn();
void setBluetoothTethering(boolean value);
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 4858f14..bba329d 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -433,7 +433,19 @@
* the mode from the theme will be used.
*/
public int softInputMode;
-
+
+ /**
+ * The desired extra UI options for this activity and its main window.
+ * Set from the {@link android.R.attr#uiOptions} attribute in the
+ * activity's manifest.
+ */
+ public int uiOptions = 0;
+
+ /**
+ * Flag for use with uiOptions.
+ */
+ public static final int UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW = 1;
+
public ActivityInfo() {
}
@@ -448,6 +460,7 @@
screenOrientation = orig.screenOrientation;
configChanges = orig.configChanges;
softInputMode = orig.softInputMode;
+ uiOptions = orig.uiOptions;
}
/**
@@ -479,6 +492,9 @@
+ " configChanges=0x" + Integer.toHexString(configChanges)
+ " softInputMode=0x" + Integer.toHexString(softInputMode));
}
+ if (uiOptions != 0) {
+ pw.println(prefix + " uiOptions=0x" + Integer.toHexString(uiOptions));
+ }
super.dumpBack(pw, prefix);
}
@@ -503,6 +519,7 @@
dest.writeInt(screenOrientation);
dest.writeInt(configChanges);
dest.writeInt(softInputMode);
+ dest.writeInt(uiOptions);
}
public static final Parcelable.Creator<ActivityInfo> CREATOR
@@ -526,5 +543,6 @@
screenOrientation = source.readInt();
configChanges = source.readInt();
softInputMode = source.readInt();
+ uiOptions = source.readInt();
}
}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index ddb6ef0..65a8750 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -91,6 +91,13 @@
public String backupAgentName;
/**
+ * The default extra UI options for activities in this application.
+ * Set from the {@link android.R.attr#uiOptions} attribute in the
+ * activity's manifest.
+ */
+ public int uiOptions = 0;
+
+ /**
* Value for {@link #flags}: if set, this application is installed in the
* device's system image.
*/
@@ -456,6 +463,9 @@
if (descriptionRes != 0) {
pw.println(prefix + "description=0x"+Integer.toHexString(descriptionRes));
}
+ if (uiOptions != 0) {
+ pw.println(prefix + "uiOptions=0x" + Integer.toHexString(uiOptions));
+ }
super.dumpBack(pw, prefix);
}
@@ -509,6 +519,7 @@
installLocation = orig.installLocation;
manageSpaceActivityName = orig.manageSpaceActivityName;
descriptionRes = orig.descriptionRes;
+ uiOptions = orig.uiOptions;
}
@@ -547,6 +558,7 @@
dest.writeString(manageSpaceActivityName);
dest.writeString(backupAgentName);
dest.writeInt(descriptionRes);
+ dest.writeInt(uiOptions);
}
public static final Parcelable.Creator<ApplicationInfo> CREATOR
@@ -584,6 +596,7 @@
manageSpaceActivityName = source.readString();
backupAgentName = source.readString();
descriptionRes = source.readInt();
+ uiOptions = source.readInt();
}
/**
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 53d6bb1..22fdc98 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -598,7 +598,12 @@
assmgr = new AssetManager();
assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Build.VERSION.RESOURCES_SDK_INT);
+
int cookie = assmgr.addAssetPath(packageFilePath);
+ if (cookie == 0) {
+ return null;
+ }
+
parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml");
} catch (Exception e) {
if (assmgr != null) assmgr.close();
@@ -1645,6 +1650,9 @@
}
}
+ ai.uiOptions = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestApplication_uiOptions, 0);
+
sa.recycle();
if (outError[0] != null) {
@@ -1850,6 +1858,10 @@
a.info.theme = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestActivity_theme, 0);
+ a.info.uiOptions = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestActivity_uiOptions,
+ a.info.applicationInfo.uiOptions);
+
String str;
str = sa.getNonConfigurationString(
com.android.internal.R.styleable.AndroidManifestActivity_permission, 0);
@@ -2091,6 +2103,7 @@
info.screenOrientation = target.info.screenOrientation;
info.taskAffinity = target.info.taskAffinity;
info.theme = target.info.theme;
+ info.uiOptions = target.info.uiOptions;
Activity a = new Activity(mParseActivityAliasArgs, info);
if (outError[0] != null) {
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index b487764..58c79fc 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -131,7 +131,7 @@
private static final int CAMERA_MSG_RAW_IMAGE = 0x080;
private static final int CAMERA_MSG_COMPRESSED_IMAGE = 0x100;
private static final int CAMERA_MSG_RAW_IMAGE_NOTIFY = 0x200;
- private static final int CAMERA_MSG_METADATA_FACE = 0x400;
+ private static final int CAMERA_MSG_PREVIEW_METADATA = 0x400;
private static final int CAMERA_MSG_ALL_MSGS = 0x4FF;
private int mNativeContext; // accessed by native methods
@@ -721,7 +721,7 @@
}
return;
- case CAMERA_MSG_METADATA_FACE:
+ case CAMERA_MSG_PREVIEW_METADATA:
if (mFaceListener != null) {
mFaceListener.onFaceDetection((Face[])msg.obj, mCamera);
}
@@ -1156,6 +1156,9 @@
* @hide
*/
public static class Face {
+ public Face() {
+ }
+
/**
* Bounds of the face. (-1000, -1000) represents the top-left of the
* camera field of view, and (1000, 1000) represents the bottom-right of
@@ -1168,7 +1171,7 @@
*
* @see #startFaceDetection(int)
*/
- Rect rect;
+ public Rect rect;
/**
* The confidence level of the face. The range is 1 to 100. 100 is the
@@ -1177,32 +1180,32 @@
*
* @see #startFaceDetection(int)
*/
- int score;
+ public int score;
/**
* An unique id per face while the face is visible to the tracker. If
* the face leaves the field-of-view and comes back, it will get a new
* id. If the value is 0, id is not supported.
*/
- int id;
+ public int id;
/**
* The coordinates of the center of the left eye. The range is -1000 to
* 1000. null if this is not supported.
*/
- Point leftEye;
+ public Point leftEye;
/**
* The coordinates of the center of the right eye. The range is -1000 to
* 1000. null if this is not supported.
*/
- Point rightEye;
+ public Point rightEye;
/**
* The coordinates of the center of the mouth. The range is -1000 to
* 1000. null if this is not supported.
*/
- Point mouth;
+ public Point mouth;
}
// Error codes match the enum in include/ui/Camera.h
@@ -1471,6 +1474,7 @@
"preferred-preview-size-for-video";
private static final String KEY_MAX_NUM_DETECTED_FACES_HW = "max-num-detected-faces-hw";
private static final String KEY_MAX_NUM_DETECTED_FACES_SW = "max-num-detected-faces-sw";
+ private static final String KEY_RECORDING_HINT = "recording-hint";
// Parameter key suffix for supported values.
private static final String SUPPORTED_VALUES_SUFFIX = "-values";
@@ -1704,6 +1708,7 @@
private static final String PIXEL_FORMAT_YUV420P = "yuv420p";
private static final String PIXEL_FORMAT_RGB565 = "rgb565";
private static final String PIXEL_FORMAT_JPEG = "jpeg";
+ private static final String PIXEL_FORMAT_BAYER_RGGB = "bayer-rggb";
private HashMap<String, String> mMap;
@@ -2254,6 +2259,7 @@
case ImageFormat.YV12: return PIXEL_FORMAT_YUV420P;
case ImageFormat.RGB_565: return PIXEL_FORMAT_RGB565;
case ImageFormat.JPEG: return PIXEL_FORMAT_JPEG;
+ case ImageFormat.BAYER_RGGB: return PIXEL_FORMAT_BAYER_RGGB;
default: return null;
}
}
@@ -3172,6 +3178,37 @@
throw new IllegalArgumentException("Invalid face detection type " + type);
}
+ /**
+ * Sets the hint of the recording mode. If this is true, {@link
+ * android.media.MediaRecorder#start()} may be faster or has less
+ * glitches. This should be called before starting the preview for the
+ * best result. But it is allowed to change the hint while the preview
+ * is active. The default value is false.
+ *
+ * The apps can still call {@link #takePicture(Camera.ShutterCallback,
+ * Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback)}
+ * when the hint is true. The apps can call MediaRecorder.start() when
+ * the hint is false. But the performance may be worse.
+ *
+ * @param hint true if the apps intend to record a video using
+ * {@link android.media.MediaRecorder}.
+ * @hide
+ */
+ public void setRecordingHint(boolean hint) {
+ set(KEY_RECORDING_HINT, hint ? TRUE : FALSE);
+ }
+
+ /**
+ * Gets the current recording hint.
+ *
+ * @return the current recording hint state.
+ * @see #setRecordingHint(boolean)
+ * @hide
+ */
+ public boolean getRecordingHint() {
+ return TRUE.equals(get(KEY_RECORDING_HINT));
+ }
+
// Splits a comma delimited string to an ArrayList of String.
// Return null if the passing string is null or the size is 0.
private ArrayList<String> split(String str) {
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index b548623..551926c 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -408,6 +408,23 @@
}
/**
+ * Returns the current default USB function.
+ *
+ * @return name of the default function.
+ *
+ * {@hide}
+ */
+ public String getDefaultFunction() {
+ String functions = SystemProperties.get("persist.sys.usb.config", "");
+ int commaIndex = functions.indexOf(',');
+ if (commaIndex > 0) {
+ return functions.substring(0, commaIndex);
+ } else {
+ return functions;
+ }
+ }
+
+ /**
* Sets the current USB function.
* If function is null, then the current function is set to the default function.
*
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a564d97..eb9cd21 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -16,10 +16,11 @@
package android.net;
+import static com.android.internal.util.Preconditions.checkNotNull;
+
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.os.Binder;
-import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import java.net.InetAddress;
@@ -67,11 +68,19 @@
* is set to {@code true} if there are no connected networks at all.
*/
public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
+
/**
* The lookup key for a {@link NetworkInfo} object. Retrieve with
* {@link android.content.Intent#getParcelableExtra(String)}.
+ *
+ * @deprecated Since {@link NetworkInfo} can vary based on UID, applications
+ * should always obtain network information through
+ * {@link #getActiveNetworkInfo()} or
+ * {@link #getAllNetworkInfo()}.
*/
+ @Deprecated
public static final String EXTRA_NETWORK_INFO = "networkInfo";
+
/**
* The lookup key for a boolean that indicates whether a connect event
* is for a network to which the connectivity manager was failing over
@@ -515,6 +524,19 @@
}
/**
+ * Return quota status for the current active network, or {@code null} if no
+ * network is active. Quota status can change rapidly, so these values
+ * shouldn't be cached.
+ */
+ public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
+ try {
+ return mService.getActiveNetworkQuotaInfo();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
* Gets the value of the setting for enabling Mobile data.
*
* @return Whether mobile data is enabled.
@@ -546,10 +568,7 @@
* {@hide}
*/
public ConnectivityManager(IConnectivityManager service) {
- if (service == null) {
- throw new IllegalArgumentException("missing IConnectivityManager");
- }
- mService = service;
+ mService = checkNotNull(service, "missing IConnectivityManager");
}
/**
diff --git a/core/java/android/net/DnsPinger.java b/core/java/android/net/DnsPinger.java
index f2d84eb..81738f3 100644
--- a/core/java/android/net/DnsPinger.java
+++ b/core/java/android/net/DnsPinger.java
@@ -17,20 +17,27 @@
package android.net;
import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.LinkProperties;
-import android.net.NetworkUtils;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Slog;
+import com.android.internal.util.Protocol;
+
+import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketTimeoutException;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* Performs a simple DNS "ping" by sending a "server status" query packet to the
@@ -40,42 +47,174 @@
* API may not differentiate between a time out and a failure lookup (which we
* really care about).
* <p>
- * TODO : More general API. Socket does not bind to specified connection type
- * TODO : Choice of DNS query location - current looks up www.android.com
*
* @hide
*/
-public final class DnsPinger {
+public final class DnsPinger extends Handler {
private static final boolean V = true;
- /** Number of bytes for the query */
- private static final int DNS_QUERY_BASE_SIZE = 32;
-
- /** The DNS port */
+ private static final int RECEIVE_POLL_INTERVAL_MS = 30;
private static final int DNS_PORT = 53;
+ /** Short socket timeout so we don't block one any 'receive' call */
+ private static final int SOCKET_TIMEOUT_MS = 1;
+
/** Used to generate IDs */
- private static Random sRandom = new Random();
+ private static final Random sRandom = new Random();
+ private static final AtomicInteger sCounter = new AtomicInteger();
private ConnectivityManager mConnectivityManager = null;
- private Context mContext;
- private int mConnectionType;
- private InetAddress mDefaultDns;
-
+ private final Context mContext;
+ private final int mConnectionType;
+ private final Handler mTarget;
+ private final InetAddress mDefaultDns;
private String TAG;
+ private static final int BASE = Protocol.BASE_DNS_PINGER;
+
/**
- * @param connectionType The connection type from {@link ConnectivityManager}
+ * Async response packet for dns pings.
+ * arg1 is the ID of the ping, also returned by {@link #pingDnsAsync(InetAddress, int, int)}
+ * arg2 is the delay, or is negative on error.
*/
- public DnsPinger(String TAG, Context context, int connectionType) {
+ public static final int DNS_PING_RESULT = BASE;
+ /** An error code for a {@link #DNS_PING_RESULT} packet */
+ public static final int TIMEOUT = -1;
+ /** An error code for a {@link #DNS_PING_RESULT} packet */
+ public static final int SOCKET_EXCEPTION = -2;
+
+ /**
+ * Send a new ping via a socket. arg1 is ID, arg2 is timeout, obj is InetAddress to ping
+ */
+ private static final int ACTION_PING_DNS = BASE + 1;
+ private static final int ACTION_LISTEN_FOR_RESPONSE = BASE + 2;
+ private static final int ACTION_CANCEL_ALL_PINGS = BASE + 3;
+
+ private List<ActivePing> mActivePings = new ArrayList<ActivePing>();
+ private int mEventCounter;
+
+ private class ActivePing {
+ DatagramSocket socket;
+ int internalId;
+ short packetId;
+ int timeout;
+ Integer result;
+ long start = SystemClock.elapsedRealtime();
+ }
+
+ public DnsPinger(Context context, String TAG, Looper looper,
+ Handler target, int connectionType) {
+ super(looper);
+ this.TAG = TAG;
mContext = context;
+ mTarget = target;
mConnectionType = connectionType;
if (!ConnectivityManager.isNetworkTypeValid(connectionType)) {
- Slog.e(TAG, "Invalid connectionType in constructor: " + connectionType);
+ throw new IllegalArgumentException("Invalid connectionType in constructor: "
+ + connectionType);
}
- this.TAG = TAG;
-
mDefaultDns = getDefaultDns();
+ mEventCounter = 0;
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case ACTION_PING_DNS:
+ try {
+ ActivePing newActivePing = new ActivePing();
+ InetAddress dnsAddress = (InetAddress) msg.obj;
+ newActivePing.internalId = msg.arg1;
+ newActivePing.timeout = msg.arg2;
+ newActivePing.socket = new DatagramSocket();
+ // Set some socket properties
+ newActivePing.socket.setSoTimeout(SOCKET_TIMEOUT_MS);
+
+ // Try to bind but continue ping if bind fails
+ try {
+ newActivePing.socket.setNetworkInterface(NetworkInterface.getByName(
+ getCurrentLinkProperties().getInterfaceName()));
+ } catch (Exception e) {
+ Slog.w(TAG,"sendDnsPing::Error binding to socket", e);
+ }
+
+ newActivePing.packetId = (short) sRandom.nextInt();
+ byte[] buf = mDnsQuery.clone();
+ buf[0] = (byte) (newActivePing.packetId >> 8);
+ buf[1] = (byte) newActivePing.packetId;
+
+ // Send the DNS query
+ DatagramPacket packet = new DatagramPacket(buf,
+ buf.length, dnsAddress, DNS_PORT);
+ if (V) {
+ Slog.v(TAG, "Sending a ping to " + dnsAddress.getHostAddress()
+ + " with ID " + newActivePing.packetId + ".");
+ }
+
+ newActivePing.socket.send(packet);
+ mActivePings.add(newActivePing);
+ mEventCounter++;
+ sendMessageDelayed(obtainMessage(ACTION_LISTEN_FOR_RESPONSE, mEventCounter, 0),
+ RECEIVE_POLL_INTERVAL_MS);
+ } catch (IOException e) {
+ sendResponse((short) msg.arg1, SOCKET_EXCEPTION);
+ }
+ break;
+ case ACTION_LISTEN_FOR_RESPONSE:
+ if (msg.arg1 != mEventCounter) {
+ break;
+ }
+ for (ActivePing curPing : mActivePings) {
+ try {
+ /** Each socket will block for {@link #SOCKET_TIMEOUT_MS} in receive() */
+ byte[] responseBuf = new byte[2];
+ DatagramPacket replyPacket = new DatagramPacket(responseBuf, 2);
+ curPing.socket.receive(replyPacket);
+ // Check that ID field matches (we're throwing out the rest of the packet)
+ if (responseBuf[0] == (byte) (curPing.packetId >> 8) &&
+ responseBuf[1] == (byte) curPing.packetId) {
+ curPing.result =
+ (int) (SystemClock.elapsedRealtime() - curPing.start);
+ } else {
+ if (V) {
+ Slog.v(TAG, "response ID didn't match, ignoring packet");
+ }
+ }
+ } catch (SocketTimeoutException e) {
+ // A timeout here doesn't mean anything - squelsh this exception
+ } catch (Exception e) {
+ if (V) {
+ Slog.v(TAG, "DnsPinger.pingDns got socket exception: ", e);
+ }
+ curPing.result = SOCKET_EXCEPTION;
+ }
+ }
+ Iterator<ActivePing> iter = mActivePings.iterator();
+ while (iter.hasNext()) {
+ ActivePing curPing = iter.next();
+ if (curPing.result != null) {
+ sendResponse(curPing.internalId, curPing.result);
+ curPing.socket.close();
+ iter.remove();
+ } else if (SystemClock.elapsedRealtime() >
+ curPing.start + curPing.timeout) {
+ sendResponse(curPing.internalId, TIMEOUT);
+ curPing.socket.close();
+ iter.remove();
+ }
+ }
+ if (!mActivePings.isEmpty()) {
+ sendMessageDelayed(obtainMessage(ACTION_LISTEN_FOR_RESPONSE, mEventCounter, 0),
+ RECEIVE_POLL_INTERVAL_MS);
+ }
+ break;
+ case ACTION_CANCEL_ALL_PINGS:
+ for (ActivePing activePing : mActivePings)
+ activePing.socket.close();
+ mActivePings.clear();
+ removeMessages(ACTION_PING_DNS);
+ break;
+ }
}
/**
@@ -99,6 +238,30 @@
return dnses.iterator().next();
}
+ /**
+ * Send a ping. The response will come via a {@link #DNS_PING_RESULT} to the handler
+ * specified at creation.
+ * @param dns address of dns server to ping
+ * @param timeout timeout for ping
+ * @return an ID field, which will also be included in the {@link #DNS_PING_RESULT} message.
+ */
+ public int pingDnsAsync(InetAddress dns, int timeout, int delay) {
+ int id = sCounter.incrementAndGet();
+ sendMessageDelayed(obtainMessage(ACTION_PING_DNS, id, timeout, dns), delay);
+ return id;
+ }
+
+ public void cancelPings() {
+ obtainMessage(ACTION_CANCEL_ALL_PINGS).sendToTarget();
+ }
+
+ private void sendResponse(int internalId, int responseVal) {
+ if(V) {
+ Slog.v(TAG, "Responding with id " + internalId + " and val " + responseVal);
+ }
+ mTarget.sendMessage(obtainMessage(DNS_PING_RESULT, internalId, responseVal));
+ }
+
private LinkProperties getCurrentLinkProperties() {
if (mConnectivityManager == null) {
mConnectivityManager = (ConnectivityManager) mContext.getSystemService(
@@ -123,106 +286,18 @@
}
}
- /**
- * @return time to response. Negative value on error.
- */
- public long pingDns(InetAddress dnsAddress, int timeout) {
- DatagramSocket socket = null;
- try {
- socket = new DatagramSocket();
-
- // Set some socket properties
- socket.setSoTimeout(timeout);
-
- // Try to bind but continue ping if bind fails
- try {
- socket.setNetworkInterface(NetworkInterface.getByName(
- getCurrentLinkProperties().getInterfaceName()));
- } catch (Exception e) {
- Slog.d(TAG,"pingDns::Error binding to socket", e);
- }
-
- byte[] buf = constructQuery();
-
- // Send the DNS query
-
- DatagramPacket packet = new DatagramPacket(buf,
- buf.length, dnsAddress, DNS_PORT);
- long start = SystemClock.elapsedRealtime();
- socket.send(packet);
-
- // Wait for reply (blocks for the above timeout)
- DatagramPacket replyPacket = new DatagramPacket(buf, buf.length);
- socket.receive(replyPacket);
-
- // If a timeout occurred, an exception would have been thrown. We
- // got a reply!
- return SystemClock.elapsedRealtime() - start;
-
- } catch (SocketTimeoutException e) {
- // Squelch this exception.
- return -1;
- } catch (Exception e) {
- if (V) {
- Slog.v(TAG, "DnsPinger.pingDns got socket exception: ", e);
- }
- return -2;
- } finally {
- if (socket != null) {
- socket.close();
- }
- }
-
- }
-
- /**
- * @return google.com DNS query packet
- */
- private static byte[] constructQuery() {
- byte[] buf = new byte[DNS_QUERY_BASE_SIZE];
-
- // [0-1] bytes are an ID, generate random ID for this query
- buf[0] = (byte) sRandom.nextInt(256);
- buf[1] = (byte) sRandom.nextInt(256);
-
- // [2-3] bytes are for flags.
- buf[2] = 0x01; // Recursion desired
-
- // [4-5] bytes are for number of queries (QCOUNT)
- buf[5] = 0x01;
-
- // [6-7] [8-9] [10-11] are all counts of other fields we don't use
-
- // [12-15] for www
- writeString(buf, 12, "www");
-
- // [16-22] for google
- writeString(buf, 16, "google");
-
- // [23-26] for com
- writeString(buf, 23, "com");
-
- // [27] is a null byte terminator byte for the url
-
- // [28-29] bytes are for QTYPE, set to 1 = A (host address)
- buf[29] = 0x01;
-
- // [30-31] bytes are for QCLASS, set to 1 = IN (internet)
- buf[31] = 0x01;
-
- return buf;
- }
-
- /**
- * Writes the string's length and its contents to the buffer
- */
- private static void writeString(byte[] buf, int startPos, String string) {
- int pos = startPos;
-
- // Write the length first
- buf[pos++] = (byte) string.length();
- for (int i = 0; i < string.length(); i++) {
- buf[pos++] = (byte) string.charAt(i);
- }
- }
+ private static final byte[] mDnsQuery = new byte[] {
+ 0, 0, // [0-1] is for ID (will set each time)
+ 0, 0, // [2-3] are flags. Set byte[2] = 1 for recursion desired (RD) on. Currently off.
+ 0, 1, // [4-5] bytes are for number of queries (QCOUNT)
+ 0, 0, // [6-7] unused count field for dns response packets
+ 0, 0, // [8-9] unused count field for dns response packets
+ 0, 0, // [10-11] unused count field for dns response packets
+ 3, 'w', 'w', 'w',
+ 6, 'g', 'o', 'o', 'g', 'l', 'e',
+ 3, 'c', 'o', 'm',
+ 0, // null terminator of address (also called empty TLD)
+ 0, 1, // QTYPE, set to 1 = A (host address)
+ 0, 1 // QCLASS, set to 1 = IN (internet)
+ };
}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index b1d99a4..f391200 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -18,6 +18,7 @@
import android.net.LinkProperties;
import android.net.NetworkInfo;
+import android.net.NetworkQuotaInfo;
import android.net.NetworkState;
import android.net.ProxyProperties;
import android.os.IBinder;
@@ -47,6 +48,8 @@
NetworkState[] getAllNetworkState();
+ NetworkQuotaInfo getActiveNetworkQuotaInfo();
+
boolean setRadios(boolean onOff);
boolean setRadio(int networkType, boolean turnOn);
diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index 3e07b0a..633c38e0 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -18,6 +18,8 @@
import android.net.INetworkPolicyListener;
import android.net.NetworkPolicy;
+import android.net.NetworkQuotaInfo;
+import android.net.NetworkState;
import android.net.NetworkTemplate;
/**
@@ -27,6 +29,7 @@
*/
interface INetworkPolicyManager {
+ /** Control UID policies. */
void setUidPolicy(int uid, int policy);
int getUidPolicy(int uid);
@@ -35,12 +38,17 @@
void registerListener(INetworkPolicyListener listener);
void unregisterListener(INetworkPolicyListener listener);
+ /** Control network policies atomically. */
void setNetworkPolicies(in NetworkPolicy[] policies);
NetworkPolicy[] getNetworkPolicies();
+ /** Snooze limit on policy matching given template. */
void snoozePolicy(in NetworkTemplate template);
+ /** Control if background data is restricted system-wide. */
void setRestrictBackground(boolean restrictBackground);
boolean getRestrictBackground();
+ NetworkQuotaInfo getNetworkQuotaInfo(in NetworkState state);
+
}
diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl
index 0548250..b65506c 100644
--- a/core/java/android/net/INetworkStatsService.aidl
+++ b/core/java/android/net/INetworkStatsService.aidl
@@ -23,16 +23,21 @@
/** {@hide} */
interface INetworkStatsService {
- /** Return historical stats for traffic that matches template. */
- NetworkStatsHistory getHistoryForNetwork(in NetworkTemplate template);
- /** Return historical stats for specific UID traffic that matches template. */
- NetworkStatsHistory getHistoryForUid(in NetworkTemplate template, int uid, int tag);
+ /** Return historical network layer stats for traffic that matches template. */
+ NetworkStatsHistory getHistoryForNetwork(in NetworkTemplate template, int fields);
+ /** Return historical network layer stats for specific UID traffic that matches template. */
+ NetworkStatsHistory getHistoryForUid(in NetworkTemplate template, int uid, int tag, int fields);
- /** Return usage summary for traffic that matches template. */
+ /** Return network layer usage summary for traffic that matches template. */
NetworkStats getSummaryForNetwork(in NetworkTemplate template, long start, long end);
- /** Return usage summary per UID for traffic that matches template. */
+ /** Return network layer usage summary per UID for traffic that matches template. */
NetworkStats getSummaryForAllUid(in NetworkTemplate template, long start, long end, boolean includeTags);
+ /** Return data layer snapshot of UID network usage. */
+ NetworkStats getDataLayerSnapshotForUid(int uid);
+ /** Increment data layer count of operations performed for UID and tag. */
+ void incrementOperationCount(int uid, int tag, int operationCount);
+
/** Force update of statistics. */
void forceUpdate();
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index f3c863f..5501f38 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -95,9 +95,7 @@
mTarget = target;
mContext = context;
- HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread");
- handlerThread.start();
- mHandler = new MdstHandler(handlerThread.getLooper(), this);
+ mHandler = new MdstHandler(target.getLooper(), this);
IntentFilter filter = new IntentFilter();
filter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
@@ -121,22 +119,22 @@
switch (msg.what) {
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
- if (DBG) {
+ if (VDBG) {
mMdst.log("MdstHandler connected");
}
mMdst.mDataConnectionTrackerAc = (AsyncChannel) msg.obj;
} else {
- if (DBG) {
+ if (VDBG) {
mMdst.log("MdstHandler %s NOT connected error=" + msg.arg1);
}
}
break;
case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
- mMdst.log("Disconnected from DataStateTracker");
+ if (VDBG) mMdst.log("Disconnected from DataStateTracker");
mMdst.mDataConnectionTrackerAc = null;
break;
default: {
- mMdst.log("Ignorning unknown message=" + msg);
+ if (VDBG) mMdst.log("Ignorning unknown message=" + msg);
break;
}
}
@@ -223,13 +221,13 @@
mLinkProperties = intent.getParcelableExtra(
Phone.DATA_LINK_PROPERTIES_KEY);
if (mLinkProperties == null) {
- log("CONNECTED event did not supply link properties.");
+ loge("CONNECTED event did not supply link properties.");
mLinkProperties = new LinkProperties();
}
mLinkCapabilities = intent.getParcelableExtra(
Phone.DATA_LINK_CAPABILITIES_KEY);
if (mLinkCapabilities == null) {
- log("CONNECTED event did not supply link capabilities.");
+ loge("CONNECTED event did not supply link capabilities.");
mLinkCapabilities = new LinkCapabilities();
}
setDetailedState(DetailedState.CONNECTED, reason, apnName);
@@ -240,7 +238,7 @@
if (TextUtils.equals(reason, Phone.REASON_LINK_PROPERTIES_CHANGED)) {
mLinkProperties = intent.getParcelableExtra(Phone.DATA_LINK_PROPERTIES_KEY);
if (mLinkProperties == null) {
- log("No link property in LINK_PROPERTIES change event.");
+ loge("No link property in LINK_PROPERTIES change event.");
mLinkProperties = new LinkProperties();
}
// Just update reason field in this NetworkInfo
@@ -271,7 +269,7 @@
setDetailedState(DetailedState.FAILED, reason, apnName);
} else if (intent.getAction().
equals(DataConnectionTracker.ACTION_DATA_CONNECTION_TRACKER_MESSENGER)) {
- if (DBG) log(mApnType + " got ACTION_DATA_CONNECTION_TRACKER_MESSENGER");
+ if (VDBG) log(mApnType + " got ACTION_DATA_CONNECTION_TRACKER_MESSENGER");
mMessenger = intent.getParcelableExtra(DataConnectionTracker.EXTRA_MESSENGER);
AsyncChannel ac = new AsyncChannel();
ac.connect(mContext, MobileDataStateTracker.this.mHandler, mMessenger);
@@ -439,7 +437,7 @@
*/
for (int retry = 0; retry < 2; retry++) {
if (mPhoneService == null) {
- log("Ignoring mobile radio request because could not acquire PhoneService");
+ loge("Ignoring mobile radio request because could not acquire PhoneService");
break;
}
@@ -450,7 +448,7 @@
}
}
- log("Could not set radio power to " + (turnOn ? "on" : "off"));
+ loge("Could not set radio power to " + (turnOn ? "on" : "off"));
return false;
}
@@ -459,12 +457,12 @@
*/
public void setDataEnable(boolean enabled) {
try {
- log("setDataEnable: E enabled=" + enabled);
+ if (DBG) log("setDataEnable: E enabled=" + enabled);
mDataConnectionTrackerAc.sendMessage(DataConnectionTracker.CMD_SET_DATA_ENABLE,
enabled ? DataConnectionTracker.ENABLED : DataConnectionTracker.DISABLED);
- log("setDataEnable: X enabled=" + enabled);
+ if (VDBG) log("setDataEnable: X enabled=" + enabled);
} catch (Exception e) {
- log("setDataEnable: X mAc was null" + e);
+ loge("setDataEnable: X mAc was null" + e);
}
}
@@ -475,15 +473,15 @@
public void setDependencyMet(boolean met) {
Bundle bundle = Bundle.forPair(DataConnectionTracker.APN_TYPE_KEY, mApnType);
try {
- log("setDependencyMet: E met=" + met);
+ if (DBG) log("setDependencyMet: E met=" + met);
Message msg = Message.obtain();
msg.what = DataConnectionTracker.CMD_SET_DEPENDENCY_MET;
msg.arg1 = (met ? DataConnectionTracker.ENABLED : DataConnectionTracker.DISABLED);
msg.setData(bundle);
mDataConnectionTrackerAc.sendMessage(msg);
- log("setDependencyMet: X met=" + met);
+ if (VDBG) log("setDependencyMet: X met=" + met);
} catch (NullPointerException e) {
- log("setDependencyMet: X mAc was null" + e);
+ loge("setDependencyMet: X mAc was null" + e);
}
}
@@ -510,7 +508,7 @@
*/
for (int retry = 0; retry < 2; retry++) {
if (mPhoneService == null) {
- log("Ignoring feature request because could not acquire PhoneService");
+ loge("Ignoring feature request because could not acquire PhoneService");
break;
}
@@ -525,7 +523,7 @@
}
}
- log("Could not " + (enable ? "enable" : "disable") + " APN type \"" + apnType + "\"");
+ loge("Could not " + (enable ? "enable" : "disable") + " APN type \"" + apnType + "\"");
return Phone.APN_REQUEST_FAILED;
}
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 1e9d813..9d253c7 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -189,9 +189,10 @@
*/
public static void snapToCycleDay(Time time, int cycleDay) {
if (cycleDay > time.getActualMaximum(MONTH_DAY)) {
- // cycle day isn't valid this month; snap to 1st of next month
+ // cycle day isn't valid this month; snap to last second of month
time.month += 1;
time.monthDay = 1;
+ time.second = -1;
} else {
time.monthDay = cycleDay;
}
diff --git a/core/java/android/nfc/ILlcpServiceSocket.aidl b/core/java/android/net/NetworkQuotaInfo.aidl
similarity index 74%
rename from core/java/android/nfc/ILlcpServiceSocket.aidl
rename to core/java/android/net/NetworkQuotaInfo.aidl
index 581c21d..98a02c4 100644
--- a/core/java/android/nfc/ILlcpServiceSocket.aidl
+++ b/core/java/android/net/NetworkQuotaInfo.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open 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,13 +14,6 @@
* limitations under the License.
*/
-package android.nfc;
+package android.net;
-/**
- * {@hide}
- */
-interface ILlcpServiceSocket
-{
- int accept(int nativeHandle);
- void close(int nativeHandle);
-}
+parcelable NetworkQuotaInfo;
diff --git a/core/java/android/net/NetworkQuotaInfo.java b/core/java/android/net/NetworkQuotaInfo.java
new file mode 100644
index 0000000..b85f925
--- /dev/null
+++ b/core/java/android/net/NetworkQuotaInfo.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.net;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Information about quota status on a specific network.
+ */
+public class NetworkQuotaInfo implements Parcelable {
+ private final long mEstimatedBytes;
+ private final long mSoftLimitBytes;
+ private final long mHardLimitBytes;
+
+ public static final long NO_LIMIT = -1;
+
+ /** {@hide} */
+ public NetworkQuotaInfo(long estimatedBytes, long softLimitBytes, long hardLimitBytes) {
+ mEstimatedBytes = estimatedBytes;
+ mSoftLimitBytes = softLimitBytes;
+ mHardLimitBytes = hardLimitBytes;
+ }
+
+ /** {@hide} */
+ public NetworkQuotaInfo(Parcel in) {
+ mEstimatedBytes = in.readLong();
+ mSoftLimitBytes = in.readLong();
+ mHardLimitBytes = in.readLong();
+ }
+
+ public long getEstimatedBytes() {
+ return mEstimatedBytes;
+ }
+
+ public long getSoftLimitBytes() {
+ return mSoftLimitBytes;
+ }
+
+ public long getHardLimitBytes() {
+ return mHardLimitBytes;
+ }
+
+ /** {@inheritDoc} */
+ public int describeContents() {
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeLong(mEstimatedBytes);
+ out.writeLong(mSoftLimitBytes);
+ out.writeLong(mHardLimitBytes);
+ }
+
+ public static final Creator<NetworkQuotaInfo> CREATOR = new Creator<NetworkQuotaInfo>() {
+ public NetworkQuotaInfo createFromParcel(Parcel in) {
+ return new NetworkQuotaInfo(in);
+ }
+
+ public NetworkQuotaInfo[] newArray(int size) {
+ return new NetworkQuotaInfo[size];
+ }
+ };
+}
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index fbff7d8..f2fcb8f 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -21,6 +21,8 @@
import android.os.SystemClock;
import android.util.SparseBooleanArray;
+import com.android.internal.util.Objects;
+
import java.io.CharArrayWriter;
import java.io.PrintWriter;
import java.util.Arrays;
@@ -56,6 +58,7 @@
private long[] rxPackets;
private long[] txBytes;
private long[] txPackets;
+ private long[] operations;
public static class Entry {
public String iface;
@@ -65,12 +68,18 @@
public long rxPackets;
public long txBytes;
public long txPackets;
+ public long operations;
public Entry() {
+ this(IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
+ }
+
+ public Entry(long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
+ this(IFACE_ALL, UID_ALL, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, operations);
}
public Entry(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes,
- long txPackets) {
+ long txPackets, long operations) {
this.iface = iface;
this.uid = uid;
this.tag = tag;
@@ -78,6 +87,7 @@
this.rxPackets = rxPackets;
this.txBytes = txBytes;
this.txPackets = txPackets;
+ this.operations = operations;
}
}
@@ -91,6 +101,7 @@
this.rxPackets = new long[initialSize];
this.txBytes = new long[initialSize];
this.txPackets = new long[initialSize];
+ this.operations = new long[initialSize];
}
public NetworkStats(Parcel parcel) {
@@ -103,11 +114,32 @@
rxPackets = parcel.createLongArray();
txBytes = parcel.createLongArray();
txPackets = parcel.createLongArray();
+ operations = parcel.createLongArray();
+ }
+
+ /** {@inheritDoc} */
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(elapsedRealtime);
+ dest.writeInt(size);
+ dest.writeStringArray(iface);
+ dest.writeIntArray(uid);
+ dest.writeIntArray(tag);
+ dest.writeLongArray(rxBytes);
+ dest.writeLongArray(rxPackets);
+ dest.writeLongArray(txBytes);
+ dest.writeLongArray(txPackets);
+ dest.writeLongArray(operations);
}
public NetworkStats addValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
long txBytes, long txPackets) {
- return addValues(new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets));
+ return addValues(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, 0L);
+ }
+
+ public NetworkStats addValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
+ long txBytes, long txPackets, long operations) {
+ return addValues(
+ new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
}
/**
@@ -124,6 +156,7 @@
rxPackets = Arrays.copyOf(rxPackets, newLength);
txBytes = Arrays.copyOf(txBytes, newLength);
txPackets = Arrays.copyOf(txPackets, newLength);
+ operations = Arrays.copyOf(operations, newLength);
}
iface[size] = entry.iface;
@@ -133,6 +166,7 @@
rxPackets[size] = entry.rxPackets;
txBytes[size] = entry.txBytes;
txPackets[size] = entry.txPackets;
+ operations[size] = entry.operations;
size++;
return this;
@@ -150,6 +184,7 @@
entry.rxPackets = rxPackets[i];
entry.txBytes = txBytes[i];
entry.txPackets = txPackets[i];
+ entry.operations = operations[i];
return entry;
}
@@ -167,8 +202,9 @@
}
public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
- long txBytes, long txPackets) {
- return combineValues(new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets));
+ long txBytes, long txPackets, long operations) {
+ return combineValues(
+ new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
}
/**
@@ -186,6 +222,7 @@
rxPackets[i] += entry.rxPackets;
txBytes[i] += entry.txBytes;
txPackets[i] += entry.txPackets;
+ operations[i] += entry.operations;
}
return this;
}
@@ -195,7 +232,7 @@
*/
public int findIndex(String iface, int uid, int tag) {
for (int i = 0; i < size; i++) {
- if (equal(iface, this.iface[i]) && uid == this.uid[i] && tag == this.tag[i]) {
+ if (Objects.equal(iface, this.iface[i]) && uid == this.uid[i] && tag == this.tag[i]) {
return i;
}
}
@@ -203,6 +240,22 @@
}
/**
+ * Splice in {@link #operations} from the given {@link NetworkStats} based
+ * on matching {@link #uid} and {@link #tag} rows. Ignores {@link #iface},
+ * since operation counts are at data layer.
+ */
+ public void spliceOperationsFrom(NetworkStats stats) {
+ for (int i = 0; i < size; i++) {
+ final int j = stats.findIndex(IFACE_ALL, uid[i], tag[i]);
+ if (j == -1) {
+ operations[i] = 0;
+ } else {
+ operations[i] = stats.operations[j];
+ }
+ }
+ }
+
+ /**
* Return list of unique interfaces known by this data structure.
*/
public String[] getUniqueIfaces() {
@@ -289,15 +342,17 @@
entry.rxPackets = rxPackets[i];
entry.txBytes = txBytes[i];
entry.txPackets = txPackets[i];
+ entry.operations = operations[i];
} else {
// existing row, subtract remote value
entry.rxBytes = rxBytes[i] - value.rxBytes[j];
entry.rxPackets = rxPackets[i] - value.rxPackets[j];
entry.txBytes = txBytes[i] - value.txBytes[j];
entry.txPackets = txPackets[i] - value.txPackets[j];
+ entry.operations = operations[i] - value.operations[j];
if (enforceMonotonic
&& (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0
- || entry.txPackets < 0)) {
+ || entry.txPackets < 0 || entry.operations < 0)) {
throw new IllegalArgumentException("found non-monotonic values");
}
if (clampNegative) {
@@ -305,6 +360,7 @@
entry.rxPackets = Math.max(0, entry.rxPackets);
entry.txBytes = Math.max(0, entry.txBytes);
entry.txPackets = Math.max(0, entry.txPackets);
+ entry.operations = Math.max(0, entry.operations);
}
}
@@ -314,10 +370,6 @@
return result;
}
- private static boolean equal(Object a, Object b) {
- return a == b || (a != null && a.equals(b));
- }
-
public void dump(String prefix, PrintWriter pw) {
pw.print(prefix);
pw.print("NetworkStats: elapsedRealtime="); pw.println(elapsedRealtime);
@@ -325,11 +377,12 @@
pw.print(prefix);
pw.print(" iface="); pw.print(iface[i]);
pw.print(" uid="); pw.print(uid[i]);
- pw.print(" tag="); pw.print(tag[i]);
+ pw.print(" tag=0x"); pw.print(Integer.toHexString(tag[i]));
pw.print(" rxBytes="); pw.print(rxBytes[i]);
pw.print(" rxPackets="); pw.print(rxPackets[i]);
pw.print(" txBytes="); pw.print(txBytes[i]);
- pw.print(" txPackets="); pw.println(txPackets[i]);
+ pw.print(" txPackets="); pw.print(txPackets[i]);
+ pw.print(" operations="); pw.println(operations[i]);
}
}
@@ -345,19 +398,6 @@
return 0;
}
- /** {@inheritDoc} */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(elapsedRealtime);
- dest.writeInt(size);
- dest.writeStringArray(iface);
- dest.writeIntArray(uid);
- dest.writeIntArray(tag);
- dest.writeLongArray(rxBytes);
- dest.writeLongArray(rxPackets);
- dest.writeLongArray(txBytes);
- dest.writeLongArray(txPackets);
- }
-
public static final Creator<NetworkStats> CREATOR = new Creator<NetworkStats>() {
public NetworkStats createFromParcel(Parcel in) {
return new NetworkStats(in);
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java
index 8bd1738..c917af9 100644
--- a/core/java/android/net/NetworkStatsHistory.java
+++ b/core/java/android/net/NetworkStatsHistory.java
@@ -16,6 +16,16 @@
package android.net;
+import static android.net.NetworkStats.IFACE_ALL;
+import static android.net.NetworkStats.TAG_NONE;
+import static android.net.NetworkStats.UID_ALL;
+import static android.net.NetworkStatsHistory.DataStreamUtils.readFullLongArray;
+import static android.net.NetworkStatsHistory.DataStreamUtils.readVarLongArray;
+import static android.net.NetworkStatsHistory.DataStreamUtils.writeVarLongArray;
+import static android.net.NetworkStatsHistory.Entry.UNKNOWN;
+import static android.net.NetworkStatsHistory.ParcelUtils.readLongArray;
+import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray;
+
import android.os.Parcel;
import android.os.Parcelable;
@@ -41,40 +51,64 @@
*/
public class NetworkStatsHistory implements Parcelable {
private static final int VERSION_INIT = 1;
+ private static final int VERSION_ADD_PACKETS = 2;
- // TODO: teach about varint encoding to use less disk space
- // TODO: extend to record rxPackets/txPackets
+ public static final int FIELD_RX_BYTES = 0x01;
+ public static final int FIELD_RX_PACKETS = 0x02;
+ public static final int FIELD_TX_BYTES = 0x04;
+ public static final int FIELD_TX_PACKETS = 0x08;
+ public static final int FIELD_OPERATIONS = 0x10;
- private final long bucketDuration;
+ public static final int FIELD_ALL = 0xFFFFFFFF;
+
+ private long bucketDuration;
private int bucketCount;
private long[] bucketStart;
private long[] rxBytes;
+ private long[] rxPackets;
private long[] txBytes;
+ private long[] txPackets;
+ private long[] operations;
public static class Entry {
+ public static final long UNKNOWN = -1;
+
public long bucketStart;
public long bucketDuration;
public long rxBytes;
+ public long rxPackets;
public long txBytes;
+ public long txPackets;
+ public long operations;
}
public NetworkStatsHistory(long bucketDuration) {
- this(bucketDuration, 10);
+ this(bucketDuration, 10, FIELD_ALL);
}
public NetworkStatsHistory(long bucketDuration, int initialSize) {
+ this(bucketDuration, initialSize, FIELD_ALL);
+ }
+
+ public NetworkStatsHistory(long bucketDuration, int initialSize, int fields) {
this.bucketDuration = bucketDuration;
bucketStart = new long[initialSize];
- rxBytes = new long[initialSize];
- txBytes = new long[initialSize];
+ if ((fields & FIELD_RX_BYTES) != 0) rxBytes = new long[initialSize];
+ if ((fields & FIELD_RX_PACKETS) != 0) rxPackets = new long[initialSize];
+ if ((fields & FIELD_TX_BYTES) != 0) txBytes = new long[initialSize];
+ if ((fields & FIELD_TX_PACKETS) != 0) txPackets = new long[initialSize];
+ if ((fields & FIELD_OPERATIONS) != 0) operations = new long[initialSize];
bucketCount = 0;
}
public NetworkStatsHistory(Parcel in) {
bucketDuration = in.readLong();
bucketStart = readLongArray(in);
- rxBytes = in.createLongArray();
- txBytes = in.createLongArray();
+ rxBytes = readLongArray(in);
+ rxPackets = readLongArray(in);
+ txBytes = readLongArray(in);
+ txPackets = readLongArray(in);
+ operations = readLongArray(in);
bucketCount = bucketStart.length;
}
@@ -83,7 +117,10 @@
out.writeLong(bucketDuration);
writeLongArray(out, bucketStart, bucketCount);
writeLongArray(out, rxBytes, bucketCount);
+ writeLongArray(out, rxPackets, bucketCount);
writeLongArray(out, txBytes, bucketCount);
+ writeLongArray(out, txPackets, bucketCount);
+ writeLongArray(out, operations, bucketCount);
}
public NetworkStatsHistory(DataInputStream in) throws IOException {
@@ -91,9 +128,23 @@
switch (version) {
case VERSION_INIT: {
bucketDuration = in.readLong();
- bucketStart = readLongArray(in);
- rxBytes = readLongArray(in);
- txBytes = readLongArray(in);
+ bucketStart = readFullLongArray(in);
+ rxBytes = readFullLongArray(in);
+ rxPackets = new long[bucketStart.length];
+ txBytes = readFullLongArray(in);
+ txPackets = new long[bucketStart.length];
+ operations = new long[bucketStart.length];
+ bucketCount = bucketStart.length;
+ break;
+ }
+ case VERSION_ADD_PACKETS: {
+ bucketDuration = in.readLong();
+ bucketStart = readVarLongArray(in);
+ rxBytes = readVarLongArray(in);
+ rxPackets = readVarLongArray(in);
+ txBytes = readVarLongArray(in);
+ txPackets = readVarLongArray(in);
+ operations = readVarLongArray(in);
bucketCount = bucketStart.length;
break;
}
@@ -104,11 +155,14 @@
}
public void writeToStream(DataOutputStream out) throws IOException {
- out.writeInt(VERSION_INIT);
+ out.writeInt(VERSION_ADD_PACKETS);
out.writeLong(bucketDuration);
- writeLongArray(out, bucketStart, bucketCount);
- writeLongArray(out, rxBytes, bucketCount);
- writeLongArray(out, txBytes, bucketCount);
+ writeVarLongArray(out, bucketStart, bucketCount);
+ writeVarLongArray(out, rxBytes, bucketCount);
+ writeVarLongArray(out, rxPackets, bucketCount);
+ writeVarLongArray(out, txBytes, bucketCount);
+ writeVarLongArray(out, txPackets, bucketCount);
+ writeVarLongArray(out, operations, bucketCount);
}
/** {@inheritDoc} */
@@ -147,8 +201,11 @@
final Entry entry = recycle != null ? recycle : new Entry();
entry.bucketStart = bucketStart[i];
entry.bucketDuration = bucketDuration;
- entry.rxBytes = rxBytes[i];
- entry.txBytes = txBytes[i];
+ entry.rxBytes = getLong(rxBytes, i, UNKNOWN);
+ entry.rxPackets = getLong(rxPackets, i, UNKNOWN);
+ entry.txBytes = getLong(txBytes, i, UNKNOWN);
+ entry.txPackets = getLong(txPackets, i, UNKNOWN);
+ entry.operations = getLong(operations, i, UNKNOWN);
return entry;
}
@@ -156,17 +213,27 @@
* Record that data traffic occurred in the given time range. Will
* distribute across internal buckets, creating new buckets as needed.
*/
- public void recordData(long start, long end, long rx, long tx) {
- if (rx < 0 || tx < 0) {
- throw new IllegalArgumentException(
- "tried recording negative data: rx=" + rx + ", tx=" + tx);
+ @Deprecated
+ public void recordData(long start, long end, long rxBytes, long txBytes) {
+ recordData(start, end,
+ new NetworkStats.Entry(IFACE_ALL, UID_ALL, TAG_NONE, rxBytes, 0L, txBytes, 0L, 0L));
+ }
+
+ /**
+ * Record that data traffic occurred in the given time range. Will
+ * distribute across internal buckets, creating new buckets as needed.
+ */
+ public void recordData(long start, long end, NetworkStats.Entry entry) {
+ if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0 || entry.txPackets < 0
+ || entry.operations < 0) {
+ throw new IllegalArgumentException("tried recording negative data");
}
// create any buckets needed by this range
ensureBuckets(start, end);
// distribute data usage into buckets
- final long duration = end - start;
+ long duration = end - start;
for (int i = bucketCount - 1; i >= 0; i--) {
final long curStart = bucketStart[i];
final long curEnd = curStart + bucketDuration;
@@ -177,10 +244,22 @@
if (curStart > end) continue;
final long overlap = Math.min(curEnd, end) - Math.max(curStart, start);
- if (overlap > 0) {
- this.rxBytes[i] += rx * overlap / duration;
- this.txBytes[i] += tx * overlap / duration;
- }
+ if (overlap <= 0) continue;
+
+ // integer math each time is faster than floating point
+ final long fracRxBytes = entry.rxBytes * overlap / duration;
+ final long fracRxPackets = entry.rxPackets * overlap / duration;
+ final long fracTxBytes = entry.txBytes * overlap / duration;
+ final long fracTxPackets = entry.txPackets * overlap / duration;
+ final int fracOperations = (int) (entry.operations * overlap / duration);
+
+ addLong(rxBytes, i, fracRxBytes); entry.rxBytes -= fracRxBytes;
+ addLong(rxPackets, i, fracRxPackets); entry.rxPackets -= fracRxPackets;
+ addLong(txBytes, i, fracTxBytes); entry.txBytes -= fracTxBytes;
+ addLong(txPackets, i, fracTxPackets); entry.txPackets -= fracTxPackets;
+ addLong(operations, i, fracOperations); entry.operations -= fracOperations;
+
+ duration -= overlap;
}
}
@@ -189,10 +268,19 @@
* for combining together stats for external reporting.
*/
public void recordEntireHistory(NetworkStatsHistory input) {
+ final NetworkStats.Entry entry = new NetworkStats.Entry(
+ IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
for (int i = 0; i < input.bucketCount; i++) {
final long start = input.bucketStart[i];
final long end = start + input.bucketDuration;
- recordData(start, end, input.rxBytes[i], input.txBytes[i]);
+
+ entry.rxBytes = getLong(input.rxBytes, i, 0L);
+ entry.rxPackets = getLong(input.rxPackets, i, 0L);
+ entry.txBytes = getLong(input.txBytes, i, 0L);
+ entry.txPackets = getLong(input.txPackets, i, 0L);
+ entry.operations = getLong(input.operations, i, 0L);
+
+ recordData(start, end, entry);
}
}
@@ -222,8 +310,11 @@
if (bucketCount >= bucketStart.length) {
final int newLength = Math.max(bucketStart.length, 10) * 3 / 2;
bucketStart = Arrays.copyOf(bucketStart, newLength);
- rxBytes = Arrays.copyOf(rxBytes, newLength);
- txBytes = Arrays.copyOf(txBytes, newLength);
+ if (rxBytes != null) rxBytes = Arrays.copyOf(rxBytes, newLength);
+ if (rxPackets != null) rxPackets = Arrays.copyOf(rxPackets, newLength);
+ if (txBytes != null) txBytes = Arrays.copyOf(txBytes, newLength);
+ if (txPackets != null) txPackets = Arrays.copyOf(txPackets, newLength);
+ if (operations != null) operations = Arrays.copyOf(operations, newLength);
}
// create gap when inserting bucket in middle
@@ -232,13 +323,19 @@
final int length = bucketCount - index;
System.arraycopy(bucketStart, index, bucketStart, dstPos, length);
- System.arraycopy(rxBytes, index, rxBytes, dstPos, length);
- System.arraycopy(txBytes, index, txBytes, dstPos, length);
+ if (rxBytes != null) System.arraycopy(rxBytes, index, rxBytes, dstPos, length);
+ if (rxPackets != null) System.arraycopy(rxPackets, index, rxPackets, dstPos, length);
+ if (txBytes != null) System.arraycopy(txBytes, index, txBytes, dstPos, length);
+ if (txPackets != null) System.arraycopy(txPackets, index, txPackets, dstPos, length);
+ if (operations != null) System.arraycopy(operations, index, operations, dstPos, length);
}
bucketStart[index] = start;
- rxBytes[index] = 0;
- txBytes[index] = 0;
+ setLong(rxBytes, index, 0L);
+ setLong(rxPackets, index, 0L);
+ setLong(txBytes, index, 0L);
+ setLong(txPackets, index, 0L);
+ setLong(operations, index, 0L);
bucketCount++;
}
@@ -259,8 +356,11 @@
if (i > 0) {
final int length = bucketStart.length;
bucketStart = Arrays.copyOfRange(bucketStart, i, length);
- rxBytes = Arrays.copyOfRange(rxBytes, i, length);
- txBytes = Arrays.copyOfRange(txBytes, i, length);
+ if (rxBytes != null) rxBytes = Arrays.copyOfRange(rxBytes, i, length);
+ if (rxPackets != null) rxPackets = Arrays.copyOfRange(rxPackets, i, length);
+ if (txBytes != null) txBytes = Arrays.copyOfRange(txBytes, i, length);
+ if (txPackets != null) txPackets = Arrays.copyOfRange(txPackets, i, length);
+ if (operations != null) operations = Arrays.copyOfRange(operations, i, length);
bucketCount -= i;
}
}
@@ -281,8 +381,11 @@
final Entry entry = recycle != null ? recycle : new Entry();
entry.bucketStart = start;
entry.bucketDuration = end - start;
- entry.rxBytes = 0;
- entry.txBytes = 0;
+ entry.rxBytes = rxBytes != null ? 0 : UNKNOWN;
+ entry.rxPackets = rxPackets != null ? 0 : UNKNOWN;
+ entry.txBytes = txBytes != null ? 0 : UNKNOWN;
+ entry.txPackets = txPackets != null ? 0 : UNKNOWN;
+ entry.operations = operations != null ? 0 : UNKNOWN;
for (int i = bucketCount - 1; i >= 0; i--) {
final long curStart = bucketStart[i];
@@ -295,14 +398,16 @@
// include full value for active buckets, otherwise only fractional
final boolean activeBucket = curStart < now && curEnd > now;
- final long overlap = Math.min(curEnd, end) - Math.max(curStart, start);
- if (activeBucket || overlap == bucketDuration) {
- entry.rxBytes += rxBytes[i];
- entry.txBytes += txBytes[i];
- } else if (overlap > 0) {
- entry.rxBytes += rxBytes[i] * overlap / bucketDuration;
- entry.txBytes += txBytes[i] * overlap / bucketDuration;
- }
+ final long overlap = activeBucket ? bucketDuration
+ : Math.min(curEnd, end) - Math.max(curStart, start);
+ if (overlap <= 0) continue;
+
+ // integer math each time is faster than floating point
+ if (rxBytes != null) entry.rxBytes += rxBytes[i] * overlap / bucketDuration;
+ if (rxPackets != null) entry.rxPackets += rxPackets[i] * overlap / bucketDuration;
+ if (txBytes != null) entry.txBytes += txBytes[i] * overlap / bucketDuration;
+ if (txPackets != null) entry.txPackets += txPackets[i] * overlap / bucketDuration;
+ if (operations != null) entry.operations += operations[i] * overlap / bucketDuration;
}
return entry;
@@ -312,20 +417,31 @@
* @deprecated only for temporary testing
*/
@Deprecated
- public void generateRandom(long start, long end, long rx, long tx) {
+ public void generateRandom(long start, long end, long rxBytes, long rxPackets, long txBytes,
+ long txPackets, long operations) {
ensureBuckets(start, end);
+ final NetworkStats.Entry entry = new NetworkStats.Entry(
+ IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
final Random r = new Random();
- while (rx > 1024 && tx > 1024) {
+ while (rxBytes > 1024 && rxPackets > 128 && txBytes > 1024 && txPackets > 128
+ && operations > 32) {
final long curStart = randomLong(r, start, end);
final long curEnd = randomLong(r, curStart, end);
- final long curRx = randomLong(r, 0, rx);
- final long curTx = randomLong(r, 0, tx);
- recordData(curStart, curEnd, curRx, curTx);
+ entry.rxBytes = randomLong(r, 0, rxBytes);
+ entry.rxPackets = randomLong(r, 0, rxPackets);
+ entry.txBytes = randomLong(r, 0, txBytes);
+ entry.txPackets = randomLong(r, 0, txPackets);
+ entry.operations = randomLong(r, 0, operations);
- rx -= curRx;
- tx -= curTx;
+ rxBytes -= entry.rxBytes;
+ rxPackets -= entry.rxPackets;
+ txBytes -= entry.txBytes;
+ txPackets -= entry.txPackets;
+ operations -= entry.operations;
+
+ recordData(curStart, curEnd, entry);
}
}
@@ -346,8 +462,12 @@
for (int i = start; i < bucketCount; i++) {
pw.print(prefix);
pw.print(" bucketStart="); pw.print(bucketStart[i]);
- pw.print(" rxBytes="); pw.print(rxBytes[i]);
- pw.print(" txBytes="); pw.println(txBytes[i]);
+ if (rxBytes != null) pw.print(" rxBytes="); pw.print(rxBytes[i]);
+ if (rxPackets != null) pw.print(" rxPackets="); pw.print(rxPackets[i]);
+ if (txBytes != null) pw.print(" txBytes="); pw.print(txBytes[i]);
+ if (txPackets != null) pw.print(" txPackets="); pw.print(txPackets[i]);
+ if (operations != null) pw.print(" operations="); pw.print(operations[i]);
+ pw.println();
}
}
@@ -368,41 +488,117 @@
}
};
- private static long[] readLongArray(DataInputStream in) throws IOException {
- final int size = in.readInt();
- final long[] values = new long[size];
- for (int i = 0; i < values.length; i++) {
- values[i] = in.readLong();
- }
- return values;
+ private static long getLong(long[] array, int i, long value) {
+ return array != null ? array[i] : value;
}
- private static void writeLongArray(DataOutputStream out, long[] values, int size) throws IOException {
- if (size > values.length) {
- throw new IllegalArgumentException("size larger than length");
+ private static void setLong(long[] array, int i, long value) {
+ if (array != null) array[i] = value;
+ }
+
+ private static void addLong(long[] array, int i, long value) {
+ if (array != null) array[i] += value;
+ }
+
+ /**
+ * Utility methods for interacting with {@link DataInputStream} and
+ * {@link DataOutputStream}, mostly dealing with writing partial arrays.
+ */
+ public static class DataStreamUtils {
+ @Deprecated
+ public static long[] readFullLongArray(DataInputStream in) throws IOException {
+ final int size = in.readInt();
+ final long[] values = new long[size];
+ for (int i = 0; i < values.length; i++) {
+ values[i] = in.readLong();
+ }
+ return values;
}
- out.writeInt(size);
- for (int i = 0; i < size; i++) {
- out.writeLong(values[i]);
+
+ /**
+ * Read variable-length {@link Long} using protobuf-style approach.
+ */
+ public static long readVarLong(DataInputStream in) throws IOException {
+ int shift = 0;
+ long result = 0;
+ while (shift < 64) {
+ byte b = in.readByte();
+ result |= (long) (b & 0x7F) << shift;
+ if ((b & 0x80) == 0)
+ return result;
+ shift += 7;
+ }
+ throw new ProtocolException("malformed long");
+ }
+
+ /**
+ * Write variable-length {@link Long} using protobuf-style approach.
+ */
+ public static void writeVarLong(DataOutputStream out, long value) throws IOException {
+ while (true) {
+ if ((value & ~0x7FL) == 0) {
+ out.writeByte((int) value);
+ return;
+ } else {
+ out.writeByte(((int) value & 0x7F) | 0x80);
+ value >>>= 7;
+ }
+ }
+ }
+
+ public static long[] readVarLongArray(DataInputStream in) throws IOException {
+ final int size = in.readInt();
+ if (size == -1) return null;
+ final long[] values = new long[size];
+ for (int i = 0; i < values.length; i++) {
+ values[i] = readVarLong(in);
+ }
+ return values;
+ }
+
+ public static void writeVarLongArray(DataOutputStream out, long[] values, int size)
+ throws IOException {
+ if (values == null) {
+ out.writeInt(-1);
+ return;
+ }
+ if (size > values.length) {
+ throw new IllegalArgumentException("size larger than length");
+ }
+ out.writeInt(size);
+ for (int i = 0; i < size; i++) {
+ writeVarLong(out, values[i]);
+ }
}
}
- private static long[] readLongArray(Parcel in) {
- final int size = in.readInt();
- final long[] values = new long[size];
- for (int i = 0; i < values.length; i++) {
- values[i] = in.readLong();
+ /**
+ * Utility methods for interacting with {@link Parcel} structures, mostly
+ * dealing with writing partial arrays.
+ */
+ public static class ParcelUtils {
+ public static long[] readLongArray(Parcel in) {
+ final int size = in.readInt();
+ if (size == -1) return null;
+ final long[] values = new long[size];
+ for (int i = 0; i < values.length; i++) {
+ values[i] = in.readLong();
+ }
+ return values;
}
- return values;
- }
- private static void writeLongArray(Parcel out, long[] values, int size) {
- if (size > values.length) {
- throw new IllegalArgumentException("size larger than length");
- }
- out.writeInt(size);
- for (int i = 0; i < size; i++) {
- out.writeLong(values[i]);
+ public static void writeLongArray(Parcel out, long[] values, int size) {
+ if (values == null) {
+ out.writeInt(-1);
+ return;
+ }
+ if (size > values.length) {
+ throw new IllegalArgumentException("size larger than length");
+ }
+ out.writeInt(size);
+ for (int i = 0; i < size; i++) {
+ out.writeLong(values[i]);
+ }
}
}
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index e054930..f138e49 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -20,14 +20,13 @@
import android.app.backup.BackupManager;
import android.content.Context;
import android.media.MediaPlayer;
-import android.os.IBinder;
-import android.os.INetworkManagementService;
import android.os.RemoteException;
import android.os.ServiceManager;
import com.android.server.NetworkManagementSocketTagger;
import dalvik.system.SocketTagger;
+
import java.net.Socket;
import java.net.SocketException;
@@ -172,7 +171,7 @@
}
// take snapshot in time; we calculate delta later
- sActiveProfilingStart = getNetworkStatsForUid(context);
+ sActiveProfilingStart = getDataLayerSnapshotForUid(context);
}
}
@@ -190,7 +189,7 @@
}
// subtract starting values and return delta
- final NetworkStats profilingStop = getNetworkStatsForUid(context);
+ final NetworkStats profilingStop = getDataLayerSnapshotForUid(context);
final NetworkStats profilingDelta = profilingStop.subtractClamped(
sActiveProfilingStart);
sActiveProfilingStart = null;
@@ -199,6 +198,28 @@
}
/**
+ * Increment count of network operations performed under the given
+ * accounting tag. This can be used to derive bytes-per-operation.
+ *
+ * @param tag Accounting tag used in {@link #setThreadStatsTag(int)}.
+ * @param operationCount Number of operations to increment count by.
+ */
+ public static void incrementOperationCount(int tag, int operationCount) {
+ if (operationCount < 0) {
+ throw new IllegalArgumentException("operation count can only be incremented");
+ }
+
+ final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
+ ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
+ final int uid = android.os.Process.myUid();
+ try {
+ statsService.incrementOperationCount(uid, tag, operationCount);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
* Get the total number of packets transmitted through the mobile interface.
*
* @return number of packets. If the statistics are not supported by this device,
@@ -461,14 +482,12 @@
* Return detailed {@link NetworkStats} for the current UID. Requires no
* special permission.
*/
- private static NetworkStats getNetworkStatsForUid(Context context) {
- final IBinder binder = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
- final INetworkManagementService service = INetworkManagementService.Stub.asInterface(
- binder);
-
+ private static NetworkStats getDataLayerSnapshotForUid(Context context) {
+ final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
+ ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
final int uid = android.os.Process.myUid();
try {
- return service.getNetworkStatsUidDetail(uid);
+ return statsService.getDataLayerSnapshotForUid(uid);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
diff --git a/core/java/android/net/VpnBuilder.java b/core/java/android/net/VpnBuilder.java
deleted file mode 100644
index 4582523..0000000
--- a/core/java/android/net/VpnBuilder.java
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.net;
-
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-
-import com.android.internal.net.VpnConfig;
-
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.DatagramSocket;
-import java.net.Socket;
-import java.util.ArrayList;
-
-/**
- * VpnBuilder is a framework which enables applications to build their
- * own VPN solutions. In general, it creates a virtual network interface,
- * configures addresses and routing rules, and returns a file descriptor
- * to the application. Each read from the descriptor retrieves an outgoing
- * packet which was routed to the interface. Each write to the descriptor
- * injects an incoming packet just like it was received from the interface.
- * The framework is running on Internet Protocol (IP), so packets are
- * always started with IP headers. The application then completes a VPN
- * connection by processing and exchanging packets with a remote server
- * over a secured tunnel.
- *
- * <p>Letting applications intercept packets raises huge security concerns.
- * Besides, a VPN application can easily break the network, and two of them
- * may conflict with each other. The framework takes several actions to
- * address these issues. Here are some key points:
- * <ul>
- * <li>User action is required to create a VPN connection.</li>
- * <li>There can be only one VPN connection running at the same time. The
- * existing interface is deactivated when a new one is created.</li>
- * <li>A system-managed notification is shown during the lifetime of a
- * VPN connection.</li>
- * <li>A system-managed dialog gives the information of the current VPN
- * connection. It also provides a button to disconnect.</li>
- * <li>The network is restored automatically when the file descriptor is
- * closed. It also covers the cases when a VPN application is crashed
- * or killed by the system.</li>
- * </ul>
- *
- * <p>There are two primary methods in this class: {@link #prepare} and
- * {@link #establish}. The former deals with the user action and stops
- * the existing VPN connection created by another application. The latter
- * creates a VPN interface using the parameters supplied to this builder.
- * An application must call {@link #prepare} to grant the right to create
- * an interface, and it can be revoked at any time by another application.
- * The application got revoked is notified by an {@link #ACTION_VPN_REVOKED}
- * broadcast. Here are the general steps to create a VPN connection:
- * <ol>
- * <li>When the user press the button to connect, call {@link #prepare}
- * and launch the intent if necessary.</li>
- * <li>Register a receiver for {@link #ACTION_VPN_REVOKED} broadcasts.
- * <li>Connect to the remote server and negotiate the network parameters
- * of the VPN connection.</li>
- * <li>Use those parameters to configure a VpnBuilder and create a VPN
- * interface by calling {@link #establish}.</li>
- * <li>Start processing packets between the returned file descriptor and
- * the VPN tunnel.</li>
- * <li>When an {@link #ACTION_VPN_REVOKED} broadcast is received, the
- * interface is already deactivated by the framework. Close the file
- * descriptor and shut down the VPN tunnel gracefully.
- * </ol>
- * Methods in this class can be used in activities and services. However,
- * the intent returned from {@link #prepare} must be launched from an
- * activity. The broadcast receiver can be registered at any time, but doing
- * it before calling {@link #establish} effectively avoids race conditions.
- *
- * <p class="note">Using this class requires
- * {@link android.Manifest.permission#VPN} permission.
- * @hide
- */
-public class VpnBuilder {
-
- /**
- * Broadcast intent action indicating that the VPN application has been
- * revoked. This can be only received by the target application on the
- * receiver explicitly registered using {@link Context#registerReceiver}.
- *
- * <p>This is a protected intent that can only be sent by the system.
- */
- public static final String ACTION_VPN_REVOKED = VpnConfig.ACTION_VPN_REVOKED;
-
- /**
- * Use IConnectivityManager instead since those methods are hidden and
- * not available in ConnectivityManager.
- */
- private static IConnectivityManager getService() {
- return IConnectivityManager.Stub.asInterface(
- ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
- }
-
- /**
- * Prepare to establish a VPN connection. This method returns {@code null}
- * if the VPN application is already prepared. Otherwise, it returns an
- * {@link Intent} to a system activity. The application should launch the
- * activity using {@link Activity#startActivityForResult} to get itself
- * prepared. The activity may pop up a dialog to require user action, and
- * the result will come back to the application through its
- * {@link Activity#onActivityResult}. The application becomes prepared if
- * the result is {@link Activity#RESULT_OK}, and it is granted to create a
- * VPN interface by calling {@link #establish}.
- *
- * <p>Only one application can be granted at the same time. The right
- * is revoked when another application is granted. The application
- * losing the right will be notified by an {@link #ACTION_VPN_REVOKED}
- * broadcast, and its VPN interface will be deactivated by the system.
- * The application should then notify the remote server and disconnect
- * gracefully. Unless the application becomes prepared again, subsequent
- * calls to {@link #establish} will return {@code null}.
- *
- * @see #establish
- * @see #ACTION_VPN_REVOKED
- */
- public static Intent prepare(Context context) {
- try {
- if (getService().prepareVpn(context.getPackageName(), null)) {
- return null;
- }
- } catch (RemoteException e) {
- // ignore
- }
- return VpnConfig.getIntentForConfirmation();
- }
-
- private VpnConfig mConfig = new VpnConfig();
- private StringBuilder mAddresses = new StringBuilder();
- private StringBuilder mRoutes = new StringBuilder();
-
- /**
- * Set the name of this session. It will be displayed in system-managed
- * dialogs and notifications. This is recommended not required.
- */
- public VpnBuilder setSession(String session) {
- mConfig.session = session;
- return this;
- }
-
- /**
- * Set the {@link PendingIntent} to an activity for users to configure
- * the VPN connection. If it is not set, the button to configure will
- * not be shown in system-managed dialogs.
- */
- public VpnBuilder setConfigureIntent(PendingIntent intent) {
- mConfig.configureIntent = intent;
- return this;
- }
-
- /**
- * Set the maximum transmission unit (MTU) of the VPN interface. If it
- * is not set, the default value in the operating system will be used.
- *
- * @throws IllegalArgumentException if the value is not positive.
- */
- public VpnBuilder setMtu(int mtu) {
- if (mtu <= 0) {
- throw new IllegalArgumentException("Bad mtu");
- }
- mConfig.mtu = mtu;
- return this;
- }
-
- /**
- * Private method to validate address and prefixLength.
- */
- private static void check(InetAddress address, int prefixLength) {
- if (address.isLoopbackAddress()) {
- throw new IllegalArgumentException("Bad address");
- }
- if (address instanceof Inet4Address) {
- if (prefixLength < 0 || prefixLength > 32) {
- throw new IllegalArgumentException("Bad prefixLength");
- }
- } else if (address instanceof Inet6Address) {
- if (prefixLength < 0 || prefixLength > 128) {
- throw new IllegalArgumentException("Bad prefixLength");
- }
- } else {
- throw new IllegalArgumentException("Unsupported family");
- }
- }
-
- /**
- * Convenience method to add a network address to the VPN interface
- * using a numeric address string. See {@link InetAddress} for the
- * definitions of numeric address formats.
- *
- * @throws IllegalArgumentException if the address is invalid.
- * @see #addAddress(InetAddress, int)
- */
- public VpnBuilder addAddress(String address, int prefixLength) {
- return addAddress(InetAddress.parseNumericAddress(address), prefixLength);
- }
-
- /**
- * Add a network address to the VPN interface. Both IPv4 and IPv6
- * addresses are supported. At least one address must be set before
- * calling {@link #establish}.
- *
- * @throws IllegalArgumentException if the address is invalid.
- */
- public VpnBuilder addAddress(InetAddress address, int prefixLength) {
- check(address, prefixLength);
-
- if (address.isAnyLocalAddress()) {
- throw new IllegalArgumentException("Bad address");
- }
-
- mAddresses.append(String.format(" %s/%d", address.getHostAddress(), prefixLength));
- return this;
- }
-
- /**
- * Convenience method to add a network route to the VPN interface
- * using a numeric address string. See {@link InetAddress} for the
- * definitions of numeric address formats.
- *
- * @see #addRoute(InetAddress, int)
- * @throws IllegalArgumentException if the route is invalid.
- */
- public VpnBuilder addRoute(String address, int prefixLength) {
- return addRoute(InetAddress.parseNumericAddress(address), prefixLength);
- }
-
- /**
- * Add a network route to the VPN interface. Both IPv4 and IPv6
- * routes are supported.
- *
- * @throws IllegalArgumentException if the route is invalid.
- */
- public VpnBuilder addRoute(InetAddress address, int prefixLength) {
- check(address, prefixLength);
-
- int offset = prefixLength / 8;
- byte[] bytes = address.getAddress();
- if (offset < bytes.length) {
- if ((byte)(bytes[offset] << (prefixLength % 8)) != 0) {
- throw new IllegalArgumentException("Bad address");
- }
- while (++offset < bytes.length) {
- if (bytes[offset] != 0) {
- throw new IllegalArgumentException("Bad address");
- }
- }
- }
-
- mRoutes.append(String.format(" %s/%d", address.getHostAddress(), prefixLength));
- return this;
- }
-
- /**
- * Convenience method to add a DNS server to the VPN connection
- * using a numeric address string. See {@link InetAddress} for the
- * definitions of numeric address formats.
- *
- * @throws IllegalArgumentException if the address is invalid.
- * @see #addDnsServer(InetAddress)
- */
- public VpnBuilder addDnsServer(String address) {
- return addDnsServer(InetAddress.parseNumericAddress(address));
- }
-
- /**
- * Add a DNS server to the VPN connection. Both IPv4 and IPv6
- * addresses are supported. If none is set, the DNS servers of
- * the default network will be used.
- *
- * @throws IllegalArgumentException if the address is invalid.
- */
- public VpnBuilder addDnsServer(InetAddress address) {
- if (address.isLoopbackAddress() || address.isAnyLocalAddress()) {
- throw new IllegalArgumentException("Bad address");
- }
- if (mConfig.dnsServers == null) {
- mConfig.dnsServers = new ArrayList<String>();
- }
- mConfig.dnsServers.add(address.getHostAddress());
- return this;
- }
-
- /**
- * Add a search domain to the DNS resolver.
- */
- public VpnBuilder addSearchDomain(String domain) {
- if (mConfig.searchDomains == null) {
- mConfig.searchDomains = new ArrayList<String>();
- }
- mConfig.searchDomains.add(domain);
- return this;
- }
-
- /**
- * Create a VPN interface using the parameters supplied to this builder.
- * The interface works on IP packets, and a file descriptor is returned
- * for the application to access them. Each read retrieves an outgoing
- * packet which was routed to the interface. Each write injects an
- * incoming packet just like it was received from the interface. The file
- * descriptor is put into non-blocking mode by default to avoid blocking
- * Java threads. To use the file descriptor completely in native space,
- * see {@link ParcelFileDescriptor#detachFd()}. The application MUST
- * close the file descriptor when the VPN connection is terminated. The
- * VPN interface will be removed and the network will be restored by the
- * framework automatically.
- *
- * <p>To avoid conflicts, there can be only one active VPN interface at
- * the same time. Usually network parameters are never changed during the
- * lifetime of a VPN connection. It is also common for an application to
- * create a new file descriptor after closing the previous one. However,
- * it is rare but not impossible to have two interfaces while performing a
- * seamless handover. In this case, the old interface will be deactivated
- * when the new one is configured successfully. Both file descriptors are
- * valid but now outgoing packets will be routed to the new interface.
- * Therefore, after draining the old file descriptor, the application MUST
- * close it and start using the new file descriptor. If the new interface
- * cannot be created, the existing interface and its file descriptor remain
- * untouched.
- *
- * <p>An exception will be thrown if the interface cannot be created for
- * any reason. However, this method returns {@code null} if the application
- * is not prepared or is revoked by another application. This helps solve
- * possible race conditions while handling {@link #ACTION_VPN_REVOKED}
- * broadcasts.
- *
- * @return {@link ParcelFileDescriptor} of the VPN interface, or
- * {@code null} if the application is not prepared.
- * @throws IllegalArgumentException if a parameter is not accepted by the
- * operating system.
- * @throws IllegalStateException if a parameter cannot be applied by the
- * operating system.
- * @see #prepare
- */
- public ParcelFileDescriptor establish() {
- mConfig.addresses = mAddresses.toString();
- mConfig.routes = mRoutes.toString();
-
- try {
- return getService().establishVpn(mConfig);
- } catch (RemoteException e) {
- throw new IllegalStateException(e);
- }
- }
-
- /**
- * Protect a socket from VPN connections. The socket will be bound to the
- * current default network interface, so its traffic will not be forwarded
- * through VPN. This method is useful if some connections need to be kept
- * outside of VPN. For example, a VPN tunnel should protect itself if its
- * destination is covered by VPN routes. Otherwise its outgoing packets
- * will be sent back to the VPN interface and cause an infinite loop.
- *
- * <p>The socket is NOT closed by this method.
- *
- * @return {@code true} on success.
- */
- public static boolean protect(int socket) {
- ParcelFileDescriptor dup = null;
- try {
- dup = ParcelFileDescriptor.fromFd(socket);
- return getService().protectVpn(dup);
- } catch (Exception e) {
- return false;
- } finally {
- try {
- dup.close();
- } catch (Exception e) {
- // ignore
- }
- }
- }
-
- /**
- * Protect a {@link Socket} from VPN connections.
- *
- * @return {@code true} on success.
- * @see #protect(int)
- */
- public static boolean protect(Socket socket) {
- return protect(socket.getFileDescriptor$().getInt$());
- }
-
- /**
- * Protect a {@link DatagramSocket} from VPN connections.
- *
- * @return {@code true} on success.
- * @see #protect(int)
- */
- public static boolean protect(DatagramSocket socket) {
- return protect(socket.getFileDescriptor$().getInt$());
- }
-}
diff --git a/core/java/android/nfc/ILlcpConnectionlessSocket.aidl b/core/java/android/nfc/ILlcpConnectionlessSocket.aidl
deleted file mode 100644
index c6d84e5..0000000
--- a/core/java/android/nfc/ILlcpConnectionlessSocket.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.nfc;
-
-import android.nfc.LlcpPacket;
-
-/**
- * @hide
- */
-interface ILlcpConnectionlessSocket
-{
- void close(int nativeHandle);
- int getSap(int nativeHandle);
- LlcpPacket receiveFrom(int nativeHandle);
- int sendTo(int nativeHandle, in LlcpPacket packet);
-}
\ No newline at end of file
diff --git a/core/java/android/nfc/ILlcpSocket.aidl b/core/java/android/nfc/ILlcpSocket.aidl
deleted file mode 100644
index 3166e72..0000000
--- a/core/java/android/nfc/ILlcpSocket.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.nfc;
-
-/**
- * @hide
- */
-interface ILlcpSocket
-{
- int close(int nativeHandle);
- int connect(int nativeHandle, int sap);
- int connectByName(int nativeHandle, String sn);
- int getLocalSap(int nativeHandle);
- int getLocalSocketMiu(int nativeHandle);
- int getLocalSocketRw(int nativeHandle);
- int getRemoteSocketMiu(int nativeHandle);
- int getRemoteSocketRw(int nativeHandle);
- int receive(int nativeHandle, out byte[] receiveBuffer);
- int send(int nativeHandle, in byte[] data);
-}
\ No newline at end of file
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 2ed6619..83a055c 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -22,13 +22,8 @@
import android.nfc.NdefMessage;
import android.nfc.Tag;
import android.nfc.TechListParcel;
-import android.nfc.ILlcpSocket;
-import android.nfc.ILlcpServiceSocket;
-import android.nfc.ILlcpConnectionlessSocket;
import android.nfc.INdefPushCallback;
import android.nfc.INfcTag;
-import android.nfc.IP2pTarget;
-import android.nfc.IP2pInitiator;
import android.nfc.INfcAdapterExtras;
/**
@@ -36,12 +31,7 @@
*/
interface INfcAdapter
{
- ILlcpSocket getLlcpInterface();
- ILlcpConnectionlessSocket getLlcpConnectionlessInterface();
- ILlcpServiceSocket getLlcpServiceInterface();
INfcTag getNfcTagInterface();
- IP2pTarget getP2pTargetInterface();
- IP2pInitiator getP2pInitiatorInterface();
INfcAdapterExtras getNfcAdapterExtrasInterface();
// NfcAdapter-class related methods
@@ -54,10 +44,6 @@
void disableForegroundNdefPush(in ComponentName activity);
// Non-public methods
- // TODO: check and complete
- int createLlcpConnectionlessSocket(int sap);
- int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength);
- int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength);
boolean disable();
boolean enable();
boolean enableZeroClick();
diff --git a/core/java/android/nfc/INfcAdapterExtras.aidl b/core/java/android/nfc/INfcAdapterExtras.aidl
old mode 100755
new mode 100644
diff --git a/core/java/android/nfc/IP2pInitiator.aidl b/core/java/android/nfc/IP2pInitiator.aidl
deleted file mode 100644
index 931f1f8..0000000
--- a/core/java/android/nfc/IP2pInitiator.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.nfc;
-
-/**
- * @hide
- */
-interface IP2pInitiator
-{
- byte[] getGeneralBytes(int nativeHandle);
- int getMode(int nativeHandle);
- byte[] receive(int nativeHandle);
- boolean send(int nativeHandle, in byte[] data);
-}
\ No newline at end of file
diff --git a/core/java/android/nfc/IP2pTarget.aidl b/core/java/android/nfc/IP2pTarget.aidl
deleted file mode 100644
index ddaaed42..0000000
--- a/core/java/android/nfc/IP2pTarget.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.nfc;
-
-/**
- * @hide
- */
-interface IP2pTarget
-{
- byte[] getGeneralBytes(int nativeHandle);
- int getMode(int nativeHandle);
- int connect(int nativeHandle);
- boolean disconnect(int nativeHandle);
- byte[] transceive(int nativeHandle, in byte[] data);
-}
\ No newline at end of file
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index b668f30..6ba3451 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -21,6 +21,7 @@
import android.os.Parcelable;
import java.lang.UnsupportedOperationException;
+import java.nio.charset.Charset;
import java.nio.charset.Charsets;
import java.util.Arrays;
@@ -139,6 +140,22 @@
*/
public static final byte[] RTD_HANDOVER_SELECT = {0x48, 0x73}; // "Hs"
+ /**
+ * RTD Android app type. For use with TNF_EXTERNAL.
+ * <p>
+ * The payload of a record with type RTD_ANDROID_APP
+ * should be the package name identifying an application.
+ * Multiple RTD_ANDROID_APP records may be included
+ * in a single {@link NdefMessage}.
+ * <p>
+ * Use {@link #createApplicationRecord(String)} to create
+ * RTD_ANDROID_APP records.
+ * @hide
+ */
+ // TODO unhide for ICS
+ // TODO recheck docs
+ public static final byte[] RTD_ANDROID_APP = "android.com:pkg".getBytes();
+
private static final byte FLAG_MB = (byte) 0x80;
private static final byte FLAG_ME = (byte) 0x40;
private static final byte FLAG_CF = (byte) 0x20;
@@ -333,6 +350,29 @@
}
/**
+ * Creates an Android application NDEF record.
+ * <p>
+ * When an Android device dispatches an {@link NdefMessage}
+ * containing one or more Android application records,
+ * the applications contained in those records will be the
+ * preferred target for the NDEF_DISCOVERED intent, in
+ * the order in which they appear in the {@link NdefMessage}.
+ * <p>
+ * If none of the applications are installed on the device,
+ * a Market link will be opened to the first application.
+ * <p>
+ * Note that Android application records do not overrule
+ * applications that have called {@link NfcAdapter#enableForegroundDispatch}.
+ * @hide
+ */
+ // TODO unhide for ICS
+ // TODO recheck javadoc - should mention this works from ICS only
+ public static NdefRecord createApplicationRecord(String packageName) {
+ return new NdefRecord(TNF_EXTERNAL_TYPE, RTD_ANDROID_APP, new byte[] {},
+ packageName.getBytes(Charsets.US_ASCII));
+ }
+
+ /**
* Creates an NDEF record of well known type URI.
*/
public static NdefRecord createUri(Uri uri) {
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 3704248..bc4e00c 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -240,6 +240,11 @@
void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces);
/**
+ * Return status of bandwidth control module.
+ */
+ boolean isBandwidthControlEnabled();
+
+ /**
* Configures bandwidth throttling on an interface.
*/
void setInterfaceThrottle(String iface, int rxKbps, int txKbps);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d3ff8f8..a6c3387 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1445,17 +1445,16 @@
public static final String VOLUME_BLUETOOTH_SCO = "volume_bluetooth_sco";
/**
- * Whether the notifications should use the ring volume (value of 1) or
- * a separate notification volume (value of 0). In most cases, users
- * will have this enabled so the notification and ringer volumes will be
- * the same. However, power users can disable this and use the separate
- * notification volume control.
+ * Whether the notifications should use the ring volume (value of 1) or a separate
+ * notification volume (value of 0). In most cases, users will have this enabled so the
+ * notification and ringer volumes will be the same. However, power users can disable this
+ * and use the separate notification volume control.
* <p>
- * Note: This is a one-off setting that will be removed in the future
- * when there is profile support. For this reason, it is kept hidden
- * from the public APIs.
+ * Note: This is a one-off setting that will be removed in the future when there is profile
+ * support. For this reason, it is kept hidden from the public APIs.
*
* @hide
+ * @deprecated
*/
public static final String NOTIFICATIONS_USE_RING_VOLUME =
"notifications_use_ring_volume";
diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java
index a31374f..814f50b 100644
--- a/core/java/android/provider/VoicemailContract.java
+++ b/core/java/android/provider/VoicemailContract.java
@@ -41,7 +41,7 @@
* </ul>
*
* <P> The minimum permission needed to access this content provider is
- * {@link Manifest.permission#READ_WRITE_OWN_VOICEMAIL}
+ * {@link Manifest.permission#ADD_VOICEMAIL}
*
* <P>Voicemails are inserted by what is called as a "voicemail source"
* application, which is responsible for syncing voicemail data between a remote
@@ -92,7 +92,7 @@
public static final String SOURCE_PACKAGE_FIELD = "source_package";
/** Defines fields exposed through the /voicemail path of this content provider. */
- public static final class Voicemails implements BaseColumns {
+ public static final class Voicemails implements BaseColumns, OpenableColumns {
/** Not instantiable. */
private Voicemails() {
}
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index fd277d0..8c04853 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -187,28 +187,14 @@
return false;
}
- private synchronized boolean addAudioSink(BluetoothDevice device) {
- String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
- String propValues[] = (String []) getSinkPropertiesNative(path);
- if (propValues == null) {
- Log.e(TAG, "Error while getting AudioSink properties for device: " + device);
- return false;
+ private synchronized void addAudioSink(BluetoothDevice device) {
+ if (mAudioDevices.get(device) == null) {
+ mAudioDevices.put(device, BluetoothA2dp.STATE_DISCONNECTED);
}
- Integer state = null;
- // Properties are name-value pairs
- for (int i = 0; i < propValues.length; i+=2) {
- if (propValues[i].equals(PROPERTY_STATE)) {
- state = new Integer(convertBluezSinkStringToState(propValues[i+1]));
- break;
- }
- }
- mAudioDevices.put(device, state);
- handleSinkStateChange(device, BluetoothA2dp.STATE_DISCONNECTED, state);
- return true;
}
private synchronized void onBluetoothEnable() {
- String devices = mBluetoothService.getProperty("Devices");
+ String devices = mBluetoothService.getProperty("Devices", true);
if (devices != null) {
String [] paths = devices.split(",");
for (String path: paths) {
@@ -259,9 +245,7 @@
return false;
}
- if (mAudioDevices.get(device) == null && !addAudioSink(device)) {
- return false;
- }
+ addAudioSink(device);
String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
if (path == null) {
@@ -495,6 +479,7 @@
// This is for an incoming connection for a device not known to us.
// We have authorized it and bluez state has changed.
addAudioSink(device);
+ handleSinkStateChange(device, BluetoothA2dp.STATE_DISCONNECTED, state);
} else {
if (state == BluetoothA2dp.STATE_PLAYING && mPlayingA2dpDevice == null) {
mPlayingA2dpDevice = device;
diff --git a/core/java/android/server/BluetoothAdapterStateMachine.java b/core/java/android/server/BluetoothAdapterStateMachine.java
index 83f5a9f..031375e 100644
--- a/core/java/android/server/BluetoothAdapterStateMachine.java
+++ b/core/java/android/server/BluetoothAdapterStateMachine.java
@@ -39,7 +39,7 @@
* (BluetootOn)<----------------------<-
* | ^ -------------------->- |
* | | | |
- * TURN_OFF | | BECAME_PAIRABLE m1 | | USER_TURN_ON
+ * TURN_OFF | | BECAME_PAIRABLE m1 | | USER_TURN_ON
* AIRPLANE_MODE_ON | | | |
* V | | |
* (Switching) (PerProcessState)
@@ -47,7 +47,7 @@
* BECAME_NON_PAIRABLE& | | TURN_ON(_CONTINUE) | |
* ALL_DEVICES_DISCONNECTED | | m2 | |
* V |------------------------< | BECAME_PAIRABLE
- * (HotOff)---------------------------- PER_PROCESS_TURN_ON
+ * (HotOff)-------------------------->- PER_PROCESS_TURN_ON
* / ^
* / | SERVICE_RECORD_LOADED
* | |
@@ -59,7 +59,7 @@
* (PowerOff) <----- initial state
*
* Legend:
- * m1 = USER_TURN_OFF
+ * m1 = TURN_HOT
* m2 = Transition to HotOff when number of process wanting BT on is 0.
* BECAME_NON_PAIRABLE will make the transition.
*/
@@ -73,6 +73,9 @@
static final int USER_TURN_ON = 1;
// We get this message when user tries to turn off BT
static final int USER_TURN_OFF = 2;
+ // Per process enable / disable messages
+ static final int PER_PROCESS_TURN_ON = 3;
+ static final int PER_PROCESS_TURN_OFF = 4;
// Message(what) to report a event that the state machine need to respond to
//
@@ -102,9 +105,8 @@
private static final int TURN_ON_CONTINUE = 102;
// Unload firmware, turning off Bluetooth module power
private static final int TURN_COLD = 103;
- // Per process enable / disable messages
- static final int PER_PROCESS_TURN_ON = 104;
- static final int PER_PROCESS_TURN_OFF = 105;
+ // Device disconnecting timeout happens
+ private static final int DEVICES_DISCONNECT_TIMEOUT = 104;
private Context mContext;
private BluetoothService mBluetoothService;
@@ -120,6 +122,9 @@
// this is the BluetoothAdapter state that reported externally
private int mPublicState;
+ // timeout value waiting for all the devices to be disconnected
+ private static final int DEVICES_DISCONNECT_TIMEOUT_TIME = 3000;
+
BluetoothAdapterStateMachine(Context context, BluetoothService bluetoothService,
BluetoothAdapter bluetoothAdapter) {
super(TAG);
@@ -156,7 +161,7 @@
private class PowerOff extends State {
@Override
public void enter() {
- if (DBG) log("Enter PowerOff: ");
+ if (DBG) log("Enter PowerOff: " + getCurrentMessage().what);
}
@Override
public boolean processMessage(Message message) {
@@ -214,8 +219,9 @@
case PER_PROCESS_TURN_OFF:
perProcessCallback(false, (IBluetoothStateChangeCallback) message.obj);
break;
- case AIRPLANE_MODE_ON:
- case USER_TURN_OFF: // ignore
+ case USER_TURN_OFF:
+ Log.w(TAG, "PowerOff received: " + message.what);
+ case AIRPLANE_MODE_ON: // ignore
break;
default:
return NOT_HANDLED;
@@ -280,7 +286,7 @@
@Override
public void enter() {
- if (DBG) log("Enter WarmUp");
+ if (DBG) log("Enter WarmUp: " + getCurrentMessage().what);
}
@Override
@@ -301,7 +307,8 @@
case PER_PROCESS_TURN_OFF:
deferMessage(message);
break;
- case USER_TURN_OFF: // ignore
+ case USER_TURN_OFF:
+ Log.w(TAG, "WarmUp received: " + message.what);
break;
default:
return NOT_HANDLED;
@@ -319,7 +326,7 @@
private class HotOff extends State {
@Override
public void enter() {
- if (DBG) log("Enter HotOff:");
+ if (DBG) log("Enter HotOff: " + getCurrentMessage().what);
}
@Override
@@ -344,7 +351,6 @@
mBluetoothService.shutoffBluetooth();
mEventLoop.stop();
transitionTo(mPowerOff);
- // ASSERT no support of config_bluetooth_adapter_quick_switch
broadcastState(BluetoothAdapter.STATE_OFF);
break;
case AIRPLANE_MODE_OFF:
@@ -354,8 +360,6 @@
broadcastState(BluetoothAdapter.STATE_TURNING_ON);
}
break;
- case USER_TURN_OFF: // ignore
- break;
case PER_PROCESS_TURN_ON:
transitionTo(mPerProcessState);
@@ -368,6 +372,8 @@
case PER_PROCESS_TURN_OFF:
perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj);
break;
+ case USER_TURN_OFF: // ignore
+ break;
default:
return NOT_HANDLED;
}
@@ -380,8 +386,7 @@
@Override
public void enter() {
- int what = getCurrentMessage().what;
- if (DBG) log("Enter Switching: " + what);
+ if (DBG) log("Enter Switching: " + getCurrentMessage().what);
}
@Override
public boolean processMessage(Message message) {
@@ -390,27 +395,38 @@
boolean retValue = HANDLED;
switch(message.what) {
case BECAME_PAIRABLE:
- String[] propVal = {"Pairable", mBluetoothService.getProperty("Pairable")};
- mEventLoop.onPropertyChanged(propVal);
-
- // run bluetooth now that it's turned on
- mBluetoothService.runBluetooth();
+ mBluetoothService.initBluetoothAfterTurningOn();
transitionTo(mBluetoothOn);
broadcastState(BluetoothAdapter.STATE_ON);
+ // run bluetooth now that it's turned on
+ // Note runBluetooth should be called only in adapter STATE_ON
+ mBluetoothService.runBluetooth();
break;
case BECAME_NON_PAIRABLE:
if (mBluetoothService.getAdapterConnectionState() ==
BluetoothAdapter.STATE_DISCONNECTED) {
+ removeMessages(DEVICES_DISCONNECT_TIMEOUT);
transitionTo(mHotOff);
finishSwitchingOff();
}
break;
case ALL_DEVICES_DISCONNECTED:
+ removeMessages(DEVICES_DISCONNECT_TIMEOUT);
if (mBluetoothService.getScanMode() == BluetoothAdapter.SCAN_MODE_NONE) {
transitionTo(mHotOff);
finishSwitchingOff();
}
break;
+ case DEVICES_DISCONNECT_TIMEOUT:
+ sendMessage(ALL_DEVICES_DISCONNECTED);
+ // reset the hardware for error recovery
+ Log.e(TAG, "Devices failed to disconnect, reseting...");
+ deferMessage(obtainMessage(TURN_COLD));
+ if (mContext.getResources().getBoolean
+ (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
+ deferMessage(obtainMessage(TURN_HOT));
+ }
+ break;
case USER_TURN_ON:
case AIRPLANE_MODE_OFF:
case AIRPLANE_MODE_ON:
@@ -438,11 +454,10 @@
}
private class BluetoothOn extends State {
- private boolean mPersistBluetoothOff = false;
@Override
public void enter() {
- if (DBG) log("Enter BluetoothOn: " + mPersistBluetoothOff);
+ if (DBG) log("Enter BluetoothOn: " + getCurrentMessage().what);
}
@Override
public boolean processMessage(Message message) {
@@ -460,7 +475,7 @@
}
if (!mBluetoothService.isApplicationStateChangeTrackerEmpty()) {
transitionTo(mPerProcessState);
- deferMessage(obtainMessage(USER_TURN_OFF));
+ deferMessage(obtainMessage(TURN_HOT));
break;
}
//$FALL-THROUGH$ to AIRPLANE_MODE_ON
@@ -469,6 +484,7 @@
broadcastState(BluetoothAdapter.STATE_TURNING_OFF);
mBluetoothService.switchConnectable(false);
mBluetoothService.disconnectDevices();
+ sendMessageDelayed(DEVICES_DISCONNECT_TIMEOUT, DEVICES_DISCONNECT_TIMEOUT_TIME);
// we turn all the way to PowerOff with AIRPLANE_MODE_ON
if (message.what == AIRPLANE_MODE_ON) {
@@ -477,8 +493,9 @@
deferMessage(obtainMessage(AIRPLANE_MODE_ON));
}
break;
- case AIRPLANE_MODE_OFF: // ignore
- case USER_TURN_ON: // ignore
+ case AIRPLANE_MODE_OFF:
+ case USER_TURN_ON:
+ Log.w(TAG, "BluetoothOn received: " + message.what);
break;
case PER_PROCESS_TURN_ON:
perProcessCallback(true, (IBluetoothStateChangeCallback)message.obj);
@@ -500,7 +517,7 @@
@Override
public void enter() {
- if (DBG) log("Enter PerProcessState");
+ if (DBG) log("Enter PerProcessState: " + getCurrentMessage().what);
}
@Override
@@ -523,28 +540,40 @@
case USER_TURN_ON:
broadcastState(BluetoothAdapter.STATE_TURNING_ON);
persistSwitchSetting(true);
-
- String[] propVal = {"Pairable", mBluetoothService.getProperty("Pairable")};
- mEventLoop.onPropertyChanged(propVal);
-
- // run bluetooth now that it's turned on
- mBluetoothService.runBluetooth();
+ mBluetoothService.initBluetoothAfterTurningOn();
transitionTo(mBluetoothOn);
broadcastState(BluetoothAdapter.STATE_ON);
+ // run bluetooth now that it's turned on
+ mBluetoothService.runBluetooth();
break;
- case USER_TURN_OFF:
+ case TURN_HOT:
broadcastState(BluetoothAdapter.STATE_TURNING_OFF);
if (mBluetoothService.getAdapterConnectionState() !=
BluetoothAdapter.STATE_DISCONNECTED) {
mBluetoothService.disconnectDevices();
+ sendMessageDelayed(DEVICES_DISCONNECT_TIMEOUT,
+ DEVICES_DISCONNECT_TIMEOUT_TIME);
break;
}
//$FALL-THROUGH$ all devices are already disconnected
case ALL_DEVICES_DISCONNECTED:
+ removeMessages(DEVICES_DISCONNECT_TIMEOUT);
mBluetoothService.finishDisable();
broadcastState(BluetoothAdapter.STATE_OFF);
break;
- case PER_PROCESS_TURN_OFF:
+ case DEVICES_DISCONNECT_TIMEOUT:
+ mBluetoothService.finishDisable();
+ broadcastState(BluetoothAdapter.STATE_OFF);
+ Log.e(TAG, "Devices fail to disconnect, reseting...");
+ transitionTo(mHotOff);
+ deferMessage(obtainMessage(TURN_COLD));
+ for (IBluetoothStateChangeCallback c:
+ mBluetoothService.getApplicationStateChangeCallbacks()) {
+ perProcessCallback(false, c);
+ deferMessage(obtainMessage(PER_PROCESS_TURN_ON, c));
+ }
+ break;
+ case PER_PROCESS_TURN_OFF:
perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj);
if (mBluetoothService.isApplicationStateChangeTrackerEmpty()) {
mBluetoothService.switchConnectable(false);
@@ -563,6 +592,9 @@
// we turn all the way to PowerOff with AIRPLANE_MODE_ON
deferMessage(obtainMessage(AIRPLANE_MODE_ON));
break;
+ case USER_TURN_OFF:
+ Log.w(TAG, "PerProcessState received: " + message.what);
+ break;
default:
return NOT_HANDLED;
}
diff --git a/core/java/android/server/BluetoothBondState.java b/core/java/android/server/BluetoothBondState.java
index 30a8b2a..4e2608e 100644
--- a/core/java/android/server/BluetoothBondState.java
+++ b/core/java/android/server/BluetoothBondState.java
@@ -90,6 +90,7 @@
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
mContext.registerReceiver(mReceiver, filter);
+ readAutoPairingData();
}
synchronized void setPendingOutgoingBonding(String address) {
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 9b9196a..d73f8c9 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -54,7 +54,6 @@
private final BluetoothAdapter mAdapter;
private final BluetoothAdapterStateMachine mBluetoothState;
private BluetoothA2dp mA2dp;
- private BluetoothInputDevice mInputDevice;
private final Context mContext;
// The WakeLock is used for bringing up the LCD during a pairing request
// from remote device when Android is in Suspend state.
@@ -134,15 +133,11 @@
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.A2DP) {
mA2dp = (BluetoothA2dp) proxy;
- } else if (profile == BluetoothProfile.INPUT_DEVICE) {
- mInputDevice = (BluetoothInputDevice) proxy;
}
}
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.A2DP) {
mA2dp = null;
- } else if (profile == BluetoothProfile.INPUT_DEVICE) {
- mInputDevice = null;
}
}
};
@@ -359,12 +354,10 @@
Intent intent;
adapterProperties.setProperty(name, propValues[1]);
if (propValues[1].equals("true")) {
- mBluetoothService.setIsDiscovering(true);
intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
} else {
// Stop the discovery.
mBluetoothService.cancelDiscovery();
- mBluetoothService.setIsDiscovering(false);
intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
}
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
@@ -803,21 +796,25 @@
"Incoming A2DP / AVRCP connection from " + address);
mA2dp.allowIncomingConnect(device, authorized);
}
- } else if (mInputDevice != null && BluetoothUuid.isInputDevice(uuid)) {
+ } else if (BluetoothUuid.isInputDevice(uuid)) {
// We can have more than 1 input device connected.
- authorized = mInputDevice.getPriority(device) > BluetoothInputDevice.PRIORITY_OFF;
- if (authorized) {
- Log.i(TAG, "First check pass for incoming HID connection from " + address);
- // notify profile state change
- mBluetoothService.notifyIncomingHidConnection(address);
- } else {
- Log.i(TAG, "Rejecting incoming HID connection from " + address);
- mBluetoothService.allowIncomingHidConnect(device, authorized);
- }
- } else if (BluetoothUuid.isBnep(uuid) && mBluetoothService.allowIncomingTethering()){
- authorized = true;
+ authorized = mBluetoothService.getInputDevicePriority(device) >
+ BluetoothInputDevice.PRIORITY_OFF;
+ if (authorized) {
+ Log.i(TAG, "First check pass for incoming HID connection from " + address);
+ // notify profile state change
+ mBluetoothService.notifyIncomingHidConnection(address);
+ } else {
+ Log.i(TAG, "Rejecting incoming HID connection from " + address);
+ mBluetoothService.allowIncomingProfileConnect(device, authorized);
+ }
+ } else if (BluetoothUuid.isBnep(uuid)) {
+ // PAN doesn't go to the state machine, accept or reject from here
+ authorized = mBluetoothService.allowIncomingTethering();
+ mBluetoothService.allowIncomingProfileConnect(device, authorized);
} else {
Log.i(TAG, "Rejecting incoming " + deviceUuid + " connection from " + address);
+ mBluetoothService.allowIncomingProfileConnect(device, authorized);
}
log("onAgentAuthorize(" + objectPath + ", " + deviceUuid + ") = " + authorized);
}
diff --git a/core/java/android/server/BluetoothPanProfileHandler.java b/core/java/android/server/BluetoothPanProfileHandler.java
index 0d63e19..37cfdc4 100644
--- a/core/java/android/server/BluetoothPanProfileHandler.java
+++ b/core/java/android/server/BluetoothPanProfileHandler.java
@@ -145,13 +145,14 @@
return false;
}
- handlePanDeviceStateChange(device, BluetoothPan.STATE_CONNECTING,
+ // Send interface as null as it is not known
+ handlePanDeviceStateChange(device, null, BluetoothPan.STATE_CONNECTING,
BluetoothPan.LOCAL_PANU_ROLE);
if (mBluetoothService.connectPanDeviceNative(objectPath, "nap")) {
debugLog("connecting to PAN");
return true;
} else {
- handlePanDeviceStateChange(device, BluetoothPan.STATE_DISCONNECTED,
+ handlePanDeviceStateChange(device, null, BluetoothPan.STATE_DISCONNECTED,
BluetoothPan.LOCAL_PANU_ROLE);
errorLog("could not connect to PAN");
return false;
@@ -168,16 +169,16 @@
panDevice.mLocalRole == BluetoothPan.LOCAL_NAP_ROLE) {
String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
- handlePanDeviceStateChange(device, BluetoothPan.STATE_DISCONNECTING,
- panDevice.mLocalRole);
+ handlePanDeviceStateChange(device, panDevice.mIface,
+ BluetoothPan.STATE_DISCONNECTING, panDevice.mLocalRole);
if (!mBluetoothService.disconnectPanServerDeviceNative(objectPath,
device.getAddress(),
- panDevice.mIfaceAddr)) {
+ panDevice.mIface)) {
errorLog("could not disconnect Pan Server Device "+device.getAddress());
// Restore prev state
- handlePanDeviceStateChange(device, state,
+ handlePanDeviceStateChange(device, panDevice.mIface, state,
panDevice.mLocalRole);
return false;
@@ -230,19 +231,19 @@
return false;
}
- handlePanDeviceStateChange(device, BluetoothPan.STATE_DISCONNECTING,
+ handlePanDeviceStateChange(device, panDevice.mIface, BluetoothPan.STATE_DISCONNECTING,
panDevice.mLocalRole);
if (panDevice.mLocalRole == BluetoothPan.LOCAL_NAP_ROLE) {
if (!mBluetoothService.disconnectPanServerDeviceNative(objectPath, device.getAddress(),
panDevice.mIface)) {
// Restore prev state, this shouldn't happen
- handlePanDeviceStateChange(device, state, panDevice.mLocalRole);
+ handlePanDeviceStateChange(device, panDevice.mIface, state, panDevice.mLocalRole);
return false;
}
} else {
if (!mBluetoothService.disconnectPanDeviceNative(objectPath)) {
// Restore prev state, this shouldn't happen
- handlePanDeviceStateChange(device, state, panDevice.mLocalRole);
+ handlePanDeviceStateChange(device, panDevice.mIface, state, panDevice.mLocalRole);
return false;
}
}
@@ -291,6 +292,7 @@
panDevice.mState = state;
panDevice.mIfaceAddr = ifaceAddr;
panDevice.mLocalRole = role;
+ panDevice.mIface = iface;
}
Intent intent = new Intent(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
@@ -304,11 +306,6 @@
mBluetoothService.sendConnectionStateChange(device, state, prevState);
}
- void handlePanDeviceStateChange(BluetoothDevice device,
- int state, int role) {
- handlePanDeviceStateChange(device, null, state, role);
- }
-
private class BluetoothPanDevice {
private int mState;
private String mIfaceAddr;
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 0d95a58..0357958 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -96,7 +96,6 @@
private boolean mIsAirplaneToggleable;
private BluetoothAdapterStateMachine mBluetoothState;
private boolean mRestart = false; // need to call enable() after disable()
- private boolean mIsDiscovering;
private int[] mAdapterSdpHandles;
private ParcelUuid[] mAdapterUuids;
@@ -213,8 +212,6 @@
disableNative();
}
- mIsDiscovering = false;
-
mBondState = new BluetoothBondState(context, this);
mAdapterProperties = new BluetoothAdapterProperties(context, this);
mDeviceProperties = new BluetoothDeviceProperties(this);
@@ -411,7 +408,6 @@
intent.putExtra(BluetoothAdapter.EXTRA_SCAN_MODE, BluetoothAdapter.SCAN_MODE_NONE);
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- mIsDiscovering = false;
mAdapterProperties.clear();
mServiceRecordToPid.clear();
@@ -482,8 +478,6 @@
if (!setupNativeDataNative()) {
return false;
}
- mIsDiscovering = false;
-
switchConnectable(false);
updateSdpRecords();
return true;
@@ -587,16 +581,21 @@
}
/**
+ * This method is called immediately before Bluetooth module is turned on after
+ * the adapter became pariable.
+ * It inits bond state and profile state before STATE_ON intent is broadcasted.
+ */
+ /*package*/ void initBluetoothAfterTurningOn() {
+ mBondState.initBondState();
+ initProfileState();
+ }
+
+ /**
* This method is called immediately after Bluetooth module is turned on.
* It starts auto-connection and places bluetooth on sign onto the battery
* stats
*/
/*package*/ void runBluetooth() {
- mIsDiscovering = false;
- mBondState.readAutoPairingData();
- mBondState.initBondState();
- initProfileState();
-
autoConnect();
// Log bluetooth on to battery stats.
@@ -787,18 +786,27 @@
}
if (allowOnlyInOnState) {
- setPropertyBoolean("Pairable", pairable);
setPropertyBoolean("Discoverable", discoverable);
+ setPropertyBoolean("Pairable", pairable);
} else {
// allowed to set the property through native layer directly
- setAdapterPropertyBooleanNative("Pairable", pairable ? 1 : 0);
setAdapterPropertyBooleanNative("Discoverable", discoverable ? 1 : 0);
+ // do setting pairable after setting discoverable since the adapter
+ // state machine uses pairable event for state change
+ setAdapterPropertyBooleanNative("Pairable", pairable ? 1 : 0);
}
return true;
}
- /*package*/ synchronized String getProperty(String name) {
- if (!isEnabledInternal()) return null;
+ /*package*/ synchronized String getProperty(String name, boolean checkState) {
+ // If checkState is false, check if the event loop is running.
+ // before making the call to Bluez
+ if (checkState) {
+ if (!isEnabledInternal()) return null;
+ } else if (!mEventLoop.isEventLoopRunning()) {
+ return null;
+ }
+
return mAdapterProperties.getProperty(name);
}
@@ -824,17 +832,19 @@
public synchronized String getAddress() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return getProperty("Address");
+ // Don't check state since we want to provide address, even if BT is off
+ return getProperty("Address", false);
}
public synchronized String getName() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return getProperty("Name");
+ // Don't check state since we want to provide name, even if BT is off
+ return getProperty("Name", false);
}
public synchronized ParcelUuid[] getUuids() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- String value = getProperty("UUIDs");
+ String value = getProperty("UUIDs", true);
if (value == null) return null;
return convertStringToParcelUuid(value);
}
@@ -914,7 +924,7 @@
*/
public synchronized int getDiscoverableTimeout() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- String timeout = getProperty("DiscoverableTimeout");
+ String timeout = getProperty("DiscoverableTimeout", true);
if (timeout != null)
return Integer.valueOf(timeout);
else
@@ -926,8 +936,8 @@
if (!isEnabledInternal())
return BluetoothAdapter.SCAN_MODE_NONE;
- boolean pairable = getProperty("Pairable").equals("true");
- boolean discoverable = getProperty("Discoverable").equals("true");
+ boolean pairable = getProperty("Pairable", true).equals("true");
+ boolean discoverable = getProperty("Discoverable", true).equals("true");
return bluezStringToScanMode (pairable, discoverable);
}
@@ -949,11 +959,13 @@
public synchronized boolean isDiscovering() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return mIsDiscovering;
- }
- /* package */ void setIsDiscovering(boolean isDiscovering) {
- mIsDiscovering = isDiscovering;
+ String discoveringProperty = getProperty("Discovering", false);
+ if (discoveringProperty == null) {
+ return false;
+ }
+
+ return discoveringProperty.equals("true");
}
private boolean isBondingFeasible(String address) {
@@ -1562,6 +1574,8 @@
@Override
public boolean changeApplicationBluetoothState(boolean on,
IBluetoothStateChangeCallback callback, IBinder binder) {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+
int pid = Binder.getCallingPid();
//mStateChangeTracker is a synchronized map
if (!mStateChangeTracker.containsKey(pid)) {
@@ -2113,7 +2127,16 @@
}
}
- public boolean allowIncomingHidConnect(BluetoothDevice device, boolean allow) {
+ /**
+ * Handle incoming profile acceptance for profiles handled by Bluetooth Service,
+ * currently PAN and HID. This also is the catch all for all rejections for profiles
+ * that is not supported.
+ *
+ * @param device - Bluetooth Device
+ * @param allow - true / false
+ * @return
+ */
+ public boolean allowIncomingProfileConnect(BluetoothDevice device, boolean allow) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
String address = device.getAddress();
@@ -2123,11 +2146,11 @@
Integer data = getAuthorizationAgentRequestData(address);
if (data == null) {
- Log.w(TAG, "allowIncomingHidConnect(" + device +
+ Log.w(TAG, "allowIncomingProfileConnect(" + device +
") called but no native data available");
return false;
}
- if (DBG) log("allowIncomingHidConnect: " + device + " : " + allow + " : " + data);
+ if (DBG) log("allowIncomingProfileConnect: " + device + " : " + allow + " : " + data);
return setAuthorizationNative(address, allow, data.intValue());
}
@@ -2327,7 +2350,7 @@
synchronized String[] getKnownDevices() {
String[] bonds = null;
- String val = getProperty("Devices");
+ String val = getProperty("Devices", true);
if (val != null) {
bonds = val.split(",");
}
@@ -2336,7 +2359,7 @@
private void initProfileState() {
String[] bonds = null;
- String val = mAdapterProperties.getProperty("Devices");
+ String val = getProperty("Devices", false);
if (val != null) {
bonds = val.split(",");
}
diff --git a/core/java/android/service/textservice/SpellCheckerService.java b/core/java/android/service/textservice/SpellCheckerService.java
index 6f70ab8..3e2e38e 100644
--- a/core/java/android/service/textservice/SpellCheckerService.java
+++ b/core/java/android/service/textservice/SpellCheckerService.java
@@ -22,6 +22,7 @@
import android.app.Service;
import android.content.Intent;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -43,45 +44,6 @@
private final SpellCheckerServiceBinder mBinder = new SpellCheckerServiceBinder(this);
- /**
- * Get suggestions for specified text in TextInfo.
- * This function will run on the incoming IPC thread. So, this is not called on the main thread,
- * but will be called in series on another thread.
- * @param textInfo the text metadata
- * @param suggestionsLimit the number of limit of suggestions returned
- * @param locale the locale for getting suggestions
- * @return SuggestionInfo which contains suggestions for textInfo
- */
- public abstract SuggestionsInfo getSuggestions(
- TextInfo textInfo, int suggestionsLimit, String locale);
-
- /**
- * A batch process of onGetSuggestions.
- * This function will run on the incoming IPC thread. So, this is not called on the main thread,
- * but will be called in series on another thread.
- * @param textInfos an array of the text metadata
- * @param locale the locale for getting suggestions
- * @param suggestionsLimit the number of limit of suggestions returned
- * @param sequentialWords true if textInfos can be treated as sequential words.
- * @return an array of SuggestionInfo of onGetSuggestions
- */
- public SuggestionsInfo[] getSuggestionsMultiple(
- TextInfo[] textInfos, String locale, int suggestionsLimit, boolean sequentialWords) {
- final int length = textInfos.length;
- final SuggestionsInfo[] retval = new SuggestionsInfo[length];
- for (int i = 0; i < length; ++i) {
- retval[i] = getSuggestions(textInfos[i], suggestionsLimit, locale);
- retval[i].setCookieAndSequence(textInfos[i].getCookie(), textInfos[i].getSequence());
- }
- return retval;
- }
-
- /**
- * Request to abort all tasks executed in SpellChecker.
- * This function will run on the incoming IPC thread. So, this is not called on the main thread,
- * but will be called in series on another thread.
- */
- public void cancel() {}
/**
* Implement to return the implementation of the internal spell checker
@@ -95,36 +57,125 @@
return mBinder;
}
- private static class SpellCheckerSessionImpl extends ISpellCheckerSession.Stub {
- private final WeakReference<SpellCheckerService> mInternalServiceRef;
- private final String mLocale;
- private final ISpellCheckerSessionListener mListener;
+ /**
+ * Factory method to create a spell checker session impl
+ * @return SpellCheckerSessionImpl which should be overridden by a concrete implementation.
+ */
+ public abstract Session createSession();
- public SpellCheckerSessionImpl(
- SpellCheckerService service, String locale, ISpellCheckerSessionListener listener) {
- mInternalServiceRef = new WeakReference<SpellCheckerService>(service);
- mLocale = locale;
+ /**
+ * This abstract class should be overridden by a concrete implementation of a spell checker.
+ */
+ public abstract class Session {
+ private InternalISpellCheckerSession mInternalSession;
+
+ /**
+ * @hide
+ */
+ public final void setInternalISpellCheckerSession(InternalISpellCheckerSession session) {
+ mInternalSession = session;
+ }
+
+ /**
+ * This is called after the class is initialized, at which point it knows it can call
+ * getLocale() etc...
+ */
+ public abstract void onCreate();
+
+ /**
+ * Get suggestions for specified text in TextInfo.
+ * This function will run on the incoming IPC thread.
+ * So, this is not called on the main thread,
+ * but will be called in series on another thread.
+ * @param textInfo the text metadata
+ * @param suggestionsLimit the number of limit of suggestions returned
+ * @return SuggestionInfo which contains suggestions for textInfo
+ */
+ public abstract SuggestionsInfo onGetSuggestions(TextInfo textInfo, int suggestionsLimit);
+
+ /**
+ * A batch process of onGetSuggestions.
+ * This function will run on the incoming IPC thread.
+ * So, this is not called on the main thread,
+ * but will be called in series on another thread.
+ * @param textInfos an array of the text metadata
+ * @param suggestionsLimit the number of limit of suggestions returned
+ * @param sequentialWords true if textInfos can be treated as sequential words.
+ * @return an array of SuggestionInfo of onGetSuggestions
+ */
+ public SuggestionsInfo[] onGetSuggestionsMultiple(TextInfo[] textInfos,
+ int suggestionsLimit, boolean sequentialWords) {
+ final int length = textInfos.length;
+ final SuggestionsInfo[] retval = new SuggestionsInfo[length];
+ for (int i = 0; i < length; ++i) {
+ retval[i] = onGetSuggestions(textInfos[i], suggestionsLimit);
+ retval[i].setCookieAndSequence(
+ textInfos[i].getCookie(), textInfos[i].getSequence());
+ }
+ return retval;
+ }
+
+ /**
+ * Request to abort all tasks executed in SpellChecker.
+ * This function will run on the incoming IPC thread.
+ * So, this is not called on the main thread,
+ * but will be called in series on another thread.
+ */
+ public void onCancel() {}
+
+ /**
+ * @return Locale for this session
+ */
+ public String getLocale() {
+ return mInternalSession.getLocale();
+ }
+
+ /**
+ * @return Bundle for this session
+ */
+ public Bundle getBundle() {
+ return mInternalSession.getBundle();
+ }
+ }
+
+ // Preventing from exposing ISpellCheckerSession.aidl, create an internal class.
+ private static class InternalISpellCheckerSession extends ISpellCheckerSession.Stub {
+ private final ISpellCheckerSessionListener mListener;
+ private final Session mSession;
+ private final String mLocale;
+ private final Bundle mBundle;
+
+ public InternalISpellCheckerSession(String locale, ISpellCheckerSessionListener listener,
+ Bundle bundle, Session session) {
mListener = listener;
+ mSession = session;
+ mLocale = locale;
+ mBundle = bundle;
+ session.setInternalISpellCheckerSession(this);
}
@Override
- public void getSuggestionsMultiple(
+ public void onGetSuggestionsMultiple(
TextInfo[] textInfos, int suggestionsLimit, boolean sequentialWords) {
- final SpellCheckerService service = mInternalServiceRef.get();
- if (service == null) return;
try {
mListener.onGetSuggestions(
- service.getSuggestionsMultiple(textInfos, mLocale,
- suggestionsLimit, sequentialWords));
+ mSession.onGetSuggestionsMultiple(
+ textInfos, suggestionsLimit, sequentialWords));
} catch (RemoteException e) {
}
}
@Override
- public void cancel() {
- final SpellCheckerService service = mInternalServiceRef.get();
- if (service == null) return;
- service.cancel();
+ public void onCancel() {
+ mSession.onCancel();
+ }
+
+ public String getLocale() {
+ return mLocale;
+ }
+
+ public Bundle getBundle() {
+ return mBundle;
}
}
@@ -137,10 +188,14 @@
@Override
public ISpellCheckerSession getISpellCheckerSession(
- String locale, ISpellCheckerSessionListener listener) {
+ String locale, ISpellCheckerSessionListener listener, Bundle bundle) {
final SpellCheckerService service = mInternalServiceRef.get();
if (service == null) return null;
- return new SpellCheckerSessionImpl(service, locale, listener);
+ final Session session = service.createSession();
+ final InternalISpellCheckerSession internalSession =
+ new InternalISpellCheckerSession(locale, listener, bundle, session);
+ session.onCreate();
+ return internalSession;
}
}
}
diff --git a/core/java/android/text/TextDirectionHeuristics.java b/core/java/android/text/TextDirectionHeuristics.java
index 5f9ffc5..20170bf 100644
--- a/core/java/android/text/TextDirectionHeuristics.java
+++ b/core/java/android/text/TextDirectionHeuristics.java
@@ -164,6 +164,7 @@
case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
case Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING:
case Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE:
+ case Character.DIRECTIONALITY_ARABIC_NUMBER:
return TriState.TRUE;
default:
return TriState.UNKNOWN;
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 346adc8..f2b6b1f 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -135,7 +135,7 @@
/**
* Updates the hardware renderer for the specified surface.
*
- * @param holder The holder for the surface to hardware accelerate.
+ * @param holder The holder for the surface to hardware accelerate
*/
abstract void updateSurface(SurfaceHolder holder) throws Surface.OutOfResourcesException;
@@ -148,9 +148,11 @@
/**
* This method should be invoked whenever the current hardware renderer
- * context should be reset.
+ * context should be reset.
+ *
+ * @param holder The holder for the surface to hardware accelerate
*/
- abstract void invalidate();
+ abstract void invalidate(SurfaceHolder holder);
/**
* This method should be invoked to ensure the hardware renderer is in
@@ -633,16 +635,8 @@
destroySurface();
// Create an EGL surface we can render into.
- mEglSurface = sEgl.eglCreateWindowSurface(sEglDisplay, sEglConfig, holder, null);
-
- if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) {
- int error = sEgl.eglGetError();
- if (error == EGL_BAD_NATIVE_WINDOW) {
- Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
- return null;
- }
- throw new RuntimeException("createWindowSurface failed "
- + getEGLErrorString(error));
+ if (!createSurface(holder)) {
+ return null;
}
/*
@@ -685,16 +679,17 @@
if (full && mCanvas != null) {
mCanvas = null;
}
-
- if (!isEnabled() || mDestroyed) return;
- mDestroyed = true;
+ if (!isEnabled() || mDestroyed) {
+ setEnabled(false);
+ return;
+ }
destroySurface();
-
- mGl = null;
-
setEnabled(false);
+
+ mDestroyed = true;
+ mGl = null;
}
void destroySurface() {
@@ -706,13 +701,40 @@
}
@Override
- void invalidate() {
+ void invalidate(SurfaceHolder holder) {
// Cancels any existing buffer to ensure we'll get a buffer
// of the right size before we call eglSwapBuffers
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
- EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+ if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
+ sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
+ mEglSurface = null;
+ setEnabled(false);
+ }
+
+ if (holder.getSurface().isValid()) {
+ if (!createSurface(holder)) {
+ return;
+ }
+ setEnabled(true);
+ }
}
-
+
+ private boolean createSurface(SurfaceHolder holder) {
+ mEglSurface = sEgl.eglCreateWindowSurface(sEglDisplay, sEglConfig, holder, null);
+
+ if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) {
+ int error = sEgl.eglGetError();
+ if (error == EGL_BAD_NATIVE_WINDOW) {
+ Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
+ return false;
+ }
+ throw new RuntimeException("createWindowSurface failed "
+ + getEGLErrorString(error));
+ }
+ return true;
+ }
+
@Override
boolean validate() {
return checkCurrent() != SURFACE_STATE_ERROR;
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 836867b..7a96a50 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -29,30 +29,84 @@
private static final String LOG_TAG = "Surface";
private static final boolean DEBUG_RELEASE = false;
+ /* orientations for setOrientation() */
+ public static final int ROTATION_0 = 0;
+ public static final int ROTATION_90 = 1;
+ public static final int ROTATION_180 = 2;
+ public static final int ROTATION_270 = 3;
+
+ /**
+ * Does this object hold a valid surface? Returns true if it holds
+ * a physical surface, so lockCanvas() will succeed. Otherwise
+ * returns false.
+ */
+ public native boolean isValid();
+
+ /** Release the local reference to the server-side surface.
+ * Always call release() when you're done with a Surface. This will
+ * make the surface invalid.
+ */
+ public native void release();
+
+ /** draw into a surface */
+ public Canvas lockCanvas(Rect dirty) throws OutOfResourcesException, IllegalArgumentException {
+ /*
+ * the dirty rectangle may be expanded to the surface's size, if for
+ * instance it has been resized or if the bits were lost, since the last
+ * call.
+ */
+ return lockCanvasNative(dirty);
+ }
+
+ /** unlock the surface and asks a page flip */
+ public native void unlockCanvasAndPost(Canvas canvas);
+
+ /**
+ * unlock the surface. the screen won't be updated until
+ * post() or postAll() is called
+ */
+ public native void unlockCanvas(Canvas canvas);
+
+ @Override
+ public String toString() {
+ return "Surface(name=" + mName + ", identity=" + getIdentity() + ")";
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public native void readFromParcel(Parcel source);
+ public native void writeToParcel(Parcel dest, int flags);
+
+ /**
+ * Exception thrown when a surface couldn't be created or resized
+ */
+ public static class OutOfResourcesException extends Exception {
+ public OutOfResourcesException() {
+ }
+ public OutOfResourcesException(String name) {
+ super(name);
+ }
+ }
+
+ /*
+ * -----------------------------------------------------------------------
+ * No user serviceable parts beyond this point
+ * -----------------------------------------------------------------------
+ */
+
/* flags used in constructor (keep in sync with ISurfaceComposer.h) */
- /** Surface is created hidden */
+ /** Surface is created hidden @hide */
public static final int HIDDEN = 0x00000004;
- /** The surface is to be used by hardware accelerators or DMA engines
- * @deprecated this is ignored, this value is set automatically when needed.
- */
- @Deprecated
- public static final int HARDWARE = 0x00000010;
-
- /** Implies "HARDWARE", the surface is to be used by the GPU;
- * additionally the backbuffer is never preserved for these
- * surfaces.
- * @deprecated this is ignored, this value is set automatically when needed.
- */
- @Deprecated
- public static final int GPU = 0x00000028;
-
/** The surface contains secure content, special measures will
* be taken to disallow the surface's content to be copied from
* another process. In particular, screenshots and VNC servers will
* be disabled, but other measures can take place, for instance the
- * surface might not be hardware accelerated. */
+ * surface might not be hardware accelerated.
+ * @hide*/
public static final int SECURE = 0x00000080;
/** Creates a surface where color components are interpreted as
@@ -75,20 +129,11 @@
*
* In some rare situations, a non pre-multiplied surface is preferable.
*
+ * @hide
*/
public static final int NON_PREMULTIPLIED = 0x00000100;
/**
- * Creates a surface without a rendering buffer. Instead, the content
- * of the surface must be pushed by an external entity. This type
- * of surface can be used for efficient camera preview or movie
- * playback.
- *
- * @deprecated not support by the system anymore
- */
- @Deprecated
- public static final int PUSH_BUFFERS = 0x00000200;
- /**
* Indicates that the surface must be considered opaque, even if its
* pixel format is set to translucent. This can be useful if an
* application needs full RGBA 8888 support for instance but will
@@ -109,7 +154,7 @@
// 0x1000 is reserved for an independent DRM protected flag in framework
- /** Creates a normal surface. This is the default. */
+ /** Creates a normal surface. This is the default. @hide */
public static final int FX_SURFACE_NORMAL = 0x00000000;
/** Creates a Blur surface. Everything behind this surface is blurred
@@ -117,6 +162,7 @@
* is not settable or guaranteed.
* It is an error to lock a Blur surface, since it doesn't have
* a backing store.
+ * @hide
*/
public static final int FX_SURFACE_BLUR = 0x00010000;
@@ -124,55 +170,35 @@
* by the amount specified in {@link #setAlpha}.
* It is an error to lock a Dim surface, since it doesn't have
* a backing store.
+ * @hide
*/
public static final int FX_SURFACE_DIM = 0x00020000;
- /** Mask used for FX values above */
+ /** Mask used for FX values above @hide */
public static final int FX_SURFACE_MASK = 0x000F0000;
/* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */
- /** Hide the surface. Equivalent to calling hide(). */
+ /** Hide the surface. Equivalent to calling hide(). @hide */
public static final int SURFACE_HIDDEN = 0x01;
- /** Freeze the surface. Equivalent to calling freeze(). */
+ /** Freeze the surface. Equivalent to calling freeze(). @hide */
public static final int SURFACE_FROZEN = 0x02;
- /**
- * @deprecated Use {@link #SURFACE_FROZEN} instead.
- */
- @Deprecated
- public static final int SURACE_FROZEN = 0x02;
-
- /** Enable dithering when compositing this surface */
+ /** Enable dithering when compositing this surface @hide */
public static final int SURFACE_DITHER = 0x04;
-
- public static final int SURFACE_BLUR_FREEZE= 0x10;
-
- /* orientations for setOrientation() */
- public static final int ROTATION_0 = 0;
- public static final int ROTATION_90 = 1;
- public static final int ROTATION_180 = 2;
- public static final int ROTATION_270 = 3;
- /**
- * Disable the orientation animation
- * {@hide}
- */
+ /** Disable the orientation animation @hide */
public static final int FLAGS_ORIENTATION_ANIMATION_DISABLE = 0x000000001;
// The mSurfaceControl will only be present for Surfaces used by the window
// server or system processes. When this class is parceled we defer to the
- // mSurfaceControl to do the parceling. Otherwise we parcel the mNativeSurface.
- @SuppressWarnings("unused")
+ // mSurfaceControl to do the parceling. Otherwise we parcel the
+ // mNativeSurface.
private int mSurfaceControl;
- @SuppressWarnings("unused")
private int mSaveCount;
- @SuppressWarnings("unused")
private Canvas mCanvas;
- @SuppressWarnings("unused")
private int mNativeSurface;
- @SuppressWarnings("unused")
private int mSurfaceGenerationId;
private String mName;
@@ -184,19 +210,8 @@
// non compatibility mode.
private Matrix mCompatibleMatrix;
- @SuppressWarnings("unused")
private Exception mCreationStack;
- /**
- * Exception thrown when a surface couldn't be created or resized
- */
- public static class OutOfResourcesException extends Exception {
- public OutOfResourcesException() {
- }
- public OutOfResourcesException(String name) {
- super(name);
- }
- }
/*
* We use a class initializer to allow the native code to cache some
@@ -219,10 +234,7 @@
initFromSurfaceTexture(surfaceTexture);
}
- /**
- * create a surface
- * {@hide}
- */
+ /** create a surface @hide */
public Surface(SurfaceSession s,
int pid, int display, int w, int h, int format, int flags)
throws OutOfResourcesException {
@@ -233,10 +245,7 @@
init(s,pid,null,display,w,h,format,flags);
}
- /**
- * create a surface with a name
- * {@hide}
- */
+ /** create a surface with a name @hide */
public Surface(SurfaceSession s,
int pid, String name, int display, int w, int h, int format, int flags)
throws OutOfResourcesException {
@@ -251,7 +260,7 @@
/**
* Create an empty surface, which will later be filled in by
* readFromParcel().
- * {@hide}
+ * @hide
*/
public Surface() {
if (DEBUG_RELEASE) {
@@ -260,16 +269,35 @@
mCanvas = new CompatibleCanvas();
}
+ private Surface(Parcel source) throws OutOfResourcesException {
+ init(source);
+ }
+
/**
- * A Canvas class that can handle the compatibility mode. This does two things differently.
+ * Copy another surface to this one. This surface now holds a reference
+ * to the same data as the original surface, and is -not- the owner.
+ * @hide
+ */
+ public native void copyFrom(Surface o);
+
+ /** @hide */
+ public int getGenerationId() {
+ return mSurfaceGenerationId;
+ }
+
+ /**
+ * A Canvas class that can handle the compatibility mode. This does two
+ * things differently.
* <ul>
- * <li> Returns the width and height of the target metrics, rather than native.
- * For example, the canvas returns 320x480 even if an app is running in WVGA high density.
- * <li> Scales the matrix in setMatrix by the application scale, except if the matrix looks
- * like obtained from getMatrix. This is a hack to handle the case that an application
- * uses getMatrix to keep the original matrix, set matrix of its own, then set the original
- * matrix back. There is no perfect solution that works for all cases, and there are a lot of
- * cases that this model does not work, but we hope this works for many apps.
+ * <li>Returns the width and height of the target metrics, rather than
+ * native. For example, the canvas returns 320x480 even if an app is running
+ * in WVGA high density.
+ * <li>Scales the matrix in setMatrix by the application scale, except if
+ * the matrix looks like obtained from getMatrix. This is a hack to handle
+ * the case that an application uses getMatrix to keep the original matrix,
+ * set matrix of its own, then set the original matrix back. There is no
+ * perfect solution that works for all cases, and there are a lot of cases
+ * that this model does not work, but we hope this works for many apps.
* </ul>
*/
private class CompatibleCanvas extends Canvas {
@@ -318,7 +346,8 @@
}
/**
- * Sets the translator used to scale canvas's width/height in compatibility mode.
+ * Sets the translator used to scale canvas's width/height in compatibility
+ * mode.
*/
void setCompatibilityTranslator(Translator translator) {
if (translator != null) {
@@ -328,73 +357,29 @@
}
}
- /**
- * Copy another surface to this one. This surface now holds a reference
- * to the same data as the original surface, and is -not- the owner.
- * {@hide}
- */
- public native void copyFrom(Surface o);
-
- /**
- * Does this object hold a valid surface? Returns true if it holds
- * a physical surface, so lockCanvas() will succeed. Otherwise
- * returns false.
- */
- public native boolean isValid();
-
- /**
- * @hide
- */
- public int getGenerationId() {
- return mSurfaceGenerationId;
- }
-
/** Free all server-side state associated with this surface and
- * release this object's reference. {@hide} */
+ * release this object's reference. @hide */
public native void destroy();
- /** Release the local reference to the server-side surface. @hide */
- public native void release();
+ private native Canvas lockCanvasNative(Rect dirty);
- /** draw into a surface */
- public Canvas lockCanvas(Rect dirty) throws OutOfResourcesException, IllegalArgumentException
- {
- /* the dirty rectangle may be expanded to the surface's size, if
- * for instance it has been resized or if the bits were lost, since
- * the last call.
- */
- return lockCanvasNative(dirty);
- }
-
- private native Canvas lockCanvasNative(Rect dirty);
-
- /** unlock the surface and asks a page flip */
- public native void unlockCanvasAndPost(Canvas canvas);
-
- /**
- * unlock the surface. the screen won't be updated until
- * post() or postAll() is called
+ /*
+ * set display parameters & screenshots
*/
- public native void unlockCanvas(Canvas canvas);
- /** start/end a transaction {@hide} */
- public static native void openTransaction();
- /** {@hide} */
- public static native void closeTransaction();
-
/**
* Freezes the specified display, No updating of the screen will occur
* until unfreezeDisplay() is called. Everything else works as usual though,
* in particular transactions.
* @param display
- * {@hide}
+ * @hide
*/
public static native void freezeDisplay(int display);
/**
* resume updating the specified display.
* @param display
- * {@hide}
+ * @hide
*/
public static native void unfreezeDisplay(int display);
@@ -403,7 +388,7 @@
* @param display
* @param orientation
* @param flags
- * {@hide}
+ * @hide
*/
public static native void setOrientation(int display, int orientation, int flags);
@@ -411,6 +396,7 @@
* set the orientation of the given display.
* @param display
* @param orientation
+ * @hide
*/
public static void setOrientation(int display, int orientation) {
setOrientation(display, orientation, 0);
@@ -441,44 +427,43 @@
*/
public static native Bitmap screenshot(int width, int height, int minLayer, int maxLayer);
- /**
+
+ /*
* set surface parameters.
* needs to be inside open/closeTransaction block
*/
+
+ /** start a transaction @hide */
+ public static native void openTransaction();
+ /** end a transaction @hide */
+ public static native void closeTransaction();
+ /** @hide */
public native void setLayer(int zorder);
+ /** @hide */
public native void setPosition(int x, int y);
+ /** @hide */
public native void setSize(int w, int h);
-
+ /** @hide */
public native void hide();
+ /** @hide */
public native void show();
+ /** @hide */
public native void setTransparentRegionHint(Region region);
+ /** @hide */
public native void setAlpha(float alpha);
- public native void setMatrix(float dsdx, float dtdx,
- float dsdy, float dtdy);
-
+ /** @hide */
+ public native void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy);
+ /** @hide */
public native void freeze();
+ /** @hide */
public native void unfreeze();
-
+ /** @hide */
public native void setFreezeTint(int tint);
-
+ /** @hide */
public native void setFlags(int flags, int mask);
- @Override
- public String toString() {
- return "Surface(name=" + mName + ", identity=" + getIdentity() + ")";
- }
- private Surface(Parcel source) throws OutOfResourcesException {
- init(source);
- }
-
- public int describeContents() {
- return 0;
- }
-
- public native void readFromParcel(Parcel source);
- public native void writeToParcel(Parcel dest, int flags);
-
+
public static final Parcelable.Creator<Surface> CREATOR
= new Parcelable.Creator<Surface>()
{
@@ -496,7 +481,6 @@
}
};
- /* no user serviceable parts here ... */
@Override
protected void finalize() throws Throwable {
try {
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 96d6f09..76aa21f 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -204,6 +204,7 @@
}
mLayer.destroy();
+ mSurface.release();
mSurface = null;
mLayer = null;
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 914824c..ad76928 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10221,6 +10221,7 @@
}
canvas.restoreToCount(restoreCount);
+ canvas.setBitmap(null);
if (attachInfo != null) {
// Restore the cached Canvas for our siblings
@@ -10289,6 +10290,7 @@
mPrivateFlags = flags;
canvas.restoreToCount(restoreCount);
+ canvas.setBitmap(null);
if (attachInfo != null) {
// Restore the cached Canvas for our siblings
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index dbcbd6e..9520958 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -220,6 +220,7 @@
private final int mMaximumDrawingCacheSize;
private final int mOverscrollDistance;
private final int mOverflingDistance;
+ private final boolean mFadingMarqueeEnabled;
private boolean sHasPermanentMenuKey;
private boolean sHasPermanentMenuKeySet;
@@ -246,6 +247,7 @@
mMaximumDrawingCacheSize = MAXIMUM_DRAWING_CACHE_SIZE;
mOverscrollDistance = OVERSCROLL_DISTANCE;
mOverflingDistance = OVERFLING_DISTANCE;
+ mFadingMarqueeEnabled = true;
}
/**
@@ -297,6 +299,9 @@
sHasPermanentMenuKey = false;
}
}
+
+ mFadingMarqueeEnabled = res.getBoolean(
+ com.android.internal.R.bool.config_ui_enableFadingMarquee);
}
/**
@@ -673,4 +678,12 @@
public boolean hasPermanentMenuKey() {
return sHasPermanentMenuKey;
}
+
+ /**
+ * @hide
+ * @return Whether or not marquee should use fading edges.
+ */
+ public boolean isFadingMarqueeEnabled() {
+ return mFadingMarqueeEnabled;
+ }
}
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 96e550e..65e72c9 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -1094,6 +1094,9 @@
}
public void post(Object... data) {
+ if (data[1] != null) {
+ ((Canvas) data[1]).setBitmap(null);
+ }
if (data[0] != null) {
((Bitmap) data[0]).recycle();
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index b22ab7e..ec4c5a29 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1253,6 +1253,11 @@
mScroller.abortAnimation();
}
disposeResizeBuffer();
+ // Our surface is gone
+ if (mAttachInfo.mHardwareRenderer != null &&
+ mAttachInfo.mHardwareRenderer.isEnabled()) {
+ mAttachInfo.mHardwareRenderer.destroy(true);
+ }
} else if (surfaceGenerationId != mSurface.getGenerationId() &&
mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) {
fullRedrawNeeded = true;
@@ -1273,7 +1278,7 @@
}
} catch (RemoteException e) {
}
-
+
if (DEBUG_ORIENTATION) Log.v(
TAG, "Relayout returned: frame=" + frame + ", surface=" + mSurface);
@@ -1344,7 +1349,7 @@
mAttachInfo.mHardwareRenderer.isEnabled())) {
mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight);
if (!hwInitialized) {
- mAttachInfo.mHardwareRenderer.invalidate();
+ mAttachInfo.mHardwareRenderer.invalidate(mHolder);
}
}
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index 9e9f46f..662137a 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -26,7 +26,6 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.AudioService;
import android.media.AudioSystem;
@@ -36,13 +35,9 @@
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
-import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.ImageView;
-import android.widget.ProgressBar;
import android.widget.SeekBar;
-import android.widget.TextView;
-import android.widget.Toast;
import android.widget.SeekBar.OnSeekBarChangeListener;
import java.util.HashMap;
@@ -52,6 +47,10 @@
*
* This code really should be moved elsewhere.
*
+ * Seriously, it really really should be moved elsewhere. This is used by
+ * android.media.AudioService, which actually runs in the system process, to
+ * show the volume dialog when the user changes the volume. What a mess.
+ *
* @hide
*/
public class VolumePanel extends Handler implements OnSeekBarChangeListener, View.OnClickListener
@@ -89,30 +88,16 @@
private static final int MSG_TIMEOUT = 5;
private static final int MSG_RINGER_MODE_CHANGED = 6;
-// private static final int RINGTONE_VOLUME_TEXT = com.android.internal.R.string.volume_ringtone;
-// private static final int MUSIC_VOLUME_TEXT = com.android.internal.R.string.volume_music;
-// private static final int INCALL_VOLUME_TEXT = com.android.internal.R.string.volume_call;
-// private static final int ALARM_VOLUME_TEXT = com.android.internal.R.string.volume_alarm;
-// private static final int UNKNOWN_VOLUME_TEXT = com.android.internal.R.string.volume_unknown;
-// private static final int NOTIFICATION_VOLUME_TEXT =
-// com.android.internal.R.string.volume_notification;
-// private static final int BLUETOOTH_INCALL_VOLUME_TEXT =
-// com.android.internal.R.string.volume_bluetooth_call;
-
protected Context mContext;
private AudioManager mAudioManager;
protected AudioService mAudioService;
private boolean mRingIsSilent;
+ private boolean mShowCombinedVolumes;
/** Dialog containing all the sliders */
private final Dialog mDialog;
/** Dialog's content view */
private final View mView;
-// private final TextView mMessage;
-// private final TextView mAdditionalMessage;
-// private final ImageView mSmallStreamIcon;
-// private final ImageView mLargeStreamIcon;
-// private final ProgressBar mLevel;
/** Contains the sliders and their touchable icons */
private final ViewGroup mSliderGroup;
@@ -127,7 +112,7 @@
private HashMap<Integer,StreamControl> mStreamControls;
// List of stream types and their order
- // RING and VOICE_CALL are hidden unless explicitly requested
+ // RING, VOICE_CALL & BLUETOOTH_SCO are hidden unless explicitly requested
private static final int [] STREAM_TYPES = {
AudioManager.STREAM_BLUETOOTH_SCO,
AudioManager.STREAM_RING,
@@ -136,10 +121,18 @@
AudioManager.STREAM_NOTIFICATION
};
+ private static final int [] CONTENT_DESCRIPTIONS = {
+ R.string.volume_icon_description_bluetooth,
+ R.string.volume_icon_description_ringer,
+ R.string.volume_icon_description_incall,
+ R.string.volume_icon_description_media,
+ R.string.volume_icon_description_notification
+ };
+
// These icons need to correspond to the ones above.
private static final int [] STREAM_ICONS_NORMAL = {
R.drawable.ic_audio_bt,
- R.drawable.ic_audio_phone,
+ R.drawable.ic_audio_ring_notif,
R.drawable.ic_audio_phone,
R.drawable.ic_audio_vol,
R.drawable.ic_audio_notification,
@@ -148,7 +141,7 @@
// These icons need to correspond to the ones above.
private static final int [] STREAM_ICONS_MUTED = {
R.drawable.ic_audio_bt,
- R.drawable.ic_audio_phone,
+ R.drawable.ic_audio_ring_notif_mute,
R.drawable.ic_audio_phone,
R.drawable.ic_audio_vol_mute,
R.drawable.ic_audio_notification_mute,
@@ -184,7 +177,6 @@
});
mSliderGroup = (ViewGroup) mView.findViewById(R.id.slider_group);
mMoreButton = (ImageView) mView.findViewById(R.id.expand_button);
- mMoreButton.setOnClickListener(this);
mDivider = (ImageView) mView.findViewById(R.id.expand_button_divider);
mDialog = new Dialog(context, R.style.Theme_Panel_Volume);
@@ -201,20 +193,22 @@
window.setGravity(Gravity.TOP);
WindowManager.LayoutParams lp = window.getAttributes();
lp.token = null;
- lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
+ lp.type = WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
window.setAttributes(lp);
window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
-// mMessage = (TextView) view.findViewById(com.android.internal.R.id.message);
-// mAdditionalMessage =
-// (TextView) view.findViewById(com.android.internal.R.id.additional_message);
-// mSmallStreamIcon = (ImageView) view.findViewById(com.android.internal.R.id.other_stream_icon);
-// mLargeStreamIcon = (ImageView) view.findViewById(com.android.internal.R.id.ringer_stream_icon);
-// mLevel = (ProgressBar) view.findViewById(com.android.internal.R.id.level);
-
mToneGenerators = new ToneGenerator[AudioSystem.getNumStreamTypes()];
mVibrator = new Vibrator();
+ mShowCombinedVolumes = !context.getResources().getBoolean(R.bool.config_voice_capable);
+ // If we don't want to show multiple volumes, hide the settings button and divider
+ if (!mShowCombinedVolumes) {
+ mMoreButton.setVisibility(View.GONE);
+ mDivider.setVisibility(View.GONE);
+ } else {
+ mMoreButton.setOnClickListener(this);
+ }
+
listenToRingerMode();
}
@@ -242,6 +236,7 @@
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mStreamControls = new HashMap<Integer,StreamControl>(STREAM_TYPES.length);
+ Resources res = mContext.getResources();
for (int i = 0; i < STREAM_TYPES.length; i++) {
StreamControl sc = new StreamControl();
sc.streamType = STREAM_TYPES[i];
@@ -250,6 +245,7 @@
sc.icon = (ImageView) sc.group.findViewById(R.id.stream_icon);
sc.icon.setOnClickListener(this);
sc.icon.setTag(sc);
+ sc.icon.setContentDescription(res.getString(CONTENT_DESCRIPTIONS[i]));
sc.iconRes = STREAM_ICONS_NORMAL[i];
sc.iconMuteRes = STREAM_ICONS_MUTED[i];
sc.icon.setImageResource(sc.iconRes);
@@ -275,13 +271,19 @@
updateSlider(active);
}
+ addOtherVolumes();
+ }
+
+ private void addOtherVolumes() {
+ if (!mShowCombinedVolumes) return;
+
for (int i = 0; i < STREAM_TYPES.length; i++) {
// Skip the phone specific ones and the active one
final int streamType = STREAM_TYPES[i];
if (streamType == AudioManager.STREAM_RING
|| streamType == AudioManager.STREAM_VOICE_CALL
|| streamType == AudioManager.STREAM_BLUETOOTH_SCO
- || streamType == activeStreamType) {
+ || streamType == mActiveStreamType) {
continue;
}
StreamControl sc = mStreamControls.get(streamType);
@@ -392,31 +394,23 @@
case AudioManager.STREAM_RING: {
// setRingerIcon();
-// message = RINGTONE_VOLUME_TEXT;
Uri ringuri = RingtoneManager.getActualDefaultRingtoneUri(
mContext, RingtoneManager.TYPE_RINGTONE);
if (ringuri == null) {
-// additionalMessage =
-// com.android.internal.R.string.volume_music_hint_silent_ringtone_selected;
mRingIsSilent = true;
}
break;
}
case AudioManager.STREAM_MUSIC: {
-// message = MUSIC_VOLUME_TEXT;
// Special case for when Bluetooth is active for music
if ((mAudioManager.getDevicesForStream(AudioManager.STREAM_MUSIC) &
(AudioManager.DEVICE_OUT_BLUETOOTH_A2DP |
AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) != 0) {
-// additionalMessage =
-// com.android.internal.R.string.volume_music_hint_playing_through_bluetooth;
-// setLargeIcon(com.android.internal.R.drawable.ic_volume_bluetooth_ad2p);
setMusicIcon(R.drawable.ic_audio_bt, R.drawable.ic_audio_bt_mute);
} else {
setMusicIcon(R.drawable.ic_audio_vol, R.drawable.ic_audio_vol_mute);
-// setSmallIcon(index);
}
break;
}
@@ -429,25 +423,17 @@
*/
index++;
max++;
-// message = INCALL_VOLUME_TEXT;
-// setSmallIcon(index);
break;
}
case AudioManager.STREAM_ALARM: {
-// message = ALARM_VOLUME_TEXT;
-// setSmallIcon(index);
break;
}
case AudioManager.STREAM_NOTIFICATION: {
-// message = NOTIFICATION_VOLUME_TEXT;
-// setSmallIcon(index);
Uri ringuri = RingtoneManager.getActualDefaultRingtoneUri(
mContext, RingtoneManager.TYPE_NOTIFICATION);
if (ringuri == null) {
-// additionalMessage =
-// com.android.internal.R.string.volume_music_hint_silent_ringtone_selected;
mRingIsSilent = true;
}
break;
@@ -461,29 +447,10 @@
*/
index++;
max++;
-// message = BLUETOOTH_INCALL_VOLUME_TEXT;
-// setLargeIcon(com.android.internal.R.drawable.ic_volume_bluetooth_in_call);
break;
}
}
-// String messageString = Resources.getSystem().getString(message);
-// if (!mMessage.getText().equals(messageString)) {
-// mMessage.setText(messageString);
-// }
-//
-// if (additionalMessage == 0) {
-// mAdditionalMessage.setVisibility(View.GONE);
-// } else {
-// mAdditionalMessage.setVisibility(View.VISIBLE);
-// mAdditionalMessage.setText(Resources.getSystem().getString(additionalMessage));
-// }
-
-// if (max != mLevel.getMax()) {
-// mLevel.setMax(max);
-// }
-// mLevel.setProgress(index);
-
StreamControl sc = mStreamControls.get(streamType);
if (sc != null) {
sc.seekbarView.setProgress(index);
@@ -493,7 +460,9 @@
mAudioManager.forceVolumeControlStream(streamType);
mDialog.setContentView(mView);
// Showing dialog - use collapsed state
- collapse();
+ if (mShowCombinedVolumes) {
+ collapse();
+ }
mDialog.show();
}
@@ -566,31 +535,6 @@
}
// /**
-// * Makes the small icon visible, and hides the large icon.
-// *
-// * @param index The volume index, where 0 means muted.
-// */
-// private void setSmallIcon(int index) {
-// mLargeStreamIcon.setVisibility(View.GONE);
-// mSmallStreamIcon.setVisibility(View.VISIBLE);
-//
-// mSmallStreamIcon.setImageResource(index == 0
-// ? com.android.internal.R.drawable.ic_volume_off_small
-// : com.android.internal.R.drawable.ic_volume_small);
-// }
-//
-// /**
-// * Makes the large image view visible with the given icon.
-// *
-// * @param resId The icon to display.
-// */
-// private void setLargeIcon(int resId) {
-// mSmallStreamIcon.setVisibility(View.GONE);
-// mLargeStreamIcon.setVisibility(View.VISIBLE);
-// mLargeStreamIcon.setImageResource(resId);
-// }
-//
-// /**
// * Makes the ringer icon visible with an icon that is chosen
// * based on the current ringer mode.
// */
@@ -627,11 +571,6 @@
}
protected void onFreeResources() {
- // We'll keep the views, just ditch the cached drawable and hence
- // bitmaps
-// mSmallStreamIcon.setImageDrawable(null);
-// mLargeStreamIcon.setImageDrawable(null);
-
synchronized (this) {
for (int i = mToneGenerators.length - 1; i >= 0; i--) {
if (mToneGenerators[i] != null) {
@@ -718,7 +657,7 @@
mAudioManager.setRingerMode(mAudioManager.isSilentMode()
? AudioManager.RINGER_MODE_NORMAL : AudioManager.RINGER_MODE_SILENT);
// Expand the dialog if it hasn't been expanded yet.
- if (!isExpanded()) expand();
+ if (mShowCombinedVolumes && !isExpanded()) expand();
}
resetTimeout();
}
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index e07085c..6ac679c 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1213,5 +1213,10 @@
* @see android.app.Activity#getVolumeControlStream()
*/
public abstract int getVolumeControlStream();
-
+
+ /**
+ * Set extra options that will influence the UI for this window.
+ * @param uiOptions Flags specifying extra options for this window.
+ */
+ public void setUiOptions(int uiOptions) { }
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index d1ad113..ff378a6 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -394,6 +394,13 @@
public static final int TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19;
/**
+ * Window type: The volume level overlay/dialog shown when the user
+ * changes the system volume.
+ * @hide
+ */
+ public static final int TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW+20;
+
+ /**
* End of types of system windows.
*/
public static final int LAST_SYSTEM_WINDOW = 2999;
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 9be2a67..c93b564 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -784,7 +784,7 @@
builder.append("\n");
}
} else {
- builder.append("; recordCount: ").append(getAddedCount());
+ builder.append("; recordCount: ").append(getRecordCount());
}
return builder.toString();
}
diff --git a/core/java/android/service/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java
similarity index 96%
rename from core/java/android/service/textservice/SpellCheckerSession.java
rename to core/java/android/view/textservice/SpellCheckerSession.java
index 0dff3a6..b940b80 100644
--- a/core/java/android/service/textservice/SpellCheckerSession.java
+++ b/core/java/android/view/textservice/SpellCheckerSession.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.service.textservice;
+package android.view.textservice;
import com.android.internal.textservice.ISpellCheckerSession;
import com.android.internal.textservice.ISpellCheckerSessionListener;
@@ -38,6 +38,12 @@
public class SpellCheckerSession {
private static final String TAG = SpellCheckerSession.class.getSimpleName();
private static final boolean DBG = false;
+ /**
+ * Name under which a SpellChecker service component publishes information about itself.
+ * This meta-data must reference an XML resource.
+ **/
+ public static final String SERVICE_META_DATA = "android.view.textservice.scs";
+
private static final int MSG_ON_GET_SUGGESTION_MULTIPLE = 1;
@@ -227,7 +233,7 @@
Log.w(TAG, "Cancel spell checker tasks.");
}
try {
- mISpellCheckerSession.cancel();
+ mISpellCheckerSession.onCancel();
} catch (RemoteException e) {
Log.e(TAG, "Failed to cancel " + e);
}
@@ -241,7 +247,7 @@
Log.w(TAG, "Get suggestions from the spell checker.");
}
try {
- mISpellCheckerSession.getSuggestionsMultiple(
+ mISpellCheckerSession.onGetSuggestionsMultiple(
scp.mTextInfos, scp.mSuggestionsLimit, scp.mSequentialWords);
} catch (RemoteException e) {
Log.e(TAG, "Failed to get suggestions " + e);
diff --git a/core/java/android/view/textservice/SuggestionsInfo.java b/core/java/android/view/textservice/SuggestionsInfo.java
index 3332f1e..ed0f89d 100644
--- a/core/java/android/view/textservice/SuggestionsInfo.java
+++ b/core/java/android/view/textservice/SuggestionsInfo.java
@@ -34,9 +34,9 @@
/**
* Flag of the attributes of the suggestions that can be obtained by
* {@link #getSuggestionsAttributes}: this tells that the text service thinks the requested
- * word looks a typo.
+ * word looks like a typo.
*/
- public static final int RESULT_ATTR_LOOKS_TYPO = 0x0002;
+ public static final int RESULT_ATTR_LOOKS_LIKE_TYPO = 0x0002;
private final int mSuggestionsAttributes;
private final String[] mSuggestions;
private final boolean mSuggestionsAvailable;
diff --git a/core/java/android/view/textservice/TextServicesManager.java b/core/java/android/view/textservice/TextServicesManager.java
index ae253cf..d60ce4f 100644
--- a/core/java/android/view/textservice/TextServicesManager.java
+++ b/core/java/android/view/textservice/TextServicesManager.java
@@ -19,12 +19,12 @@
import com.android.internal.textservice.ITextServicesManager;
import android.content.Context;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.service.textservice.SpellCheckerSession;
-import android.service.textservice.SpellCheckerSession.SpellCheckerSessionListener;
import android.util.Log;
+import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;
import java.util.Locale;
@@ -74,27 +74,27 @@
*/
// TODO: Add a method to get enabled spell checkers.
// TODO: Handle referToSpellCheckerLanguageSettings
- public SpellCheckerSession newSpellCheckerSession(Locale locale,
+ public SpellCheckerSession newSpellCheckerSession(Bundle bundle, Locale locale,
SpellCheckerSessionListener listener, boolean referToSpellCheckerLanguageSettings) {
if (listener == null) {
throw new NullPointerException();
}
// TODO: set a proper locale instead of the dummy locale
final String localeString = locale == null ? "en" : locale.toString();
- final SpellCheckerInfo info;
+ final SpellCheckerInfo sci;
try {
- info = sService.getCurrentSpellChecker(localeString);
+ sci = sService.getCurrentSpellChecker(localeString);
} catch (RemoteException e) {
return null;
}
- if (info == null) {
+ if (sci == null) {
return null;
}
- final SpellCheckerSession session = new SpellCheckerSession(info, sService, listener);
+ final SpellCheckerSession session = new SpellCheckerSession(sci, sService, listener);
try {
- sService.getSpellCheckerService(info, localeString,
+ sService.getSpellCheckerService(sci.getId(), localeString,
session.getTextServicesSessionListener(),
- session.getSpellCheckerSessionListener());
+ session.getSpellCheckerSessionListener(), bundle);
} catch (RemoteException e) {
return null;
}
@@ -128,4 +128,18 @@
return null;
}
}
+
+ /**
+ * @hide
+ */
+ public void setCurrentSpellChecker(SpellCheckerInfo sci) {
+ try {
+ if (sci == null) {
+ throw new NullPointerException("SpellCheckerInfo is null");
+ }
+ sService.setCurrentSpellChecker(sci.getId());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error in setCurrentSpellChecker: " + e);
+ }
+ }
}
diff --git a/core/java/android/webkit/DeviceMotionService.java b/core/java/android/webkit/DeviceMotionService.java
index 7d7a0f0..b4d5759 100755
--- a/core/java/android/webkit/DeviceMotionService.java
+++ b/core/java/android/webkit/DeviceMotionService.java
@@ -99,6 +99,7 @@
mUpdateRunnable = new Runnable() {
@Override
public void run() {
+ assert mIsRunning;
mManager.onMotionChange(new Double(mLastAcceleration[0]),
new Double(mLastAcceleration[1]), new Double(mLastAcceleration[2]),
INTERVAL_MILLIS);
@@ -157,6 +158,11 @@
assert WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName());
assert(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER);
+ // We may get callbacks after the call to getSensorManager().unregisterListener() returns.
+ if (!mIsRunning) {
+ return;
+ }
+
boolean firstData = mLastAcceleration == null;
mLastAcceleration = event.values;
if (firstData) {
diff --git a/core/java/android/webkit/DeviceOrientationService.java b/core/java/android/webkit/DeviceOrientationService.java
index f3c0576..47c8ab7 100755
--- a/core/java/android/webkit/DeviceOrientationService.java
+++ b/core/java/android/webkit/DeviceOrientationService.java
@@ -188,6 +188,7 @@
assert(event.values.length == 3);
assert WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName());
+ // We may get callbacks after the call to getSensorManager().unregisterListener() returns.
if (!mIsRunning) {
return;
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index f4fd551..7620a63 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -8405,9 +8405,9 @@
}
}
- // Called by JNI to invalidate the View, given rectangle coordinates in
- // content space
- private void pageSwapCallback() {
+ /** @hide Called by JNI when pages are swapped (only occurs with hardware
+ * acceleration) */
+ protected void pageSwapCallback() {
if (inEditingMode()) {
didUpdateWebTextViewDimensions(ANYWHERE);
}
@@ -8426,11 +8426,11 @@
WebViewCore.ViewState viewState = draw.mViewState;
boolean isPictureAfterFirstLayout = viewState != null;
- // Request a callback on pageSwap (to reposition the webtextview)
- boolean registerPageSwapCallback =
- !mZoomManager.isFixedLengthAnimationInProgress() && inEditingMode();
-
if (updateBaseLayer) {
+ // Request a callback on pageSwap (to reposition the webtextview)
+ boolean registerPageSwapCallback =
+ !mZoomManager.isFixedLengthAnimationInProgress() && inEditingMode();
+
setBaseLayer(draw.mBaseLayer, draw.mInvalRegion,
getSettings().getShowVisualIndicator(),
isPictureAfterFirstLayout, registerPageSwapCallback);
@@ -9084,6 +9084,16 @@
}
}
+ /** @hide send content invalidate */
+ protected void contentInvalidateAll() {
+ mWebViewCore.sendMessage(EventHub.CONTENT_INVALIDATE_ALL);
+ }
+
+ /** @hide call pageSwapCallback upon next page swap */
+ protected void registerPageSwapCallback() {
+ nativeRegisterPageSwapCallback();
+ }
+
/**
* Begin collecting per-tile profiling data
*
@@ -9245,6 +9255,7 @@
private native void nativeStopGL();
private native Rect nativeSubtractLayers(Rect content);
private native int nativeTextGeneration();
+ private native void nativeRegisterPageSwapCallback();
private native void nativeTileProfilingStart();
private native float nativeTileProfilingStop();
private native void nativeTileProfilingClear();
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 8d8023b..400cdbd 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -999,6 +999,7 @@
static final int DUMP_V8COUNTERS = 173;
static final int SET_JS_FLAGS = 174;
+ static final int CONTENT_INVALIDATE_ALL = 175;
// Geolocation
static final int GEOLOCATION_PERMISSIONS_PROVIDE = 180;
@@ -1503,6 +1504,10 @@
nativeSetJsFlags((String)msg.obj);
break;
+ case CONTENT_INVALIDATE_ALL:
+ nativeContentInvalidateAll();
+ break;
+
case SAVE_WEBARCHIVE:
WebView.SaveWebArchiveMessage saveMessage =
(WebView.SaveWebArchiveMessage)msg.obj;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index cadf2ab..9737a5a9 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -628,6 +628,9 @@
private int mGlowPaddingLeft;
private int mGlowPaddingRight;
+ private int mLastAccessibilityScrollEventFromIndex;
+ private int mLastAccessibilityScrollEventToIndex;
+
/**
* Interface definition for a callback to be invoked when the list or grid
* has been scrolled.
@@ -1265,6 +1268,24 @@
}
@Override
+ public void sendAccessibilityEvent(int eventType) {
+ // Since this class calls onScrollChanged even if the mFirstPosition and the
+ // child count have not changed we will avoid sending duplicate accessibility
+ // events.
+ if (eventType == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
+ final int lastPosition = mFirstPosition + getChildCount();
+ if (mLastAccessibilityScrollEventFromIndex == mFirstPosition
+ && mLastAccessibilityScrollEventToIndex == lastPosition) {
+ return;
+ } else {
+ mLastAccessibilityScrollEventFromIndex = mFirstPosition;
+ mLastAccessibilityScrollEventToIndex = lastPosition;
+ }
+ }
+ super.sendAccessibilityEvent(eventType);
+ }
+
+ @Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
event.setScrollable(true);
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 00c75a9..9f5737e 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -277,6 +277,7 @@
* called, false otherwise is returned.
*/
public boolean performItemClick(View view, int position, long id) {
+ view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
if (mOnItemClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
mOnItemClickListener.onItemClick(this, view, position, id);
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 00ebe0d..7ad5d6c 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -116,6 +116,8 @@
private int mOverlayPosition;
+ private boolean mMatchDragPosition;
+
private static final int FADE_TIMEOUT = 1500;
private final Rect mTmpRect = new Rect();
@@ -262,6 +264,9 @@
ta.recycle();
+ mMatchDragPosition = context.getApplicationInfo().targetSdkVersion >=
+ android.os.Build.VERSION_CODES.HONEYCOMB;
+
setScrollbarPosition(mList.getVerticalScrollbarPosition());
}
@@ -417,7 +422,7 @@
}
return;
}
- if (totalItemCount - visibleItemCount > 0 && mState != STATE_DRAGGING ) {
+ if (totalItemCount - visibleItemCount > 0 && mState != STATE_DRAGGING) {
mThumbY = getThumbPositionForListPosition(firstVisibleItem, visibleItemCount,
totalItemCount);
if (mChangedBounds) {
@@ -595,7 +600,7 @@
if (mSectionIndexer == null) {
getSectionsFromIndexer();
}
- if (mSectionIndexer == null) {
+ if (mSectionIndexer == null || !mMatchDragPosition) {
return ((mList.getHeight() - mThumbH) * firstVisibleItem)
/ (totalItemCount - visibleItemCount);
}
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index f999960..390002b 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -32,12 +32,13 @@
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static android.view.Gravity.*;
+import static android.view.View.MeasureSpec.EXACTLY;
+import static android.view.View.MeasureSpec.makeMeasureSpec;
import static java.lang.Math.max;
import static java.lang.Math.min;
@@ -92,8 +93,21 @@
*
* <h4>Excess Space Distribution</h4>
*
- * A child's ability to stretch is controlled using the flexibility
- * properties of its row and column groups.
+ * A child's ability to stretch is inferred from the alignment properties of
+ * its row and column groups (which are typically set by setting the
+ * {@link LayoutParams#setGravity(int) gravity} property of the child's layout parameters).
+ * If alignment was defined along a given axis then the component
+ * is taken as flexible in along that axis. If no alignment was set,
+ * the component is instead assumed to be inflexible. Multiple components in
+ * the same row or column group are considered to act in <em>parallel</em>. Such a
+ * group is flexible only if <em>all</em> of the components
+ * within it are flexible. Row and column groups that sit either side of a common boundary
+ * are instead considered to act in <em>series</em>. The composite group made of these two
+ * elements is flexible if <em>one</em> of its elements is flexible.
+ * <p>
+ * To make a column stretch, make sure all of the components inside it define a
+ * gravity. To prevent a column from stretching, ensure that one of the components
+ * in the column does not define a gravity.
* <p>
* <p>
* See {@link GridLayout.LayoutParams} for a full description of the
@@ -175,7 +189,7 @@
private static final int DEFAULT_ORIENTATION = HORIZONTAL;
private static final int DEFAULT_COUNT = UNDEFINED;
private static final boolean DEFAULT_USE_DEFAULT_MARGINS = false;
- private static final boolean DEFAULT_ORDER_PRESERVED = false;
+ private static final boolean DEFAULT_ORDER_PRESERVED = true;
private static final int DEFAULT_ALIGNMENT_MODE = ALIGN_MARGINS;
private static final int DEFAULT_CONTAINER_MARGIN = 0;
private static final int MAX_SIZE = 100000;
@@ -198,8 +212,6 @@
private int mOrientation = DEFAULT_ORIENTATION;
private boolean mUseDefaultMargins = DEFAULT_USE_DEFAULT_MARGINS;
private int mAlignmentMode = DEFAULT_ALIGNMENT_MODE;
- private Alignment mColumnAlignment = LEFT;
- private Alignment mRowAlignment = BASELINE;
private int mDefaultGap;
// Constructors
@@ -238,6 +250,7 @@
* {@inheritDoc}
*/
public GridLayout(Context context) {
+ //noinspection NullableProblems
this(context, null);
}
@@ -382,10 +395,6 @@
*/
public void setUseDefaultMargins(boolean useDefaultMargins) {
mUseDefaultMargins = useDefaultMargins;
- if (useDefaultMargins) {
- int padding = mDefaultGap;
- setPadding(padding, padding, padding, padding);
- }
requestLayout();
}
@@ -440,22 +449,13 @@
}
/**
- * When this property is {@code false}, the default state, GridLayout
- * is at liberty to choose an order that better suits the heights of its children.
- <p>
* When this property is {@code true}, GridLayout is forced to place the row boundaries
* so that their associated grid indices are in ascending order in the view.
* <p>
- * GridLayout implements this specification by creating ordering constraints between
- * the variables that represent the locations of the row boundaries.
- *
- * When this property is {@code true}, constraints are added for each pair of consecutive
- * indices: i.e. between row boundaries: {@code [0..1], [1..2], [2..3],...} etc.
- *
- * When the property is {@code false}, the ordering constraints are placed
- * only between boundaries that separate opposing edges of the layout's children.
+ * When this property is {@code false} GridLayout is at liberty to place the vertical row
+ * boundaries in whatever order best fits the given constraints.
* <p>
- * The default value of this property is {@code false}.
+ * The default value of this property is {@code true}.
* @param rowOrderPreserved {@code true} to force GridLayout to respect the order
* of row boundaries
@@ -485,22 +485,13 @@
}
/**
- * When this property is {@code false}, the default state, GridLayout
- * is at liberty to choose an order that better suits the widths of its children.
- <p>
* When this property is {@code true}, GridLayout is forced to place the column boundaries
* so that their associated grid indices are in ascending order in the view.
* <p>
- * GridLayout implements this specification by creating ordering constraints between
- * the variables that represent the locations of the column boundaries.
- *
- * When this property is {@code true}, constraints are added for each pair of consecutive
- * indices: i.e. between column boundaries: {@code [0..1], [1..2], [2..3],...} etc.
- *
- * When the property is {@code false}, the ordering constraints are placed
- * only between boundaries that separate opposing edges of the layout's children.
+ * When this property is {@code false} GridLayout is at liberty to place the horizontal column
+ * boundaries in whatever order best fits the given constraints.
* <p>
- * The default value of this property is {@code false}.
+ * The default value of this property is {@code true}.
*
* @param columnOrderPreserved use {@code true} to force GridLayout to respect the order
* of column boundaries.
@@ -525,14 +516,7 @@
return result;
}
- private static int sum(int[] a) {
- int result = 0;
- for (int i = 0, N = a.length; i < N; i++) {
- result += a[i];
- }
- return result;
- }
-
+ @SuppressWarnings("unchecked")
private static <T> T[] append(T[] a, T[] b) {
T[] result = (T[]) Array.newInstance(a.getClass().getComponentType(), a.length + b.length);
System.arraycopy(a, 0, result, 0, a.length);
@@ -558,7 +542,11 @@
}
}
+ /** @noinspection UnusedParameters*/
private int getDefaultMargin(View c, boolean horizontal, boolean leading) {
+ if (c.getClass() == Space.class) {
+ return 0;
+ }
return mDefaultGap / 2;
}
@@ -578,7 +566,7 @@
return getDefaultMargin(c, isAtEdge, horizontal, leading);
}
- private int getMargin(View view, boolean horizontal, boolean leading) {
+ private int getMargin1(View view, boolean horizontal, boolean leading) {
LayoutParams lp = getLayoutParams(view);
int margin = horizontal ?
(leading ? lp.leftMargin : lp.rightMargin) :
@@ -586,6 +574,19 @@
return margin == UNDEFINED ? getDefaultMarginValue(view, lp, horizontal, leading) : margin;
}
+ private int getMargin(View view, boolean horizontal, boolean leading) {
+ if (mAlignmentMode == ALIGN_MARGINS) {
+ return getMargin1(view, horizontal, leading);
+ } else {
+ Axis axis = horizontal ? mHorizontalAxis : mVerticalAxis;
+ int[] margins = leading ? axis.getLeadingMargins() : axis.getTrailingMargins();
+ LayoutParams lp = getLayoutParams(view);
+ Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
+ int index = leading ? spec.span.min : spec.span.max;
+ return margins[index];
+ }
+ }
+
private int getTotalMargin(View child, boolean horizontal) {
return getMargin(child, horizontal, true) + getMargin(child, horizontal, false);
}
@@ -594,72 +595,92 @@
return (value != UNDEFINED) ? value : defaultValue;
}
+ private static boolean fits(int[] a, int value, int start, int end) {
+ if (end > a.length) {
+ return false;
+ }
+ for (int i = start; i < end; i++) {
+ if (a[i] > value) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static void procrusteanFill(int[] a, int start, int end, int value) {
+ int length = a.length;
+ Arrays.fill(a, Math.min(start, length), Math.min(end, length), value);
+ }
+
+ private static void setCellGroup(LayoutParams lp, int row, int rowSpan, int col, int colSpan) {
+ lp.setRowSpecSpan(new Interval(row, row + rowSpan));
+ lp.setColumnSpecSpan(new Interval(col, col + colSpan));
+ }
+
+ // Logic to avert infinite loops by ensuring that the cells can be placed somewhere.
+ private static int clip(Interval minorRange, boolean minorWasDefined, int count) {
+ int size = minorRange.size();
+ if (count == 0) {
+ return size;
+ }
+ int min = minorWasDefined ? min(minorRange.min, count) : 0;
+ return min(size, count - min);
+ }
+
// install default indices for cells that don't define them
private void validateLayoutParams() {
- new Object() {
- public int maxSize = 0;
+ final boolean horizontal = (mOrientation == HORIZONTAL);
+ final int axisCount = horizontal ? mHorizontalAxis.count : mVerticalAxis.count;
+ final int count = valueIfDefined(axisCount, 0);
- private int valueIfDefined2(int value, int defaultValue) {
- if (value != UNDEFINED) {
- maxSize = 0;
- return value;
- } else {
- return defaultValue;
- }
+ int major = 0;
+ int minor = 0;
+ int[] maxSizes = new int[count];
+
+ for (int i = 0, N = getChildCount(); i < N; i++) {
+ LayoutParams lp = getLayoutParams1(getChildAt(i));
+
+ final Interval majorRange = (horizontal ? lp.rowSpec : lp.columnSpec).span;
+ final boolean majorWasDefined = (majorRange.min != UNDEFINED);
+ final int majorSpan = majorRange.size();
+ if (majorWasDefined) {
+ major = majorRange.min;
}
- {
- final boolean horizontal = (mOrientation == HORIZONTAL);
- final int axis = horizontal ? mHorizontalAxis.count : mVerticalAxis.count;
- final int count = valueIfDefined(axis, Integer.MAX_VALUE);
+ final Interval minorRange = (horizontal ? lp.columnSpec : lp.rowSpec).span;
+ final boolean minorWasDefined = (minorRange.min != UNDEFINED);
+ final int minorSpan = clip(minorRange, minorWasDefined, count);
+ if (minorWasDefined) {
+ minor = minorRange.min;
+ }
- int row = 0;
- int col = 0;
- for (int i = 0, N = getChildCount(); i < N; i++) {
- View c = getChildAt(i);
- LayoutParams lp = getLayoutParams1(c);
-
- final Spec colSpec = lp.columnSpec;
- final Interval cols = colSpec.span;
- final int colSpan = cols.size();
-
- final Spec rowSpec = lp.rowSpec;
- final Interval rows = rowSpec.span;
- final int rowSpan = rows.size();
-
- if (horizontal) {
- row = valueIfDefined2(rows.min, row);
-
- int newCol = valueIfDefined(cols.min, (col + colSpan > count) ? 0 : col);
- if (newCol < col) {
- row += maxSize;
- maxSize = 0;
+ if (count != 0) {
+ // Find suitable row/col values when at least one is undefined.
+ if (!majorWasDefined || !minorWasDefined) {
+ while (!fits(maxSizes, major, minor, minor + minorSpan)) {
+ if (minorWasDefined) {
+ major++;
+ } else {
+ if (minor + minorSpan <= count) {
+ minor++;
+ } else {
+ minor = 0;
+ major++;
+ }
}
- col = newCol;
- maxSize = max(maxSize, rowSpan);
- } else {
- col = valueIfDefined2(cols.min, col);
-
- int newRow = valueIfDefined(rows.min, (row + rowSpan > count) ? 0 : row);
- if (newRow < row) {
- col += maxSize;
- maxSize = 0;
- }
- row = newRow;
- maxSize = max(maxSize, colSpan);
- }
-
- lp.setColumnSpecSpan(new Interval(col, col + colSpan));
- lp.setRowSpecSpan(new Interval(row, row + rowSpan));
-
- if (horizontal) {
- col = col + colSpan;
- } else {
- row = row + rowSpan;
}
}
+ procrusteanFill(maxSizes, minor, minor + minorSpan, major + majorSpan);
}
- };
+
+ if (horizontal) {
+ setCellGroup(lp, major, majorSpan, minor, minorSpan);
+ } else {
+ setCellGroup(lp, minor, minorSpan, major, majorSpan);
+ }
+
+ minor = minor + minorSpan;
+ }
invalidateStructure();
}
@@ -667,7 +688,7 @@
mLayoutParamsValid = false;
mHorizontalAxis.invalidateStructure();
mVerticalAxis.invalidateStructure();
- // This can end up being done twice. But better that than not at all.
+ // This can end up being done twice. Better twice than not at all.
invalidateValues();
}
@@ -715,13 +736,8 @@
graphics.drawLine(dx + x1, dy + y1, dx + x2, dy + y2, paint);
}
- private void drawRectangle(Canvas graphics, int x1, int y1, int x2, int y2, Paint paint) {
- x2 = x2 - 1;
- y2 = y2 - 1;
- graphics.drawLine(x1, y1, x1, y2, paint);
- graphics.drawLine(x1, y1, x2, y1, paint);
- graphics.drawLine(x1, y2, x2, y2, paint);
- graphics.drawLine(x2, y1, x2, y2, paint);
+ private static void drawRect(Canvas canvas, int x1, int y1, int x2, int y2, Paint paint) {
+ canvas.drawRect(x1, y1, x2 - 1, y2 - 1, paint);
}
@Override
@@ -733,6 +749,7 @@
int width = getWidth() - getPaddingLeft() - getPaddingRight();
Paint paint = new Paint();
+ paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.argb(50, 255, 255, 255));
int[] xs = mHorizontalAxis.locations;
@@ -755,22 +772,18 @@
paint.setColor(Color.BLUE);
for (int i = 0; i < getChildCount(); i++) {
View c = getChildAt(i);
- drawRectangle(canvas,
- c.getLeft(),
- c.getTop(),
- c.getRight(),
- c.getBottom(), paint);
+ drawRect(canvas, c.getLeft(), c.getTop(), c.getRight(), c.getBottom(), paint);
}
// Draw margins
paint.setColor(Color.MAGENTA);
for (int i = 0; i < getChildCount(); i++) {
View c = getChildAt(i);
- drawRectangle(canvas,
- c.getLeft() - getMargin(c, true, true),
- c.getTop() - getMargin(c, false, true),
- c.getRight() + getMargin(c, true, false),
- c.getBottom() + getMargin(c, false, false), paint);
+ drawRect(canvas,
+ c.getLeft() - getMargin1(c, true, true),
+ c.getTop() - getMargin1(c, false, true),
+ c.getRight() + getMargin1(c, true, false),
+ c.getBottom() + getMargin1(c, false, false), paint);
}
}
}
@@ -857,11 +870,7 @@
if (isGone(c)) {
return 0;
}
- int result = getMeasurement(c, horizontal);
- if (mAlignmentMode == ALIGN_MARGINS) {
- return result + getTotalMargin(c, horizontal);
- }
- return result;
+ return getMeasurement(c, horizontal) + getTotalMargin(c, horizontal);
}
@Override
@@ -872,7 +881,7 @@
private Alignment getAlignment(Alignment alignment, boolean horizontal) {
return (alignment != UNDEFINED_ALIGNMENT) ? alignment :
- (horizontal ? mColumnAlignment : mRowAlignment);
+ (horizontal ? LEFT : BASELINE);
}
// Layout container
@@ -902,6 +911,9 @@
mHorizontalAxis.layout(targetWidth - paddingLeft - paddingRight);
mVerticalAxis.layout(targetHeight - paddingTop - paddingBottom);
+ int[] hLocations = mHorizontalAxis.getLocations();
+ int[] vLocations = mVerticalAxis.getLocations();
+
for (int i = 0, N = getChildCount(); i < N; i++) {
View c = getChildAt(i);
if (isGone(c)) continue;
@@ -912,11 +924,11 @@
Interval colSpan = columnSpec.span;
Interval rowSpan = rowSpec.span;
- int x1 = mHorizontalAxis.getLocationIncludingMargin(true, colSpan.min);
- int y1 = mVerticalAxis.getLocationIncludingMargin(true, rowSpan.min);
+ int x1 = hLocations[colSpan.min];
+ int y1 = vLocations[rowSpan.min];
- int x2 = mHorizontalAxis.getLocationIncludingMargin(false, colSpan.max);
- int y2 = mVerticalAxis.getLocationIncludingMargin(false, rowSpan.max);
+ int x2 = hLocations[colSpan.max];
+ int y2 = vLocations[rowSpan.max];
int cellWidth = x2 - x1;
int cellHeight = y2 - y1;
@@ -933,36 +945,29 @@
Bounds rowBounds = mVerticalAxis.getGroupBounds().getValue(i);
// Gravity offsets: the location of the alignment group relative to its cell group.
+ //noinspection NullableProblems
int c2ax = protect(hAlign.getAlignmentValue(null, cellWidth - colBounds.size(true)));
+ //noinspection NullableProblems
int c2ay = protect(vAlign.getAlignmentValue(null, cellHeight - rowBounds.size(true)));
- if (mAlignmentMode == ALIGN_MARGINS) {
- int leftMargin = getMargin(c, true, true);
- int topMargin = getMargin(c, false, true);
- int rightMargin = getMargin(c, true, false);
- int bottomMargin = getMargin(c, false, false);
+ int leftMargin = getMargin(c, true, true);
+ int topMargin = getMargin(c, false, true);
+ int rightMargin = getMargin(c, true, false);
+ int bottomMargin = getMargin(c, false, false);
- // Same calculation as getMeasurementIncludingMargin()
- int mWidth = leftMargin + pWidth + rightMargin;
- int mHeight = topMargin + pHeight + bottomMargin;
+ // Same calculation as getMeasurementIncludingMargin()
+ int mWidth = leftMargin + pWidth + rightMargin;
+ int mHeight = topMargin + pHeight + bottomMargin;
- // Alignment offsets: the location of the view relative to its alignment group.
- int a2vx = colBounds.getOffset(c, hAlign, mWidth);
- int a2vy = rowBounds.getOffset(c, vAlign, mHeight);
+ // Alignment offsets: the location of the view relative to its alignment group.
+ int a2vx = colBounds.getOffset(c, hAlign, mWidth);
+ int a2vy = rowBounds.getOffset(c, vAlign, mHeight);
- dx = c2ax + a2vx + leftMargin;
- dy = c2ay + a2vy + topMargin;
+ dx = c2ax + a2vx + leftMargin;
+ dy = c2ay + a2vy + topMargin;
- cellWidth -= leftMargin + rightMargin;
- cellHeight -= topMargin + bottomMargin;
- } else {
- // Alignment offsets: the location of the view relative to its alignment group.
- int a2vx = colBounds.getOffset(c, hAlign, pWidth);
- int a2vy = rowBounds.getOffset(c, vAlign, pHeight);
-
- dx = c2ax + a2vx;
- dy = c2ay + a2vy;
- }
+ cellWidth -= leftMargin + rightMargin;
+ cellHeight -= topMargin + bottomMargin;
int type = PRF;
int width = hAlign.getSizeInCell(c, pWidth, cellWidth, type);
@@ -970,6 +975,9 @@
int cx = paddingLeft + x1 + dx;
int cy = paddingTop + y1 + dy;
+ if (width != c.getMeasuredWidth() || height != c.getMeasuredHeight()) {
+ c.measure(makeMeasureSpec(width, EXACTLY), makeMeasureSpec(height, EXACTLY));
+ }
c.layout(cx, cy, cx + width, cy + height);
}
}
@@ -1237,53 +1245,6 @@
return topologicalSort(arcs.toArray(new Arc[arcs.size()]));
}
- private boolean[] findUsed(Collection<Arc> arcs) {
- boolean[] result = new boolean[getCount()];
- for (Arc arc : arcs) {
- Interval span = arc.span;
- int min = min(span.min, span.max);
- int max = max(span.min, span.max);
- for (int i = min; i < max; i++) {
- result[i] = true;
- }
- }
- return result;
- }
-
- // todo unify with findUsed above. Both routines analyze which rows/columns are empty.
- private Collection<Interval> getSpacers() {
- List<Interval> result = new ArrayList<Interval>();
- int V = getCount() + 1;
- int[] leadingEdgeCount = new int[V];
- int[] trailingEdgeCount = new int[V];
- for (int i = 0, N = getChildCount(); i < N; i++) {
- View c = getChildAt(i);
- if (isGone(c)) continue;
- LayoutParams lp = getLayoutParams(c);
- Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
- Interval span = spec.span;
- leadingEdgeCount[span.min]++;
- trailingEdgeCount[span.max]++;
- }
-
- int lastTrailingEdge = 0;
-
- // treat the parent's edges like peer edges of the opposite type
- trailingEdgeCount[0] = 1;
- leadingEdgeCount[V - 1] = 1;
-
- for (int i = 0; i < V; i++) {
- if (trailingEdgeCount[i] > 0) {
- lastTrailingEdge = i;
- continue; // if this is also a leading edge, don't add a space of length zero
- }
- if (leadingEdgeCount[i] > 0) {
- result.add(new Interval(lastTrailingEdge, i));
- }
- }
- return result;
- }
-
private void addComponentSizes(List<Arc> result, PackedMap<Interval, MutableInt> links) {
for (int i = 0; i < links.keys.length; i++) {
Interval key = links.keys[i];
@@ -1300,28 +1261,11 @@
// Add the maximum values from the components.
addComponentSizes(maxs, getBackwardLinks());
- // Find redundant rows/cols and glue them together with 0-length arcs to link the tree
- boolean[] used = findUsed(mins);
- for (int i = 0; i < getCount(); i++) {
- if (!used[i]) {
- Interval span = new Interval(i, i + 1);
- include(mins, span, new MutableInt(0));
- include(maxs, span.inverse(), new MutableInt(0));
- }
- }
-
// Add ordering constraints to prevent row/col sizes from going negative
if (mOrderPreserved) {
// Add a constraint for every row/col
for (int i = 0; i < getCount(); i++) {
- if (used[i]) {
- include(mins, new Interval(i, i + 1), new MutableInt(0));
- }
- }
- } else {
- // Add a constraint for each row/col that separates opposing component edges
- for (Interval gap : getSpacers()) {
- include(mins, gap, new MutableInt(0));
+ include(mins, new Interval(i, i + 1), new MutableInt(0));
}
}
@@ -1409,10 +1353,9 @@
String axis = horizontal ? "horizontal" : "vertical";
int N = getCount() + 1; // The number of vertices is the number of columns/rows + 1.
- boolean changed = false;
// We take one extra pass over traditional Bellman-Ford (and omit their final step)
for (int i = 0; i < N; i++) {
- changed = false;
+ boolean changed = false;
for (int j = 0, length = arcs.length; j < length; j++) {
changed |= relax(locations, arcs[j]);
}
@@ -1463,7 +1406,7 @@
Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
Interval span = spec.span;
int index = leading ? span.min : span.max;
- margins[index] = max(margins[index], getMargin(c, horizontal, leading));
+ margins[index] = max(margins[index], getMargin1(c, horizontal, leading));
}
}
@@ -1489,34 +1432,8 @@
return trailingMargins;
}
- private void addMargins() {
- int[] leadingMargins = getLeadingMargins();
- int[] trailingMargins = getTrailingMargins();
-
- int delta = 0;
- for (int i = 0, N = getCount(); i < N; i++) {
- int margins = leadingMargins[i] + trailingMargins[i + 1];
- delta += margins;
- locations[i + 1] += delta;
- }
- }
-
- private int getLocationIncludingMargin(boolean leading, int index) {
- int location = locations[index];
- int margin;
- if (mAlignmentMode != ALIGN_MARGINS) {
- margin = (leading ? leadingMargins : trailingMargins)[index];
- } else {
- margin = 0;
- }
- return leading ? (location + margin) : (location - margin);
- }
-
private void computeLocations(int[] a) {
solve1(getArcs(), a);
- if (mAlignmentMode != ALIGN_MARGINS) {
- addMargins();
- }
}
private int[] getLocations() {
@@ -1538,12 +1455,6 @@
}
private void setParentConstraints(int min, int max) {
- if (mAlignmentMode != ALIGN_MARGINS) {
- int margins = sum(getLeadingMargins()) + sum(getTrailingMargins());
- min -= margins;
- max -= margins;
- }
-
parentMin.value = min;
parentMax.value = -max;
locationsValid = false;
@@ -1658,10 +1569,8 @@
*
* @attr ref android.R.styleable#GridLayout_Layout_layout_row
* @attr ref android.R.styleable#GridLayout_Layout_layout_rowSpan
- * @attr ref android.R.styleable#GridLayout_Layout_layout_rowFlexibility
* @attr ref android.R.styleable#GridLayout_Layout_layout_column
* @attr ref android.R.styleable#GridLayout_Layout_layout_columnSpan
- * @attr ref android.R.styleable#GridLayout_Layout_layout_columnFlexibility
* @attr ref android.R.styleable#GridLayout_Layout_layout_gravity
*/
public static class LayoutParams extends MarginLayoutParams {
@@ -1688,13 +1597,9 @@
private static final int COLUMN = R.styleable.GridLayout_Layout_layout_column;
private static final int COLUMN_SPAN = R.styleable.GridLayout_Layout_layout_columnSpan;
- private static final int COLUMN_FLEXIBILITY =
- R.styleable.GridLayout_Layout_layout_columnFlexibility;
private static final int ROW = R.styleable.GridLayout_Layout_layout_row;
private static final int ROW_SPAN = R.styleable.GridLayout_Layout_layout_rowSpan;
- private static final int ROW_FLEXIBILITY =
- R.styleable.GridLayout_Layout_layout_rowFlexibility;
private static final int GRAVITY = R.styleable.GridLayout_Layout_layout_gravity;
@@ -1816,13 +1721,11 @@
int column = a.getInt(COLUMN, DEFAULT_COLUMN);
int colSpan = a.getInt(COLUMN_SPAN, DEFAULT_SPAN_SIZE);
- int hFlexibility = a.getInt(COLUMN_FLEXIBILITY, Spec.UNDEFINED_FLEXIBILITY);
- this.columnSpec = spec(column, colSpan, getAlignment(gravity, true), hFlexibility);
+ this.columnSpec = spec(column, colSpan, getAlignment(gravity, true));
int row = a.getInt(ROW, DEFAULT_ROW);
int rowSpan = a.getInt(ROW_SPAN, DEFAULT_SPAN_SIZE);
- int vFlexibility = a.getInt(ROW_FLEXIBILITY, Spec.UNDEFINED_FLEXIBILITY);
- this.rowSpec = spec(row, rowSpan, getAlignment(gravity, false), vFlexibility);
+ this.rowSpec = spec(row, rowSpan, getAlignment(gravity, false));
} finally {
a.recycle();
}
@@ -1956,10 +1859,6 @@
this.values = compact(values, index);
}
- private K getKey(int i) {
- return keys[index[i]];
- }
-
private V getValue(int i) {
return values[index[i]];
}
@@ -2009,8 +1908,6 @@
of the values for each View.
*/
private static class Bounds {
- private static final Bounds GONE = new Bounds();
-
public int before;
public int after;
public int flexibility; // we're flexible iff all included specs are flexible
@@ -2046,8 +1943,8 @@
protected final void include(View c, Spec spec, GridLayout gridLayout, Axis axis) {
this.flexibility &= spec.getFlexibility();
int size = gridLayout.getMeasurementIncludingMargin(c, axis.horizontal);
- // todo test this works correctly when the returned value is UNDEFINED
Alignment alignment = gridLayout.getAlignment(spec.alignment, axis.horizontal);
+ // todo test this works correctly when the returned value is UNDEFINED
int before = alignment.getAlignmentValue(c, size);
include(before, size - before);
}
@@ -2130,6 +2027,7 @@
if (max != interval.max) {
return false;
}
+ //noinspection RedundantIfStatement
if (min != interval.min) {
return false;
}
@@ -2150,75 +2048,47 @@
}
}
- /**
- * A Spec defines the horizontal or vertical characteristics of a group of
- * cells. Each spec. defines the <em>grid indices</em>, <em>alignment</em> and
- * <em>flexibility</em> along the appropriate axis.
- * <p>
- * The <em>grid indices</em> are the leading and trailing edges of this cell group.
- * See {@link GridLayout} for a description of the conventions used by GridLayout
- * for grid indices.
- * <p>
- * The <em>alignment</em> property specifies how cells should be aligned in this group.
- * For row groups, this specifies the vertical alignment.
- * For column groups, this specifies the horizontal alignment.
- */
+ /**
+ * A Spec defines the horizontal or vertical characteristics of a group of
+ * cells. Each spec. defines the <em>grid indices</em>, <em>alignment</em> and
+ * <em>flexibility</em> along the appropriate axis.
+ * <p>
+ * The <em>grid indices</em> are the leading and trailing edges of this cell group.
+ * See {@link GridLayout} for a description of the conventions used by GridLayout
+ * for grid indices.
+ * <p>
+ * The <em>alignment</em> property specifies how cells should be aligned in this group.
+ * For row groups, this specifies the vertical alignment.
+ * For column groups, this specifies the horizontal alignment.
+ */
public static class Spec {
- private static final int UNDEFINED_FLEXIBILITY = UNDEFINED;
-
final Interval span;
-
final Alignment alignment;
- /**
- * The <em>flexibility</em> property tells GridLayout how to derive minimum and maximum size
- * values for a component. Specifications are made with respect to a child's
- * 'measured size'. A child's measured size is, in turn, controlled by its
- * height and width layout parameters which either specify a size or, in
- * the case of {@link LayoutParams#WRAP_CONTENT WRAP_CONTENT}, defer to
- * the computed size of the component.
- * <p>
- * A cell group is flexible only if <em>all</em> of its components are flexible.
- * <p>
- * By default, flexibility is {@link #INFLEXIBLE} only when alignment/gravity is undefined.
- */
- final int flexibility;
-
- private Spec(Interval span, Alignment alignment, int flexibility) {
+ private Spec(Interval span, Alignment alignment) {
this.span = span;
this.alignment = alignment;
- this.flexibility = flexibility;
- }
-
- private Spec(Interval span, Alignment alignment) {
- this(span, alignment, UNDEFINED_FLEXIBILITY);
}
/* Copying constructor */
private Spec(Spec that) {
- this(that.span, that.alignment, that.flexibility);
+ this(that.span, that.alignment);
}
- Spec(int start, int size, Alignment alignment, int flexibility) {
- this(new Interval(start, start + size), alignment, flexibility);
+ private Spec(int start, int size, Alignment alignment) {
+ this(new Interval(start, start + size), alignment);
}
private Spec copyWriteSpan(Interval span) {
- return new Spec(span, alignment, flexibility);
+ return new Spec(span, alignment);
}
private Spec copyWriteAlignment(Alignment alignment) {
- return new Spec(span, alignment, flexibility);
- }
-
- private static int defaultFlexibility(Alignment alignment) {
- return (alignment == UNDEFINED_ALIGNMENT) ? INFLEXIBLE : CAN_STRETCH;
+ return new Spec(span, alignment);
}
int getFlexibility() {
- return (flexibility != UNDEFINED_FLEXIBILITY) ?
- flexibility :
- defaultFlexibility(alignment);
+ return (alignment == UNDEFINED_ALIGNMENT) ? INFLEXIBLE : CAN_STRETCH;
}
/**
@@ -2245,6 +2115,7 @@
if (!alignment.equals(spec.alignment)) {
return false;
}
+ //noinspection RedundantIfStatement
if (!span.equals(spec.span)) {
return false;
}
@@ -2261,28 +2132,6 @@
}
/**
- * @deprecated Please use {@link #spec(int, int, Alignment)} instead,
- * all spec's that define alignments (gravity) are assumed to be able to stretch.
- *
- * @hide
- */
- @Deprecated
- public static Spec spec(int start, int size, Alignment alignment, int flexibility) {
- return new Spec(start, size, alignment, flexibility);
- }
-
- /**
- * @deprecated Please use {@link #spec(int, Alignment)} instead,
- * all spec's that define alignments (gravity) are assumed to be able to stretch.
- *
- * @hide
- */
- @Deprecated
- public static Spec spec(int start, Alignment alignment, int flexibility) {
- return spec(start, 1, alignment, flexibility);
- }
-
- /**
* Return a Spec, {@code spec}, where:
* <ul>
* <li> {@code spec.span = [start, start + size]} </li>
@@ -2294,7 +2143,7 @@
* @param alignment the alignment
*/
public static Spec spec(int start, int size, Alignment alignment) {
- return spec(start, size, alignment, Spec.UNDEFINED_FLEXIBILITY);
+ return new Spec(start, size, alignment);
}
/**
@@ -2524,15 +2373,5 @@
private static final int INFLEXIBLE = 0;
- /**
- * Indicates that a view's size should be greater than or equal to the size specified by
- * its layout parameters.
- *
- * @deprecated Please use {@link #spec(int, int, Alignment)} instead,
- * all spec's that define alignment (gravity) are assumed to able to stretch.
- *
- * @hide
- */
- @Deprecated
- public static final int CAN_STRETCH = 2;
+ private static final int CAN_STRETCH = 2;
}
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 299e1ff..fc60949 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -83,6 +83,7 @@
// Avoid allocations...
private RectF mTempSrc = new RectF();
private RectF mTempDst = new RectF();
+ private float[] mTempPoints;
private boolean mCropToPadding;
@@ -337,7 +338,6 @@
}
}
-
/**
* Sets a drawable as the content of this ImageView.
*
@@ -347,8 +347,31 @@
if (mDrawable != drawable) {
mResource = 0;
mUri = null;
+ int oldWidth = mDrawableWidth;
+ int oldHeight = mDrawableHeight;
updateDrawable(drawable);
- requestLayout();
+
+ boolean needsLayout;
+ if (mScaleType == ScaleType.CENTER) {
+ needsLayout = mDrawableWidth != oldWidth || mDrawableHeight != oldHeight;
+ } else {
+ if (mTempPoints == null) {
+ mTempPoints = new float[4];
+ }
+ float[] points = mTempPoints;
+ points[0] = oldWidth;
+ points[1] = oldHeight;
+ points[2] = mDrawableWidth;
+ points[3] = mDrawableHeight;
+ if (!mMatrix.isIdentity()) {
+ mMatrix.mapPoints(points);
+ }
+ needsLayout = points[0] != points[2] || points[1] != points[3];
+ }
+
+ if (needsLayout) {
+ requestLayout();
+ }
invalidate();
}
}
@@ -643,6 +666,9 @@
// We are allowed to change the view's height
boolean resizeHeight = false;
+ final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
+ final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
+
if (mDrawable == null) {
// If no drawable, its intrinsic size is 0.
mDrawableWidth = -1;
@@ -657,10 +683,6 @@
// We are supposed to adjust view bounds to match the aspect
// ratio of our drawable. See if that is possible.
if (mAdjustViewBounds) {
-
- int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
- int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
-
resizeWidth = widthSpecMode != MeasureSpec.EXACTLY;
resizeHeight = heightSpecMode != MeasureSpec.EXACTLY;
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index 3a22bfb..8c288d10 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -112,6 +112,7 @@
private boolean mClearingFocus;
private int mMaxWidth;
private boolean mVoiceButtonEnabled;
+ private CharSequence mOldQueryText;
private CharSequence mUserQuery;
private boolean mExpandedInActionView;
@@ -462,6 +463,7 @@
if (mIconifiedByDefault == iconified) return;
mIconifiedByDefault = iconified;
updateViewsVisibility(iconified);
+ updateQueryHint();
}
/**
@@ -970,9 +972,10 @@
updateVoiceButton(!hasText);
updateCloseButton();
updateSubmitArea();
- if (mOnQueryChangeListener != null) {
+ if (mOnQueryChangeListener != null && !TextUtils.equals(newText, mOldQueryText)) {
mOnQueryChangeListener.onQueryTextChange(newText.toString());
}
+ mOldQueryText = newText.toString();
}
private void onSubmitQuery() {
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index c4ba7c8..4b08f2d 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -1406,6 +1406,7 @@
v.setTranslationX(translationX);
drawOutline(mCanvas, bitmap);
+ mCanvas.setBitmap(null);
return bitmap;
}
@@ -1417,6 +1418,7 @@
dest.drawColor(0, PorterDuff.Mode.CLEAR);
dest.setMatrix(mIdentityMatrix);
dest.drawBitmap(mask, xy[0], xy[1], mHolographicPaint);
+ mMaskCanvas.setBitmap(null);
mask.recycle();
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index ab66676..04cf69b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -343,6 +343,9 @@
private Drawable mSelectHandleRight;
private Drawable mSelectHandleCenter;
+ // Global listener that detects changes in the global position of the TextView
+ private PositionListener mPositionListener;
+
private float mLastDownPositionX, mLastDownPositionY;
private Callback mCustomSelectionActionModeCallback;
@@ -394,7 +397,7 @@
*/
boolean onEditorAction(TextView v, int actionId, KeyEvent event);
}
-
+
public TextView(Context context) {
this(context, null);
}
@@ -999,7 +1002,8 @@
setEllipsize(TextUtils.TruncateAt.END);
break;
case 4:
- setHorizontalFadingEdgeEnabled(true);
+ setHorizontalFadingEdgeEnabled(
+ ViewConfiguration.get(context).isFadingMarqueeEnabled());
setEllipsize(TextUtils.TruncateAt.MARQUEE);
break;
}
@@ -2080,7 +2084,7 @@
TextAppearance_textStyle, -1);
setTypefaceByIndex(typefaceIndex, styleIndex);
-
+
if (appearance.getBoolean(com.android.internal.R.styleable.TextAppearance_textAllCaps,
false)) {
setTransformationMethod(new AllCapsTransformationMethod(getContext()));
@@ -3018,7 +3022,7 @@
* To style your strings, attach android.text.style.* objects to a
* {@link android.text.SpannableString SpannableString}, or see the
* <a href="{@docRoot}guide/topics/resources/available-resources.html#stringresources">
- * Available Resource Types</a> documentation for an example of setting
+ * Available Resource Types</a> documentation for an example of setting
* formatted text in the XML resource file.
*
* @attr ref android.R.styleable#TextView_text
@@ -3067,7 +3071,8 @@
if (text instanceof Spanned &&
((Spanned) text).getSpanStart(TextUtils.TruncateAt.MARQUEE) >= 0) {
- setHorizontalFadingEdgeEnabled(true);
+ setHorizontalFadingEdgeEnabled(
+ ViewConfiguration.get(mContext).isFadingMarqueeEnabled());
setEllipsize(TextUtils.TruncateAt.MARQUEE);
}
@@ -8444,6 +8449,17 @@
info.setPassword(isPassword);
}
+ @Override
+ public void sendAccessibilityEvent(int eventType) {
+ // Do not send scroll events since first they are not interesting for
+ // accessibility and second such events a generated too frequently.
+ // For details see the implementation of bringTextIntoView().
+ if (eventType == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
+ return;
+ }
+ super.sendAccessibilityEvent(eventType);
+ }
+
void sendAccessibilityEventTypeViewTextChanged(CharSequence beforeText,
int fromIndex, int removedCount, int addedCount) {
AccessibilityEvent event =
@@ -8755,32 +8771,247 @@
return ((minOffset >= selectionStart) && (maxOffset < selectionEnd));
}
+ private PositionListener getPositionListener() {
+ if (mPositionListener == null) {
+ mPositionListener = new PositionListener();
+ }
+ return mPositionListener;
+ }
+
+ private interface TextViewPositionListener {
+ public void updatePosition(int parentPositionX, int parentPositionY, boolean modified);
+ }
+
+ private class PositionListener implements ViewTreeObserver.OnPreDrawListener {
+ // 3 handles, 2 ActionPopup (suggestionsPopup first hides the others)
+ private final int MAXIMUM_NUMBER_OF_LISTENERS = 5;
+ private TextViewPositionListener[] mPositionListeners =
+ new TextViewPositionListener[MAXIMUM_NUMBER_OF_LISTENERS];
+ private boolean mCanMove[] = new boolean[MAXIMUM_NUMBER_OF_LISTENERS];
+ private boolean mPositionHasChanged = true;
+ // Absolute position of the TextView with respect to its parent window
+ private int mPositionX, mPositionY;
+ private int mNumberOfListeners;
+
+ public void addSubscriber(TextViewPositionListener positionListener, boolean canMove) {
+ if (mNumberOfListeners == 0) {
+ updatePosition();
+ ViewTreeObserver vto = TextView.this.getViewTreeObserver();
+ vto.addOnPreDrawListener(this);
+ }
+
+ int emptySlotIndex = -1;
+ for (int i = 0; i < MAXIMUM_NUMBER_OF_LISTENERS; i++) {
+ TextViewPositionListener listener = mPositionListeners[i];
+ if (listener == positionListener) {
+ return;
+ } else if (emptySlotIndex < 0 && listener == null) {
+ emptySlotIndex = i;
+ }
+ }
+
+ mPositionListeners[emptySlotIndex] = positionListener;
+ mCanMove[emptySlotIndex] = canMove;
+ mNumberOfListeners++;
+ }
+
+ public void removeSubscriber(TextViewPositionListener positionListener) {
+ for (int i = 0; i < MAXIMUM_NUMBER_OF_LISTENERS; i++) {
+ if (mPositionListeners[i] == positionListener) {
+ mPositionListeners[i] = null;
+ mNumberOfListeners--;
+ break;
+ }
+ }
+
+ if (mNumberOfListeners == 0) {
+ ViewTreeObserver vto = TextView.this.getViewTreeObserver();
+ vto.removeOnPreDrawListener(this);
+ }
+ }
+
+ public int getPositionX() {
+ return mPositionX;
+ }
+
+ public int getPositionY() {
+ return mPositionY;
+ }
+
+ @Override
+ public boolean onPreDraw() {
+ updatePosition();
+
+ for (int i = 0; i < MAXIMUM_NUMBER_OF_LISTENERS; i++) {
+ if (mPositionHasChanged || mCanMove[i]) {
+ TextViewPositionListener positionListener = mPositionListeners[i];
+ if (positionListener != null) {
+ positionListener.updatePosition(mPositionX, mPositionY,
+ mPositionHasChanged);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private void updatePosition() {
+ TextView.this.getLocationInWindow(mTempCoords);
+
+ mPositionHasChanged = mTempCoords[0] != mPositionX || mTempCoords[1] != mPositionY;
+
+ mPositionX = mTempCoords[0];
+ mPositionY = mTempCoords[1];
+ }
+
+ public boolean isVisible(int positionX, int positionY) {
+ final TextView textView = TextView.this;
+
+ if (mTempRect == null) mTempRect = new Rect();
+ final Rect clip = mTempRect;
+ clip.left = getCompoundPaddingLeft();
+ clip.top = getExtendedPaddingTop();
+ clip.right = textView.getWidth() - getCompoundPaddingRight();
+ clip.bottom = textView.getHeight() - getExtendedPaddingBottom();
+
+ final ViewParent parent = textView.getParent();
+ if (parent == null || !parent.getChildVisibleRect(textView, clip, null)) {
+ return false;
+ }
+
+ int posX = mPositionX + positionX;
+ int posY = mPositionY + positionY;
+
+ // Offset by 1 to take into account 0.5 and int rounding around getPrimaryHorizontal.
+ return posX >= clip.left - 1 && posX <= clip.right + 1 &&
+ posY >= clip.top && posY <= clip.bottom;
+ }
+
+ public boolean isOffsetVisible(int offset) {
+ final int line = mLayout.getLineForOffset(offset);
+ final int lineBottom = mLayout.getLineBottom(line);
+ final int primaryHorizontal = (int) mLayout.getPrimaryHorizontal(offset);
+ return isVisible(primaryHorizontal, lineBottom);
+ }
+ }
+
+ private abstract class PinnedPopupWindow implements TextViewPositionListener {
+ protected PopupWindow mPopupWindow;
+ protected LinearLayout mContentView;
+ int mPositionX, mPositionY;
+
+ protected abstract void createPopupWindow();
+ protected abstract void initContentView();
+ protected abstract int getTextOffset();
+ protected abstract int getVerticalLocalPosition(int line);
+ protected abstract int clipVertically(int positionY);
+
+ public PinnedPopupWindow() {
+ createPopupWindow();
+
+ mPopupWindow.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
+ mPopupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
+ mPopupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
+
+ mContentView = new LinearLayout(TextView.this.getContext());
+ LayoutParams wrapContent = new LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ mContentView.setLayoutParams(wrapContent);
+
+ initContentView();
+ mPopupWindow.setContentView(mContentView);
+ }
+
+ public void show() {
+ final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
+ mContentView.measure(
+ View.MeasureSpec.makeMeasureSpec(displayMetrics.widthPixels,
+ View.MeasureSpec.AT_MOST),
+ View.MeasureSpec.makeMeasureSpec(displayMetrics.heightPixels,
+ View.MeasureSpec.AT_MOST));
+
+ TextView.this.getPositionListener().addSubscriber(this, false);
+
+ computeLocalPosition();
+
+ final PositionListener positionListener = TextView.this.getPositionListener();
+ updatePosition(positionListener.getPositionX(), positionListener.getPositionY());
+ }
+
+ private void computeLocalPosition() {
+ final int offset = getTextOffset();
+
+ final int width = mContentView.getMeasuredWidth();
+ mPositionX = (int) (mLayout.getPrimaryHorizontal(offset) - width / 2.0f);
+ mPositionX += viewportToContentHorizontalOffset();
+
+ final int line = mLayout.getLineForOffset(offset);
+ mPositionY = getVerticalLocalPosition(line);
+ mPositionY += viewportToContentVerticalOffset();
+ }
+
+ private void updatePosition(int parentPositionX, int parentPositionY) {
+ int positionX = parentPositionX + mPositionX;
+ int positionY = parentPositionY + mPositionY;
+
+ positionY = clipVertically(positionY);
+
+ // Horizontal clipping
+ final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
+ final int width = mContentView.getMeasuredWidth();
+ positionX = Math.min(displayMetrics.widthPixels - width, positionX);
+ positionX = Math.max(0, positionX);
+
+ if (isShowing()) {
+ mPopupWindow.update(positionX, positionY, -1, -1);
+ } else {
+ mPopupWindow.showAtLocation(TextView.this, Gravity.NO_GRAVITY,
+ positionX, positionY);
+ }
+ }
+
+ public void hide() {
+ mPopupWindow.dismiss();
+ TextView.this.getPositionListener().removeSubscriber(this);
+ }
+
+ @Override
+ public void updatePosition(int parentPositionX, int parentPositionY, boolean modified) {
+ if (isShowing() && getPositionListener().isOffsetVisible(getTextOffset())) {
+ updatePosition(parentPositionX, parentPositionY);
+ } else {
+ hide();
+ }
+ }
+
+ public boolean isShowing() {
+ return mPopupWindow.isShowing();
+ }
+ }
+
private static class SuggestionRangeSpan extends UnderlineSpan {
// TODO themable, would be nice to make it a child class of TextAppearanceSpan, but
// there is no way to have underline and TextAppearanceSpan.
}
- private class SuggestionsPopupWindow implements OnClickListener {
+ private class SuggestionsPopupWindow extends PinnedPopupWindow implements OnClickListener {
private static final int MAX_NUMBER_SUGGESTIONS = 5;
private static final int NO_SUGGESTIONS = -1;
- private final PopupWindow mPopupWindow;
- private LinearLayout mSuggestionsContainer;
private WordIterator mSuggestionWordIterator;
private TextAppearanceSpan[] mHighlightSpans = new TextAppearanceSpan[0];
- public SuggestionsPopupWindow() {
+ @Override
+ protected void createPopupWindow() {
mPopupWindow = new PopupWindow(TextView.this.mContext, null,
- com.android.internal.R.attr.textSuggestionsWindowStyle);
- mPopupWindow.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
+ com.android.internal.R.attr.textSuggestionsWindowStyle);
mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
mPopupWindow.setOutsideTouchable(true);
- mPopupWindow.setClippingEnabled(true);
+ mPopupWindow.setClippingEnabled(false);
+ }
- mPopupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
- mPopupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
-
- mSuggestionsContainer = new LinearLayout(TextView.this.mContext);
- mSuggestionsContainer.setOrientation(LinearLayout.VERTICAL);
+ @Override
+ protected void initContentView() {
+ mContentView.setOrientation(LinearLayout.VERTICAL);
LayoutInflater inflater = (LayoutInflater) TextView.this.mContext.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -8793,7 +9024,7 @@
// Inflate the suggestion items once and for all.
for (int i = 0; i < MAX_NUMBER_SUGGESTIONS; i++) {
View childView = inflater.inflate(mTextEditSuggestionItemLayout,
- mSuggestionsContainer, false);
+ mContentView, false);
if (! (childView instanceof TextView)) {
throw new IllegalArgumentException(
@@ -8801,11 +9032,9 @@
}
childView.setTag(new SuggestionInfo());
- mSuggestionsContainer.addView(childView);
+ mContentView.addView(childView);
childView.setOnClickListener(this);
}
-
- mPopupWindow.setContentView(mSuggestionsContainer);
}
private class SuggestionInfo {
@@ -8825,30 +9054,61 @@
SuggestionSpan[] suggestionSpans = spannable.getSpans(pos, pos, SuggestionSpan.class);
// Cache the span length for performance reason.
- final HashMap<SuggestionSpan, Integer> spanLengthMap =
- new HashMap<SuggestionSpan, Integer>();
+ final HashMap<SuggestionSpan, Integer> spansLengths =
+ new HashMap<SuggestionSpan, Integer>();
for (SuggestionSpan suggestionSpan : suggestionSpans) {
int start = spannable.getSpanStart(suggestionSpan);
int end = spannable.getSpanEnd(suggestionSpan);
- spanLengthMap.put(suggestionSpan, end - start);
+ spansLengths.put(suggestionSpan, Integer.valueOf(end - start));
}
// The suggestions are sorted according to the lenght of the text that they cover
// (shorter first)
Arrays.sort(suggestionSpans, new Comparator<SuggestionSpan>() {
public int compare(SuggestionSpan span1, SuggestionSpan span2) {
- return spanLengthMap.get(span1) - spanLengthMap.get(span2);
+ return spansLengths.get(span1).intValue() - spansLengths.get(span2).intValue();
}
});
return suggestionSpans;
}
+ @Override
public void show() {
if (!(mText instanceof Editable)) return;
+ updateSuggestions();
- Spannable spannable = (Spannable) TextView.this.mText;
+ super.show();
+ }
+
+ @Override
+ protected int getTextOffset() {
+ return getSelectionStart();
+ }
+
+ @Override
+ protected int getVerticalLocalPosition(int line) {
+ return mLayout.getLineBottom(line);
+ }
+
+ @Override
+ protected int clipVertically(int positionY) {
+ final int height = mContentView.getMeasuredHeight();
+ final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
+ return Math.min(positionY, displayMetrics.heightPixels - height);
+ }
+
+ @Override
+ public void hide() {
+ super.hide();
+ if ((mText instanceof Editable) && mSuggestionRangeSpan != null) {
+ ((Editable) mText).removeSpan(mSuggestionRangeSpan);
+ }
+ }
+
+ private void updateSuggestions() {
+ Spannable spannable = (Spannable)TextView.this.mText;
SuggestionSpan[] suggestionSpans = getSuggestionSpans();
final int nbSpans = suggestionSpans.length;
@@ -8867,7 +9127,7 @@
String[] suggestions = suggestionSpan.getSuggestions();
int nbSuggestions = suggestions.length;
for (int suggestionIndex = 0; suggestionIndex < nbSuggestions; suggestionIndex++) {
- TextView textView = (TextView) mSuggestionsContainer.getChildAt(
+ TextView textView = (TextView) mContentView.getChildAt(
totalNbSuggestions);
textView.setText(suggestions[suggestionIndex]);
SuggestionInfo suggestionInfo = (SuggestionInfo) textView.getTag();
@@ -8887,7 +9147,7 @@
if (totalNbSuggestions == 0) {
// TODO Replace by final text, use a dedicated layout, add a fade out timer...
- TextView textView = (TextView) mSuggestionsContainer.getChildAt(0);
+ TextView textView = (TextView) mContentView.getChildAt(0);
textView.setText("No suggestions available");
SuggestionInfo suggestionInfo = (SuggestionInfo) textView.getTag();
suggestionInfo.spanStart = NO_SUGGESTIONS;
@@ -8898,26 +9158,17 @@
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
for (int i = 0; i < totalNbSuggestions; i++) {
- final TextView textView = (TextView) mSuggestionsContainer.getChildAt(i);
+ final TextView textView = (TextView) mContentView.getChildAt(i);
highlightTextDifferences(textView, spanUnionStart, spanUnionEnd);
}
}
for (int i = 0; i < totalNbSuggestions; i++) {
- mSuggestionsContainer.getChildAt(i).setVisibility(VISIBLE);
+ mContentView.getChildAt(i).setVisibility(VISIBLE);
}
for (int i = totalNbSuggestions; i < MAX_NUMBER_SUGGESTIONS; i++) {
- mSuggestionsContainer.getChildAt(i).setVisibility(GONE);
+ mContentView.getChildAt(i).setVisibility(GONE);
}
-
- final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
- final int screenWidth = displayMetrics.widthPixels;
- final int screenHeight = displayMetrics.heightPixels;
- mSuggestionsContainer.measure(
- View.MeasureSpec.makeMeasureSpec(screenWidth, View.MeasureSpec.AT_MOST),
- View.MeasureSpec.makeMeasureSpec(screenHeight, View.MeasureSpec.AT_MOST));
-
- positionAtCursor();
}
private long[] getWordLimits(CharSequence text) {
@@ -9069,17 +9320,6 @@
textView.setText(ssb);
}
- public void hide() {
- if ((mText instanceof Editable) && mSuggestionRangeSpan != null) {
- ((Editable) mText).removeSpan(mSuggestionRangeSpan);
- }
- mPopupWindow.dismiss();
- }
-
- public boolean isShowing() {
- return mPopupWindow.isShowing();
- }
-
@Override
public void onClick(View view) {
if (view instanceof TextView) {
@@ -9139,44 +9379,6 @@
}
hide();
}
-
- void positionAtCursor() {
- View contentView = mPopupWindow.getContentView();
- int width = contentView.getMeasuredWidth();
- int height = contentView.getMeasuredHeight();
- final int offset = TextView.this.getSelectionStart();
- final int line = mLayout.getLineForOffset(offset);
- final int lineBottom = mLayout.getLineBottom(line);
- float primaryHorizontal = mLayout.getPrimaryHorizontal(offset);
-
- final Rect bounds = sCursorControllerTempRect;
- bounds.left = (int) (primaryHorizontal - width / 2.0f);
- bounds.top = lineBottom;
-
- bounds.right = bounds.left + width;
- bounds.bottom = bounds.top + height;
-
- convertFromViewportToContentCoordinates(bounds);
-
- final int[] coords = mTempCoords;
- TextView.this.getLocationInWindow(coords);
- coords[0] += bounds.left;
- coords[1] += bounds.top;
-
- final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
- final int screenHeight = displayMetrics.heightPixels;
-
- // Vertical clipping
- if (coords[1] + height > screenHeight) {
- coords[1] = screenHeight - height;
- }
-
- // Horizontal clipping
- coords[0] = Math.min(displayMetrics.widthPixels - width, coords[0]);
- coords[0] = Math.max(0, coords[0]);
-
- mPopupWindow.showAtLocation(TextView.this, Gravity.NO_GRAVITY, coords[0], coords[1]);
- }
}
void showSuggestions() {
@@ -9357,7 +9559,7 @@
boolean allowText = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
- mode.setTitle(allowText ?
+ mode.setTitle(allowText ?
mContext.getString(com.android.internal.R.string.textSelectionCABTitle) : null);
mode.setSubtitle(null);
@@ -9450,29 +9652,23 @@
}
}
- private class ActionPopupWindow implements OnClickListener {
- private static final int TEXT_EDIT_ACTION_POPUP_TEXT =
+ private class ActionPopupWindow extends PinnedPopupWindow implements OnClickListener {
+ private static final int POPUP_TEXT_LAYOUT =
com.android.internal.R.layout.text_edit_action_popup_text;
- private final PopupWindow mPopupWindow;
private TextView mPasteTextView;
private TextView mReplaceTextView;
- private LinearLayout mContentView;
// Whether or not the Paste action should be available when the action popup is displayed
private boolean mWithPaste;
- public ActionPopupWindow() {
+ @Override
+ protected void createPopupWindow() {
mPopupWindow = new PopupWindow(TextView.this.mContext, null,
com.android.internal.R.attr.textSelectHandleWindowStyle);
mPopupWindow.setClippingEnabled(true);
- mPopupWindow.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL);
+ }
- mPopupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
- mPopupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
-
- mContentView = new LinearLayout(TextView.this.getContext());
- LayoutParams wrapContent = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- mContentView.setLayoutParams(wrapContent);
+ @Override
+ protected void initContentView() {
mContentView.setOrientation(LinearLayout.HORIZONTAL);
mContentView.setBackgroundResource(
com.android.internal.R.drawable.text_edit_side_paste_window);
@@ -9480,36 +9676,26 @@
LayoutInflater inflater = (LayoutInflater)TextView.this.mContext.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mPasteTextView = (TextView) inflater.inflate(TEXT_EDIT_ACTION_POPUP_TEXT, null);
+ LayoutParams wrapContent = new LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+
+ mPasteTextView = (TextView) inflater.inflate(POPUP_TEXT_LAYOUT, null);
mPasteTextView.setLayoutParams(wrapContent);
mContentView.addView(mPasteTextView);
mPasteTextView.setText(com.android.internal.R.string.paste);
mPasteTextView.setOnClickListener(this);
- mReplaceTextView = (TextView) inflater.inflate(TEXT_EDIT_ACTION_POPUP_TEXT, null);
+ mReplaceTextView = (TextView) inflater.inflate(POPUP_TEXT_LAYOUT, null);
mReplaceTextView.setLayoutParams(wrapContent);
mContentView.addView(mReplaceTextView);
mReplaceTextView.setText(com.android.internal.R.string.replace);
mReplaceTextView.setOnClickListener(this);
-
- mPopupWindow.setContentView(mContentView);
}
+ @Override
public void show() {
mPasteTextView.setVisibility(mWithPaste && canPaste() ? View.VISIBLE : View.GONE);
-
- final int size = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
- mContentView.measure(size, size);
-
- positionAtCursor();
- }
-
- public void hide() {
- mPopupWindow.dismiss();
- }
-
- public boolean isShowing() {
- return mPopupWindow.isShowing();
+ super.show();
}
@Override
@@ -9522,48 +9708,30 @@
}
}
- void positionAtCursor() {
- int width = mContentView.getMeasuredWidth();
- int height = mContentView.getMeasuredHeight();
- final int selectionStart = TextView.this.getSelectionStart();
- final int selectionEnd = TextView.this.getSelectionEnd();
- final int offset = (selectionStart + selectionEnd) / 2;
- final int line = mLayout.getLineForOffset(offset);
- final int lineTop = mLayout.getLineTop(line);
- float primaryHorizontal = mLayout.getPrimaryHorizontal(offset);
+ @Override
+ protected int getTextOffset() {
+ return (getSelectionStart() + getSelectionEnd()) / 2;
+ }
- final Rect bounds = sCursorControllerTempRect;
- bounds.left = (int) (primaryHorizontal - width / 2.0f);
- bounds.top = lineTop - height;
+ @Override
+ protected int getVerticalLocalPosition(int line) {
+ return mLayout.getLineTop(line) - mContentView.getMeasuredHeight();
+ }
- bounds.right = bounds.left + width;
- bounds.bottom = bounds.top + height;
-
- convertFromViewportToContentCoordinates(bounds);
-
- final int[] coords = mTempCoords;
- TextView.this.getLocationInWindow(coords);
- coords[0] += bounds.left;
- coords[1] += bounds.top;
-
- // Vertical clipping, move under edited line and to the side of insertion cursor
- if (coords[1] < 0) {
- coords[1] += height;
- final int lineBottom = mLayout.getLineBottom(line);
- final int lineHeight = lineBottom - lineTop;
- coords[1] += lineHeight;
+ @Override
+ protected int clipVertically(int positionY) {
+ if (positionY < 0) {
+ final int offset = getTextOffset();
+ final int line = mLayout.getLineForOffset(offset);
+ positionY += mLayout.getLineBottom(line) - mLayout.getLineTop(line);
+ positionY += mContentView.getMeasuredHeight();
// Assumes insertion and selection handles share the same height
final Drawable handle = mContext.getResources().getDrawable(mTextSelectHandleRes);
- coords[1] += handle.getIntrinsicHeight();
+ positionY += handle.getIntrinsicHeight();
}
- // Horizontal clipping
- coords[0] = Math.max(0, coords[0]);
- final int screenWidth = mContext.getResources().getDisplayMetrics().widthPixels;
- coords[0] = Math.min(screenWidth - width, coords[0]);
-
- mPopupWindow.showAtLocation(TextView.this, Gravity.NO_GRAVITY, coords[0], coords[1]);
+ return positionY;
}
public void setShowWithPaste(boolean withPaste) {
@@ -9571,7 +9739,7 @@
}
}
- private abstract class HandleView extends View implements ViewTreeObserver.OnPreDrawListener {
+ private abstract class HandleView extends View implements TextViewPositionListener {
protected Drawable mDrawable;
private final PopupWindow mContainer;
// Position with respect to the parent TextView
@@ -9579,21 +9747,19 @@
private boolean mIsDragging;
// Offset from touch position to mPosition
private float mTouchToWindowOffsetX, mTouchToWindowOffsetY;
- protected float mHotspotX;
+ protected int mHotspotX;
// Offsets the hotspot point up, so that cursor is not hidden by the finger when moving up
private float mTouchOffsetY;
// Where the touch position should be on the handle to ensure a maximum cursor visibility
private float mIdealVerticalOffset;
// Parent's (TextView) previous position in window
private int mLastParentX, mLastParentY;
- // PopupWindow container absolute position with respect to the enclosing window
- private int mContainerPositionX, mContainerPositionY;
- // Visible or not (scrolled off screen), whether or not this handle should be visible
- private boolean mIsActive = false;
- // Used to detect that setFrame was called
- private boolean mNeedsUpdate = true;
// Transient action popup window for Paste and Replace actions
protected ActionPopupWindow mActionPopupWindow;
+ // Previous text character offset
+ private int mPreviousOffset = -1;
+ // Previous text character offset
+ private boolean mPositionHasChanged = true;
// Used to delay the appearance of the action popup window
private Runnable mActionPopupShower;
@@ -9613,15 +9779,6 @@
mIdealVerticalOffset = 0.7f * handleHeight;
}
- @Override
- protected boolean setFrame(int left, int top, int right, int bottom) {
- boolean changed = super.setFrame(left, top, right, bottom);
- // onPreDraw is called for PhoneWindow before the layout of this view is
- // performed. Make sure to update position, even if container didn't move.
- if (changed) mNeedsUpdate = true;
- return changed;
- }
-
protected abstract void initDrawable();
// Touch-up filter: number of previous positions remembered
@@ -9639,12 +9796,6 @@
}
private void addPositionToTouchUpFilter(int offset) {
- if (mNumberPreviousOffsets > 0 &&
- mPreviousOffsets[mPreviousOffsetIndex] == offset) {
- // Make sure only actual changes of position are recorded.
- return;
- }
-
mPreviousOffsetIndex = (mPreviousOffsetIndex + 1) % HISTORY_SIZE;
mPreviousOffsets[mPreviousOffsetIndex] = offset;
mPreviousOffsetsTimes[mPreviousOffsetIndex] = SystemClock.uptimeMillis();
@@ -9663,28 +9814,28 @@
if (i > 0 && i < iMax &&
(now - mPreviousOffsetsTimes[index]) > TOUCH_UP_FILTER_DELAY_BEFORE) {
- updateOffset(mPreviousOffsets[index]);
+ positionAtCursorOffset(mPreviousOffsets[index]);
}
}
+ public boolean offsetHasBeenChanged() {
+ return mNumberPreviousOffsets > 1;
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());
}
public void show() {
- if (isShowing()) {
- mContainer.update(mContainerPositionX, mContainerPositionY, -1, -1);
- } else {
- mContainer.showAtLocation(TextView.this, 0,
- mContainerPositionX, mContainerPositionY);
+ if (isShowing()) return;
- if (!mIsActive) {
- ViewTreeObserver vto = TextView.this.getViewTreeObserver();
- vto.addOnPreDrawListener(this);
- mIsActive = true;
- }
- }
+ getPositionListener().addSubscriber(this, true);
+
+ // Make sure the offset is always considered new, even when focusing at same position
+ mPreviousOffset = -1;
+ positionAtCursorOffset(getCurrentCursorOffset());
+
hideActionPopupWindow();
}
@@ -9697,9 +9848,7 @@
public void hide() {
dismiss();
- ViewTreeObserver vto = TextView.this.getViewTreeObserver();
- vto.removeOnPreDrawListener(this);
- mIsActive = false;
+ TextView.this.getPositionListener().removeSubscriber(this);
}
void showActionPopupWindow(int delay, boolean withPaste) {
@@ -9732,7 +9881,7 @@
return mContainer.isShowing();
}
- private boolean isPositionVisible() {
+ private boolean isVisible() {
// Always show a dragging handle.
if (mIsDragging) {
return true;
@@ -9742,103 +9891,71 @@
return false;
}
- final int extendedPaddingTop = getExtendedPaddingTop();
- final int extendedPaddingBottom = getExtendedPaddingBottom();
- final int compoundPaddingLeft = getCompoundPaddingLeft();
- final int compoundPaddingRight = getCompoundPaddingRight();
-
- final TextView textView = TextView.this;
-
- if (mTempRect == null) mTempRect = new Rect();
- final Rect clip = mTempRect;
- clip.left = compoundPaddingLeft;
- clip.top = extendedPaddingTop;
- clip.right = textView.getWidth() - compoundPaddingRight;
- clip.bottom = textView.getHeight() - extendedPaddingBottom;
-
- final ViewParent parent = textView.getParent();
- if (parent == null || !parent.getChildVisibleRect(textView, clip, null)) {
- return false;
- }
-
- final int[] coords = mTempCoords;
- textView.getLocationInWindow(coords);
- final int posX = coords[0] + mPositionX + (int) mHotspotX;
- final int posY = coords[1] + mPositionY;
-
- // Offset by 1 to take into account 0.5 and int rounding around getPrimaryHorizontal.
- return posX >= clip.left - 1 && posX <= clip.right + 1 &&
- posY >= clip.top && posY <= clip.bottom;
+ return getPositionListener().isVisible(mPositionX + mHotspotX, mPositionY);
}
public abstract int getCurrentCursorOffset();
- public abstract void updateOffset(int offset);
+ public abstract void updateSelection(int offset);
public abstract void updatePosition(float x, float y);
protected void positionAtCursorOffset(int offset) {
- // A HandleView relies on the layout, which may be nulled by external methods.
+ // A HandleView relies on the layout, which may be nulled by external methods
if (mLayout == null) {
// Will update controllers' state, hiding them and stopping selection mode if needed
prepareCursorControllers();
return;
}
- addPositionToTouchUpFilter(offset);
- final int line = mLayout.getLineForOffset(offset);
- final int lineBottom = mLayout.getLineBottom(line);
+ if (offset != mPreviousOffset) {
+ updateSelection(offset);
+ addPositionToTouchUpFilter(offset);
+ final int line = mLayout.getLineForOffset(offset);
- mPositionX = (int) (mLayout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX);
- mPositionY = lineBottom;
+ mPositionX = (int) (mLayout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX);
+ mPositionY = mLayout.getLineBottom(line);
- // Take TextView's padding into account.
- mPositionX += viewportToContentHorizontalOffset();
- mPositionY += viewportToContentVerticalOffset();
+ // Take TextView's padding into account.
+ mPositionX += viewportToContentHorizontalOffset();
+ mPositionY += viewportToContentVerticalOffset();
+
+ mPreviousOffset = offset;
+ mPositionHasChanged = true;
+ }
}
- private void checkForContainerPositionChange() {
- positionAtCursorOffset(getCurrentCursorOffset());
-
- final int previousContainerPositionX = mContainerPositionX;
- final int previousContainerPositionY = mContainerPositionY;
-
- TextView.this.getLocationInWindow(mTempCoords);
- mContainerPositionX = mTempCoords[0] + mPositionX;
- mContainerPositionY = mTempCoords[1] + mPositionY;
-
- mNeedsUpdate |= previousContainerPositionX != mContainerPositionX;
- mNeedsUpdate |= previousContainerPositionY != mContainerPositionY;
- }
-
- public boolean onPreDraw() {
- checkForContainerPositionChange();
- if (mNeedsUpdate) {
+ public void updatePosition(int parentPositionX, int parentPositionY, boolean modified) {
+ if (modified || mPositionHasChanged) {
if (mIsDragging) {
- if (mTempCoords[0] != mLastParentX || mTempCoords[1] != mLastParentY) {
- mTouchToWindowOffsetX += mTempCoords[0] - mLastParentX;
- mTouchToWindowOffsetY += mTempCoords[1] - mLastParentY;
- mLastParentX = mTempCoords[0];
- mLastParentY = mTempCoords[1];
+ // Update touchToWindow offset in case of parent scrolling while dragging
+ if (parentPositionX != mLastParentX || parentPositionY != mLastParentY) {
+ mTouchToWindowOffsetX += parentPositionX - mLastParentX;
+ mTouchToWindowOffsetY += parentPositionY - mLastParentY;
+ mLastParentX = parentPositionX;
+ mLastParentY = parentPositionY;
}
onHandleMoved();
}
- if (isPositionVisible()) {
- mContainer.update(mContainerPositionX, mContainerPositionY, -1, -1);
-
- if (mIsActive && !isShowing()) {
- show();
+ if (isVisible()) {
+ final int positionX = parentPositionX + mPositionX;
+ final int positionY = parentPositionY + mPositionY;
+ if (isShowing()) {
+ mContainer.update(positionX, positionY, -1, -1);
+ } else {
+ mContainer.showAtLocation(TextView.this, Gravity.NO_GRAVITY,
+ positionX, positionY);
}
} else {
if (isShowing()) {
dismiss();
}
}
- mNeedsUpdate = false;
+
+ mPositionHasChanged = false;
}
- return true;
}
@Override
@@ -9855,10 +9972,9 @@
mTouchToWindowOffsetX = ev.getRawX() - mPositionX;
mTouchToWindowOffsetY = ev.getRawY() - mPositionY;
- final int[] coords = mTempCoords;
- TextView.this.getLocationInWindow(coords);
- mLastParentX = coords[0];
- mLastParentY = coords[1];
+ final PositionListener positionListener = getPositionListener();
+ mLastParentX = positionListener.getPositionX();
+ mLastParentY = positionListener.getPositionY();
mIsDragging = true;
break;
}
@@ -9961,7 +10077,7 @@
mTextSelectHandleRes);
}
mDrawable = mSelectHandleCenter;
- mHotspotX = mDrawable.getIntrinsicWidth() / 2.0f;
+ mHotspotX = mDrawable.getIntrinsicWidth() / 2;
}
@Override
@@ -9975,15 +10091,17 @@
break;
case MotionEvent.ACTION_UP:
- final float deltaX = mDownPositionX - ev.getRawX();
- final float deltaY = mDownPositionY - ev.getRawY();
- final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
- if (distanceSquared < mSquaredTouchSlopDistance) {
- if (mActionPopupWindow != null && mActionPopupWindow.isShowing()) {
- // Tapping on the handle dismisses the displayed action popup
- mActionPopupWindow.hide();
- } else {
- show(0);
+ if (!offsetHasBeenChanged()) {
+ final float deltaX = mDownPositionX - ev.getRawX();
+ final float deltaY = mDownPositionY - ev.getRawY();
+ final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
+ if (distanceSquared < mSquaredTouchSlopDistance) {
+ if (mActionPopupWindow != null && mActionPopupWindow.isShowing()) {
+ // Tapping on the handle dismisses the displayed action popup
+ mActionPopupWindow.hide();
+ } else {
+ show(0);
+ }
}
}
hideAfterDelay();
@@ -10006,13 +10124,13 @@
}
@Override
- public void updateOffset(int offset) {
+ public void updateSelection(int offset) {
Selection.setSelection((Spannable) mText, offset);
}
@Override
public void updatePosition(float x, float y) {
- updateOffset(getOffsetForPosition(x, y));
+ positionAtCursorOffset(getOffsetForPosition(x, y));
}
@Override
@@ -10036,7 +10154,7 @@
mTextSelectHandleLeftRes);
}
mDrawable = mSelectHandleLeft;
- mHotspotX = mDrawable.getIntrinsicWidth() * 3.0f / 4.0f;
+ mHotspotX = (mDrawable.getIntrinsicWidth() * 3) / 4;
}
@Override
@@ -10045,7 +10163,7 @@
}
@Override
- public void updateOffset(int offset) {
+ public void updateSelection(int offset) {
Selection.setSelection((Spannable) mText, offset, getSelectionEnd());
}
@@ -10061,7 +10179,7 @@
// Handles can not cross and selection is at least one character
if (offset >= selectionEnd) offset = selectionEnd - 1;
- Selection.setSelection((Spannable) mText, offset, selectionEnd);
+ positionAtCursorOffset(offset);
}
public ActionPopupWindow getActionPopupWindow() {
@@ -10077,7 +10195,7 @@
mTextSelectHandleRightRes);
}
mDrawable = mSelectHandleRight;
- mHotspotX = mDrawable.getIntrinsicWidth() / 4.0f;
+ mHotspotX = mDrawable.getIntrinsicWidth() / 4;
}
@Override
@@ -10086,7 +10204,7 @@
}
@Override
- public void updateOffset(int offset) {
+ public void updateSelection(int offset) {
Selection.setSelection((Spannable) mText, getSelectionStart(), offset);
}
@@ -10102,7 +10220,7 @@
// Handles can not cross and selection is at least one character
if (offset <= selectionStart) offset = selectionStart + 1;
- Selection.setSelection((Spannable) mText, selectionStart, offset);
+ positionAtCursorOffset(offset);
}
public void setActionPopupWindow(ActionPopupWindow actionPopupWindow) {
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index 1531946..6d65782 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.internal.content;
import android.os.Build;
@@ -17,6 +33,12 @@
private static native long nativeSumNativeBinaries(String file, String cpuAbi, String cpuAbi2);
+ /**
+ * Sums the size of native binaries in an APK.
+ *
+ * @param apkFile APK file to scan for native libraries
+ * @return size of all native binary files in bytes
+ */
public static long sumNativeBinariesLI(File apkFile) {
final String cpuAbi = Build.CPU_ABI;
final String cpuAbi2 = Build.CPU_ABI2;
@@ -26,6 +48,14 @@
private native static int nativeCopyNativeBinaries(String filePath, String sharedLibraryPath,
String cpuAbi, String cpuAbi2);
+ /**
+ * Copies native binaries to a shared library directory.
+ *
+ * @param apkFile APK file to scan for native libraries
+ * @param sharedLibraryDir directory for libraries to be copied to
+ * @return {@link PackageManager#INSTALL_SUCCEEDED} if successful or another
+ * error code from that class if not
+ */
public static int copyNativeBinariesIfNeededLI(File apkFile, File sharedLibraryDir) {
final String cpuAbi = Build.CPU_ABI;
final String cpuAbi2 = Build.CPU_ABI2;
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index ec64552..266728b 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -39,6 +39,8 @@
public static final int RECOMMEND_FAILED_INVALID_LOCATION = -3;
public static final int RECOMMEND_FAILED_ALREADY_EXISTS = -4;
public static final int RECOMMEND_MEDIA_UNAVAILABLE = -5;
+ public static final int RECOMMEND_FAILED_INVALID_URI = -6;
+
private static final boolean localLOGV = true;
private static final String TAG = "PackageHelper";
// App installation location settings values
diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java
index d36be10..d61a579 100644
--- a/core/java/com/android/internal/net/VpnConfig.java
+++ b/core/java/com/android/internal/net/VpnConfig.java
@@ -32,7 +32,7 @@
*/
public class VpnConfig implements Parcelable {
- public static final String ACTION_VPN_REVOKED = "android.net.vpn.action.REVOKED";
+ public static final String SERVICE_INTERFACE = "android.net.VpnService";
public static final String LEGACY_VPN = "[Legacy VPN]";
@@ -52,7 +52,7 @@
PendingIntent.FLAG_NO_CREATE : PendingIntent.FLAG_CANCEL_CURRENT);
}
- public String packagz;
+ public String user;
public String interfaze;
public String session;
public int mtu = -1;
@@ -70,7 +70,7 @@
@Override
public void writeToParcel(Parcel out, int flags) {
- out.writeString(packagz);
+ out.writeString(user);
out.writeString(interfaze);
out.writeString(session);
out.writeInt(mtu);
@@ -87,7 +87,7 @@
@Override
public VpnConfig createFromParcel(Parcel in) {
VpnConfig config = new VpnConfig();
- config.packagz = in.readString();
+ config.user = in.readString();
config.interfaze = in.readString();
config.session = in.readString();
config.mtu = in.readInt();
diff --git a/core/java/com/android/internal/nfc/LlcpConnectionlessSocket.java b/core/java/com/android/internal/nfc/LlcpConnectionlessSocket.java
deleted file mode 100644
index a9cf6b8..0000000
--- a/core/java/com/android/internal/nfc/LlcpConnectionlessSocket.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.internal.nfc;
-
-import java.io.IOException;
-
-import android.nfc.ErrorCodes;
-import android.nfc.ILlcpConnectionlessSocket;
-import android.nfc.LlcpPacket;
-import android.os.RemoteException;
-import android.util.Log;
-
-public class LlcpConnectionlessSocket {
- private static final String TAG = "LlcpConnectionlessSocket";
-
- /**
- * The handle returned by the NFC service and used to identify the LLCP connectionless socket in
- * every call of this class.
- */
- protected int mHandle;
-
-
- /**
- * The entry point for LLCP Connectionless socket operations.
- */
- protected ILlcpConnectionlessSocket mService;
-
-
- /**
- * Internal constructor for the LlcpConnectionlessSocket class.
- *
- * @param service The entry point to the Nfc Service for LLCP Connectionless socket class.
- * @param handle The handle returned by the NFC service and used to identify
- * the socket in subsequent calls.
- */
- LlcpConnectionlessSocket(ILlcpConnectionlessSocket service, int handle) {
- this.mService = service;
- this.mHandle = handle;
- }
-
- /**
- * Send data to a specific LLCP Connectionless client
- *
- * @param packet Service Access Point number related to a LLCP
- * Connectionless client and a data buffer to send
- * @throws IOException if the LLCP link has been lost or deactivated.
- */
- public void sendTo(LlcpPacket packet) throws IOException {
- try {
- int result = mService.sendTo(mHandle, packet);
- // Handle potential errors
- if (ErrorCodes.isError(result)) {
- throw new IOException();
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in sendTo(): ", e);
- }
- }
-
- /**
- * Receive data from a LLCP Connectionless client
- *
- * @return data data received from a specific LLCP Connectionless client
- * @throws IOException if the LLCP link has been lost or deactivated.
- * @see LlcpPacket
- */
- public LlcpPacket receiveFrom() throws IOException {
- try {
- LlcpPacket packet = mService.receiveFrom(mHandle);
- if (packet != null) {
- return packet;
- }else{
- // Handle potential errors
- throw new IOException();
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in receiveFrom(): ", e);
- }
- return null;
- }
-
- /**
- * Close the created Connectionless socket.
- */
- public void close() {
- try {
- mService.close(mHandle);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in close(): ", e);
- }
- }
-
- /**
- * Returns the local Service Access Point number of the socket
- *
- * @return sap
- */
- public int getSap() {
- int sap = 0;
-
- try {
- sap = mService.getSap(mHandle);
-
- } catch (RemoteException e) {
-
- e.printStackTrace();
- }
- return sap;
- }
-}
diff --git a/core/java/com/android/internal/nfc/LlcpException.java b/core/java/com/android/internal/nfc/LlcpException.java
deleted file mode 100644
index da4e91e..0000000
--- a/core/java/com/android/internal/nfc/LlcpException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.internal.nfc;
-
-/**
- * Generic exception thrown in case something unexpected happened during a
- * LLCP communication.
- */
-public class LlcpException extends Exception {
- /**
- * Constructs a new LlcpException with the current stack trace and the
- * specified detail message.
- *
- * @param s the detail message for this exception.
- */
- public LlcpException(String s) {
- super(s);
- }
-}
diff --git a/core/java/com/android/internal/nfc/LlcpServiceSocket.java b/core/java/com/android/internal/nfc/LlcpServiceSocket.java
deleted file mode 100644
index d616860..0000000
--- a/core/java/com/android/internal/nfc/LlcpServiceSocket.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.internal.nfc;
-
-import java.io.IOException;
-
-import android.nfc.ErrorCodes;
-import android.nfc.ILlcpSocket;
-import android.nfc.ILlcpServiceSocket;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * LlcpServiceSocket represents a LLCP Service to be used in a
- * Connection-oriented communication
- */
-public class LlcpServiceSocket {
-
- private static final String TAG = "LlcpServiceSocket";
-
- /**
- * The handle returned by the NFC service and used to identify the LLCP
- * Service socket in every call of this class.
- */
- protected int mHandle;
-
- /**
- * The entry point for LLCP Service socket operations.
- */
- protected ILlcpServiceSocket mService;
-
- private final ILlcpSocket mLlcpSocketService;
-
- static LlcpException convertErrorToLlcpException(int errorCode) {
- return convertErrorToLlcpException(errorCode, null);
- }
-
- static LlcpException convertErrorToLlcpException(int errorCode,
- String message) {
- if (message == null) {
- message = "";
- } else {
- message = " (" + message + ")";
- }
-
- switch (errorCode) {
- case ErrorCodes.ERROR_SOCKET_CREATION:
- return new LlcpException(
- "Error during the creation of an Llcp socket" + message);
- case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
- return new LlcpException("Not enough ressources are available"
- + message);
- default:
- return new LlcpException("Unkown error code " + errorCode + message);
- }
- }
-
- /**
- * Internal constructor for the LlcpServiceSocket class.
- *
- * @param service
- * The entry point to the Nfc Service for LlcpServiceSocket
- * class.
- * @param handle
- * The handle returned by the NFC service and used to identify
- * the socket in subsequent calls.
- * @hide
- */
- public LlcpServiceSocket(ILlcpServiceSocket service, ILlcpSocket socketService, int handle) {
- this.mService = service;
- this.mHandle = handle;
- this.mLlcpSocketService = socketService;
- }
-
- /**
- * Wait for incomming connection request from a LLCP client and accept this
- * request
- *
- * @return socket object to be used to communicate with a LLCP client
- *
- * @throws IOException
- * if the llcp link is lost or deactivated
- * @throws LlcpException
- * if not enough ressources are available
- *
- * @see LlcpSocket
- */
- public LlcpSocket accept() throws IOException, LlcpException {
-
- try {
- int handle = mService.accept(mHandle);
- // Handle potential errors
- if (ErrorCodes.isError(handle)) {
- if (handle == ErrorCodes.ERROR_IO) {
- throw new IOException();
- } else {
- throw convertErrorToLlcpException(handle);
- }
- }
-
- // Build the public LlcpSocket object
- return new LlcpSocket(mLlcpSocketService, handle);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in accept(): ", e);
- return null;
- }
-
- }
-
- /**
- * Close the created Llcp Service socket
- */
- public void close() {
- try {
- mService.close(mHandle);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in close(): ", e);
- }
- }
-}
diff --git a/core/java/com/android/internal/nfc/LlcpSocket.java b/core/java/com/android/internal/nfc/LlcpSocket.java
deleted file mode 100644
index 63888ae..0000000
--- a/core/java/com/android/internal/nfc/LlcpSocket.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.internal.nfc;
-
-import java.io.IOException;
-
-import android.nfc.ErrorCodes;
-import android.nfc.ILlcpSocket;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * LlcpClientSocket represents a LLCP Connection-Oriented client to be used in a
- * connection-oriented communication
- */
-public class LlcpSocket {
-
- private static final String TAG = "LlcpSocket";
-
- /**
- * The handle returned by the NFC service and used to identify the LLCP
- * socket in every call of this class.
- */
- protected int mHandle;
-
- /**
- * The entry point for LLCP socket operations.
- */
- protected ILlcpSocket mService;
-
- static LlcpException convertErrorToLlcpException(int errorCode) {
- return convertErrorToLlcpException(errorCode, null);
- }
-
- static LlcpException convertErrorToLlcpException(int errorCode,
- String message) {
- if (message == null) {
- message = "";
- } else {
- message = " (" + message + ")";
- }
-
- switch (errorCode) {
- case ErrorCodes.ERROR_SOCKET_CREATION:
- return new LlcpException(
- "Error during the creation of an Llcp socket" + message);
- case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
- return new LlcpException("Not enough ressources are available"
- + message);
- case ErrorCodes.ERROR_SOCKET_NOT_CONNECTED:
- return new LlcpException("Socket not connected to an Llcp Service"
- + message);
- default:
- return new LlcpException("Unkown error code " + errorCode + message);
- }
- }
-
- /**
- * Internal constructor for the LlcpSocket class.
- *
- * @param service
- * The entry point to the Nfc Service for LlcpServiceSocket
- * class.
- * @param handle
- * The handle returned by the NFC service and used to identify
- * the socket in subsequent calls.
- * @hide
- */
- public LlcpSocket(ILlcpSocket service, int handle) {
- this.mService = service;
- this.mHandle = handle;
- }
-
- /**
- * Connect request to a specific LLCP Service by its SAP.
- *
- * @param sap
- * Service Access Point number of the LLCP Service
- * @throws IOException
- * if the LLCP has been lost or deactivated.
- * @throws LlcpException
- * if the connection request is rejected by the remote LLCP
- * Service
- */
- public void connect(int sap) throws IOException, LlcpException {
- try {
- int result = mService.connect(mHandle, sap);
- // Handle potential errors
- if (ErrorCodes.isError(result)) {
- if (result == ErrorCodes.ERROR_IO) {
- throw new IOException();
- } else {
- throw convertErrorToLlcpException(result);
- }
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in accept(): ", e);
- }
- }
-
- /**
- * Connect request to a specific LLCP Service by its Service Name.
- *
- * @param sn
- * Service Name of the LLCP Service
- * @throws IOException
- * if the LLCP has been lost or deactivated.
- * @throws LlcpException
- * if the connection request is rejected by the remote LLCP
- * Service
- */
- public void connect(String sn) throws IOException, LlcpException {
- try {
- int result = mService.connectByName(mHandle, sn);
- // Handle potential errors
- if (ErrorCodes.isError(result)) {
- if (result == ErrorCodes.ERROR_IO) {
- throw new IOException();
- } else {
- throw convertErrorToLlcpException(result);
- }
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in accept(): ", e);
- }
- }
-
- /**
- * Disconnect request to the connected LLCP socket and close the created
- * socket.
- *
- * @throws IOException
- * if the LLCP has been lost or deactivated.
- */
- public void close() throws IOException {
- try {
- int result = mService.close(mHandle);
- // Handle potential errors
- if (ErrorCodes.isError(result)) {
- throw new IOException();
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in close(): ", e);
- }
- }
-
- /**
- * Send data to the connected LLCP Socket.
- *
- * @throws IOException
- * if the LLCP has been lost or deactivated.
- */
- public void send(byte[] data) throws IOException {
- try {
- int result = mService.send(mHandle, data);
- // Handle potential errors
- if (ErrorCodes.isError(result)) {
- throw new IOException();
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in send(): ", e);
- }
- }
-
- /**
- * Receive data from the connected LLCP socket
- *
- * @param receiveBuffer
- * a buffer for the received data
- * @return length length of the data received
- * @throws IOException
- * if the LLCP has been lost or deactivated.
- */
- public int receive(byte[] receiveBuffer) throws IOException {
- int receivedLength = 0;
- try {
- receivedLength = mService.receive(mHandle, receiveBuffer);
- if(receivedLength == 0){
- throw new IOException();
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in receive(): ", e);
- }
-
- return receivedLength;
- }
-
- /**
- * Returns the local Service Access Point number of the socket
- *
- * @return localSap
- */
- public int getLocalSap() {
- try {
- return mService.getLocalSap(mHandle);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getLocalSap(): ", e);
- return 0;
- }
- }
-
- /**
- * Returns the local Maximum Information Unit(MIU) of the socket
- *
- * @return miu
- */
- public int getLocalSocketMiu() {
- try {
- return mService.getLocalSocketMiu(mHandle);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getLocalSocketMiu(): ", e);
- return 0;
- }
- }
-
- /**
- * Returns the local Receive Window(RW) of the socket
- *
- * @return rw
- */
- public int getLocalSocketRw() {
- try {
- return mService.getLocalSocketRw(mHandle);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getLocalSocketRw(): ", e);
- return 0;
- }
- }
-
- /**
- * Returns the remote Maximum Information Unit(MIU) of the socket.
- * <p>
- * This method must be called when the socket is in CONNECTED_STATE
- *
- * @return remoteMiu
- * @throws LlcpException
- * if the LlcpClientSocket is not in a CONNECTED_STATE
- */
- public int getRemoteSocketMiu() throws LlcpException {
- try {
- int result = mService.getRemoteSocketMiu(mHandle);
- if(result != ErrorCodes.ERROR_SOCKET_NOT_CONNECTED){
- return result;
- }else{
- throw convertErrorToLlcpException(result);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getRemoteSocketMiu(): ", e);
- return 0;
- }
- }
-
- /**
- * Returns the remote Receive Window(RW) of the connected remote socket.
- * <p>
- * This method must be called when the socket is in CONNECTED_STATE
- *
- * @return rw
- * @throws LlcpException
- * if the LlcpClientSocket is not in a CONNECTED_STATE
- */
- public int getRemoteSocketRw() throws LlcpException {
- try {
- int result = mService.getRemoteSocketRw(mHandle);
- if( result != ErrorCodes.ERROR_SOCKET_NOT_CONNECTED){
- return result;
- }else{
- throw convertErrorToLlcpException(result);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getRemoteSocketRw(): ", e);
- return 0;
- }
- }
-}
diff --git a/core/java/com/android/internal/nfc/NfcException.java b/core/java/com/android/internal/nfc/NfcException.java
deleted file mode 100644
index 29a99c6..0000000
--- a/core/java/com/android/internal/nfc/NfcException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.internal.nfc;
-
-/**
- * Generic exception thrown in case something unexpected happened during the
- * NFCManager operations.
- */
-public class NfcException extends Exception {
- /**
- * Constructs a new NfcException with the current stack trace and the
- * specified detail message.
- *
- * @param s the detail message for this exception.
- */
- public NfcException(String s) {
- super(s);
- }
-}
diff --git a/core/java/com/android/internal/nfc/P2pDevice.java b/core/java/com/android/internal/nfc/P2pDevice.java
deleted file mode 100644
index 8ab9aad..0000000
--- a/core/java/com/android/internal/nfc/P2pDevice.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.internal.nfc;
-
-import java.io.IOException;
-
-/**
- * P2pDevice is the abstract base class for all supported P2P targets the
- * NfcManager can handle.
- */
-public abstract class P2pDevice {
-
- /**
- * Peer-to-Peer Target.
- */
- public static final short MODE_P2P_TARGET = 0x00;
-
- /**
- * Peer-to-Peer Initiator.
- */
- public static final short MODE_P2P_INITIATOR = 0x01;
-
- /**
- * Invalid target type.
- */
- public static final short MODE_INVALID = 0xff;
-
- /**
- * Target handle, used by native calls.
- */
- protected int mHandle;
-
- /**
- * Flag set when the object is closed and thus not usable any more.
- */
- protected boolean isClosed = false;
-
- /**
- * Prevent default constructor to be public.
- */
- protected P2pDevice() {
- }
-
- /**
- * Returns the remote NFC-IP1 General Bytes.
- *
- * @return remote general bytes
- * @throws IOException
- */
- public byte[] getGeneralBytes() throws IOException {
- // Should not be called directly (use subclasses overridden method instead)
- return null;
- }
-
- /**
- * Returns target type. The value returned can be one of the TYPE_*
- * constants.
- *
- * @return target type.
- */
- public int getMode() {
- // Should not be called directly (use subclasses overridden method instead)
- return MODE_INVALID;
- }
-}
diff --git a/core/java/com/android/internal/nfc/P2pInitiator.java b/core/java/com/android/internal/nfc/P2pInitiator.java
deleted file mode 100644
index 46ae9ab..0000000
--- a/core/java/com/android/internal/nfc/P2pInitiator.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.internal.nfc;
-
-import java.io.IOException;
-
-import android.nfc.IP2pInitiator;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * P2pInitiator represents the initiator in an NFC-IP1 peer-to-peer
- * communication.
- *
- * @see P2pTarget
- */
-public class P2pInitiator extends P2pDevice {
-
- private static final String TAG = "P2pInitiator";
-
- /**
- * The entry point for P2P tag operations.
- */
- private final IP2pInitiator mService;
-
- /**
- * Internal constructor for the P2pInitiator class.
- *
- * @param handle The handle returned by the NFC service and used to identify
- * the tag in subsequent calls.
- */
- P2pInitiator(IP2pInitiator service, int handle) {
- this.mService = service;
- this.mHandle = handle;
- }
-
- /**
- * Receives data from a P2pInitiator.
- *
- * @return data sent by the P2pInitiator.
- * @throws IOException if the target has been lost or if the connection has
- * been closed.
- */
- public byte[] receive() throws IOException {
- try {
- byte[] result = mService.receive(mHandle);
- if (result == null) {
- throw new IOException("Tag has been lost");
- }
- return result;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in receive(): ", e);
- return null;
- }
- }
-
- /**
- * Sends data to a P2pInitiator.
- *
- * @param data data to be sent to the P2pInitiator.
- * @throws IOException if the target has been lost or if the connection has
- * been closed.
- */
- public void send(byte[] data) throws IOException {
- try {
- boolean isSuccess = mService.send(mHandle, data);
- if (!isSuccess) {
- throw new IOException("Tag has been lost");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in send(): ", e);
- }
- }
-
- @Override
- public byte[] getGeneralBytes() {
- try {
- return mService.getGeneralBytes(mHandle);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getGeneralBytes(): ", e);
- return null;
- }
- }
-
- @Override
- public int getMode() {
- return P2pDevice.MODE_P2P_INITIATOR;
- }
-
-}
diff --git a/core/java/com/android/internal/nfc/P2pTarget.java b/core/java/com/android/internal/nfc/P2pTarget.java
deleted file mode 100644
index 7b59da3..0000000
--- a/core/java/com/android/internal/nfc/P2pTarget.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.internal.nfc;
-
-import java.io.IOException;
-
-import android.nfc.ErrorCodes;
-import android.nfc.IP2pTarget;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * P2pTarget represents the target in an NFC-IP1 peer-to-peer communication.
- *
- * @see P2pInitiator
- */
-public class P2pTarget extends P2pDevice {
-
- private static final String TAG = "P2pTarget";
-
- /**
- * The entry point for P2P tag operations.
- */
- private final IP2pTarget mService;
-
- /**
- * Flag set when the object is closed and thus not usable any more.
- */
- private final boolean isClosed = false;
-
- /**
- * Flag set when the tag is connected.
- */
- private boolean isConnected = false;
-
- /**
- * Check if tag is still opened.
- *
- * @return data sent by the P2pInitiator.
- * @throws NfcException if accessing a closed target.
- */
- public void checkState() throws NfcException {
- if(isClosed) {
- throw new NfcException("Tag has been closed.");
- }
- }
-
- /**
- * Internal constructor for the P2pTarget class.
- *
- * @param handle The handle returned by the NFC service and used to identify
- * the tag in subsequent calls.
- */
- P2pTarget(IP2pTarget service, int handle) {
- this.mService = service;
- this.mHandle = handle;
- }
-
- /**
- * Connects to the P2pTarget. This shall be called prior to any other
- * operation on the P2pTarget.
- *
- * @throws NfcException
- */
- public void connect() throws NfcException {
- // Check state
- checkState();
- if (isConnected) {
- throw new NfcException("Already connected");
- }
-
- // Perform connect
- try {
- int result = mService.connect(mHandle);
- if (ErrorCodes.isError(result)) {
- if (result == ErrorCodes.ERROR_IO) {
- throw new NfcException("Failed to connect");
- }
- else {
- // TODO(nxp)
- // throw NfcAdapter.convertErrorToNfcException(result);
- }
- }
- isConnected = true;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in connect(): ", e);
- }
- }
-
- /**
- * Disconnects from the P2p Target. This must be called so that other
- * targets can be discovered. It restarts the NFC discovery loop.
- *
- * @throws NFCException
- */
- public void disconnect() throws NfcException {
- checkState();
- try {
- mService.disconnect(mHandle);
- isConnected = true;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in disconnect(): ", e);
- }
- }
-
- /**
- * Exchanges raw data with the P2pTarget.
- *
- * @param data data to be sent to the P2pTarget
- * @return data sent in response by the P2pTarget
- * @throws IOException if the target has been lost or the connection has
- * been closed.
- * @throws NfcException in case of failure within the stack
- */
- public byte[] transceive(byte[] data) throws IOException, NfcException {
- // Check state
- checkState();
-
- // Perform transceive
- try {
- byte[] response = mService.transceive(mHandle, data);
- if (response == null) {
- throw new IOException("Transceive failed");
- }
- return response;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in transceive(): ", e);
- return null;
- }
- }
-
- /**
- * Get the General bytes of the connected P2P Target
- *
- * @return general bytes of the connected P2P Target
- * @throws IOException if the target in not in connected state
- */
- @Override
- public byte[] getGeneralBytes() throws IOException {
- try {
- if(isConnected){
- return mService.getGeneralBytes(mHandle);
- }else{
- throw new IOException("Target not in connected state");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getGeneralBytes(): ", e);
- return null;
- }
- }
-
- @Override
- public int getMode() {
- return P2pDevice.MODE_P2P_TARGET;
- }
-}
diff --git a/core/java/com/android/internal/textservice/ISpellCheckerService.aidl b/core/java/com/android/internal/textservice/ISpellCheckerService.aidl
index ff00492..67d7b3e 100644
--- a/core/java/com/android/internal/textservice/ISpellCheckerService.aidl
+++ b/core/java/com/android/internal/textservice/ISpellCheckerService.aidl
@@ -19,11 +19,13 @@
import com.android.internal.textservice.ISpellCheckerSession;
import com.android.internal.textservice.ISpellCheckerSessionListener;
+import android.os.Bundle;
+
/**
* Public interface to the global spell checker.
* @hide
*/
interface ISpellCheckerService {
ISpellCheckerSession getISpellCheckerSession(
- String locale, ISpellCheckerSessionListener listener);
+ String locale, ISpellCheckerSessionListener listener, in Bundle bundle);
}
diff --git a/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl b/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl
index 79e43510c0..5a00603 100644
--- a/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl
+++ b/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl
@@ -22,7 +22,7 @@
* @hide
*/
oneway interface ISpellCheckerSession {
- void getSuggestionsMultiple(
+ void onGetSuggestionsMultiple(
in TextInfo[] textInfos, int suggestionsLimit, boolean multipleWords);
- void cancel();
+ void onCancel();
}
diff --git a/core/java/com/android/internal/textservice/ITextServicesManager.aidl b/core/java/com/android/internal/textservice/ITextServicesManager.aidl
index eae1ac8..bb4b2a3 100644
--- a/core/java/com/android/internal/textservice/ITextServicesManager.aidl
+++ b/core/java/com/android/internal/textservice/ITextServicesManager.aidl
@@ -20,6 +20,7 @@
import com.android.internal.textservice.ITextServicesSessionListener;
import android.content.ComponentName;
+import android.os.Bundle;
import android.view.textservice.SpellCheckerInfo;
/**
@@ -28,10 +29,10 @@
*/
interface ITextServicesManager {
SpellCheckerInfo getCurrentSpellChecker(String locale);
- oneway void getSpellCheckerService(in SpellCheckerInfo info, in String locale,
+ oneway void getSpellCheckerService(String sciId, in String locale,
in ITextServicesSessionListener tsListener,
- in ISpellCheckerSessionListener scListener);
+ in ISpellCheckerSessionListener scListener, in Bundle bundle);
oneway void finishSpellCheckerService(in ISpellCheckerSessionListener listener);
- oneway void setCurrentSpellChecker(in SpellCheckerInfo info);
+ oneway void setCurrentSpellChecker(String sciId);
SpellCheckerInfo[] getEnabledSpellCheckers();
}
diff --git a/core/java/com/android/internal/util/Protocol.java b/core/java/com/android/internal/util/Protocol.java
index 9ecd29f..0cadb16 100644
--- a/core/java/com/android/internal/util/Protocol.java
+++ b/core/java/com/android/internal/util/Protocol.java
@@ -49,5 +49,6 @@
public static final int BASE_DATA_CONNECTION_AC = 0x00041000;
public static final int BASE_DATA_CONNECTION_TRACKER = 0x00042000;
+ public static final int BASE_DNS_PINGER = 0x00050000;
//TODO: define all used protocols
}
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index cbe72dd..36f0246 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -1226,6 +1226,12 @@
* be executed and upon the next message arriving
* destState.enter will be invoked.
*
+ * this function can also be called inside the enter function of the
+ * previous transition target, but the behavior is undefined when it is
+ * called mid-way through a previous transition (for example, calling this
+ * in the enter() routine of a intermediate node when the current transition
+ * target is one of the nodes descendants).
+ *
* @param destState will be the state that receives the next message.
*/
protected final void transitionTo(IState destState) {
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index 7839a08..5e70e4c 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -150,6 +150,11 @@
private CopyOnWriteArrayList<WeakReference<MenuPresenter>> mPresenters =
new CopyOnWriteArrayList<WeakReference<MenuPresenter>>();
+
+ /**
+ * Currently expanded menu item; must be collapsed when we clear.
+ */
+ private MenuItemImpl mExpandedItem;
/**
* Called by menu to notify of close and selection changes.
@@ -512,6 +517,9 @@
}
public void clear() {
+ if (mExpandedItem != null) {
+ collapseItemActionView(mExpandedItem);
+ }
mItems.clear();
onItemsChanged(true);
@@ -1223,11 +1231,14 @@
}
startDispatchingItemsChanged();
+ if (expanded) {
+ mExpandedItem = item;
+ }
return expanded;
}
public boolean collapseItemActionView(MenuItemImpl item) {
- if (mPresenters.isEmpty()) return false;
+ if (mPresenters.isEmpty() || mExpandedItem != item) return false;
boolean collapsed = false;
@@ -1242,6 +1253,9 @@
}
startDispatchingItemsChanged();
+ if (collapsed) {
+ mExpandedItem = null;
+ }
return collapsed;
}
}
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 446c842..61df5c7 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -583,7 +583,7 @@
}
public void setLogo(int resId) {
- mContext.getResources().getDrawable(resId);
+ setLogo(mContext.getResources().getDrawable(resId));
}
/**
@@ -1265,9 +1265,8 @@
@Override
public void initForMenu(Context context, MenuBuilder menu) {
// Clear the expanded action view when menus change.
- mExpandedActionView = null;
- if (mCurrentExpandedItem != null) {
- mCurrentExpandedItem.collapseActionView();
+ if (mMenu != null && mCurrentExpandedItem != null) {
+ mMenu.collapseItemActionView(mCurrentExpandedItem);
}
mMenu = menu;
}
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
index fb33748..366b983 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
@@ -29,6 +29,7 @@
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.view.ViewRootImpl;
import com.android.internal.R;
@@ -62,7 +63,8 @@
mContext = context;
mTargetView = targetView;
mKeyboardView = keyboardView;
- if (useFullScreenWidth || mKeyboardView.getLayoutParams().width == -1) {
+ if (useFullScreenWidth
+ || mKeyboardView.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT) {
createKeyboards();
} else {
createKeyboardsWithSpecificSize(mKeyboardView.getLayoutParams().width,
diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
index 0510023..ec926e4 100644
--- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
@@ -127,6 +127,7 @@
mAnimatingTargets = false;
}
};
+ private int mTargetResourceId;
public MultiWaveView(Context context) {
this(context, null);
@@ -474,6 +475,7 @@
Drawable drawable = array.getDrawable(i);
targetDrawables.add(new TargetDrawable(res, drawable));
}
+ mTargetResourceId = resourceId;
mTargetDrawables = targetDrawables;
updateTargetPositions();
}
@@ -492,6 +494,10 @@
}
}
+ public int getTargetResourceId() {
+ return mTargetResourceId;
+ }
+
/**
* Enable or disable vibrate on touch.
*
diff --git a/core/java/com/android/server/NetworkManagementSocketTagger.java b/core/java/com/android/server/NetworkManagementSocketTagger.java
index 59bef92..4667e5f 100644
--- a/core/java/com/android/server/NetworkManagementSocketTagger.java
+++ b/core/java/com/android/server/NetworkManagementSocketTagger.java
@@ -69,8 +69,8 @@
public void tag(FileDescriptor fd) throws SocketException {
final SocketTags options = threadSocketTags.get();
if (LOGD) {
- Log.d(TAG, "tagSocket(" + fd.getInt$() + ") with statsTag=" + options.statsTag
- + ", statsUid=" + options.statsUid);
+ Log.d(TAG, "tagSocket(" + fd.getInt$() + ") with statsTag=0x"
+ + Integer.toHexString(options.statsTag) + ", statsUid=" + options.statsUid);
}
try {
// TODO: skip tagging when options would be no-op
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 6e73889..170957c 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -178,6 +178,7 @@
external/icu4c/i18n \
external/icu4c/common \
external/jpeg \
+ external/harfbuzz/contrib \
external/harfbuzz/src \
external/zlib \
frameworks/opt/emoji \
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 682c3c4..f8be136 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -88,9 +88,12 @@
return canvas->getDevice()->accessBitmap(false).height();
}
- static void setBitmap(JNIEnv* env, jobject, SkCanvas* canvas,
- SkBitmap* bitmap) {
- canvas->setBitmapDevice(*bitmap);
+ static void setBitmap(JNIEnv* env, jobject, SkCanvas* canvas, SkBitmap* bitmap) {
+ if (bitmap) {
+ canvas->setBitmapDevice(*bitmap);
+ } else {
+ canvas->setDevice(NULL);
+ }
}
static int saveAll(JNIEnv* env, jobject jcanvas) {
diff --git a/core/jni/android/graphics/NinePatchImpl.cpp b/core/jni/android/graphics/NinePatchImpl.cpp
index 579749a..a3e36ee 100644
--- a/core/jni/android/graphics/NinePatchImpl.cpp
+++ b/core/jni/android/graphics/NinePatchImpl.cpp
@@ -160,14 +160,6 @@
return;
}
- // if the nine patch is bigger than the dst on a given axis we cannot
- // stretch properly so just draw the bitmap as best as possible and return
- if (bitmap.width() >= bounds.width() || bitmap.height() >= bounds.height())
- {
- canvas->drawBitmapRect(bitmap, NULL, bounds, paint);
- return;
- }
-
// should try a quick-reject test before calling lockPixels
SkAutoLockPixels alp(bitmap);
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 2de0932..ffcd1a0 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -233,6 +233,12 @@
return surfaceTexture->getTimestamp();
}
+static void SurfaceTexture_release(JNIEnv* env, jobject thiz)
+{
+ sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
+ surfaceTexture->abandon();
+}
+
// ----------------------------------------------------------------------------
static JNINativeMethod gSurfaceTextureMethods[] = {
@@ -243,6 +249,7 @@
{"nativeUpdateTexImage", "()V", (void*)SurfaceTexture_updateTexImage },
{"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix },
{"nativeGetTimestamp", "()J", (void*)SurfaceTexture_getTimestamp },
+ {"nativeRelease", "()V", (void*)SurfaceTexture_release },
};
int register_android_graphics_SurfaceTexture(JNIEnv* env)
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 30fe298..a29eb38 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -17,6 +17,10 @@
#include "TextLayoutCache.h"
#include "TextLayout.h"
+extern "C" {
+#include "harfbuzz-unicode.h"
+}
+
namespace android {
TextLayoutCache::TextLayoutCache() :
@@ -355,7 +359,9 @@
shaperItem->item.pos = start;
shaperItem->item.length = count;
shaperItem->item.bidiLevel = isRTL;
- shaperItem->item.script = isRTL ? HB_Script_Arabic : HB_Script_Common;
+
+ ssize_t iter = 0;
+ shaperItem->item.script = code_point_to_script(utf16_to_code_point(chars, count, &iter));
shaperItem->string = chars;
shaperItem->stringLength = contextCount;
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 3dcaa37..884fa78 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -45,6 +45,8 @@
jfieldID rect_right;
jfieldID rect_bottom;
jmethodID post_event;
+ jmethodID rect_constructor;
+ jmethodID face_constructor;
};
static fields_t fields;
@@ -57,8 +59,10 @@
JNICameraContext(JNIEnv* env, jobject weak_this, jclass clazz, const sp<Camera>& camera);
~JNICameraContext() { release(); }
virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);
- virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr);
+ virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr,
+ camera_frame_metadata_t *metadata);
virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
+ void postMetadata(JNIEnv *env, int32_t msgType, camera_frame_metadata_t *metadata);
void addCallbackBuffer(JNIEnv *env, jbyteArray cbb, int msgType);
void setCallbackMode(JNIEnv *env, bool installed, bool manualMode);
sp<Camera> getCamera() { Mutex::Autolock _l(mLock); return mCamera; }
@@ -74,6 +78,8 @@
jobject mCameraJObjectWeak; // weak reference to java object
jclass mCameraJClass; // strong reference to java class
sp<Camera> mCamera; // strong reference to native object
+ jclass mFaceClass; // strong reference to Face class
+ jclass mRectClass; // strong reference to Rect class
Mutex mLock;
/*
@@ -124,6 +130,12 @@
mCameraJClass = (jclass)env->NewGlobalRef(clazz);
mCamera = camera;
+ jclass faceClazz = env->FindClass("android/hardware/Camera$Face");
+ mFaceClass = (jclass) env->NewGlobalRef(faceClazz);
+
+ jclass rectClazz = env->FindClass("android/graphics/Rect");
+ mRectClass = (jclass) env->NewGlobalRef(rectClazz);
+
mManualBufferMode = false;
mManualCameraCallbackSet = false;
}
@@ -142,6 +154,14 @@
env->DeleteGlobalRef(mCameraJClass);
mCameraJClass = NULL;
}
+ if (mFaceClass != NULL) {
+ env->DeleteGlobalRef(mFaceClass);
+ mFaceClass = NULL;
+ }
+ if (mRectClass != NULL) {
+ env->DeleteGlobalRef(mRectClass);
+ mRectClass = NULL;
+ }
clearCallbackBuffers_l(env);
mCamera.clear();
}
@@ -263,7 +283,8 @@
}
}
-void JNICameraContext::postData(int32_t msgType, const sp<IMemory>& dataPtr)
+void JNICameraContext::postData(int32_t msgType, const sp<IMemory>& dataPtr,
+ camera_frame_metadata_t *metadata)
{
// VM pointer will be NULL if object is released
Mutex::Autolock _l(mLock);
@@ -273,8 +294,10 @@
return;
}
+ int32_t dataMsgType = msgType & ~CAMERA_MSG_PREVIEW_METADATA;
+
// return data based on callback type
- switch (msgType) {
+ switch (dataMsgType) {
case CAMERA_MSG_VIDEO_FRAME:
// should never happen
break;
@@ -285,23 +308,63 @@
LOGV("rawCallback");
if (mRawImageCallbackBuffers.isEmpty()) {
env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
- mCameraJObjectWeak, msgType, 0, 0, NULL);
+ mCameraJObjectWeak, dataMsgType, 0, 0, NULL);
} else {
- copyAndPost(env, dataPtr, msgType);
+ copyAndPost(env, dataPtr, dataMsgType);
}
break;
- default:
- LOGV("dataCallback(%d, %p)", msgType, dataPtr.get());
- copyAndPost(env, dataPtr, msgType);
+ // There is no data.
+ case 0:
break;
+
+ default:
+ LOGV("dataCallback(%d, %p)", dataMsgType, dataPtr.get());
+ copyAndPost(env, dataPtr, dataMsgType);
+ break;
+ }
+
+ // post frame metadata to Java
+ if (metadata && (msgType & CAMERA_MSG_PREVIEW_METADATA)) {
+ postMetadata(env, CAMERA_MSG_PREVIEW_METADATA, metadata);
}
}
void JNICameraContext::postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
{
// TODO: plumb up to Java. For now, just drop the timestamp
- postData(msgType, dataPtr);
+ postData(msgType, dataPtr, NULL);
+}
+
+void JNICameraContext::postMetadata(JNIEnv *env, int32_t msgType, camera_frame_metadata_t *metadata)
+{
+ jobjectArray obj = NULL;
+ obj = (jobjectArray) env->NewObjectArray(metadata->number_of_faces,
+ mFaceClass, NULL);
+ if (obj == NULL) {
+ LOGE("Couldn't allocate face metadata array");
+ return;
+ }
+
+ for (int i = 0; i < metadata->number_of_faces; i++) {
+ jobject face = env->NewObject(mFaceClass, fields.face_constructor);
+ env->SetObjectArrayElement(obj, i, face);
+
+ jobject rect = env->NewObject(mRectClass, fields.rect_constructor);
+ env->SetIntField(rect, fields.rect_left, metadata->faces[i].rect[0]);
+ env->SetIntField(rect, fields.rect_top, metadata->faces[i].rect[1]);
+ env->SetIntField(rect, fields.rect_right, metadata->faces[i].rect[2]);
+ env->SetIntField(rect, fields.rect_bottom, metadata->faces[i].rect[3]);
+
+ env->SetObjectField(face, fields.face_rect, rect);
+ env->SetIntField(face, fields.face_score, metadata->faces[i].score);
+
+ env->DeleteLocalRef(face);
+ env->DeleteLocalRef(rect);
+ }
+ env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
+ mCameraJObjectWeak, msgType, 0, 0, obj);
+ env->DeleteLocalRef(obj);
}
void JNICameraContext::setCallbackMode(JNIEnv *env, bool installed, bool manualMode)
@@ -715,7 +778,7 @@
}
static void android_hardware_Camera_startFaceDetection(JNIEnv *env, jobject thiz,
- jint type, jobjectArray face)
+ jint type)
{
LOGV("startFaceDetection");
JNICameraContext* context;
@@ -878,6 +941,19 @@
return -1;
}
+ clazz = env->FindClass("android/graphics/Rect");
+ fields.rect_constructor = env->GetMethodID(clazz, "<init>", "()V");
+ if (fields.rect_constructor == NULL) {
+ LOGE("Can't find android/graphics/Rect.Rect()");
+ return -1;
+ }
+
+ clazz = env->FindClass("android/hardware/Camera$Face");
+ fields.face_constructor = env->GetMethodID(clazz, "<init>", "()V");
+ if (fields.face_constructor == NULL) {
+ LOGE("Can't find android/hardware/Camera$Face.Face()");
+ return -1;
+ }
// Register native functions
return AndroidRuntime::registerNativeMethods(env, "android/hardware/Camera",
diff --git a/core/jni/android_view_VelocityTracker.cpp b/core/jni/android_view_VelocityTracker.cpp
index daa0adc..01a4c09 100644
--- a/core/jni/android_view_VelocityTracker.cpp
+++ b/core/jni/android_view_VelocityTracker.cpp
@@ -69,8 +69,7 @@
mCalculatedIdBits = idBits;
for (uint32_t index = 0; !idBits.isEmpty(); index++) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
+ uint32_t id = idBits.clearFirstMarkedBit();
float vx, vy;
mVelocityTracker.getVelocity(id, &vx, &vy);
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index 830f70e..5118351 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -51,15 +51,17 @@
namespace android {
-typedef void (*iterFunc)(JNIEnv*, void*, ZipFileRO*, ZipEntryRO, const char*);
-
// These match PackageManager.java install codes
typedef enum {
- INSTALL_SUCCEEDED = 0,
+ INSTALL_SUCCEEDED = 1,
INSTALL_FAILED_INVALID_APK = -2,
INSTALL_FAILED_INSUFFICIENT_STORAGE = -4,
+ INSTALL_FAILED_CONTAINER_ERROR = -18,
+ INSTALL_FAILED_INTERNAL_ERROR = -110,
} install_status_t;
+typedef install_status_t (*iterFunc)(JNIEnv*, void*, ZipFileRO*, ZipEntryRO, const char*);
+
// Equivalent to isFilenameSafe
static bool
isFilenameSafe(const char* filename)
@@ -140,17 +142,19 @@
return false;
}
-static void
+static install_status_t
sumFiles(JNIEnv* env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const char* fileName)
{
size_t* total = (size_t*) arg;
size_t uncompLen;
if (!zipFile->getEntryInfo(zipEntry, NULL, &uncompLen, NULL, NULL, NULL, NULL)) {
- return;
+ return INSTALL_FAILED_INVALID_APK;
}
*total += uncompLen;
+
+ return INSTALL_SUCCEEDED;
}
/*
@@ -158,7 +162,7 @@
*
* This function assumes the library and path names passed in are considered safe.
*/
-static void
+static install_status_t
copyFileIfChanged(JNIEnv *env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const char* fileName)
{
jstring* javaNativeLibPath = (jstring*) arg;
@@ -170,7 +174,8 @@
time_t modTime;
if (!zipFile->getEntryInfo(zipEntry, NULL, &uncompLen, NULL, NULL, &when, &crc)) {
- return;
+ LOGD("Couldn't read zip entry info\n");
+ return INSTALL_FAILED_INVALID_APK;
} else {
struct tm t;
ZipFileRO::zipTimeToTimespec(when, &t);
@@ -182,50 +187,50 @@
char localFileName[nativeLibPath.size() + fileNameLen + 2];
if (strlcpy(localFileName, nativeLibPath.c_str(), sizeof(localFileName)) != nativeLibPath.size()) {
- LOGD("Couldn't allocate local file name for library: %s", strerror(errno));
- return;
+ LOGD("Couldn't allocate local file name for library");
+ return INSTALL_FAILED_INTERNAL_ERROR;
}
*(localFileName + nativeLibPath.size()) = '/';
if (strlcpy(localFileName + nativeLibPath.size() + 1, fileName, sizeof(localFileName)
- nativeLibPath.size() - 1) != fileNameLen) {
- LOGD("Couldn't allocate local file name for library: %s", strerror(errno));
- return;
+ LOGD("Couldn't allocate local file name for library");
+ return INSTALL_FAILED_INTERNAL_ERROR;
}
// Only copy out the native file if it's different.
struct stat st;
if (!isFileDifferent(localFileName, uncompLen, modTime, crc, &st)) {
- return;
+ return INSTALL_SUCCEEDED;
}
char localTmpFileName[nativeLibPath.size() + TMP_FILE_PATTERN_LEN + 2];
if (strlcpy(localTmpFileName, nativeLibPath.c_str(), sizeof(localTmpFileName))
!= nativeLibPath.size()) {
- LOGD("Couldn't allocate local file name for library: %s", strerror(errno));
- return;
+ LOGD("Couldn't allocate local file name for library");
+ return INSTALL_FAILED_INTERNAL_ERROR;
}
*(localFileName + nativeLibPath.size()) = '/';
if (strlcpy(localTmpFileName + nativeLibPath.size(), TMP_FILE_PATTERN,
TMP_FILE_PATTERN_LEN - nativeLibPath.size()) != TMP_FILE_PATTERN_LEN) {
- LOGI("Couldn't allocate temporary file name for library: %s", strerror(errno));
- return;
+ LOGI("Couldn't allocate temporary file name for library");
+ return INSTALL_FAILED_INTERNAL_ERROR;
}
int fd = mkstemp(localTmpFileName);
if (fd < 0) {
LOGI("Couldn't open temporary file name: %s: %s\n", localTmpFileName, strerror(errno));
- return;
+ return INSTALL_FAILED_CONTAINER_ERROR;
}
if (!zipFile->uncompressEntry(zipEntry, fd)) {
- LOGI("Failed uncompressing %s to %s: %s", fileName, localTmpFileName, strerror(errno));
+ LOGI("Failed uncompressing %s to %s\n", fileName, localTmpFileName);
close(fd);
unlink(localTmpFileName);
- return;
+ return INSTALL_FAILED_CONTAINER_ERROR;
}
close(fd);
@@ -238,7 +243,7 @@
if (utimes(localTmpFileName, times) < 0) {
LOGI("Couldn't change modification time on %s: %s\n", localTmpFileName, strerror(errno));
unlink(localTmpFileName);
- return;
+ return INSTALL_FAILED_CONTAINER_ERROR;
}
// Set the mode to 755
@@ -246,17 +251,19 @@
if (chmod(localTmpFileName, mode) < 0) {
LOGI("Couldn't change permissions on %s: %s\n", localTmpFileName, strerror(errno));
unlink(localTmpFileName);
- return;
+ return INSTALL_FAILED_CONTAINER_ERROR;
}
// Finally, rename it to the final name.
if (rename(localTmpFileName, localFileName) < 0) {
LOGI("Couldn't rename %s to %s: %s\n", localTmpFileName, localFileName, strerror(errno));
unlink(localTmpFileName);
- return;
+ return INSTALL_FAILED_CONTAINER_ERROR;
}
LOGV("Successfully moved %s to %s\n", localTmpFileName, localFileName);
+
+ return INSTALL_SUCCEEDED;
}
static install_status_t
@@ -301,10 +308,7 @@
}
const char* lastSlash = strrchr(fileName, '/');
- if (lastSlash == NULL) {
- LOG_ASSERT("last slash was null somehow for %s\n", fileName);
- continue;
- }
+ LOG_ASSERT(lastSlash != NULL, "last slash was null somehow for %s\n", fileName);
// Check to make sure the CPU ABI of this file is one we support.
const char* cpuAbiOffset = fileName + APK_LIB_LEN;
@@ -325,12 +329,17 @@
}
// If this is a .so file, check to see if we need to copy it.
- if (!strncmp(fileName + fileNameLen - LIB_SUFFIX_LEN, LIB_SUFFIX, LIB_SUFFIX_LEN)
- && !strncmp(lastSlash, LIB_PREFIX, LIB_PREFIX_LEN)
- && isFilenameSafe(lastSlash + 1)) {
- callFunc(env, callArg, &zipFile, entry, lastSlash + 1);
- } else if (!strncmp(lastSlash + 1, GDBSERVER, GDBSERVER_LEN)) {
- callFunc(env, callArg, &zipFile, entry, lastSlash + 1);
+ if ((!strncmp(fileName + fileNameLen - LIB_SUFFIX_LEN, LIB_SUFFIX, LIB_SUFFIX_LEN)
+ && !strncmp(lastSlash, LIB_PREFIX, LIB_PREFIX_LEN)
+ && isFilenameSafe(lastSlash + 1))
+ || !strncmp(lastSlash + 1, GDBSERVER, GDBSERVER_LEN)) {
+
+ install_status_t ret = callFunc(env, callArg, &zipFile, entry, lastSlash + 1);
+
+ if (ret != INSTALL_SUCCEEDED) {
+ LOGV("Failure for entry %s", lastSlash + 1);
+ return ret;
+ }
}
}
@@ -341,7 +350,7 @@
com_android_internal_content_NativeLibraryHelper_copyNativeBinaries(JNIEnv *env, jclass clazz,
jstring javaFilePath, jstring javaNativeLibPath, jstring javaCpuAbi, jstring javaCpuAbi2)
{
- return iterateOverNativeFiles(env, javaFilePath, javaCpuAbi, javaCpuAbi2,
+ return (jint) iterateOverNativeFiles(env, javaFilePath, javaCpuAbi, javaCpuAbi2,
copyFileIfChanged, &javaNativeLibPath);
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9d0901a..57b686a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -63,7 +63,7 @@
<protected-broadcast android:name="android.app.action.EXIT_CAR_MODE" />
<protected-broadcast android:name="android.app.action.ENTER_DESK_MODE" />
<protected-broadcast android:name="android.app.action.EXIT_DESK_MODE" />
-
+
<protected-broadcast android:name="android.backup.intent.RUN" />
<protected-broadcast android:name="android.backup.intent.CLEAR" />
<protected-broadcast android:name="android.backup.intent.INIT" />
@@ -292,13 +292,12 @@
android:description="@string/permdesc_setAlarm"
android:protectionLevel="normal" />
- <!-- Allows an application to read/write the voicemails owned by its own
- package. -->
- <permission android:name="com.android.voicemail.permission.READ_WRITE_OWN_VOICEMAIL"
+ <!-- Allows an application to add voicemails into the system. -->
+ <permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL"
android:permissionGroup="android.permission-group.PERSONAL_INFO"
android:protectionLevel="dangerous"
- android:label="@string/permlab_readWriteOwnVoicemail"
- android:description="@string/permdesc_readWriteOwnVoicemail" />
+ android:label="@string/permlab_addVoicemail"
+ android:description="@string/permdesc_addVoicemail" />
<!-- ======================================= -->
<!-- Permissions for accessing location info -->
@@ -393,14 +392,6 @@
android:description="@string/permdesc_nfc"
android:label="@string/permlab_nfc" />
- <!-- Allows applications to provide VPN functionality.
- @hide Pending API council approval -->
- <permission android:name="android.permission.VPN"
- android:permissionGroup="android.permission-group.NETWORK"
- android:protectionLevel="dangerous"
- android:description="@string/permdesc_vpn"
- android:label="@string/permlab_vpn" />
-
<!-- Allows an application to use SIP service -->
<permission android:name="android.permission.USE_SIP"
android:permissionGroup="android.permission-group.NETWORK"
@@ -1504,10 +1495,6 @@
android:excludeFromRecents="true">
</activity>
- <service android:name="com.android.internal.service.wallpaper.ImageWallpaper"
- android:permission="android.permission.BIND_WALLPAPER">
- </service>
-
<receiver android:name="com.android.server.BootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_dark.9.png
index 1b34672..3239dd2 100644
--- a/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png
index 1b34672..3239dd2 100644
--- a/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_holo.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_holo.9.png
index 71ae113..6840962 100644
--- a/core/res/res/drawable-hdpi/btn_default_disabled_holo.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_disabled_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png
index 739dff3..45c957b 100644
--- a/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png
index 26976c5..45c957b 100644
--- a/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_focused_holo.9.png b/core/res/res/drawable-hdpi/btn_default_focused_holo.9.png
index 9d787f1..6549253 100644
--- a/core/res/res/drawable-hdpi/btn_default_focused_holo.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png
index 7699c47..ef3ec7a 100644
--- a/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png
index 7699c47..ef3ec7a 100644
--- a/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_normal_holo.9.png b/core/res/res/drawable-hdpi/btn_default_normal_holo.9.png
index 1e9c9d2..f4f657b 100644
--- a/core/res/res/drawable-hdpi/btn_default_normal_holo.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_normal_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png
index 27e7965..ef12e72 100644
--- a/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png
index 1dbabd3..ef12e72 100644
--- a/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_pressed_holo.9.png b/core/res/res/drawable-hdpi/btn_default_pressed_holo.9.png
index 12eec10..ec7fa78 100644
--- a/core/res/res/drawable-hdpi/btn_default_pressed_holo.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png
index 5a94b8d..93a30e3 100644
--- a/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png
index 5a94b8d..93a30e3 100644
--- a/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_small_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_small_disabled_focused_holo_dark.9.png
deleted file mode 100644
index 6781d79..0000000
--- a/core/res/res/drawable-hdpi/btn_default_small_disabled_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_small_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_small_disabled_focused_holo_light.9.png
deleted file mode 100644
index 6781d79..0000000
--- a/core/res/res/drawable-hdpi/btn_default_small_disabled_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_small_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_small_disabled_holo_dark.9.png
deleted file mode 100644
index c8460eb..0000000
--- a/core/res/res/drawable-hdpi/btn_default_small_disabled_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_small_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_small_disabled_holo_light.9.png
deleted file mode 100644
index c8460eb..0000000
--- a/core/res/res/drawable-hdpi/btn_default_small_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_small_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_small_focused_holo_dark.9.png
deleted file mode 100644
index a116400..0000000
--- a/core/res/res/drawable-hdpi/btn_default_small_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_small_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_small_focused_holo_light.9.png
deleted file mode 100644
index 0b5c05bd..0000000
--- a/core/res/res/drawable-hdpi/btn_default_small_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_small_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_small_normal_holo_dark.9.png
deleted file mode 100644
index 6a55b98..0000000
--- a/core/res/res/drawable-hdpi/btn_default_small_normal_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_small_normal_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_small_normal_holo_light.9.png
deleted file mode 100644
index 0371310..0000000
--- a/core/res/res/drawable-hdpi/btn_default_small_normal_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_small_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_small_pressed_holo_dark.9.png
deleted file mode 100644
index 4d05332..0000000
--- a/core/res/res/drawable-hdpi/btn_default_small_pressed_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_small_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_small_pressed_holo_light.9.png
deleted file mode 100644
index 4d05332..0000000
--- a/core/res/res/drawable-hdpi/btn_default_small_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png
new file mode 100644
index 0000000..5e6a9d6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png
new file mode 100644
index 0000000..eb9d740
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png
new file mode 100644
index 0000000..869a330
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png
new file mode 100644
index 0000000..7ec33dd
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
new file mode 100644
index 0000000..72d63da
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
new file mode 100644
index 0000000..fcc5cac
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png
new file mode 100644
index 0000000..baff858
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png
new file mode 100644
index 0000000..5612c51
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
old mode 100755
new mode 100644
index 63a9219..3ecf008
--- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png
old mode 100755
new mode 100644
index d977914..6e1f0dd
--- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png
old mode 100755
new mode 100644
index c04393c..90b35b8
--- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png
old mode 100755
new mode 100644
index 96bd351..6b4b388
--- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png
old mode 100755
new mode 100644
index c30b993..c0ed2c6
--- a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png
old mode 100755
new mode 100644
index 730c113..fa386b8
--- a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png
old mode 100755
new mode 100644
index 17de0eb..9fbd1e99
--- a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png
old mode 100755
new mode 100644
index 7e62cf9..1800eb4
--- a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png
old mode 100755
new mode 100644
index a06f1fc..45d99ee
--- a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png
old mode 100755
new mode 100644
index 21ad0d8..8929825
--- a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
old mode 100755
new mode 100644
index c0f6f74..5fc3fbd
--- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png
old mode 100755
new mode 100644
index c0f6f74..5fc3fbd
--- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png
old mode 100755
new mode 100644
index 44a2f8bb..b0cfa4b
--- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png
old mode 100755
new mode 100644
index 44a2f8bb..b0cfa4b
--- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png
old mode 100755
new mode 100644
index 53eb636f..054c18b
--- a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png
old mode 100755
new mode 100644
index 53eb636f..054c18b
--- a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png
old mode 100755
new mode 100644
index baab86f..a858836
--- a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png
old mode 100755
new mode 100644
index baab86f..a858836
--- a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png
old mode 100755
new mode 100644
index 6a954a6..b5aa5c1
--- a/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_light.9.png
old mode 100755
new mode 100644
index 6a954a6..b5aa5c1
--- a/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/fastscroll_label_left_holo_dark.9.png b/core/res/res/drawable-hdpi/fastscroll_label_left_holo_dark.9.png
index 3eb81a1..0a1bca8 100644
--- a/core/res/res/drawable-hdpi/fastscroll_label_left_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/fastscroll_label_left_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/fastscroll_label_left_holo_light.9.png b/core/res/res/drawable-hdpi/fastscroll_label_left_holo_light.9.png
index cc14a63..fd5b18d 100644
--- a/core/res/res/drawable-hdpi/fastscroll_label_left_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/fastscroll_label_left_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/fastscroll_label_right_holo_dark.9.png b/core/res/res/drawable-hdpi/fastscroll_label_right_holo_dark.9.png
index c59f135..97d61f4 100644
--- a/core/res/res/drawable-hdpi/fastscroll_label_right_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/fastscroll_label_right_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/fastscroll_label_right_holo_light.9.png b/core/res/res/drawable-hdpi/fastscroll_label_right_holo_light.9.png
index 054707d..9afd6ab 100644
--- a/core/res/res/drawable-hdpi/fastscroll_label_right_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/fastscroll_label_right_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/fastscroll_thumb_default_holo.png b/core/res/res/drawable-hdpi/fastscroll_thumb_default_holo.png
index bc960ab..9233636 100644
--- a/core/res/res/drawable-hdpi/fastscroll_thumb_default_holo.png
+++ b/core/res/res/drawable-hdpi/fastscroll_thumb_default_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/fastscroll_thumb_pressed_holo.png b/core/res/res/drawable-hdpi/fastscroll_thumb_pressed_holo.png
index f850e9e..396a8d6 100644
--- a/core/res/res/drawable-hdpi/fastscroll_thumb_pressed_holo.png
+++ b/core/res/res/drawable-hdpi/fastscroll_thumb_pressed_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/fastscroll_track_default_holo_dark.9.png b/core/res/res/drawable-hdpi/fastscroll_track_default_holo_dark.9.png
index 9e10a29..44502db 100644
--- a/core/res/res/drawable-hdpi/fastscroll_track_default_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/fastscroll_track_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/fastscroll_track_default_holo_light.9.png b/core/res/res/drawable-hdpi/fastscroll_track_default_holo_light.9.png
index 9e10a29..44502db 100644
--- a/core/res/res/drawable-hdpi/fastscroll_track_default_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/fastscroll_track_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/fastscroll_track_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/fastscroll_track_pressed_holo_dark.9.png
index be260dd..c5637727 100644
--- a/core/res/res/drawable-hdpi/fastscroll_track_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/fastscroll_track_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/fastscroll_track_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/fastscroll_track_pressed_holo_light.9.png
index be260dd..88f60b3 100644
--- a/core/res/res/drawable-hdpi/fastscroll_track_pressed_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/fastscroll_track_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_audio_ring_notif.png b/core/res/res/drawable-hdpi/ic_audio_ring_notif.png
new file mode 100644
index 0000000..3938778
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_audio_ring_notif.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_audio_ring_notif_mute.png b/core/res/res/drawable-hdpi/ic_audio_ring_notif_mute.png
new file mode 100644
index 0000000..499c0a3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_audio_ring_notif_mute.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_bullet_key_permission.png b/core/res/res/drawable-hdpi/ic_bullet_key_permission.png
index b6b840a..a7eaec5 100644
--- a/core/res/res/drawable-hdpi/ic_bullet_key_permission.png
+++ b/core/res/res/drawable-hdpi/ic_bullet_key_permission.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.png
new file mode 100644
index 0000000..d510e1d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.png
new file mode 100644
index 0000000..36d766d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_silent_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_silent_activated.png
index fce4980..d1938b9 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_silent_activated.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_silent_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_soundon_activated.png
index 73f01c9..f6ccbd2 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_activated.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_soundon_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_text_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_text_activated.png
index d01bdb2..10b3268 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_text_activated.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_text_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png
index d333946..d1f3015 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/progress_primary_holo_dark.9.png b/core/res/res/drawable-hdpi/progress_primary_holo_dark.9.png
index f134a59..e2c63b0 100644
--- a/core/res/res/drawable-hdpi/progress_primary_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/progress_primary_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/progress_primary_holo_light.9.png b/core/res/res/drawable-hdpi/progress_primary_holo_light.9.png
index f134a59..e2c63b0 100644
--- a/core/res/res/drawable-hdpi/progress_primary_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/progress_primary_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/progress_secondary_holo_dark.9.png b/core/res/res/drawable-hdpi/progress_secondary_holo_dark.9.png
index 22d608a..4b204e7 100644
--- a/core/res/res/drawable-hdpi/progress_secondary_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/progress_secondary_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/progress_secondary_holo_light.9.png b/core/res/res/drawable-hdpi/progress_secondary_holo_light.9.png
index 22d608a..4b204e7 100644
--- a/core/res/res/drawable-hdpi/progress_secondary_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/progress_secondary_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrollbar_handle_holo_dark.9.png b/core/res/res/drawable-hdpi/scrollbar_handle_holo_dark.9.png
index 575edee..7c82955 100644
--- a/core/res/res/drawable-hdpi/scrollbar_handle_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/scrollbar_handle_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrollbar_handle_holo_light.9.png b/core/res/res/drawable-hdpi/scrollbar_handle_holo_light.9.png
index 575edee..7c82955 100644
--- a/core/res/res/drawable-hdpi/scrollbar_handle_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/scrollbar_handle_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_disabled_holo.png b/core/res/res/drawable-hdpi/scrubber_control_disabled_holo.png
index d428e5a..822da81 100644
--- a/core/res/res/drawable-hdpi/scrubber_control_disabled_holo.png
+++ b/core/res/res/drawable-hdpi/scrubber_control_disabled_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_holo.png b/core/res/res/drawable-hdpi/scrubber_control_holo.png
index a5fb73c..9957851 100644
--- a/core/res/res/drawable-hdpi/scrubber_control_holo.png
+++ b/core/res/res/drawable-hdpi/scrubber_control_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_primary_holo.9.png b/core/res/res/drawable-hdpi/scrubber_primary_holo.9.png
index 3bc78a8..0fdd530 100644
--- a/core/res/res/drawable-hdpi/scrubber_primary_holo.9.png
+++ b/core/res/res/drawable-hdpi/scrubber_primary_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_secondary_holo.9.png b/core/res/res/drawable-hdpi/scrubber_secondary_holo.9.png
index 8eadf00..a7eaf66 100644
--- a/core/res/res/drawable-hdpi/scrubber_secondary_holo.9.png
+++ b/core/res/res/drawable-hdpi/scrubber_secondary_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_16_inner_holo.png b/core/res/res/drawable-hdpi/spinner_16_inner_holo.png
index a2a6678..8c93779 100644
--- a/core/res/res/drawable-hdpi/spinner_16_inner_holo.png
+++ b/core/res/res/drawable-hdpi/spinner_16_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_16_outer_holo.png b/core/res/res/drawable-hdpi/spinner_16_outer_holo.png
index 733e852..d272f93 100644
--- a/core/res/res/drawable-hdpi/spinner_16_outer_holo.png
+++ b/core/res/res/drawable-hdpi/spinner_16_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_20_inner_holo.png b/core/res/res/drawable-hdpi/spinner_20_inner_holo.png
index e81e002..3c371b2d 100644
--- a/core/res/res/drawable-hdpi/spinner_20_inner_holo.png
+++ b/core/res/res/drawable-hdpi/spinner_20_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_20_outer_holo.png b/core/res/res/drawable-hdpi/spinner_20_outer_holo.png
index 1da2f90..2820b5f 100644
--- a/core/res/res/drawable-hdpi/spinner_20_outer_holo.png
+++ b/core/res/res/drawable-hdpi/spinner_20_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_48_inner_holo.png b/core/res/res/drawable-hdpi/spinner_48_inner_holo.png
index 8bbe6a0..a992251 100644
--- a/core/res/res/drawable-hdpi/spinner_48_inner_holo.png
+++ b/core/res/res/drawable-hdpi/spinner_48_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_48_outer_holo.png b/core/res/res/drawable-hdpi/spinner_48_outer_holo.png
index d023d10..27452b1 100644
--- a/core/res/res/drawable-hdpi/spinner_48_outer_holo.png
+++ b/core/res/res/drawable-hdpi/spinner_48_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_76_inner_holo.png b/core/res/res/drawable-hdpi/spinner_76_inner_holo.png
index fa6cb6f..3d426e0 100644
--- a/core/res/res/drawable-hdpi/spinner_76_inner_holo.png
+++ b/core/res/res/drawable-hdpi/spinner_76_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_76_outer_holo.png b/core/res/res/drawable-hdpi/spinner_76_outer_holo.png
index 00d577f..92f77a3 100644
--- a/core/res/res/drawable-hdpi/spinner_76_outer_holo.png
+++ b/core/res/res/drawable-hdpi/spinner_76_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_activated_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_activated_holo_dark.9.png
new file mode 100644
index 0000000..d471c30
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_activated_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_activated_holo_light.9.png
new file mode 100644
index 0000000..d471c30
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png
new file mode 100644
index 0000000..001cfbb
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png
new file mode 100644
index 0000000..5e278c8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png
new file mode 100644
index 0000000..cf2e149
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png
new file mode 100644
index 0000000..63f212d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png
new file mode 100644
index 0000000..85663e6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png
new file mode 100644
index 0000000..85663e6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png
new file mode 100644
index 0000000..afddbe8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png
new file mode 100644
index 0000000..0ad6476
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_active_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_cab_active_holo_dark.9.png
deleted file mode 100644
index 7cad0c9..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_active_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_active_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_cab_active_holo_light.9.png
deleted file mode 100644
index 7cad0c9..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_active_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_default_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_cab_default_holo_dark.9.png
deleted file mode 100644
index b3f3cf7..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_default_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_default_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_cab_default_holo_light.9.png
deleted file mode 100644
index af46631..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_cab_disabled_holo_dark.9.png
deleted file mode 100644
index e672c95..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_disabled_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_cab_disabled_holo_light.9.png
deleted file mode 100644
index f499540..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_cab_focused_holo_dark.9.png
deleted file mode 100644
index f4900a5..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_focused_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_cab_focused_holo_light.9.png
deleted file mode 100644
index 1286542..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_cab_pressed_holo_dark.9.png
deleted file mode 100644
index 8b6f9dd..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_pressed_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_cab_pressed_holo_light.9.png
deleted file mode 100644
index 4f0c476..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_bullet_key_permission.png b/core/res/res/drawable-ldpi/ic_bullet_key_permission.png
index 016c0f0..4aff20c 100644
--- a/core/res/res/drawable-ldpi/ic_bullet_key_permission.png
+++ b/core/res/res/drawable-ldpi/ic_bullet_key_permission.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png
index 918f972..e5197e6 100644
--- a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png
index 918f972..e5197e6 100644
--- a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_holo.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_holo.9.png
index 1ae6cf2..9a24b9c 100644
--- a/core/res/res/drawable-mdpi/btn_default_disabled_holo.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_disabled_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png
index 0514a7c..c832855 100644
--- a/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png
index 8cc4daf..c832855 100644
--- a/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_focused_holo.9.png b/core/res/res/drawable-mdpi/btn_default_focused_holo.9.png
index 6449650..8838414 100644
--- a/core/res/res/drawable-mdpi/btn_default_focused_holo.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png
index 7f44eae2..e0a1e0d 100644
--- a/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png
index 7f44eae2..e0a1e0d 100644
--- a/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_normal_holo.9.png b/core/res/res/drawable-mdpi/btn_default_normal_holo.9.png
index 3e9e6c3..e4864c9 100644
--- a/core/res/res/drawable-mdpi/btn_default_normal_holo.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_normal_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png
index 9df36a2..3d9310a 100644
--- a/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png
index 7abdfde..3d9310a 100644
--- a/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_pressed_holo.9.png b/core/res/res/drawable-mdpi/btn_default_pressed_holo.9.png
index df4927f..18ec722 100644
--- a/core/res/res/drawable-mdpi/btn_default_pressed_holo.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png
index cb70e35..1e3314e 100644
--- a/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png
index cb70e35..1e3314e 100644
--- a/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_small_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_small_disabled_focused_holo_dark.9.png
deleted file mode 100644
index be14b35..0000000
--- a/core/res/res/drawable-mdpi/btn_default_small_disabled_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_small_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_small_disabled_focused_holo_light.9.png
deleted file mode 100644
index be14b35..0000000
--- a/core/res/res/drawable-mdpi/btn_default_small_disabled_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_small_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_small_disabled_holo_dark.9.png
deleted file mode 100644
index dd12fcb..0000000
--- a/core/res/res/drawable-mdpi/btn_default_small_disabled_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_small_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_small_disabled_holo_light.9.png
deleted file mode 100644
index dd12fcb..0000000
--- a/core/res/res/drawable-mdpi/btn_default_small_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_small_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_small_focused_holo_dark.9.png
deleted file mode 100644
index bd9975c..0000000
--- a/core/res/res/drawable-mdpi/btn_default_small_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_small_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_small_focused_holo_light.9.png
deleted file mode 100644
index 703e394..0000000
--- a/core/res/res/drawable-mdpi/btn_default_small_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_small_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_small_normal_holo_dark.9.png
deleted file mode 100644
index b77faadc..0000000
--- a/core/res/res/drawable-mdpi/btn_default_small_normal_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_small_normal_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_small_normal_holo_light.9.png
deleted file mode 100644
index ead3f5e..0000000
--- a/core/res/res/drawable-mdpi/btn_default_small_normal_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_small_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_small_pressed_holo_dark.9.png
deleted file mode 100644
index d460d0a..0000000
--- a/core/res/res/drawable-mdpi/btn_default_small_pressed_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_small_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_small_pressed_holo_light.9.png
deleted file mode 100644
index d460d0a..0000000
--- a/core/res/res/drawable-mdpi/btn_default_small_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png
new file mode 100644
index 0000000..d449d76
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
new file mode 100644
index 0000000..80fe863
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
new file mode 100644
index 0000000..196d6d9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
new file mode 100644
index 0000000..8f340d3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
new file mode 100644
index 0000000..b34b957
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
new file mode 100644
index 0000000..02f4b3d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png
new file mode 100644
index 0000000..976083f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png b/core/res/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png
new file mode 100644
index 0000000..c39dd4a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off.9.png b/core/res/res/drawable-mdpi/btn_toggle_off.9.png
index 26ee1c2..38e810c 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_off.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
old mode 100755
new mode 100644
index 1964085..5f2017d
--- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png
old mode 100755
new mode 100644
index d86a9e6..eab31e8
--- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png
old mode 100755
new mode 100644
index f3f1ab2..29f9e23
--- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png
old mode 100755
new mode 100644
index d157fed..2d3574d
--- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png
old mode 100755
new mode 100644
index f99d946..deea02d
--- a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png
old mode 100755
new mode 100644
index a313744..d480b2e
--- a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png
old mode 100755
new mode 100644
index 00a589f..7f9d813
--- a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png
old mode 100755
new mode 100644
index e16e470..848621a
--- a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png
old mode 100755
new mode 100644
index 6f7dd45..2a94003
--- a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png
old mode 100755
new mode 100644
index 490c83d..75983d8
--- a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on.9.png b/core/res/res/drawable-mdpi/btn_toggle_on.9.png
index 53e95af..ef39dec 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_on.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
old mode 100755
new mode 100644
index 45dc08f..909586a
--- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png
old mode 100755
new mode 100644
index 45dc08f..909586a
--- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png
old mode 100755
new mode 100644
index 11dc01d..d64e60a
--- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png
old mode 100755
new mode 100644
index 11dc01d..d64e60a
--- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png
old mode 100755
new mode 100644
index 2c95ebd..3b64aa1
--- a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png
old mode 100755
new mode 100644
index 2c95ebd..3b64aa1
--- a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png
old mode 100755
new mode 100644
index 7c410c0..6039850
--- a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png
old mode 100755
new mode 100644
index 7c410c0..6039850
--- a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png
old mode 100755
new mode 100644
index afb31e1..21b655b
--- a/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_light.9.png
old mode 100755
new mode 100644
index afb31e1..21b655b
--- a/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/fastscroll_label_left_holo_dark.9.png b/core/res/res/drawable-mdpi/fastscroll_label_left_holo_dark.9.png
index 0dce616..b3fd908 100644
--- a/core/res/res/drawable-mdpi/fastscroll_label_left_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/fastscroll_label_left_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/fastscroll_label_left_holo_light.9.png b/core/res/res/drawable-mdpi/fastscroll_label_left_holo_light.9.png
index e1028cc..a64d4d1 100644
--- a/core/res/res/drawable-mdpi/fastscroll_label_left_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/fastscroll_label_left_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/fastscroll_label_right_holo_dark.9.png b/core/res/res/drawable-mdpi/fastscroll_label_right_holo_dark.9.png
index b6b68ea..6469fca 100644
--- a/core/res/res/drawable-mdpi/fastscroll_label_right_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/fastscroll_label_right_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/fastscroll_label_right_holo_light.9.png b/core/res/res/drawable-mdpi/fastscroll_label_right_holo_light.9.png
index 5087013..fca2e25 100644
--- a/core/res/res/drawable-mdpi/fastscroll_label_right_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/fastscroll_label_right_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/fastscroll_thumb_default_holo.png b/core/res/res/drawable-mdpi/fastscroll_thumb_default_holo.png
index bfb55bd..fa23ea4 100644
--- a/core/res/res/drawable-mdpi/fastscroll_thumb_default_holo.png
+++ b/core/res/res/drawable-mdpi/fastscroll_thumb_default_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/fastscroll_thumb_pressed_holo.png b/core/res/res/drawable-mdpi/fastscroll_thumb_pressed_holo.png
index 89d9b01..d8233d9 100644
--- a/core/res/res/drawable-mdpi/fastscroll_thumb_pressed_holo.png
+++ b/core/res/res/drawable-mdpi/fastscroll_thumb_pressed_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/fastscroll_track_default_holo_dark.9.png b/core/res/res/drawable-mdpi/fastscroll_track_default_holo_dark.9.png
index cf8c4bb..8796e21 100644
--- a/core/res/res/drawable-mdpi/fastscroll_track_default_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/fastscroll_track_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/fastscroll_track_default_holo_light.9.png b/core/res/res/drawable-mdpi/fastscroll_track_default_holo_light.9.png
index cf8c4bb..8796e21 100644
--- a/core/res/res/drawable-mdpi/fastscroll_track_default_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/fastscroll_track_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/fastscroll_track_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/fastscroll_track_pressed_holo_dark.9.png
index fef2168..e74acea 100644
--- a/core/res/res/drawable-mdpi/fastscroll_track_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/fastscroll_track_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/fastscroll_track_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/fastscroll_track_pressed_holo_light.9.png
index fef2168..62d80a0 100644
--- a/core/res/res/drawable-mdpi/fastscroll_track_pressed_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/fastscroll_track_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_ring_notif.png b/core/res/res/drawable-mdpi/ic_audio_ring_notif.png
new file mode 100644
index 0000000..856193b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_audio_ring_notif.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_ring_notif_mute.png b/core/res/res/drawable-mdpi/ic_audio_ring_notif_mute.png
new file mode 100644
index 0000000..d5d1360
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_audio_ring_notif_mute.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_bullet_key_permission.png b/core/res/res/drawable-mdpi/ic_bullet_key_permission.png
index 68ad039..47913f6 100644
--- a/core/res/res/drawable-mdpi/ic_bullet_key_permission.png
+++ b/core/res/res/drawable-mdpi/ic_bullet_key_permission.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.png
new file mode 100644
index 0000000..1437798
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.png
new file mode 100644
index 0000000..b718258
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_silent_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_silent_activated.png
index 3b2f3fc..2bc3f52 100644
--- a/core/res/res/drawable-mdpi/ic_lockscreen_silent_activated.png
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_silent_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_soundon_activated.png
index 03f524d..637eec6 100644
--- a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_activated.png
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_soundon_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_text_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_text_activated.png
index dbfc5ba..878ff1f 100644
--- a/core/res/res/drawable-mdpi/ic_lockscreen_text_activated.png
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_text_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_unlock_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_unlock_activated.png
index df47993..0d3f756 100644
--- a/core/res/res/drawable-mdpi/ic_lockscreen_unlock_activated.png
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_unlock_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progress_primary_holo_dark.9.png b/core/res/res/drawable-mdpi/progress_primary_holo_dark.9.png
index bac0a23..4bf3cb9 100644
--- a/core/res/res/drawable-mdpi/progress_primary_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/progress_primary_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progress_primary_holo_light.9.png b/core/res/res/drawable-mdpi/progress_primary_holo_light.9.png
index bac0a23..4bf3cb9 100644
--- a/core/res/res/drawable-mdpi/progress_primary_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/progress_primary_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progress_secondary_holo_dark.9.png b/core/res/res/drawable-mdpi/progress_secondary_holo_dark.9.png
index 8be8656..b13c878 100644
--- a/core/res/res/drawable-mdpi/progress_secondary_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/progress_secondary_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progress_secondary_holo_light.9.png b/core/res/res/drawable-mdpi/progress_secondary_holo_light.9.png
index 8be8656..b13c878 100644
--- a/core/res/res/drawable-mdpi/progress_secondary_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/progress_secondary_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrollbar_handle_holo_dark.9.png b/core/res/res/drawable-mdpi/scrollbar_handle_holo_dark.9.png
index e039c4b..ca0ec0a 100644
--- a/core/res/res/drawable-mdpi/scrollbar_handle_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/scrollbar_handle_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrollbar_handle_holo_light.9.png b/core/res/res/drawable-mdpi/scrollbar_handle_holo_light.9.png
index e039c4b..ca0ec0a 100644
--- a/core/res/res/drawable-mdpi/scrollbar_handle_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/scrollbar_handle_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_primary_holo.9.png b/core/res/res/drawable-mdpi/scrubber_primary_holo.9.png
index ac63e7d..c994519 100644
--- a/core/res/res/drawable-mdpi/scrubber_primary_holo.9.png
+++ b/core/res/res/drawable-mdpi/scrubber_primary_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_secondary_holo.9.png b/core/res/res/drawable-mdpi/scrubber_secondary_holo.9.png
index 9590bdc..5e21da4 100644
--- a/core/res/res/drawable-mdpi/scrubber_secondary_holo.9.png
+++ b/core/res/res/drawable-mdpi/scrubber_secondary_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_16_inner_holo.png b/core/res/res/drawable-mdpi/spinner_16_inner_holo.png
index 537ab8c..392e1f8 100644
--- a/core/res/res/drawable-mdpi/spinner_16_inner_holo.png
+++ b/core/res/res/drawable-mdpi/spinner_16_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_16_outer_holo.png b/core/res/res/drawable-mdpi/spinner_16_outer_holo.png
index cee54b7..d862a25 100644
--- a/core/res/res/drawable-mdpi/spinner_16_outer_holo.png
+++ b/core/res/res/drawable-mdpi/spinner_16_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_20_inner_holo.png b/core/res/res/drawable-mdpi/spinner_20_inner_holo.png
index 67fb438..f5e7f73 100644
--- a/core/res/res/drawable-mdpi/spinner_20_inner_holo.png
+++ b/core/res/res/drawable-mdpi/spinner_20_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_20_outer_holo.png b/core/res/res/drawable-mdpi/spinner_20_outer_holo.png
index 25beedd..b7ecfff 100644
--- a/core/res/res/drawable-mdpi/spinner_20_outer_holo.png
+++ b/core/res/res/drawable-mdpi/spinner_20_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_48_inner_holo.png b/core/res/res/drawable-mdpi/spinner_48_inner_holo.png
index ed446d6..5231a5b 100644
--- a/core/res/res/drawable-mdpi/spinner_48_inner_holo.png
+++ b/core/res/res/drawable-mdpi/spinner_48_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_48_outer_holo.png b/core/res/res/drawable-mdpi/spinner_48_outer_holo.png
index 08b2dcd..e1e5b52 100644
--- a/core/res/res/drawable-mdpi/spinner_48_outer_holo.png
+++ b/core/res/res/drawable-mdpi/spinner_48_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_76_inner_holo.png b/core/res/res/drawable-mdpi/spinner_76_inner_holo.png
index 2d5e5a1..982f037 100644
--- a/core/res/res/drawable-mdpi/spinner_76_inner_holo.png
+++ b/core/res/res/drawable-mdpi/spinner_76_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_76_outer_holo.png b/core/res/res/drawable-mdpi/spinner_76_outer_holo.png
index 2edad73..01b6ab38 100644
--- a/core/res/res/drawable-mdpi/spinner_76_outer_holo.png
+++ b/core/res/res/drawable-mdpi/spinner_76_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_activated_holo_dark.9.png
new file mode 100644
index 0000000..34c9188
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_activated_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_activated_holo_light.9.png
new file mode 100644
index 0000000..34c9188
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png
new file mode 100644
index 0000000..b92abaf
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png
new file mode 100644
index 0000000..91f0e87
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png
new file mode 100644
index 0000000..dab7eda0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png
new file mode 100644
index 0000000..bf14605
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png
new file mode 100644
index 0000000..c733260
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png
new file mode 100644
index 0000000..c733260
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png
new file mode 100644
index 0000000..6d290a6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png
new file mode 100644
index 0000000..6dae484
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_active_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_cab_active_holo_dark.9.png
deleted file mode 100644
index 617c379..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_active_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_active_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_cab_active_holo_light.9.png
deleted file mode 100644
index 617c379..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_active_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_default_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_cab_default_holo_dark.9.png
deleted file mode 100644
index d76b123..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_default_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_default_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_cab_default_holo_light.9.png
deleted file mode 100644
index ee91044..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_cab_disabled_holo_dark.9.png
deleted file mode 100644
index fc9c109..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_disabled_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_cab_disabled_holo_light.9.png
deleted file mode 100644
index 7fc7cc1..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_cab_focused_holo_dark.9.png
deleted file mode 100644
index 0f49fe9..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_focused_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_cab_focused_holo_light.9.png
deleted file mode 100644
index 032d5d3..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_cab_pressed_holo_dark.9.png
deleted file mode 100644
index df0a935..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_pressed_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_cab_pressed_holo_light.9.png
deleted file mode 100644
index b43177b..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_dark.9.png
index eb7ce5e..8a30fab 100644
--- a/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_light.9.png
index eb7ce5e..8a30fab 100644
--- a/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_disabled_holo.9.png b/core/res/res/drawable-xhdpi/btn_default_disabled_holo.9.png
index 4e4d3d4..bb4e7f6 100644
--- a/core/res/res/drawable-xhdpi/btn_default_disabled_holo.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_disabled_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_default_disabled_holo_dark.9.png
index ee291b6..842ea9c 100644
--- a/core/res/res/drawable-xhdpi/btn_default_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_default_disabled_holo_light.9.png
index 83e5011..842ea9c 100644
--- a/core/res/res/drawable-xhdpi/btn_default_disabled_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_focused_holo.9.png b/core/res/res/drawable-xhdpi/btn_default_focused_holo.9.png
index 67f007a..5aa02c8 100644
--- a/core/res/res/drawable-xhdpi/btn_default_focused_holo.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_default_focused_holo_dark.9.png
index 4764d1b..025fc00 100644
--- a/core/res/res/drawable-xhdpi/btn_default_focused_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_default_focused_holo_light.9.png
index 4764d1b..025fc00 100644
--- a/core/res/res/drawable-xhdpi/btn_default_focused_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_normal_holo.9.png b/core/res/res/drawable-xhdpi/btn_default_normal_holo.9.png
index b949121..02360bd 100644
--- a/core/res/res/drawable-xhdpi/btn_default_normal_holo.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_normal_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_normal_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_default_normal_holo_dark.9.png
index 6a35514..5c4a2d1 100644
--- a/core/res/res/drawable-xhdpi/btn_default_normal_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_normal_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_default_normal_holo_light.9.png
index 9068d75..5c4a2d1 100644
--- a/core/res/res/drawable-xhdpi/btn_default_normal_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_pressed_holo.9.png b/core/res/res/drawable-xhdpi/btn_default_pressed_holo.9.png
index daac2e1..1833ffe 100644
--- a/core/res/res/drawable-xhdpi/btn_default_pressed_holo.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_default_pressed_holo_dark.9.png
index 94f1a5a..7fc5980 100644
--- a/core/res/res/drawable-xhdpi/btn_default_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_default_pressed_holo_light.9.png
index 94f1a5a..7fc5980 100644
--- a/core/res/res/drawable-xhdpi/btn_default_pressed_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png b/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png
new file mode 100644
index 0000000..d2cd029
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
new file mode 100644
index 0000000..0f709eb
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
new file mode 100644
index 0000000..2f4de8e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png b/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png
new file mode 100644
index 0000000..3871689e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
new file mode 100644
index 0000000..836ea6e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
new file mode 100644
index 0000000..279db1f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png b/core/res/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png
new file mode 100644
index 0000000..b26f1d2
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png b/core/res/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png
new file mode 100644
index 0000000..c23a4b2
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off.9.png
new file mode 100644
index 0000000..1406188
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..9d9c6f2
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_light.9.png
new file mode 100644
index 0000000..7d9bfd1
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_dark.9.png
new file mode 100644
index 0000000..0cddd2d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_light.9.png
new file mode 100644
index 0000000..1109fe1
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_dark.9.png
new file mode 100644
index 0000000..ec33f17
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_light.9.png
new file mode 100644
index 0000000..0b562cc
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_dark.9.png
new file mode 100644
index 0000000..93f565f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_light.9.png
new file mode 100644
index 0000000..aee803d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_dark.9.png
new file mode 100644
index 0000000..2f56666
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_light.9.png
new file mode 100644
index 0000000..d636569
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on.9.png
new file mode 100644
index 0000000..90f1e7b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..9ec3fe0c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_light.9.png
new file mode 100644
index 0000000..9ec3fe0c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_dark.9.png
new file mode 100644
index 0000000..5b8bf7b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_light.9.png
new file mode 100644
index 0000000..5b8bf7b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_dark.9.png
new file mode 100644
index 0000000..5c3318b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_light.9.png
new file mode 100644
index 0000000..5c3318b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_dark.9.png
new file mode 100644
index 0000000..ef7310a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_light.9.png
new file mode 100644
index 0000000..ef7310a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_dark.9.png
new file mode 100644
index 0000000..c55389e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_light.9.png
new file mode 100644
index 0000000..c55389e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/fastscroll_label_left_holo_dark.9.png b/core/res/res/drawable-xhdpi/fastscroll_label_left_holo_dark.9.png
new file mode 100644
index 0000000..dfc5e6b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/fastscroll_label_left_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/fastscroll_label_left_holo_light.9.png b/core/res/res/drawable-xhdpi/fastscroll_label_left_holo_light.9.png
new file mode 100644
index 0000000..eab0cb9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/fastscroll_label_left_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/fastscroll_label_right_holo_dark.9.png b/core/res/res/drawable-xhdpi/fastscroll_label_right_holo_dark.9.png
new file mode 100644
index 0000000..e3e0cde
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/fastscroll_label_right_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/fastscroll_label_right_holo_light.9.png b/core/res/res/drawable-xhdpi/fastscroll_label_right_holo_light.9.png
new file mode 100644
index 0000000..b2bd5ca
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/fastscroll_label_right_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/fastscroll_thumb_default_holo.png b/core/res/res/drawable-xhdpi/fastscroll_thumb_default_holo.png
new file mode 100644
index 0000000..cc3fe43
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/fastscroll_thumb_default_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/fastscroll_thumb_pressed_holo.png b/core/res/res/drawable-xhdpi/fastscroll_thumb_pressed_holo.png
new file mode 100644
index 0000000..ba3f566
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/fastscroll_thumb_pressed_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/fastscroll_track_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/fastscroll_track_default_holo_dark.9.png
new file mode 100644
index 0000000..431336a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/fastscroll_track_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/fastscroll_track_default_holo_light.9.png b/core/res/res/drawable-xhdpi/fastscroll_track_default_holo_light.9.png
new file mode 100644
index 0000000..431336a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/fastscroll_track_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/fastscroll_track_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/fastscroll_track_pressed_holo_dark.9.png
new file mode 100644
index 0000000..9301f5e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/fastscroll_track_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/fastscroll_track_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/fastscroll_track_pressed_holo_light.9.png
new file mode 100644
index 0000000..d22724a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/fastscroll_track_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.png
new file mode 100644
index 0000000..d545883
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.png
new file mode 100644
index 0000000..8de7b84
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_silent_activated.png
index fd81211..2900045 100644
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_activated.png
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_silent_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png
index 9edc70b..da2adc2 100644
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_text_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_text_activated.png
index 29c4572..ddebe3e 100644
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_text_activated.png
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_text_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png
index fa0be96..73d7af3 100644
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progress_primary_holo_dark.9.png b/core/res/res/drawable-xhdpi/progress_primary_holo_dark.9.png
new file mode 100644
index 0000000..dc8711f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/progress_primary_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progress_primary_holo_light.9.png b/core/res/res/drawable-xhdpi/progress_primary_holo_light.9.png
new file mode 100644
index 0000000..dc8711f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/progress_primary_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progress_secondary_holo_dark.9.png b/core/res/res/drawable-xhdpi/progress_secondary_holo_dark.9.png
new file mode 100644
index 0000000..39a168f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/progress_secondary_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progress_secondary_holo_light.9.png b/core/res/res/drawable-xhdpi/progress_secondary_holo_light.9.png
new file mode 100644
index 0000000..39a168f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/progress_secondary_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrollbar_handle_holo_dark.9.png b/core/res/res/drawable-xhdpi/scrollbar_handle_holo_dark.9.png
new file mode 100644
index 0000000..7a31d9d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/scrollbar_handle_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrollbar_handle_holo_light.9.png b/core/res/res/drawable-xhdpi/scrollbar_handle_holo_light.9.png
new file mode 100644
index 0000000..7a31d9d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/scrollbar_handle_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_disabled_holo.png b/core/res/res/drawable-xhdpi/scrubber_control_disabled_holo.png
new file mode 100644
index 0000000..c3b9bb4
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/scrubber_control_disabled_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_holo.png b/core/res/res/drawable-xhdpi/scrubber_control_holo.png
new file mode 100644
index 0000000..f72e48c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/scrubber_control_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_primary_holo.9.png b/core/res/res/drawable-xhdpi/scrubber_primary_holo.9.png
new file mode 100644
index 0000000..328bd1e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/scrubber_primary_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_secondary_holo.9.png b/core/res/res/drawable-xhdpi/scrubber_secondary_holo.9.png
new file mode 100644
index 0000000..dcc4221
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/scrubber_secondary_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_track_holo_dark.9.png b/core/res/res/drawable-xhdpi/scrubber_track_holo_dark.9.png
new file mode 100644
index 0000000..80e4400
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/scrubber_track_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_track_holo_light.9.png b/core/res/res/drawable-xhdpi/scrubber_track_holo_light.9.png
new file mode 100644
index 0000000..af96c43
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/scrubber_track_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_16_inner_holo.png b/core/res/res/drawable-xhdpi/spinner_16_inner_holo.png
index f868ff1..f5e9164 100644
--- a/core/res/res/drawable-xhdpi/spinner_16_inner_holo.png
+++ b/core/res/res/drawable-xhdpi/spinner_16_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_16_outer_holo.png b/core/res/res/drawable-xhdpi/spinner_16_outer_holo.png
index abd2d57..6f977a2 100644
--- a/core/res/res/drawable-xhdpi/spinner_16_outer_holo.png
+++ b/core/res/res/drawable-xhdpi/spinner_16_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_20_inner_holo.png b/core/res/res/drawable-xhdpi/spinner_20_inner_holo.png
index d2691d3..16c8430 100644
--- a/core/res/res/drawable-xhdpi/spinner_20_inner_holo.png
+++ b/core/res/res/drawable-xhdpi/spinner_20_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_20_outer_holo.png b/core/res/res/drawable-xhdpi/spinner_20_outer_holo.png
index a5c87d1..9593616 100644
--- a/core/res/res/drawable-xhdpi/spinner_20_outer_holo.png
+++ b/core/res/res/drawable-xhdpi/spinner_20_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_48_inner_holo.png b/core/res/res/drawable-xhdpi/spinner_48_inner_holo.png
index 24176bf..cebf1d8 100644
--- a/core/res/res/drawable-xhdpi/spinner_48_inner_holo.png
+++ b/core/res/res/drawable-xhdpi/spinner_48_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_48_outer_holo.png b/core/res/res/drawable-xhdpi/spinner_48_outer_holo.png
index 53b34ef..5a9e001 100644
--- a/core/res/res/drawable-xhdpi/spinner_48_outer_holo.png
+++ b/core/res/res/drawable-xhdpi/spinner_48_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_76_inner_holo.png b/core/res/res/drawable-xhdpi/spinner_76_inner_holo.png
index fa267b4..c68cc37 100644
--- a/core/res/res/drawable-xhdpi/spinner_76_inner_holo.png
+++ b/core/res/res/drawable-xhdpi/spinner_76_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_76_outer_holo.png b/core/res/res/drawable-xhdpi/spinner_76_outer_holo.png
index 2c1f879..611dc5a 100644
--- a/core/res/res/drawable-xhdpi/spinner_76_outer_holo.png
+++ b/core/res/res/drawable-xhdpi/spinner_76_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_activated_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_activated_holo_dark.9.png
new file mode 100644
index 0000000..85d8540
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_activated_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_activated_holo_light.9.png
new file mode 100644
index 0000000..85d8540
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png
new file mode 100644
index 0000000..31b39d7
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png
new file mode 100644
index 0000000..1527c5c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png
new file mode 100644
index 0000000..e4cef9a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png
new file mode 100644
index 0000000..1c37ece
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png
new file mode 100644
index 0000000..6aae46b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png
new file mode 100644
index 0000000..6aae46b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png
new file mode 100644
index 0000000..db2e034
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png
new file mode 100644
index 0000000..77bb433
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_keyboard_key_ics.xml b/core/res/res/drawable/btn_keyboard_key_ics.xml
new file mode 100644
index 0000000..7335cc2
--- /dev/null
+++ b/core/res/res/drawable/btn_keyboard_key_ics.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <!-- Functional keys. -->
+
+ <item android:state_single="true" android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_dark_pressed_holo" />
+ <item android:state_single="true"
+ android:drawable="@drawable/btn_keyboard_key_dark_normal_holo" />
+
+ <!-- Toggle keys. Use checkable/checked state. -->
+
+ <item android:state_checkable="true" android:state_checked="true" android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_dark_pressed_on_holo" />
+ <item android:state_checkable="true" android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_dark_pressed_off_holo" />
+ <item android:state_checkable="true" android:state_checked="true"
+ android:drawable="@drawable/btn_keyboard_key_dark_normal_on_holo" />
+ <item android:state_checkable="true"
+ android:drawable="@drawable/btn_keyboard_key_dark_normal_off_holo" />
+
+ <!-- Normal keys -->
+
+ <item android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_light_pressed_holo" />
+ <item android:drawable="@drawable/btn_keyboard_key_light_normal_holo" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/status_bar_veto.xml b/core/res/res/drawable/ic_lockscreen_camera.xml
similarity index 61%
copy from packages/SystemUI/res/drawable/status_bar_veto.xml
copy to core/res/res/drawable/ic_lockscreen_camera.xml
index 6e1b681..0e3ef37 100644
--- a/packages/SystemUI/res/drawable/status_bar_veto.xml
+++ b/core/res/res/drawable/ic_lockscreen_camera.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2011 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -13,9 +13,18 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/status_bar_veto_pressed" />
- <item android:drawable="@drawable/status_bar_veto_normal" />
-</selector>
+ <item
+ android:state_enabled="true"
+ android:state_active="false"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_camera_normal" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="true"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_camera_activated" />
+
+</selector>
diff --git a/core/res/res/drawable/spinner_cab_background_holo_dark.xml b/core/res/res/drawable/spinner_ab_holo_dark.xml
similarity index 66%
rename from core/res/res/drawable/spinner_cab_background_holo_dark.xml
rename to core/res/res/drawable/spinner_ab_holo_dark.xml
index 5572450..708b6ab 100644
--- a/core/res/res/drawable/spinner_cab_background_holo_dark.xml
+++ b/core/res/res/drawable/spinner_ab_holo_dark.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2011 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,10 +16,12 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
- android:drawable="@drawable/spinner_cab_disabled_holo_dark" />
+ android:drawable="@drawable/spinner_ab_disabled_holo_dark" />
<item android:state_pressed="true"
- android:drawable="@drawable/spinner_cab_pressed_holo_dark" />
+ android:drawable="@drawable/spinner_ab_pressed_holo_dark" />
<item android:state_pressed="false" android:state_focused="true"
- android:drawable="@drawable/spinner_cab_focused_holo_dark" />
- <item android:drawable="@drawable/spinner_cab_default_holo_dark" />
+ android:drawable="@drawable/spinner_ab_focused_holo_dark" />
+ <item android:state_activated="true"
+ android:drawable="@drawable/spinner_ab_activated_holo_dark" />
+ <item android:drawable="@drawable/spinner_ab_default_holo_dark" />
</selector>
diff --git a/core/res/res/drawable/spinner_cab_background_holo_light.xml b/core/res/res/drawable/spinner_ab_holo_light.xml
similarity index 70%
rename from core/res/res/drawable/spinner_cab_background_holo_light.xml
rename to core/res/res/drawable/spinner_ab_holo_light.xml
index 98ff48d..c4901ca 100644
--- a/core/res/res/drawable/spinner_cab_background_holo_light.xml
+++ b/core/res/res/drawable/spinner_ab_holo_light.xml
@@ -16,10 +16,12 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
- android:drawable="@drawable/spinner_cab_disabled_holo_light" />
+ android:drawable="@drawable/spinner_ab_disabled_holo_light" />
<item android:state_pressed="true"
- android:drawable="@drawable/spinner_cab_pressed_holo_light" />
+ android:drawable="@drawable/spinner_ab_pressed_holo_light" />
<item android:state_pressed="false" android:state_focused="true"
- android:drawable="@drawable/spinner_cab_focused_holo_light" />
- <item android:drawable="@drawable/spinner_cab_default_holo_light" />
+ android:drawable="@drawable/spinner_ab_focused_holo_light" />
+ <item android:state_activated="true"
+ android:drawable="@drawable/spinner_ab_activated_holo_light" />
+ <item android:drawable="@drawable/spinner_ab_default_holo_light" />
</selector>
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index 960907d..c2536b7 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -118,41 +118,36 @@
/>
<!-- Column 1 -->
- <Space android:layout_width="32dip" android:layout_rowSpan="7" />
+ <Space android:layout_width="16dip" android:layout_rowSpan="7" />
<!-- Column 2 - password entry field and PIN keyboard -->
- <LinearLayout
- android:orientation="vertical"
- android:layout_gravity="center|fill"
- android:layout_rowSpan="7">
-
- <EditText android:id="@+id/passwordEntry"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:singleLine="true"
- android:textStyle="normal"
- android:inputType="textPassword"
- android:layout_gravity="center"
- android:textSize="24sp"
- android:minEms="8"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:background="@drawable/lockscreen_password_field_dark"
- android:textColor="?android:attr/textColorPrimary"
- android:imeOptions="flagNoFullscreen"
- />
-
- <!-- Numeric keyboard -->
- <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
- android:layout_width="250dip"
- android:layout_height="100dip"
- android:layout_gravity="center"
- android:background="#40000000"
- android:layout_marginTop="5dip"
- android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
- android:visibility="gone"
+ <EditText android:id="@+id/passwordEntry"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="fill"
+ android:gravity="center"
+ android:singleLine="true"
+ android:textStyle="normal"
+ android:inputType="textPassword"
+ android:textSize="24sp"
+ android:minEms="8"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:background="@drawable/lockscreen_password_field_dark"
+ android:textColor="?android:attr/textColorPrimary"
+ android:imeOptions="flagNoFullscreen|actionDone"
/>
- </LinearLayout>
+ <!-- Numeric keyboard -->
+ <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+ android:layout_width="270dip"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="4dip"
+ android:background="#40000000"
+ android:layout_marginTop="5dip"
+ android:keyBackground="@*android:drawable/btn_keyboard_key_ics"
+ android:visibility="gone"
+ android:layout_rowSpan="6"
+ />
<!-- Music transport control -->
<include android:id="@+id/transport"
diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml
index 7a51035..cd33275 100644
--- a/core/res/res/layout/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_password_portrait.xml
@@ -94,31 +94,32 @@
android:drawablePadding="4dip"
/>
- <Space android:layout_height="100dip"/>
-
<!-- Password entry field -->
<EditText android:id="@+id/passwordEntry"
android:layout_height="wrap_content"
android:layout_width="match_parent"
+ android:layout_gravity="center_vertical|fill_horizontal"
+ android:gravity="center_horizontal"
android:singleLine="true"
android:textStyle="normal"
android:inputType="textPassword"
- android:gravity="center"
- android:textSize="22sp"
+ android:textSize="36sp"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip"
android:background="@drawable/lockscreen_password_field_dark"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="#ffffffff"/>
-
- <Space android:layout_gravity="fill" />
+ android:textColor="#ffffffff"
+ android:imeOptions="actionDone"/>
<!-- Numeric keyboard -->
<com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
android:layout_width="match_parent"
- android:layout_height="260dip"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="4dip"
+ android:paddingTop="4dip"
+ android:paddingBottom="4dip"
android:background="#40000000"
- android:keyBackground="@*android:drawable/btn_keyboard_key_fulltrans"
+ android:keyBackground="@*android:drawable/btn_keyboard_key_ics"
android:visibility="gone"
/>
@@ -139,7 +140,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dip"
- android:layout_marginRight="16dip"
android:layout_gravity="center_horizontal"
android:drawableLeft="@*android:drawable/lockscreen_emergency_button"
style="?android:attr/buttonBarButtonStyle"
@@ -153,7 +153,7 @@
layout="@layout/keyguard_transport_control"
android:layout_row="0"
android:layout_column="0"
- android:layout_rowSpan="4"
+ android:layout_rowSpan="3"
android:layout_columnSpan="1"
android:layout_gravity="fill"
/>
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock.xml b/core/res/res/layout/keyguard_screen_tab_unlock.xml
index 05c768d..6016d4e 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock.xml
@@ -129,7 +129,7 @@
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
- android:targetDrawables="@array/lockscreen_targets_when_silent"
+ android:targetDrawables="@array/lockscreen_targets_with_camera"
android:handleDrawable="@drawable/ic_lockscreen_handle"
android:waveDrawable="@drawable/ic_lockscreen_outerring"
android:outerRadius="@dimen/multiwaveview_target_placement_radius"
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
index 6440726..168bd1a 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
@@ -131,7 +131,7 @@
android:layout_height="match_parent"
android:layout_rowSpan="7"
- android:targetDrawables="@array/lockscreen_targets_when_silent"
+ android:targetDrawables="@array/lockscreen_targets_with_camera"
android:handleDrawable="@drawable/ic_lockscreen_handle"
android:waveDrawable="@drawable/ic_lockscreen_outerring"
android:outerRadius="@dimen/multiwaveview_target_placement_radius"
diff --git a/core/res/res/layout/volume_adjust.xml b/core/res/res/layout/volume_adjust.xml
index 7303003..8c580c2 100644
--- a/core/res/res/layout/volume_adjust.xml
+++ b/core/res/res/layout/volume_adjust.xml
@@ -54,6 +54,7 @@
android:padding="16dip"
android:background="?attr/selectableItemBackground"
android:src="@drawable/ic_sysbar_quicksettings"
+ android:contentDescription="@string/volume_panel_more_description"
/>
</LinearLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index e60af6d..93f0526 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1117,7 +1117,8 @@
<skip />
<!-- no translation found for paste (5629880836805036433) -->
<skip />
- <string name="pasteDisabled" msgid="7259254654641456570">"Niks om te plak nie"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<!-- no translation found for copyUrl (2538211579596067402) -->
<skip />
<string name="selectTextMode" msgid="6738556348861347240">"Kies teks..."</string>
@@ -1431,6 +1432,22 @@
<skip />
<!-- no translation found for number_picker_decrement_button (2576606679160067262) -->
<skip />
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<!-- no translation found for action_bar_home_description (5293600496601490216) -->
<skip />
<!-- no translation found for action_bar_up_description (2237496562952152589) -->
@@ -1457,6 +1474,14 @@
<skip />
<!-- no translation found for data_usage_limit_body (2182247539226163759) -->
<skip />
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<!-- no translation found for ssl_certificate (6510040486049237639) -->
<skip />
<!-- no translation found for ssl_certificate_is_valid (6825263250774569373) -->
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 716d19f..ac2bdd1 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1117,7 +1117,8 @@
<skip />
<!-- no translation found for paste (5629880836805036433) -->
<skip />
- <string name="pasteDisabled" msgid="7259254654641456570">"ምንም የሚለጠፍ የለም"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<!-- no translation found for copyUrl (2538211579596067402) -->
<skip />
<string name="selectTextMode" msgid="6738556348861347240">"ፅሁፍ ምረጥ"</string>
@@ -1431,6 +1432,22 @@
<skip />
<!-- no translation found for number_picker_decrement_button (2576606679160067262) -->
<skip />
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<!-- no translation found for action_bar_home_description (5293600496601490216) -->
<skip />
<!-- no translation found for action_bar_up_description (2237496562952152589) -->
@@ -1457,6 +1474,14 @@
<skip />
<!-- no translation found for data_usage_limit_body (2182247539226163759) -->
<skip />
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<!-- no translation found for ssl_certificate (6510040486049237639) -->
<skip />
<!-- no translation found for ssl_certificate_is_valid (6825263250774569373) -->
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 12a240a..fb313f9 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"للسماح للتطبيقات بمراقبة الأحرف التي تضغط عليها حتى عند التفاعل مع تطبيق آخر (مثل إدخال كلمة مرور). لا يجب استخدامه على الإطلاق للتطبيقات العادية."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"الالتزام بطريقة إرسال ما"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لطريقة الإرسال. لا يجب استخدامه على الإطلاق للتطبيقات العادية."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"الالتزام بخدمة إدخال النصوص"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة إدخال النصوص (على سبيل المثال، SpellCheckerService). لا يجب استخدامه على الإطلاق للتطبيقات العادية."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"الالتزام بخلفية ما"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"للسماح للمالك بالالتزام بواجهة المستوى العلوي للخلفية. لا يجب استخدامه على الإطلاق للتطبيقات العادية."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"الالتزام بخدمة أداة"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"للسماح لتطبيق ما بتعديل سجل المتصفح أو الإشارات في هاتفك. يمكن أن تستخدم التطبيقات الضارة ذلك لمسح بيانات المتصفح أو تعديلها."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"تعيين المنبه في ساعة المنبه"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"للسماح للتطبيق بضبط المنبه في تطبيق ساعة منبه مثبّت. ربما لا تنفذ بعض تطبيقات المنبه هذه الميزة."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"الوصول إلى رسائل البريد الصوتي التي يديرها هذا التطبيق"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"للسماح للتطبيق بتخزين واسترداد رسائل البريد الصوتي التي يمكنه الوصول إلى الخدمة المرتبطة بها فقط."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"تعديل أذونات الموقع الجغرافي للمتصفح"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"للسماح لتطبيق ما بتعديل أذونات الموقع الجغرافي للمتصفح. يمكن أن تستخدم التطبيقات الضارة هذا للسماح بإرسال معلومات الموقع إلى مواقع ويب عشوائية."</string>
<string name="save_password_message" msgid="767344687139195790">"هل تريد من المتصفح تذكر كلمة المرور هذه؟"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"قص"</string>
<string name="copy" msgid="2681946229533511987">"نسخ"</string>
<string name="paste" msgid="5629880836805036433">"لصق"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"ليس هناك شيء للصقه"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"نسخ عنوان URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"تحديد نص..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"تحديد النص"</string>
@@ -919,22 +916,14 @@
<item quantity="one" msgid="1634101450343277345">"هناك شبكة Wi-Fi مفتوحة متاحة"</item>
<item quantity="other" msgid="7915895323644292768">"هناك شبكات Wi-Fi مفتوحة متاحة"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"تم تعطيل شبكة Wi-Fi."</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"تم تعطيل شبكة Wi-Fi مؤقتًا بسبب اتصال خاطئ."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"اتصال Wi-Fi مباشر"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"ابدأ تشغيل اتصالWi-Fi المباشر. يؤدي ذلك إلى إيقاف تشغيل عميل/نقطة اتصال Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"أخفق بدء اتصال Wi-Fi مباشر."</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"هناك طلب اتصال Wi-Fi مباشر من <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. انقر على موافق للقبول."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"هناك طلب إعداد اتصال Wi-Fi مباشر من <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. أدخل رقم التعريف الشخصي للبدء."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"يجب إدخال رقم التعريف الشخصي لـ WPS <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> في الجهاز النظير <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> حتى يبدأ إعداد الاتصال."</string>
<string name="select_character" msgid="3365550120617701745">"إدراج حرف"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"تطبيق غير معروف"</string>
<string name="sms_control_title" msgid="7296612781128917719">"إرسال رسائل قصيرة SMS"</string>
@@ -983,8 +972,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"التوصيل كجهاز وسائط"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"التوصيل ككاميرا"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"التوصيل كأداة تثبيت"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"الاتصال بجهاز USB ملحق"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"المس للاطلاع على خيارات USB الأخرى"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"تهيئة وحدة تخزين USB"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"تنسيق بطاقة SD"</string>
@@ -1104,6 +1092,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"حدد حسابًا."</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"زيادة"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"تناقص"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"التنقل إلى الشاشة الرئيسية"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"التنقل إلى أعلى"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"المزيد من الخيارات"</string>
@@ -1117,6 +1121,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"تم تعطيل بيانات شبكة الجيل الرابع"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"تم تعطيل بيانات الجوال"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"انقر للتمكين."</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"شهادة الأمان"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"هذه الشهادة صالحة."</string>
<string name="issued_to" msgid="454239480274921032">"إصدار لـ:"</string>
@@ -1134,6 +1146,5 @@
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"عرض الكل..."</string>
<string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"تحديد نشاط"</string>
<string name="share_action_provider_share_with" msgid="1791316789651185229">"مشاركة مع..."</string>
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"تم قفل الجهاز."</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index f20ef1b..2707b65 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"Изрязване"</string>
<string name="copy" msgid="2681946229533511987">"Копиране"</string>
<string name="paste" msgid="5629880836805036433">"Поставяне"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Нищо за поставяне"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Копиране на URL адреса"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Избиране на текст..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Избиране на текст"</string>
@@ -1104,6 +1105,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Избор на профил"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Увеличаване"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Намаляване"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Придвижване към „Начало“"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Придвижване нагоре"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Още опции"</string>
@@ -1117,6 +1134,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G данните са деактивирани"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Мобилните данни са деактивирани"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"докоснете за активиране"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Сертификат за сигурност"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Този сертификат е валиден."</string>
<string name="issued_to" msgid="454239480274921032">"Издаден на:"</string>
@@ -1132,10 +1157,8 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"Пръстов отпечатък SHA-256:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"Пръстов отпечатък SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Вижте всички..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Избор на активност"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Споделяне с..."</string>
<!-- no translation found for status_bar_device_locked (3092703448690669768) -->
<skip />
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index cb57c33..5eb1eb9 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"Retalla"</string>
<string name="copy" msgid="2681946229533511987">"Copia"</string>
<string name="paste" msgid="5629880836805036433">"Enganxa"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Cap elem. per engan."</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Copia l\'URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Selecciona el text..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Selecció de text"</string>
@@ -880,12 +881,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Aplicació redirigida"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> s\'està executant."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> es va iniciar originalment."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Escala"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Mostra sempre"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Torna a activar-ho amb Configuració > Aplicacions > Gestiona les aplicacions."</string>
<string name="smv_application" msgid="295583804361236288">"L\'aplicació <xliff:g id="APPLICATION">%1$s</xliff:g> (procés <xliff:g id="PROCESS">%2$s</xliff:g>) ha incomplert la seva política autoimposada de mode estricte."</string>
<string name="smv_process" msgid="5120397012047462446">"El procés <xliff:g id="PROCESS">%1$s</xliff:g> ha incomplert la seva política de mode estricte."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> s\'està executant"</string>
@@ -941,18 +939,12 @@
<string name="sms_control_message" msgid="1289331457999236205">"S\'estan enviant molts missatges SMS. Seleccioneu \"D\'acord\" per continuar o \"Cancel·la\" per aturar l\'enviament."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"D\'acord"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Cancel·la"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"Extracció de la targeta SIM"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"La xarxa de telefonia mòbil no estarà disponible fins que no canviïs la targeta SIM."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Fet"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"Addició de la targeta SIM"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Cal que reiniciïs el dispositiu per accedir a la xarxa de telefonia mòbil."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Reinicia"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Estableix l\'hora"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Establiment de data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Defineix"</string>
@@ -1104,6 +1096,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Selecciona un compte"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Incrementa"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Disminueix"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Torna a la pàgina d\'inici"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Mou cap a dalt"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Més opcions"</string>
@@ -1117,6 +1125,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Dades 4G desactivades"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Dades mòbils desactivades"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"pica per activar-lo"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Certificat de seguretat"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Aquest certificat és vàlid."</string>
<string name="issued_to" msgid="454239480274921032">"Emès per a:"</string>
@@ -1132,7 +1148,7 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"Empremta SHA-256:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"Empremta SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Mostra-ho tot"</string>
- <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Selecció d\'activitat"</string>
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Selecció d’activitat"</string>
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Ús compartit amb..."</string>
<!-- no translation found for status_bar_device_locked (3092703448690669768) -->
<skip />
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index c074e7b..edc0b41 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"Vyjmout"</string>
<string name="copy" msgid="2681946229533511987">"Kopírovat"</string>
<string name="paste" msgid="5629880836805036433">"Vložit"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Není co vložit"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Kopírovat adresu URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Vybrat text..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Výběr textu"</string>
@@ -880,12 +881,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Aplikace přesměrována"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Je spuštěna aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Původně byla spuštěna aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Měřítko"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Vždy zobrazovat"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Tuto možnost můžete opět aktivovat v části Nastavení > Aplikace > Správa aplikací."</string>
<string name="smv_application" msgid="295583804361236288">"Aplikace <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) porušila své vlastní vynucené zásady StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> porušil své vlastní vynucené zásady StrictMode."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Běží aplikace <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -941,18 +939,12 @@
<string name="sms_control_message" msgid="1289331457999236205">"Je odesílán velký počet zpráv SMS. Vyberte OK, chcete-li pokračovat, nebo Zrušit, chcete-li odesílání ukončit."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Zrušit"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"Karta SIM odebrána"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Mobilní síť bude nedostupná, dokud nevyměníte kartu SIM."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Hotovo"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"Karta SIM přidána."</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Mobilní síť bude přístupná po restartu zařízení."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Restartovat"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Nastavení času"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastavení data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Nastavit"</string>
@@ -1104,6 +1096,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Vybrat účet"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Zvýšení"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Snížení"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Přejít na plochu"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Přejít nahoru"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Další možnosti"</string>
@@ -1117,6 +1125,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Datové přenosy 4G jsou zakázány"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobilní data jsou zakázána"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"klepnutím povolíte"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Certifikát zabezpečení"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Tento certifikát je platný."</string>
<string name="issued_to" msgid="454239480274921032">"Vydáno pro:"</string>
@@ -1133,7 +1149,7 @@
<string name="sha1_fingerprint" msgid="7930330235269404581">"Digitální otisk SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Zobrazit vše..."</string>
<string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Vybrat činnost"</string>
- <string name="share_action_provider_share_with" msgid="1791316789651185229">"Sdílet..."</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Sdílet s..."</string>
<!-- no translation found for status_bar_device_locked (3092703448690669768) -->
<skip />
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 0038b29..b8b53ad 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Tillader, at en applikation registrerer taster, du trykker på, selv når du interagerer med andre applikationer (f.eks. ved indtastning af adgangskode). Bør aldrig være nødvendigt til normale applikationer."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"forpligt til en inputmetode"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Tillader, at brugeren forpligter sig til en inputmetodes grænseflade på øverste niveau. Bør aldrig være nødvendig til normale applikationer."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"forpligte sig til en sms-tjeneste"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Tillader brugeren at forpligte sig på en teksttjenestes grænseflade (f. eks. SpellCheckerService) på øverste niveau. Bør aldrig være nødvendig til almindelige programmer."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"forpligt til et tapet"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Tillader, at brugeren forpligter sig til et tapets grænseflade på øverste niveau. Bør aldrig være nødvendig til normale applikationer."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"forpligt til en widgettjeneste"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Tillader, at en applikation ændrer browseroversigten eller bogmærker, der er gemt på din telefon. Ondsindede applikationer kan bruge dette til at slette eller ændre din browsers data."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"angiv alarm i alarmprogram"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Tillader, at applikationen angiver en alarm i et installeret alarmprogram. Nogle alarmprogrammer kan ikke implementere denne funktion."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Få adgang til telefonsvarerbeskeder, der administreres af dette program"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Tillader, at applikationen kun gemmer og henter de telefonsvarerbeskeder, som dets tilknyttede tjeneste kan få adgang til."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Skift browsertilladelser for geografisk placering"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Giver en applikation tilladelse til at ændre browserens tilladelser for geografisk placering. Skadelige applikationer kan bruge dette til at tillade, at placeringsoplysninger sendes til vilkårlige websteder."</string>
<string name="save_password_message" msgid="767344687139195790">"Ønsker du, at browseren skal huske denne adgangskode?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Klip"</string>
<string name="copy" msgid="2681946229533511987">"Kopier"</string>
<string name="paste" msgid="5629880836805036433">"Indsæt"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Intet at indsætte"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Kopier webadresse"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Marker tekst..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Tekstmarkering"</string>
@@ -919,22 +916,14 @@
<item quantity="one" msgid="1634101450343277345">"Åbent Wi-Fi-netværk tilgængeligt"</item>
<item quantity="other" msgid="7915895323644292768">"Der er åbne Wi-Fi-netværk tilgængelige"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Et Wi-Fi-netværk blev deaktiveret"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Et Wi-Fi-netværk blev midlertidigt deaktiveret på grund af dårlig forbindelse."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Start Wi-Fi Direct-drift. Dette vil slukke for Wi-Fi-klient / hotspot-drift."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Kunne ikke starte Wi-Fi Direct"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Anmodning om konfiguration af Wi-Fi Direct-forbindelse fra <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Klik på OK for at acceptere."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Anmodning om konfiguration af Wi-Fi Direct-forbindelse fra <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Indtast pinkode for at fortsætte."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"WPS-pinkoden <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> skal angives på peer-enheden <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> for at fortsætte konfiguration af forbindelsen"</string>
<string name="select_character" msgid="3365550120617701745">"Indsæt tegn"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Ukendt applikation"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Sender sms-beskeder"</string>
@@ -983,8 +972,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Tilsluttet som en medieenhed"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Tilsluttet som et kamera"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Tilsluttet som et installationsprogram"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tilsluttet et USB-ekstraudstyr"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Tryk for at se andre valgmuligheder for USB-tilslutning"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Formater USB-lager"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"Formater SD-kort"</string>
@@ -1104,6 +1092,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Vælg en konto"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Optælling"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Nedtælling"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Naviger hjem"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Naviger op"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Flere valgmuligheder"</string>
@@ -1117,6 +1121,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G-data er deaktiveret"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobildata er deaktiveret"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"tryk for at aktivere"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Sikkerhedscertifikat"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Dette certifikat er gyldigt."</string>
<string name="issued_to" msgid="454239480274921032">"Udstedt til:"</string>
@@ -1134,6 +1146,5 @@
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Se alle..."</string>
<string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Vælg aktivitet"</string>
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Del med..."</string>
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Enhed låst."</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 508b65d..a185a0f 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"Ausschneiden"</string>
<string name="copy" msgid="2681946229533511987">"Kopieren"</string>
<string name="paste" msgid="5629880836805036433">"Einfügen"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Nichts zum Einfügen"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"URL kopieren"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Text auswählen..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Textauswahl"</string>
@@ -1104,6 +1105,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Konto auswählen"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Erhöhen"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Verringern"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Zur Startseite navigieren"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Nach oben navigieren"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Weitere Optionen"</string>
@@ -1117,6 +1134,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G-Daten deaktiviert"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobile Daten deaktiviert"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"Zum Aktivieren klicken"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Sicherheitszertifikat"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Dies ist ein gültiges Zertifikat."</string>
<string name="issued_to" msgid="454239480274921032">"Ausgestellt für:"</string>
@@ -1132,10 +1157,8 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256-Fingerabdruck:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1-Fingerabdruck:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Alle anzeigen..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Aktion auswählen"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Teilen mit..."</string>
<!-- no translation found for status_bar_device_locked (3092703448690669768) -->
<skip />
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 1bf806a..7491472 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Επιτρέπει σε εφαρμογές να παρακολουθούν τα πλήκτρα που πατάτε, ακόμη και σε μια άλλη εφαρμογή (όπως π.χ. η καταχώρηση ενός κωδικού πρόσβασης). Δεν είναι απαραίτητο για συνήθεις εφαρμογές."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"δέσμευση σε μέθοδο εισόδου"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας μεθόδου εισόδου. Δεν είναι απαραίτητο για συνήθεις εφαρμογές."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"σύνδεση σε υπηρεσία ανταλλαγής μηνυμάτων"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Επιτρέπει στον κάτοχο τη σύνδεση με τη διεπαφή ανωτέρου επιπέδου μιας υπηρεσίας ανταλλαγής μηνυμάτων (π.χ. SpellCheckerService). Δεν είναι απαραίτητο για κανονικές εφαρμογές."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"δέσμευση σε ταπετσαρία"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας ταπετσαρίας. Δεν είναι απαραίτητο για συνήθεις εφαρμογές."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"δέσμευση σε υπηρεσία γραφικών στοιχείων"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Επιτρέπει σε μια εφαρμογή να τροποποιήσει το ιστορικό ή τους σελιδοδείκτες του προγράμματος περιήγησης που βρίσκονται αποθηκευμένα στο τηλέφωνό σας. Κακόβουλες εφαρμογές μπορούν να το χρησιμοποιήσουν για να διαγράψουν ή να τροποποιήσουν τα δεδομένα του προγράμματος περιήγησης."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"ρύθμιση ειδοποίησης σε ξυπνητήρι"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Επιτρέπει στην εφαρμογή να ρυθμίσει μια ειδοποίηση σε μια εγκατεστημένη εφαρμογή ξυπνητηριού. Κάποιες εφαρμογές ξυπνητηριού ενδέχεται να μην περιλαμβάνουν αυτή τη λειτουργία."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Πρόσβαση σε μηνύματα αυτόματου τηλεφωνητή, τα οποία διαχειρίζεται αυτή η εφαρμογή"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Επιτρέπει στην εφαρμογή την αποθήκευση και την ανάκτηση μόνο μηνυμάτων αυτόματου τηλεφωνητή, στα οποία έχει πρόσβαση η σχετική υπηρεσία."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Τροποποίηση δικαιωμάτων γεωγραφικής θέσης προγράμματος περιήγησης"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Επιτρέπει σε μια εφαρμογή την τροποποίηση των δικαιωμάτων γεωγραφικής θέσης του προγράμματος περιήγησης. Οι κακόβουλες εφαρμογές μπορούν να το χρησιμοποιήσουν για να επιτρέψουν την αποστολή στοιχείων τοποθεσίας σε αυθαίρετους ιστότοπους."</string>
<string name="save_password_message" msgid="767344687139195790">"Θέλετε το πρόγραμμα περιήγησης να διατηρήσει αυτόν τον κωδικό πρόσβασης;"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Αποκοπή"</string>
<string name="copy" msgid="2681946229533511987">"Αντιγραφή"</string>
<string name="paste" msgid="5629880836805036433">"Επικόλληση"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Καν. στοιχ. για επικ."</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Αντιγραφή διεύθυνσης URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Επιλογή κειμένου..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Επιλογή κειμένου"</string>
@@ -880,12 +877,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Ανακατεύθυνση εφαρμογής"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> εκτελείται τώρα."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Έγινε εκκίνηση πρώτα της εφαρμογής <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Κλίμακα"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Να εμφανίζονται πάντα"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Ενεργοποίηση αυτής της εφαρμογής από τις Ρυθμίσεις > Εφαρμογές > Διαχείριση εφαρμογών."</string>
<string name="smv_application" msgid="295583804361236288">"Η εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> (διεργασία <xliff:g id="PROCESS">%2$s</xliff:g>) παραβίασε την αυτοεπιβαλόμενη πολιτική StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Η διεργασία <xliff:g id="PROCESS">%1$s</xliff:g> παραβίασε την αυτοεπιβαλόμενη πολιτική StrictMode."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Η εφαρμογή <xliff:g id="APP">%1$s</xliff:g> εκτελείται"</string>
@@ -919,40 +913,26 @@
<item quantity="one" msgid="1634101450343277345">"Υπάρχει διαθέσιμο ανοικτό δίκτυο Wi-Fi"</item>
<item quantity="other" msgid="7915895323644292768">"Υπάρχουν διαθέσιμα ανοικτά δίκτυα Wi-Fi"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Ένα δίκτυο Wi-Fi ήταν απενεργοποιημένο."</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Ένα δίκτυο Wi-Fi ήταν προσωρινά απενεργοποιημένο λόγω κακής σύνδεσης."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Ξεκινήστε τη λειτουργία Wi-Fi Direct. Θα απενεργοποιηθεί η λειτουργία πελάτη/φορητού σημείου πρόσβασης Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Αποτυχία έναρξης Wi-Fi Direct"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Αίτημα για ρύθμιση σύνδεσης Wi-Fi Direct από το <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Κάντε κλικ στο κουμπί OK για αποδοχή."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Αίτημα ρύθμισης σύνδεσης Wi-Fi Direct από τη διεύθυνση <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Καταχωρίστε το pin για να συνεχίσετε."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"Το pin WPS <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> πρέπει να καταχωριστεί στην ομότιμη συσκευή <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> για να συνεχιστεί η ρύθμιση της σύνδεσης"</string>
<string name="select_character" msgid="3365550120617701745">"Εισαγωγή χαρακτήρα"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Άγνωστη εφαρμογή"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Αποστολή μηνυμάτων SMS"</string>
<string name="sms_control_message" msgid="1289331457999236205">"Αποστέλλεται μεγάλος αριθμός μηνυμάτων SMS. Επιλέξτε \"OK\" για συνέχεια, ή \"Ακύρωση\" για διακοπή αποστολής."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Ακύρωση"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"Η κάρτα SIM αφαιρέθηκε"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Το δίκτυο κινητής τηλεφωνίας δεν θα είναι διαθέσιμο έως ότου αντικαταστήσετε την κάρτα SIM."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Τέλος"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"Προστέθηκε κάρτα SIM"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Πρέπει να επανεκκινήσετε τη συσκευή σας για να αποκτήσετε πρόσβαση στο δίκτυο κινητής τηλεφωνίας"</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Επανεκκίνηση"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Ρύθμιση ώρας"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Ορισμός ημερομηνίας"</string>
<string name="date_time_set" msgid="5777075614321087758">"Ορισμός"</string>
@@ -983,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Συνδεδεμένο ως συσκευή πολυμέσων"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Συνδεδεμένο ως φωτογραφική μηχανή"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Συνδεδεμένο ως πρόγραμμα εγκατάστασης"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Σύνδεση σε αξεσουάρ USB"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Αγγίξτε για άλλες επιλογές USB"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Διαγρ. απ. χώρου USB"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"Διαμόρφωση κάρτας SD"</string>
@@ -1104,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Επιλογή λογαριασμού"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Αύξηση"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Μείωση"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Πλοήγηση στην αρχική σελίδα"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Πλοήγηση προς τα επάνω"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Περισσότερες επιλογές"</string>
@@ -1117,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Τα δεδομένα 4G απενεργοποιήθηκαν"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Τα δεδομ. κιν. τηλεφ. απενεργοπ."</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"πατήστε για ενεργοποίηση"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Πιστοποιητικό ασφαλείας"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Αυτό το πιστοποιητικό είναι έγκυρο."</string>
<string name="issued_to" msgid="454239480274921032">"Εκδόθηκε σε:"</string>
@@ -1132,10 +1135,7 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"Αποτύπωμα SHA-256"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"Αποτύπωμα SHA-1"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Εμφάνιση όλων..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Επιλογή δραστηριότητας"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Κοινή χρήση με..."</string>
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Η συσκευή κλειδώθηκε."</string>
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index a22fafc..39e85ed 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Allows applications to watch the keys that you press even when interacting with another application (such as entering a password). Should never be needed for normal applications."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"bind to an input method"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Allows the holder to bind to the top-level interface of an input method. Should never be needed for normal applications."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"bind to a text service"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Allows the holder to bind to the top-level interface of a text service (e.g. SpellCheckerService). Should never be needed for normal applications."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"bind to wallpaper"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Allows the holder to bind to the top-level interface of wallpaper. Should never be needed for normal applications."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bind to a widget service"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Allows an application to modify the browser\'s history or bookmarks stored on your phone. Malicious applications can use this to erase or modify your browser\'s data."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"set alarm in alarm clock"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Allows the application to set an alarm in an installed alarm clock application. Some alarm clock applications may not implement this feature."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Access voicemails managed by this application"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Allows the application to store and retrieve only voicemails that its associated service can access."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Modify Browser geo-location permissions"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Allows an application to modify the browser\'s geo-location permissions. Malicious applications can use this to allow the sending of location information to arbitrary websites."</string>
<string name="save_password_message" msgid="767344687139195790">"Do you want the browser to remember this password?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Cut"</string>
<string name="copy" msgid="2681946229533511987">"Copy"</string>
<string name="paste" msgid="5629880836805036433">"Paste"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Nothing to paste"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Copy URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Select text..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Text selection"</string>
@@ -916,22 +913,14 @@
<item quantity="one" msgid="1634101450343277345">"Open available Wi-Fi network"</item>
<item quantity="other" msgid="7915895323644292768">"Open Wi-Fi networks available"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"A Wi-Fi network was disabled"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"A Wi-Fi network was temporarily disabled due to bad connectivity."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Start Wi-Fi Direct operation. This will turn off Wi-Fi client/hotspot operation."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Failed to start Wi-Fi Direct"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Wi-Fi Direct connection setup request from <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Click OK to accept."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Wi-Fi Direct connection setup request from <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Enter PIN to proceed."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"WPS pin <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> needs to be entered on the peer device <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> for connection setup to proceed"</string>
<string name="select_character" msgid="3365550120617701745">"Insert character"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Unknown application"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Sending SMS messages"</string>
@@ -974,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Connected as a media device"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Connected as a camera"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Connected as an installer"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Touch for other USB options"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Format USB storage"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"Format SD card"</string>
@@ -1095,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Select an account"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Increment"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Decrement"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Navigate home"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navigate up"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"More options"</string>
@@ -1108,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G data disabled"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobile data disabled"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"Tap to enable"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Security certificate"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"This certificate is valid."</string>
<string name="issued_to" msgid="454239480274921032">"Issued to:"</string>
@@ -1125,6 +1137,5 @@
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"See all..."</string>
<string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Select activity"</string>
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Share with..."</string>
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Device locked."</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 7c61d39..c07551e 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Admite que las aplicaciones observen las teclas que presionas, incluso al interactuar con otra aplicación (como el ingreso de una contraseña). Se debe evitar utilizarlo en aplicaciones normales."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"vincular a un método de entrada"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Permite al propietario vincularse a la interfaz de nivel superior de un método de entrada. Se debe evitar utilizarlo en aplicaciones normales."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"vincular a un servicio de texto"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Permite al titular vincularse a la interfaz de nivel superior de un servicio de texto (por ejemplo, SpellCheckerService). Nunca debe ser necesario para las aplicaciones normales."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"vincular a un fondo de pantalla"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Permite al propietario vincularse a la interfaz de nivel superior de un fondo de pantalla. Se debe evitar utilizarlo en aplicaciones normales."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vincular a un servicio de widget"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Permite a una aplicación modificar el historial y los marcadores del navegador almacenados en tu teléfono. Las aplicaciones maliciosas pueden utilizarlo para borrar o modificar tus datos."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"configurar alarma en reloj alarma"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Permite que la aplicación configure una alarma en una aplicación instalada de reloj alarma. Es posible que algunas aplicaciones de reloj alarma no implementen esta función."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Buzones de voz de acceso administrados por esta aplicación."</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Permite que la aplicación almacene y recupere solo buzones de voz a los que sus servicios asociados pueden acceder."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Modificar los permisos de ubicación geográfica del navegador"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Permite que una aplicación modifique los permisos de ubicación geográfica del navegador. Las aplicaciones maliciosas pueden utilizarlos para permitir el envío de información sobre la ubicación a sitos web de forma arbitraria."</string>
<string name="save_password_message" msgid="767344687139195790">"¿Quieres recordar esta contraseña en el navegador?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Cortar"</string>
<string name="copy" msgid="2681946229533511987">"Copiar"</string>
<string name="paste" msgid="5629880836805036433">"Pegar"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Nada que pegar"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Seleccionar texto..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Selección de texto"</string>
@@ -880,12 +877,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Se redirigió la aplicación"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando ahora."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> se inició originalmente."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Escala"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Mostrar siempre"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Volver a habilitar esto con Configuración > Aplicaciones > Administrar aplicaciones."</string>
<string name="smv_application" msgid="295583804361236288">"La aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> (proceso <xliff:g id="PROCESS">%2$s</xliff:g>) ha violado su política StrictMode autoimpuesta."</string>
<string name="smv_process" msgid="5120397012047462446">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> ha violado su política StrictMode autoimpuesta."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> en ejecución"</string>
@@ -919,40 +913,26 @@
<item quantity="one" msgid="1634101450343277345">"Abrir red disponible de Wi-Fi"</item>
<item quantity="other" msgid="7915895323644292768">"Abrir redes disponibles de Wi-Fi"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Una red Wi-Fi se ha inhabilitado."</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Una red Wi-Fi ha sido temporalmente inhabilitada debido a mala conectividad."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Iniciar operación de Wi-Fi Direct. Esto desactivará la operación de cliente/zona Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Error al iniciar el Wi-Fi Direct"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Solicitud de configuración de conexión de Wi-Fi Direct desde <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Haz clic en Aceptar."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Solicitud de configuración de conexión de Wi-Fi Direct desde <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Ingresa el llamado para continuar."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"El llamado a WPS <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> necesita ser ingresado en el dispositivo de pares <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> para que la configuración de la conexión continúe."</string>
<string name="select_character" msgid="3365550120617701745">"Insertar caracteres"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Aplicación desconocida"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Enviando mensajes SMS"</string>
<string name="sms_control_message" msgid="1289331457999236205">"Se envía una gran cantidad de mensajes SMS. Selecciona \"Aceptar\" para continuar o \"Cancelar\" para detener el envío."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"Aceptar"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Cancelar"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"Tarjeta SIM eliminada"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"La red para celulares no estará disponible hasta que cambies la tarjeta SIM."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Finalizado"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"Tarjeta SIM agregada"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Debes reiniciar tu dispositivo para acceder a la red para celulares."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Reiniciar"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Configurar hora"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Configurar fecha"</string>
<string name="date_time_set" msgid="5777075614321087758">"Establecer"</string>
@@ -983,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Conectado como un dispositivo de medios"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Conectado como una cámara"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Conectado como un instalador"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Toca para otras opciones de USB"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Formatear almacenamiento USB"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"Formatear tarjeta SD"</string>
@@ -1104,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Seleccionar una cuenta"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Incremento"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Decremento"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Desplazarse hasta la página principal"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Desplazarse hacia arriba"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Más opciones"</string>
@@ -1117,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Datos de 4 GB desactivados"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Datos móviles desactivados"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"pulsa para habilitarla"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Certificado de seguridad"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Este certificado es válido."</string>
<string name="issued_to" msgid="454239480274921032">"Emitido a:"</string>
@@ -1134,6 +1137,5 @@
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Ver todas..."</string>
<string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Seleccionar actividad"</string>
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Compartir con..."</string>
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloqueado"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 1179764..c858179 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"Cortar"</string>
<string name="copy" msgid="2681946229533511987">"Copiar"</string>
<string name="paste" msgid="5629880836805036433">"Pegar"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Portapapeles vacío"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Seleccionar texto..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Selección de texto"</string>
@@ -880,12 +881,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Aplicación redireccionada"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Inicialmente, se inició la aplicación <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Escala"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Mostrar siempre"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Vuelve a habilitar esta opción en Ajustes > Aplicaciones > Administrar aplicaciones."</string>
<string name="smv_application" msgid="295583804361236288">"La aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> (proceso <xliff:g id="PROCESS">%2$s</xliff:g>) ha infringido su política StrictMode autoaplicable."</string>
<string name="smv_process" msgid="5120397012047462446">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> ha infringido su política StrictMode autoaplicable."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> en ejecución"</string>
@@ -941,18 +939,12 @@
<string name="sms_control_message" msgid="1289331457999236205">"Se ha enviado un número elevado de mensajes SMS. Selecciona \"Aceptar\" para continuar o \"Cancelar\" para interrumpir el envío."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"Aceptar"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Cancelar"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"Tarjeta SIM eliminada"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"La red móvil volverá a estar disponible cuando sustituyas la tarjeta SIM."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Listo"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"Tarjeta SIM añadida"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Para acceder a la red móvil, debes reiniciar el dispositivo."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Reiniciar"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Establecer hora"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Establecer fecha"</string>
<string name="date_time_set" msgid="5777075614321087758">"Establecer"</string>
@@ -1104,6 +1096,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Seleccionar una cuenta"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Aumentar"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Disminuir"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Ir al escritorio"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Desplazarse hacia arriba"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Más opciones"</string>
@@ -1117,6 +1125,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Datos 4G inhabilitados"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Datos móviles inhabilitados"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"tocar para habilitar"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Certificado de seguridad"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Este certificado es válido."</string>
<string name="issued_to" msgid="454239480274921032">"Emitido para:"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 35fc0b9..0a32aa4 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"برش"</string>
<string name="copy" msgid="2681946229533511987">"کپی"</string>
<string name="paste" msgid="5629880836805036433">"جای گذاری"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"چیزی برای جای گذاری نیست"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"کپی URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"انتخاب متن..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"انتخاب متن"</string>
@@ -1104,6 +1105,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"انتخاب یک حساب"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"افزایش"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"کاهش"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"رفتن به صفحه اصلی"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"حرکت به بالا"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"سایر گزینه ها"</string>
@@ -1117,6 +1134,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"داده 4G غیر فعال شده است"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"داده های تلفن همراه غیرفعال شد"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"برای فعال کردن ضربه بزنید"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"گواهی امنیتی"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"این گواهی معتبر است."</string>
<string name="issued_to" msgid="454239480274921032">"صادر شده برای:"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 2e3f921..c8d29eb 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Antaa sovelluksien tarkkailla painamiasi näppäimiä jopa toisten sovellusten käytön yhteydessä (kuten salasanoja syötettäessä). Ei tavallisten sovelluksien käyttöön."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"sitoudu syöttötapaan"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Antaa sovelluksen sitoutua syöttötavan ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"sitoudu tekstipalveluun"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Sovellus voi sitoutua tekstipalvelun (esim. SpellCheckerService) korkeimman tason käyttöliittymään. Ei pitäisi tarvita tavallisissa sovelluksissa."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"sido taustakuvaan"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Antaa sovelluksen sitoutua taustakuvan ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"sitoudu widget-palveluun"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Antaa sovelluksen muokata puhelimeen tallennettuja selaimen historia- ja kirjanmerkkitietoja. Haitalliset sovellukset voivat käyttää tätä pyyhkiäkseen tai muokatakseen selaimen tietoja."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"aseta herätys herätyskelloon"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Antaa sovelluksen asettaa herätyksen asennettuun herätyskellosovellukseen. Kaikki herätyskellosovellukset eivät välttämättä käytä tätä ominaisuutta."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Käytä tämän sovelluksen hallinnoimia vastaajaviestejä"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Antaa sovelluksen tallentaa ja noutaa vain siihen liitetyn palvelun käyttämiä vastaajaviestejä."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"muokkaa selaimen maantieteellisen sijainnin lupia"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Antaa sovelluksen muokata selaimen maantieteellisen sijainnin lupia. Haitalliset sovellukset saattavat käyttää tätä sijaintitietojen lähettämiseen satunnaisiin verkkosivustoihin."</string>
<string name="save_password_message" msgid="767344687139195790">"Haluatko selaimen muistavan tämän salasanan?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Leikkaa"</string>
<string name="copy" msgid="2681946229533511987">"Kopioi"</string>
<string name="paste" msgid="5629880836805036433">"Liitä"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Ei mitään liitettävää"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Kopioi URL-osoite"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Tekstin valinta..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Tekstin valinta"</string>
@@ -919,22 +916,14 @@
<item quantity="one" msgid="1634101450343277345">"Avoin wifi-verkko käytettävissä"</item>
<item quantity="other" msgid="7915895323644292768">"Avoimia wifi-verkkoja käytettävissä"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Wifi-verkko poistettu käytöstä"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Wifi-verkko oli tilapäisesti pois käytöstä huonon yhteyden vuoksi."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Suora wifi-yhteys"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Käynnistä suora wifi-toiminto. Wifi-yhteyspistetoiminto poistetaan käytöstä."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Suoran wifi-yhteyden käynnistäminen epäonnistui"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Suoran wifi-yhteyden muodostuspyyntö osoitteesta <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Hyväksy valitsemalla OK."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Suoran wifi-yhteyden muodostuspyyntö osoitteesta <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Jatka antamalla PIN-koodi."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"WPS-PIN <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> tulee merkitä vertaislaitteeseen <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g>, jotta yhteyden muodostamista voidaan jatkaa"</string>
<string name="select_character" msgid="3365550120617701745">"Lisää merkki"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Tuntematon sovellus"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Tekstiviestien lähettäminen"</string>
@@ -983,8 +972,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Kytketty medialaitteena"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Kytketty kamerana"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Kytketty asennusohjelmana"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Liitetty USB-laitteeseen"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Käytä muita USB-vaihtoehtoja koskettamalla"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Alusta USB-tila"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"Alusta SD-kortti"</string>
@@ -1104,6 +1092,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Valitse tili"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Lisää"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Vähennä"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Siirry etusivulle"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Siirry ylös"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Lisää asetuksia"</string>
@@ -1117,6 +1121,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G-tiedonsiirto pois käytöstä"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobiilitiedonsiirto pois käytöstä"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"ota käyttöön napauttamalla"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Suojausvarmenne"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Varmenne on voimassa."</string>
<string name="issued_to" msgid="454239480274921032">"Varmenteen saaja:"</string>
@@ -1132,10 +1144,7 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256-tunnistetiedosto"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1-tunnistetiedosto"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Näytä kaikki..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Valitse toiminto"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Jaa seuraavien kautta:"</string>
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Laite lukittu."</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index a10b203..2821a9b 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"Couper"</string>
<string name="copy" msgid="2681946229533511987">"Copier"</string>
<string name="paste" msgid="5629880836805036433">"Coller"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Presse-papiers vide"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Copier l\'URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Sélect. le texte..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Sélection de texte"</string>
@@ -1104,6 +1105,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Sélectionner un compte"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Augmenter"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Diminuer"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Retour à l\'accueil"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Parcourir vers le haut"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Plus d\'options"</string>
@@ -1117,6 +1134,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Données 4G désactivées"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Données mobiles désactivées"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"appuyer pour activer"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Certificat de sécurité"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Ce certificat est valide."</string>
<string name="issued_to" msgid="454239480274921032">"Délivré à :"</string>
@@ -1132,10 +1157,8 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"Empreinte SHA-256 :"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"Empreinte SHA-1 :"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Tout afficher..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Sélectionner une activité"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Partager avec..."</string>
<!-- no translation found for status_bar_device_locked (3092703448690669768) -->
<skip />
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 72ea506..e36e51a 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"Izreži"</string>
<string name="copy" msgid="2681946229533511987">"Kopiraj"</string>
<string name="paste" msgid="5629880836805036433">"Zalijepi"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Ništa za lijepljenje"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Kopiraj URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Odabir teksta..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Odabir teksta"</string>
@@ -880,12 +881,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Aplikacija preusmjerena"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> se izvodi sada."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> pokrenuta je prva."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Mjerilo"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Uvijek prikaži"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Ponovno omogući ovo uz Postavke > Aplikacije > Upravljanje aplikacijama."</string>
<string name="smv_application" msgid="295583804361236288">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) prekršila je svoje vlastito pravilo StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> prekršio je svoje vlastito pravilo StrictMode."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Izvodi se <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -941,18 +939,12 @@
<string name="sms_control_message" msgid="1289331457999236205">"Šalje se velika količina SMS poruka. Odaberite \"U redu\" za nastavak, ili za prekid slanja odaberite \"Odustani\"."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"U redu"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Odustani"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"SIM kartica uklonjena"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Mobilna mreža neće biti dostupna sve dok ne vratite SIM karticu."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Gotovo"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"SIM kartica dodana"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Morate ponovno pokrenuti uređaj za pristup mobilnoj mreži."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Ponovno pokreni"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Postavljanje vremena"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Postavi datum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Postavi"</string>
@@ -1104,6 +1096,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Odaberite račun"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Povećaj"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Smanji"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Kreni na početnu"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Kreni gore"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Više opcija"</string>
@@ -1117,6 +1125,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G podaci su onemogućeni"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobilni podaci su onemogućeni"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"Dotaknite za omogućivanje"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Sigurnosni certifikat"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Ovaj je certifikat valjan."</string>
<string name="issued_to" msgid="454239480274921032">"Izdano za:"</string>
@@ -1132,10 +1148,8 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 otisak prsta:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 otisak prsta:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Prikaži sve..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Odaberite aktivnost"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Dijeli sa..."</string>
<!-- no translation found for status_bar_device_locked (3092703448690669768) -->
<skip />
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 3a5fd40..3c41460 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Lehetővé teszi az alkalmazások számára, hogy figyeljék a lenyomott billentyűket még másik alkalmazás használata esetén is (például jelszó beírásakor). A normál alkalmazásoknak erre soha nincs szüksége."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"összekapcsolás egy beviteli módszerrel"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Lehetővé teszi a használó számára a beviteli módszer legfelső szintű kezelőfelületéhez való csatlakozást. A normál alkalmazások soha nem használják ezt."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"csatlakozás szövegszolgáltatáshoz"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Lehetővé teszi, hogy a tulajdonos egy szöveges szolgáltatás felső szintjéhez kapcsolódjon (pl. SpellCheckerService). A szokásos alkalmazásokhoz szinte soha nincs szükség rá."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"összekapcsolás háttérképpel"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Lehetővé teszi a használó számára, hogy csatlakozzon egy háttérkép legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szüksége."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"csatlakozás modulszolgáltatáshoz"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Lehetővé teszi egy alkalmazás számára, hogy módosítsa a telefonon tárolt böngészési előzményeket és könyvjelzőket. A rosszindulatú alkalmazások felhasználhatják ezt a böngésző adatainak törlésére vagy módosítására."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"ébresztő beállítása az ébresztőórában"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Lehetővé teszi az alkalmazások számára, hogy beállítsanak egy ébresztőt egy telepített ébresztőóra alkalmazásban. Egyes ilyen alkalmazásokban lehet, hogy nem működik ez a funkció."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Hozzáférés az alkalmazás által kezelt hangüzenetekhez"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Lehetővé teszi, hogy az alkalmazás csak azokat a hangüzeneteket tárolja és kérje le, amelyekhez a kapcsolódó szolgáltatás hozzáfér."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"A böngésző helymeghatározási engedélyeinek módosítása"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Lehetővé teszi egy alkalmazás számára, hogy módosítsa a böngésző helymeghatározási engedélyeit. A rosszindulatú alkalmazások kihasználhatják ezt arra, hogy helyadatokat küldjenek tetszőleges webhelyeknek."</string>
<string name="save_password_message" msgid="767344687139195790">"Szeretné, hogy a böngésző megjegyezze a jelszót?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Kivágás"</string>
<string name="copy" msgid="2681946229533511987">"Másolás"</string>
<string name="paste" msgid="5629880836805036433">"Beillesztés"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Nincs mit bemásolni"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"URL másolása"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Szöveg kijelölése..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Szöveg kijelölése"</string>
@@ -880,12 +877,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Alk. átirányítva"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> éppen fut."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> volt eredetileg elindítva."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Skála"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Mindig megjelenik"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Ismételt bekapcsolás a Beállítások > Alkalmazások > Alkalmazások kezelése alatt."</string>
<string name="smv_application" msgid="295583804361236288">"<xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás (<xliff:g id="PROCESS">%2$s</xliff:g> folyamat) megsértette az általa kényszerített Szigorú üzemmód irányelvet."</string>
<string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> folyamat megsértette az általa kényszerített Szigorú üzemmód irányelvet."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> fut"</string>
@@ -919,40 +913,26 @@
<item quantity="one" msgid="1634101450343277345">"Nyílt Wi-Fi hálózat elérhető"</item>
<item quantity="other" msgid="7915895323644292768">"Nyílt Wi-Fi hálózatok elérhetők"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Egy Wi-Fi hálózat le lett tiltva"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"A Wi-Fi hálózat átmenetileg letiltásra került a gyenge kapcsolat miatt."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Wi-Fi Direct indítása. A Wi-Fi kliens/hotspot kikapcsol."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Nem sikerült elindítani a Wi-Fi Direct kapcsolatot"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Wi-Fi Direct kapcsolódási kérés a következőtől: <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Az elfogadáshoz kattintson az OK gombra."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Wi-Fi Direct csatlakoztatási kérés a következőtől: <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Adja meg a PIN kódot a folytatáshoz."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"A(z) <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> WPS PIN kódot kell beírni a partnereszközön (<xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g>) a csatlakoztatás folytatásához"</string>
<string name="select_character" msgid="3365550120617701745">"Karakter beszúrása"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Ismeretlen alkalmazás"</string>
<string name="sms_control_title" msgid="7296612781128917719">"SMS-ek küldése"</string>
<string name="sms_control_message" msgid="1289331457999236205">"Nagyszámú SMS-t kíván elküldeni. A folytatáshoz válassza az \"OK\", a küldés leállításához a \"Mégse\" lehetőséget."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Mégse"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"SIM-kártya eltávolítva"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"A mobilhálózat addig nem lesz elérhető, amíg nem cseréli ki a SIM-kártyát."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Kész"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"SIM-kártya hozzáadva"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"A mobilhálózat eléréséhez újra kell indítania eszközét."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Újraindítás"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Idő beállítása"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Dátum beállítása"</string>
<string name="date_time_set" msgid="5777075614321087758">"Beállítás"</string>
@@ -983,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Csatlakoztatva médiaeszközként"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Csatlakoztatva kameraként"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Csatlakoztatva telepítőként"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Csatlakoztatva egy USB-kiegészítőhöz"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Érintse meg a további USB-opciókért"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Az USB-tár formázása"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"SD-kártya formázása"</string>
@@ -1104,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Fiók kiválasztása"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Növelés"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Csökkentés"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Ugrás a főoldalra"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Felfele mozgás"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"További lehetőségek"</string>
@@ -1117,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G adatforgalom letiltva"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobil adatforgalom letiltva"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"koppintson az engedélyezéshez"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Biztonsági tanúsítvány"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"A tanúsítvány érvényes."</string>
<string name="issued_to" msgid="454239480274921032">"Kiállítva a következőnek:"</string>
@@ -1134,6 +1137,5 @@
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Összes megtekintése..."</string>
<string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Tevékenység kiválasztása"</string>
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Megosztás..."</string>
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Az eszköz le van zárva."</string>
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 85b8012..66a742f 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Mengizinkan aplikasi melihat tombol yang Anda tekan bahkan ketika berinteraksi dengan aplikasi lain (seperti memasukkan sandi). Tidak pernah diperlukan untuk aplikasi normal."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"mengikat ke metode masukan"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi pada suatu metode masukan. Tidak diperlukan untuk aplikasi normal."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"mengikat ke layanan teks"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi pada suatu layanan teks (mis. SpellCheckerService). Tidak diperlukan untuk aplikasi normal."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"mengikat ke wallpaper"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi dari suatu wallpaper. Tidak diperlukan untuk aplikasi normal."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"mengikat ke layanan widget"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Mengizinkan aplikasi mengubah riwayat atau bookmark Peramban yang tersimpan pada ponsel. Aplikasi hasad dapat menggunakan ini untuk menghapus atau mengubah data Peramban."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"setel alarm di jam alarm"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Perbolehkan aplikasi untuk menyetel alarm di aplikasi jam alarm yang terpasang. Beberapa aplikasi jam alarm tidak dapat menerapkan fitur ini."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Mengakses kotak pesan yang dikelola oleh aplikasi ini"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Memungkinkan aplikasi menyimpan dan mengambil kotak pesan yang hanya dapat diakses oleh layanan terkait."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Ubah izin geolokasi Peramban"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Mengizinkan aplikasi mengubah izin geolokasi Peramban. Aplikasi hasad dapat menggunakan ini untuk mengizinkan pengiriman informasi lokasi ke situs web sembarangan."</string>
<string name="save_password_message" msgid="767344687139195790">"Apakah Anda ingin peramban menyimpan sandi ini?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Potong"</string>
<string name="copy" msgid="2681946229533511987">"Salin"</string>
<string name="paste" msgid="5629880836805036433">"Tempel"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Tidak ada yang disalin"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Salin URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Pilih teks..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Pemilihan teks"</string>
@@ -919,22 +916,14 @@
<item quantity="one" msgid="1634101450343277345">"Jaringan Wi-Fi terbuka tersedia"</item>
<item quantity="other" msgid="7915895323644292768">"Jaringan Wi-Fi terbuka tersedia"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Jaringan Wi-Fi sedang dinonaktifkan"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Untuk sementara jaringan Wi-Fi dinonaktifkan karena sambungan buruk."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Langsung"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Mulai operasi Wi-Fi Langsung. Opsi ini akan mematikan operasi hotspot/klien WiFi."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Gagal memulai Wi-Fi Langsung"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Permintaan penyiapan sambungan WiFI Langsung dari <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Klik OK untuk menerima."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Permintaan penyiapan sambungan WiFi Langsung dari <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Masukkan pin untuk melanjutkan."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"Pin WPS <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> harus dimasukkan pada perangkat rekan <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> agar penyiapan sambungan dapat dilanjutkan"</string>
<string name="select_character" msgid="3365550120617701745">"Sisipkan huruf"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Aplikasi tidak dikenal"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Mengirim pesan SMS"</string>
@@ -983,8 +972,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Terhubung sebagai perangkat media"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Terhubung sebagai kamera"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Terhubung sebagai pemasang"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tersambung ke aksesori USB"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Sentuh untuk opsi USB lainnya"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Format penyimpanan USB"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"Format kartu SD"</string>
@@ -1104,6 +1092,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Pilih akun"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Penambahan"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Pengurangan"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Navigasi ke beranda"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navigasi naik"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Opsi lainnya"</string>
@@ -1117,6 +1121,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Data 4G dinonaktifkan"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Data seluler dinonaktifkan"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"ketuk untuk mengaktifkan"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Sertifikat keamanan"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Sertifikat ini valid."</string>
<string name="issued_to" msgid="454239480274921032">"Diterbitkan ke:"</string>
@@ -1132,10 +1144,7 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"Sidik jari SHA-256:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"Sidik jari SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Lihat semua..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Pilih aktivitas"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Berbagi dengan..."</string>
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Perangkat terkunci."</string>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 147cb70..4137fb7 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Consente il rilevamento da parte delle applicazioni dei tasti premuti anche durante l\'interazione con un\'altra applicazione (come nel caso di inserimento di una password). Non dovrebbe essere mai necessario per le normali applicazioni."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"associaz. a un metodo di inserimento"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Consente l\'associazione all\'interfaccia principale di un metodo di inserimento. Non dovrebbe essere mai necessario per le normali applicazioni."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"associazione a un servizio di testo"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio di testo (ad esempio SpellCheckerService). Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"associazione a sfondo"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Consente l\'associazione di uno sfondo all\'interfaccia principale. Non dovrebbe mai essere necessario per le normali applicazioni."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"associazione a un servizio widget"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Consente a un\'applicazione di modificare la cronologia o i segnalibri del browser memorizzati sul telefono. Le applicazioni dannose possono sfruttare questa possibilità per cancellare o modificare i dati del browser."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"impostazione allarmi nella sveglia"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Consente all\'applicazione di impostare un allarme in un\'applicazione sveglia installata. Alcune applicazioni sveglia potrebbero non supportare questa funzione."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Accesso ai messaggi vocali gestiti da questa applicazione"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Consente all\'applicazione di memorizzare e recuperare soltanto i messaggi vocali a cui può accedere il suo servizio associato."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Modifica le autorizzazioni di localizzazione geografica del browser"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Consente a un\'applicazione di modificare le autorizzazioni di localizzazione geografica del browser. Le applicazioni dannose possono utilizzare questa autorizzazione per consentire l\'invio di informazioni sulla posizione a siti web arbitrari."</string>
<string name="save_password_message" msgid="767344687139195790">"Memorizzare la password nel browser?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Taglia"</string>
<string name="copy" msgid="2681946229533511987">"Copia"</string>
<string name="paste" msgid="5629880836805036433">"Incolla"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Niente da incollare"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Copia URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Seleziona testo..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Selezione testo"</string>
@@ -880,12 +877,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Applicazione reindirizzata"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> è ora in esecuzione."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> già avviata."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Scala"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Mostra sempre"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Riattiva questa modalità utilizzando Impostazioni > Applicazioni > Gestisci applicazioni."</string>
<string name="smv_application" msgid="295583804361236288">"L\'applicazione <xliff:g id="APPLICATION">%1$s</xliff:g> (processo <xliff:g id="PROCESS">%2$s</xliff:g>) ha violato la norma StrictMode autoimposta."</string>
<string name="smv_process" msgid="5120397012047462446">"Il processo <xliff:g id="PROCESS">%1$s</xliff:g> ha violato la norma StrictMode autoimposta."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> in esecuzione"</string>
@@ -919,40 +913,26 @@
<item quantity="one" msgid="1634101450343277345">"Rete Wi-Fi aperta disponibile"</item>
<item quantity="other" msgid="7915895323644292768">"Reti Wi-Fi aperte disponibili"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"È stata disattivata una rete Wi-Fi"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Una rete Wi-Fi è stata temporaneamente disattivata a causa di una pessima connessione."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Avvia funzionamento Wi-Fi Direct. Verrà disattivato il funzionamento con hotspot/client Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Impossibile avviare Wi-Fi Direct"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Richiesta di configurazione della connessione Wi-Fi Direct da <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Fai clic su OK per accettare."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Richiesta di configurazione della connessione Wi-Fi Direct da <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Inserisci il PIN per continuare."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"Per la continuazione della configurazione della connessione è necessario inserire un codice PIN WPS <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> sul dispositivo peer <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g>."</string>
<string name="select_character" msgid="3365550120617701745">"Inserisci carattere"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Applicazione sconosciuta"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Invio SMS"</string>
<string name="sms_control_message" msgid="1289331457999236205">"È in corso l\'invio di numerosi SMS. Seleziona \"OK\" per continuare, oppure \"Annulla\" per interrompere l\'invio."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Annulla"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"Scheda SIM rimossa"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"La rete mobile sarà disponibile dopo la sostituzione della scheda SIM."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Fine"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"Scheda SIM aggiunta"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Devi riavviare il dispositivo per poter accedere alla rete mobile."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Riavvia"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Imposta ora"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Imposta data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Imposta"</string>
@@ -983,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Collegato come dispositivo multimediale"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Collegato come fotocamera"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Collegato come installer"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Collegato a un accessorio USB"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Tocca per altre opzioni USB"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Formatta archivio USB"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"Formatta scheda SD"</string>
@@ -1104,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Seleziona un account"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Aumenta"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Diminuisci"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Vai alla home page"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Vai in alto"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Altre opzioni"</string>
@@ -1117,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Dati 4G disattivati"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Dati mobili disattivati"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"tocca per attivare"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Certificato di protezione"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Questo certificato è valido."</string>
<string name="issued_to" msgid="454239480274921032">"Rilasciato a:"</string>
@@ -1134,6 +1137,5 @@
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Mostra tutto..."</string>
<string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Seleziona attività"</string>
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Condividi con..."</string>
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloccato."</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 159af64..873e5bc 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"גזור"</string>
<string name="copy" msgid="2681946229533511987">"העתק"</string>
<string name="paste" msgid="5629880836805036433">"הדבק"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"אין מה להדביק"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"העתק כתובת אתר"</string>
<string name="selectTextMode" msgid="6738556348861347240">"בחר טקסט..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"בחירת טקסט"</string>
@@ -1104,6 +1105,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"בחר חשבון"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"הוספה"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"הפחתה"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"נווט לדף הבית"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"נווט למעלה"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"אפשרויות נוספות"</string>
@@ -1117,6 +1134,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"נתוני 4G מושבתים"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"נתונים לנייד מושבתים"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"הקש כדי להפעיל"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"אישור אבטחה"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"אישור זה תקף."</string>
<string name="issued_to" msgid="454239480274921032">"הוקצה ל:"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index c2b6dd2..16266d0 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"別のアプリケーションへの入力(パスワードなど)でもキー入力を監視することをアプリケーションに許可します。通常のアプリケーションではまったく必要ありません。"</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"入力方法に関連付ける"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"入力方法のトップレベルインターフェースに関連付けることを所有者に許可します。通常のアプリケーションにはまったく必要ありません。"</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"テキストサービスにバインド"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"テキストサービス(SpellCheckerServiceなど)のトップレベルインターフェースへのバインドを所有者に許可します。通常のアプリケーションでは不要です。"</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"壁紙にバインド"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"壁紙のトップレベルインターフェースへのバインドを所有者に許可します。通常のアプリケーションでは不要です。"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ウィジェットサービスにバインド"</string>
@@ -712,9 +710,9 @@
<string name="autofill_county" msgid="237073771020362891">"郡"</string>
<string name="autofill_island" msgid="4020100875984667025">"島"</string>
<string name="autofill_district" msgid="8400735073392267672">"地区"</string>
- <string name="autofill_department" msgid="5343279462564453309">"県"</string>
+ <string name="autofill_department" msgid="5343279462564453309">"部署"</string>
<string name="autofill_prefecture" msgid="2028499485065800419">"都道府県"</string>
- <string name="autofill_parish" msgid="8202206105468820057">"行政区"</string>
+ <string name="autofill_parish" msgid="8202206105468820057">"教区"</string>
<string name="autofill_area" msgid="3547409050889952423">"地域"</string>
<string name="autofill_emirate" msgid="2893880978835698818">"首長国"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"ブラウザの履歴とブックマークを読み取る"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"携帯電話に保存されているブラウザの履歴やブックマークの修正をアプリケーショに許可します。これにより悪意のあるアプリケーションが、ブラウザのデータを消去または変更する恐れがあります。"</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"アラームの設定"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"インストール済みアラームアプリケーションのアラーム設定をアプリケーションに許可します。この機能が実装されていないアラームアプリケーションもあります。"</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"このアプリケーションで管理されているボイスメールにアクセス"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"関連サービスでアクセス可能なボイスメールのみを保存および取得することをアプリケーションに許可します。"</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"ブラウザの位置情報へのアクセス権を変更"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"ブラウザの位置情報に対するアクセス権の変更をアプリケーションに許可します。この設定では、悪意のあるアプリケーションが任意のウェブサイトに位置情報を送信する可能性があります。"</string>
<string name="save_password_message" msgid="767344687139195790">"このパスワードをブラウザで保存しますか?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"切り取り"</string>
<string name="copy" msgid="2681946229533511987">"コピー"</string>
<string name="paste" msgid="5629880836805036433">"貼り付け"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"クリップボードが空です"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"URLをコピー"</string>
<string name="selectTextMode" msgid="6738556348861347240">"テキストを選択..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"テキスト選択"</string>
@@ -880,12 +877,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"アプリのリダイレクト"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g>が実行中です。"</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g>が最初に起動していました。"</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"スケール"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"常に表示"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"[設定]>[アプリケーション]>[アプリケーションの管理]で再度有効にできます。"</string>
<string name="smv_application" msgid="295583804361236288">"アプリケーション<xliff:g id="APPLICATION">%1$s</xliff:g>(プロセス<xliff:g id="PROCESS">%2$s</xliff:g>)でStrictModeポリシー違反がありました。"</string>
<string name="smv_process" msgid="5120397012047462446">"プロセス<xliff:g id="PROCESS">%1$s</xliff:g>でStrictModeポリシー違反がありました。"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g>を実行中"</string>
@@ -919,40 +913,26 @@
<item quantity="one" msgid="1634101450343277345">"Wi-Fiオープンネットワークが利用できます"</item>
<item quantity="other" msgid="7915895323644292768">"Wi-Fiオープンネットワークが利用できます"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Wi-Fiネットワークが無効になりました"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"接続の不具合によりWi-Fiネットワークは一時的に無効になりました。"</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Wi-Fi Directの操作を開始します。これによりWi-Fiクライアント/アクセスポイントの操作がオフになります。"</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Wi-Fi Directを開始できませんでした"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"<xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>からのWi-Fi Direct接続設定リクエスト。[OK]をクリックして受け入れます。"</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"<xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>からのWi-Fi Direct接続設定リクエスト。PINを入力して続行します。"</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"接続設定を続行するには、ピアデバイス<xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g>でWPS PIN <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g>を入力する必要があります"</string>
<string name="select_character" msgid="3365550120617701745">"文字を挿入"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"不明なアプリケーション"</string>
<string name="sms_control_title" msgid="7296612781128917719">"SMSメッセージの送信中"</string>
<string name="sms_control_message" msgid="1289331457999236205">"大量のSMSメッセージを送信しようとしています。[OK]で送信、[キャンセル]で中止します。"</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"キャンセル"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"SIMカードが取り外されました"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"モバイルネットワークはSIMカードを交換するまで利用できません。"</string>
+ <string name="sim_done_button" msgid="827949989369963775">"完了"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"SIMカードが追加されました"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"モバイルネットワークにアクセスするには端末を再起動する必要があります。"</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"再起動"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"時刻設定"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"日付設定"</string>
<string name="date_time_set" msgid="5777075614321087758">"設定"</string>
@@ -983,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"メディアデバイスとして接続"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"カメラとして接続"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"インストーラとして接続"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USBアクセサリを接続しました"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"他のUSBオプションをタップしてください"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"USBストレージのフォーマット"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"SDカードをフォーマット"</string>
@@ -1104,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"アカウントを選択"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"増やす"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"減らす"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"ホームへ移動"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"上へ移動"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"その他のオプション"</string>
@@ -1117,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4Gデータが無効になりました"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"モバイルデータが無効になりました"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"有効にするにはタップしてください"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"セキュリティ証明書"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"証明書は有効です。"</string>
<string name="issued_to" msgid="454239480274921032">"発行先:"</string>
@@ -1132,10 +1135,7 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256指紋:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1指紋:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"すべて見る..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"操作の選択"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"共有相手..."</string>
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"端末がロックされています。"</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 0c4c4b8..08a13eb 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"애플리케이션이 다른 애플리케이션과 상호작용할 때에도 사용자가 누르는 키(예: 비밀번호 입력)를 볼 수 있도록 합니다. 일반 애플리케이션에는 절대로 필요하지 않습니다."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"입력 방법 연결"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"권한을 가진 프로그램이 입력 방법에 대한 최상위 인터페이스를 사용하도록 합니다. 일반 애플리케이션에는 절대로 필요하지 않습니다."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"텍스트 서비스 연결"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"사용자가 텍스트 서비스(예: SpellCheckerService)의 최상위 인터페이스에 바인딩할 수 있게 합니다. 일반 애플리케이션에는 절대로 필요하지 않습니다."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"배경화면 연결"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"권한을 가진 프로그램이 배경화면에 대한 최상위 인터페이스를 사용하도록 합니다. 일반 애플리케이션에는 절대로 필요하지 않습니다."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"위젯 서비스와 연결"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"애플리케이션이 휴대전화에 저장된 브라우저 기록 또는 북마크를 수정할 수 있도록 허용합니다. 이 경우 악성 애플리케이션이 브라우저의 데이터를 지우거나 수정할 수 있습니다."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"알람 시계에 알람 설정"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"실치된 알람 시계 애플리케이션에 알람을 설정하도록 허용합니다. 일부 알람 시계 애플리케이션은 이 기능을 구현하지 않을 수 있습니다."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"이 애플리케이션에서 관리하는 음성사서함에 액세스"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"애플리케이션이 관련 서비스에서 액세스할 수 있는 음성사서함만 저장하고 검색할 수 있도록 합니다."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"브라우저 위치 정보 수정 권한"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"애플리케이션이 브라우저의 위치 정보 권한을 수정할 수 있도록 합니다. 악성 애플리케이션이 이를 사용하여 임의의 웹사이트에 위치 정보를 보낼 수도 있습니다."</string>
<string name="save_password_message" msgid="767344687139195790">"브라우저에 이 비밀번호를 저장하시겠습니까?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"잘라내기"</string>
<string name="copy" msgid="2681946229533511987">"복사"</string>
<string name="paste" msgid="5629880836805036433">"붙여넣기"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"붙여넣을 내용이 없습니다."</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"URL 복사"</string>
<string name="selectTextMode" msgid="6738556348861347240">"텍스트 선택..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"텍스트 선택"</string>
@@ -919,22 +916,14 @@
<item quantity="one" msgid="1634101450343277345">"개방형 Wi-Fi 네트워크 사용 가능"</item>
<item quantity="other" msgid="7915895323644292768">"개방형 Wi-Fi 네트워크 사용 가능"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Wi-Fi 네트워크가 사용중지되었습니다."</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Wi-Fi 네트워크가 잘못된 연결로 인해 일시적으로 사용중지되었습니다."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Wi-Fi Direct 작업을 시작합니다. 이 작업으로 Wi-Fi 클라이언트/핫스팟 작업이 사용중지됩니다."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Wi-Fi Direct를 시작하지 못했습니다."</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"<xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>에서 Wi-Fi Direct 연결 설정을 요청합니다. 수락하려면 확인을 클릭하세요."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"<xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>에서 Wi-Fi Direct 연결 설정을 요청합니다. 계속 진행하려면 PIN을 입력하세요."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"연결 설정을 계속하려면 WPS 핀(<xliff:g id="P2P_WPS_PIN">%1$s</xliff:g>)을 피어 기기(<xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g>)에 입력해야 합니다."</string>
<string name="select_character" msgid="3365550120617701745">"문자 삽입"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"알 수 없는 애플리케이션"</string>
<string name="sms_control_title" msgid="7296612781128917719">"SMS 메시지를 보내는 중"</string>
@@ -983,8 +972,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"미디어 기기로 연결됨"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"카메라로 연결됨"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"설치 프로그램으로 연결됨"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB 액세서리에 연결됨"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"다른 USB 옵션을 보려면 터치하세요."</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"USB 저장소 포맷"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"SD 카드 포맷"</string>
@@ -1104,6 +1092,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"계정 선택"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"올리기"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"줄이기"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"홈 탐색"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"위로 탐색"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"옵션 더보기"</string>
@@ -1117,6 +1121,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G 데이터 사용중지됨"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"모바일 데이터 사용중지됨"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"사용하려면 누르세요."</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"보안 인증서"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"유효한 인증서입니다."</string>
<string name="issued_to" msgid="454239480274921032">"발급 대상:"</string>
@@ -1134,6 +1146,5 @@
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"전체 보기..."</string>
<string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"활동 선택"</string>
<string name="share_action_provider_share_with" msgid="1791316789651185229">"공유 대상..."</string>
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"기기 잠김"</string>
</resources>
diff --git a/core/res/res/values-land/arrays.xml b/core/res/res/values-land/arrays.xml
index 92d5a87..fd492ec 100644
--- a/core/res/res/values-land/arrays.xml
+++ b/core/res/res/values-land/arrays.xml
@@ -34,4 +34,11 @@
<item>@drawable/ic_lockscreen_silent</item>
</array>
+ <array name="lockscreen_targets_with_camera">
+ <item>@null</item>
+ <item>@drawable/ic_lockscreen_unlock</item>
+ <item>@null</item>
+ <item>@drawable/ic_lockscreen_camera</item>
+ </array>
+
</resources>
diff --git a/core/res/res/values-land/dimens.xml b/core/res/res/values-land/dimens.xml
index 388eb38..02bb3c8 100644
--- a/core/res/res/values-land/dimens.xml
+++ b/core/res/res/values-land/dimens.xml
@@ -22,7 +22,7 @@
<!-- Default height of a key in the password keyboard for alpha -->
<dimen name="password_keyboard_key_height_alpha">47dip</dimen>
<!-- Default height of a key in the password keyboard for numeric -->
- <dimen name="password_keyboard_key_height_numeric">60dip</dimen>
+ <dimen name="password_keyboard_key_height_numeric">50dip</dimen>
<!-- Default correction for the space key in the password keyboard -->
<dimen name="password_keyboard_spacebar_vertical_correction">2dip</dimen>
<dimen name="preference_widget_width">72dp</dimen>
diff --git a/core/res/res/values-large/themes.xml b/core/res/res/values-large/themes.xml
index 9e3e0bb..871a131 100644
--- a/core/res/res/values-large/themes.xml
+++ b/core/res/res/values-large/themes.xml
@@ -16,6 +16,21 @@
** limitations under the License.
*/
-->
+
+<!--
+===============================================================
+ PLEASE READ
+===============================================================
+
+The Holo themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see themes_device_defaults.xml.
+
+===============================================================
+ PLEASE READ
+===============================================================
+ -->
<resources>
<style name="Theme.Holo.DialogWhenLarge"
parent="@android:style/Theme.Holo.Dialog.MinWidth">
diff --git a/core/res/res/values-large/themes_device_defaults.xml b/core/res/res/values-large/themes_device_defaults.xml
new file mode 100644
index 0000000..52fff5c
--- /dev/null
+++ b/core/res/res/values-large/themes_device_defaults.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+===============================================================
+ PLEASE READ
+===============================================================
+This file contains the themes that are the Device Defaults.
+If you want to edit themes to skin your device, do it here.
+We recommend that you do not edit themes.xml and instead edit
+this file.
+
+Editing this file instead of themes.xml will greatly simplify
+merges for future platform versions and CTS compliance will be
+easier.
+===============================================================
+ PLEASE READ
+===============================================================
+ -->
+<resources>
+ <style name="Theme.DeviceDefault.DialogWhenLarge"
+ parent="@android:style/Theme.DeviceDefault.Dialog.MinWidth">
+ <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+ </style>
+ <style name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar"
+ parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar.MinWidth">
+ <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+ </style>
+ <style name="Theme.DeviceDefault.Light.DialogWhenLarge"
+ parent="@android:style/Theme.DeviceDefault.Light.Dialog.MinWidth">
+ </style>
+ <style name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar"
+ parent="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar.MinWidth">
+ </style>
+</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 1e18e3c..5dc26d8 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"Iškirpti"</string>
<string name="copy" msgid="2681946229533511987">"Kopijuoti"</string>
<string name="paste" msgid="5629880836805036433">"Įklijuoti"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Nėra, ką įklijuoti"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Kopijuoti URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Pasirinkti tekstą..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Teksto pasirinkimas"</string>
@@ -880,12 +881,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Programa nukreipta"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ dabar vykdoma."</string>
<string name="launch_warning_original" msgid="188102023021668683">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ buvo iš pradžių paleista."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Mastelis"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Visada rodyti"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Iš naujo įgalinkite tai apsilankę skiltyje „Nustatymai“ > „Programos“ > „Valdyti programas“."</string>
<string name="smv_application" msgid="295583804361236288">"Programa „<xliff:g id="APPLICATION">%1$s</xliff:g>“ (procesas „<xliff:g id="PROCESS">%2$s</xliff:g>“) pažeidė savo vykdomą „StrictMode“ politiką."</string>
<string name="smv_process" msgid="5120397012047462446">"„<xliff:g id="PROCESS">%1$s</xliff:g>“ procesas pažeidė savo vykdomą „StrictMode“ politiką."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Vykdoma „<xliff:g id="APP">%1$s</xliff:g>“"</string>
@@ -941,18 +939,12 @@
<string name="sms_control_message" msgid="1289331457999236205">"Siunčiama daug SMS pranešimų. Pasirinkite „Gerai“, jei norite tęsti, arba „Atšaukti“, jei norite sustabdyti siuntimą."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"Gerai"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Atšaukti"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"SIM kortelė pašalinta"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Mobiliojo ryšio tinklas bus nepasiekiamas, kol pakeisite SIM kortelę."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Atlikta"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"SIM kortelė pridėta"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Kad pasiektumėte mobiliojo ryšio tinklą, turite iš naujo paleisti įrenginį."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Paleisti iš naujo"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Nustatyti laiką"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Nustatyti datą"</string>
<string name="date_time_set" msgid="5777075614321087758">"Nustatyti"</string>
@@ -1104,6 +1096,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Pasirinkti paskyrą"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Padidinti"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Sumažinti"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Naršyti pagrindinį puslapį"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Naršyti į viršų"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Daugiau parinkčių"</string>
@@ -1117,6 +1125,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G duomenys neleidžiami"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobilieji duomenys neleidžiami"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"jei norite įgalinti, palieskite"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Saugos sertifikatas"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Šis sertifikatas galioja."</string>
<string name="issued_to" msgid="454239480274921032">"Išduota:"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 43d640b..7d845f4 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Ļauj lietojumprogrammām sekot līdzi nospiestajiem taustiņiem, mijiedarbojoties ar citu lietojumprogrammu (piemēram, ievadot paroli). Parastajām lietojumprogrammām nekad nav nepieciešama."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"saistīt ar ievades metodi"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Ļauj īpašniekam saistīt ar ievades metodes augšējā līmeņa saskarni. Parastajām lietojumprogrammām nekad nav nepieciešama."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"saistīt ar īsziņu pakalpojumu"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Ļauj īpašniekam veikt saistīšanu ar īsziņu pakalpojuma augstākā līmeņa interfeisu (piem., SpellCheckerService). Nekad nav nepieciešama parastām lietojumprogrammām."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"saistīt ar tapeti"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Ļauj īpašniekam saistīties ar tapetes augšējā līmeņa saskarni. Parastajās lietojumprogrammās nekad nav nepieciešama."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"saistīt ar logrīka pakalpojumu"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Ļauj lietojumprogrammai pārveidot tālrunī saglabāto pārlūkprogrammas vēsturi un grāmatzīmes. Ļaunprātīgas lietojumprogrammas var to izmantot, lai dzēstu vai pārveidotu pārlūkprogrammas datus."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"iestatīt trauksmi modinātājpulkstenī"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Ļauj lietojumprogrammai iestatīt trauksmi instalētajā modinātājpulksteņa lietojumprogrammā. Dažās modinātājpulksteņu lietojumprogrammās šī funkcija var nebūt īstenojama."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Piekļuve balss pasta ziņojumiem, kas tiek pārvaldīti šajā lietojumprogrammā"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Ļauj lietojumprogrammai glabāt un izgūt tikai tos balss pasta ziņojumus, kuriem var piekļūt no saistītā pakalpojuma."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Pārveidot pārlūkprogrammas ģeogrāfiskās atrašanās vietas atļaujas"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Ļauj lietojumprogrammai pārveidot pārlūkprogrammas ģeogrāfiskās atrašanās vietas atļaujas. Ļaunprātīgas lietojumprogrammas var to izmantot, lai atļautu atrašanās vietas informācijas sūtīšanu uz citām vietnēm."</string>
<string name="save_password_message" msgid="767344687139195790">"Vai vēlaties, lai pārlūkprogrammā tiktu saglabāta šī parole?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Izgriezt"</string>
<string name="copy" msgid="2681946229533511987">"Kopēt"</string>
<string name="paste" msgid="5629880836805036433">"Ielīmēt"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Nav ielīmējamu vien."</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Kopēt URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Atlasīt tekstu..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Teksta atlase"</string>
@@ -880,12 +877,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Lietojumpr. ir novirzīta"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> tagad darbojas."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Sākotnēji tika palaista lietojumprogramma <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Mērogs"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Rādīt vienmēr"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Iespējojiet atkārtoti, izmantojot Iestatījumi > Lietojumprogrammas > Pārvaldīt lietojumprogrammas."</string>
<string name="smv_application" msgid="295583804361236288">"Lietojumprogramma <xliff:g id="APPLICATION">%1$s</xliff:g> (process <xliff:g id="PROCESS">%2$s</xliff:g>) ir pārkāpusi savu pašieviesto StrictMode politiku."</string>
<string name="smv_process" msgid="5120397012047462446">"Process <xliff:g id="PROCESS">%1$s</xliff:g> ir pārkāpis savu pašieviesto StrictMode politiku."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> darbojas"</string>
@@ -919,40 +913,26 @@
<item quantity="one" msgid="1634101450343277345">"Ir pieejams atvērts Wi-Fi tīkls"</item>
<item quantity="other" msgid="7915895323644292768">"Ir pieejami atvērti Wi-Fi tīkli."</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Wi-Fi tīkls tika atspējots."</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Wi-Fi tīkls tika īslaicīgi atspējots sliktas savienojamības dēļ."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Sākt Wi-Fi Direct darbību. Tiks izslēgta Wi-Fi klienta/tīklāja darbība."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Neizdevās palaist Wi-Fi Direct"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Wi-Fi Direct savienojuma iestatīšanas pieprasījums no adreses <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Noklikšķiniet uz Labi, lai apstiprinātu."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Wi-Fi Direct savienojuma iestatīšanas pieprasījums no adreses <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Lai turpinātu, ievadiet PIN."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"Lai turpinātu savienojuma iestatīšanu, vienādranga ierīcē <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> ir jāievada WPS PIN <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g>."</string>
<string name="select_character" msgid="3365550120617701745">"Ievietojiet rakstzīmi"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Nezināma lietojumprogramma"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Īsziņu sūtīšana"</string>
<string name="sms_control_message" msgid="1289331457999236205">"Tiek sūtīts liels īsziņu skaits. Atlasiet Labi, lai turpinātu, vai Atcelt, lai apturētu sūtīšanu."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"Labi"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Atcelt"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"SIM karte ir izņemta."</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Mobilo sakaru tīkls nebūs pieejams, līdz nomainīsiet SIM karti."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Gatavs"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"SIM karte ir pievienota."</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Lai piekļūtu mobilo sakaru tīklam, restartējiet ierīci."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Restartēt"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Laika iestatīšana"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Datuma iestatīšana"</string>
<string name="date_time_set" msgid="5777075614321087758">"Iestatīt"</string>
@@ -983,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Pievienots kā multivides ierīce"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Pievienots kā kamera"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Pievienots kā instalēšanas programma"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ir izveidots savienojums ar USB piederumu."</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Pieskarieties, lai skatītu citas USB opcijas."</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"USB kr. formatēšana"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"SD kartes formatēšana"</string>
@@ -1104,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Atlasīt kontu"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Palielināt"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Samazināt"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Pārvietoties uz sākuma ekrānu"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Pārvietoties augšup"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Vairāk opciju"</string>
@@ -1117,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G dati ir atspējoti"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobilie dati ir atspējoti"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"pieskarieties, lai iespējotu"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Drošības sertifikāts"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Sertifikāts ir derīgs."</string>
<string name="issued_to" msgid="454239480274921032">"Izdots:"</string>
@@ -1132,8 +1135,7 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 identifikators"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 identifikators:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Skatīt visas"</string>
- <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Darbību atlasīšana"</string>
- <string name="share_action_provider_share_with" msgid="1791316789651185229">"Kopīgot ar..."</string>
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Darbības atlase"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Koplietot ar..."</string>
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Ierīce bloķēta"</string>
</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 3921be9..3625fde 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Membenarkan aplikasi melihat kekunci yang anda tekan walaupun semasa berinteraksi dengan aplikasi lain (seperti memasukkan kata laluan). Seharusnya tidak sekali-kali diperlukan untuk aplikasi biasa."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"terikat kepada kaedah input"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi kaedah input itu. Tidak sekali-kali diperlukan untuk aplikasi biasa."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"terikat kepada perkhidmatan teks"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Membenarkan pemegang mengikat kepada antara muka tahap tinggi perkhidmatan teks(mis. PerkhidmatanPenyemakEjaan). Tidak seharusnya diperlukan untuk aplikasi biasa."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"terikat pada kertas dinding"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi kertas dinding. Tidak sekali-kali diperlukan untuk aplikasi biasa."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"terikat kepada perkhidmatan widget"</string>
@@ -726,10 +724,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Membenarkan aplikasi mengubah suai sejarah atau penanda halaman Penyemak Imbas yang disimpan pada telefon anda. Aplikasi berniat jahat boleh menggunakannya untuk memadamkan atau mengubah data Penyemak Imbas anda."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"menetapkan penggera pada jam penggera"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Membenarkan aplikasi menetapkan penggera dalam aplikasi jam penggera yang dipasang. Sesetengah aplikasi jam penggera mungkin tidak melaksanakan ciri ini."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Akses mel suara yang diurus oleh aplikasi ini"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Membenarkan aplikasi menyimpan dan mendapatkan semula mel suara yang boleh diakses oleh perkhidmatan berkaitan sahaja."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Ubah suai kebenaran geolokasi Penyemak Imbas"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Membenarkan aplikasi mengubah suai kebenaran geolokasi Penyemak Imbas. Aplikasi berniat jahat boleh menggunakannya untuk membenarkan penghantaran maklumat lokasi ke sembarangan tapak web."</string>
<string name="save_password_message" msgid="767344687139195790">"Adakah anda mahu penyemak imbas mengingati kata laluan ini?"</string>
@@ -845,7 +841,8 @@
<string name="cut" msgid="3092569408438626261">"Potong"</string>
<string name="copy" msgid="2681946229533511987">"Salin"</string>
<string name="paste" msgid="5629880836805036433">"Tampal"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Tiada apa utk ditmpl"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Salin URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Pilih teks..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Pemilihan teks"</string>
@@ -921,22 +918,14 @@
<item quantity="one" msgid="1634101450343277345">"Rangkaian Wi-Fi terbuka tersedia"</item>
<item quantity="other" msgid="7915895323644292768">"Rangkaian Wi-Fi terbuka tersedia"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Rangkaian Wi-Fi telah dilumpuhkan"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Rangkaian Wi-Fi dilumpuhkan buat sementara waktu kerana sambungan teruk."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Langsung"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Mulakan pengendalian Wi-Fi Langsung. Hal ini akan mematikan pengendalian klien Wi-Fi/titik panas."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Gagal memulakan Wi-Fi Langsung"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Permintaan persediaan sambungan Wi-Fi Langsung dari <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Klik OK untuk menerima."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Permintaan persediaan sambungan Wi-Fi Langsung dari <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Buang pin untuk meneruskan."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"Pin WPS <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> perlu dimasukkan pada peranti rakan <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> untuk penyediaan sambungan untuk meneruskan"</string>
<string name="select_character" msgid="3365550120617701745">"Masukkan aksara"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Aplikasi tidak dikenali"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Menghantar mesej SMS"</string>
@@ -985,8 +974,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Disambungkan sebagai peranti media"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Disambungkan sebagai kamera"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Disambungkan sebagai pemasang"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Disambungkan kepada aksesori USB"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Sentuh untuk mendapatkan pilihan USB yang lain"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Format storan USB"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"Format kad SD"</string>
@@ -1106,6 +1094,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Pilih akaun"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Kenaikan"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Penyusutan"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Navigasi laman utama"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navigasi ke atas"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Lagi pilihan"</string>
@@ -1119,6 +1123,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Data 4G dilumpuhkan"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Data mudah alih dilumpuhkan"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"ketik untuk mendayakan"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Sijil keselamatan"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Sijil ini sah."</string>
<string name="issued_to" msgid="454239480274921032">"Dikeluarkan kepada:"</string>
@@ -1134,10 +1146,7 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"Cap jari SHA-256:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"Cap jari SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Lihat semua..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Pilih aktiviti"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Kongsi dengan..."</string>
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Peranti dikunci."</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 7db3f31..2eada6e 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Lar applikasjonen overvåke tastetrykk selv når interaksjonen er med et annet program (som å skrive inn et passord). Vanlige applikasjoner bør aldri trenge dette."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"binde til en inndatametode"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Lar applikasjonen binde til toppnivågrensesnittet for en inndatametode. Vanlige applikasjoner bør aldri trenge dette."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"binde til en teksttjeneste"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Gir innehaveren rett til å binde seg til øverste grensesnittnivå for en teksttjeneste (f.eks SpellCheckerService). Bør aldri være nødvendig for normal bruk."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"bind til bakgrunnsbilde"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Lar innehaveren binde det øverste nivået av grensesnittet til en bakgrunnsbilder. Skal ikke være nødvendig for vanlige programmer."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bind til modultjenste"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Lar applikasjonen endre nettleserens logg og bokmerker lagret på telefonen. Ondsinnede applikasjoner kan bruke dette til å fjerne eller redigere nettleserens data."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"angi alarm i alarmklokke"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Lar programmet angi en alarm i et installert alarmklokkeprogram. Det kan hende at enkelte alarmklokkeprogrammer ikke implementerer denne funksjonen."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Tilgang til talepostmeldinger administrert av denne applikasjonen"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Gir applikasjonen mulighet til å lagre og hente bare talepostmeldinger som den tilhørende tjenesten har tilgang til."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Endre nettleserens tillatelser for geografisk posisjonering"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Tillater programmet å endre nettleserens tillatelser for geografisk posisjonering. Skadelige programmer kan bruke denne funksjonen til å sende posisjonsopplysninger til vilkårlige nettsteder."</string>
<string name="save_password_message" msgid="767344687139195790">"Ønsker du at nettleseren skal huske dette passordet?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Klipp ut"</string>
<string name="copy" msgid="2681946229533511987">"Kopier"</string>
<string name="paste" msgid="5629880836805036433">"Lim inn"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Ingenting å lime inn"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Kopier URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Marker tekst"</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Merket tekst"</string>
@@ -919,22 +916,14 @@
<item quantity="one" msgid="1634101450343277345">"Åpent trådløsnett i nærheten"</item>
<item quantity="other" msgid="7915895323644292768">"Åpne trådløsnett i nærheten"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Et Wi-Fi-nettverk er deaktivert"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Et Wi-Fi-nettverk er midlertidig deaktivert på grunn av dårlig tilkobling."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Start Wi-Fi Direct-handling. Dette deaktiverer Wi-Fi-klienten og -handlingen."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Kan ikke starte Wi-Fi Direct"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Forespørsel om tilkoblingskonfigurasjon for Wi-Fi Direct fra <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Klikk på OK for å godta."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Forespørsel om tilkoblingskonfigurasjon for Wi-Fi Direct fra <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Oppgi personlig kode for å fortsette."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"Personlig WPS-kode <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> må må oppgis på mottakerenheten <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> for å fortsette tilkoblingskonfigurasjonen"</string>
<string name="select_character" msgid="3365550120617701745">"Sett inn tegn"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Ukjent applikasjon"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Sender SMS-meldinger"</string>
@@ -983,8 +972,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Tilkoblet som medieenhet"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Tilkoblet som kamera"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Tilkoblet som installasjonsprogram"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Koblet til et USB-tilbehør"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Berør for andre USB-alternativer"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Formaterer USB-lagring"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"Formatere minnekort"</string>
@@ -1104,6 +1092,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Velg en konto"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Øke"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Senke"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Gå til startsiden"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Gå opp"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Flere alternativer"</string>
@@ -1117,6 +1121,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G-data er deaktivert"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobildata er deaktivert"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"klikk for å aktivere"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Sikkerhetssertifikat"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Sertifikatet er gyldig."</string>
<string name="issued_to" msgid="454239480274921032">"Utstedt til:"</string>
@@ -1132,10 +1144,7 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256-fingeravtrykk"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1-fingeravtrykk"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Se alle"</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Velg aktivitet"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Del med"</string>
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Enheten er låst."</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 52873e1..21ea3bd 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Hiermee kan een app uw toetsaanslagen registreren, zelfs tijdens de interactie met een andere app (zoals de invoer van een wachtwoord). Nooit vereist voor normale apps."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"verbinden aan een invoermethode"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Hiermee staat u de houder toe zich te verbinden met de hoofdinterface van een invoermethode. Nooit vereist voor normale apps."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"koppelen aan een sms-service"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Hiermee kan de gebruiker koppelen met de hoofdinterface van een sms-service (zoals SpellCheckerService). Dit is niet nodig voor normale apps."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"verbinden met een achtergrond"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Hiermee staat u de houder toe zich te verbinden met de hoofdinterface van een achtergrond. Nooit vereist voor normale apps."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"verbinden met een widgetservice"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Hiermee kan een app de op uw telefoon opgeslagen browsergeschiedenis of bladwijzers wijzigen. Schadelijke apps kunnen hiermee uw browsergegevens verwijderen of wijzigen."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"alarm instellen in wekker"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Hiermee kan de app een alarm instellen in een geïnstalleerde wekker-app. Deze functie wordt door sommige wekker-apps niet geïmplementeerd."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Toegang tot voicemails die door deze app worden beheerd"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Hiermee kan de app alleen voicemails opslaan en ophalen waartoe de bijbehorende service toegang heeft."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Geolocatierechten voor browser aanpassen"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Staat een app toe de geolocatierechten van de browser aan te passen. Schadelijke apps kunnen dit gebruiken om locatiegegevens te verzenden naar willekeurige websites."</string>
<string name="save_password_message" msgid="767344687139195790">"Wilt u dat de browser dit wachtwoord onthoudt?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Knippen"</string>
<string name="copy" msgid="2681946229533511987">"Kopiëren"</string>
<string name="paste" msgid="5629880836805036433">"Plakken"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Niets te plakken"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"URL kopiëren"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Tekst selecteren..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Tekstselectie"</string>
@@ -880,12 +877,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"App omgeleid"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> is nu actief."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> was het eerst gestart."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Schaal"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Altijd weergeven"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Dit opnieuw inschakelen via \'Instellingen\' > \'Apps\' > \'Apps beheren\'."</string>
<string name="smv_application" msgid="295583804361236288">"De app <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) heeft het zelf afgedwongen StrictMode-beleid geschonden."</string>
<string name="smv_process" msgid="5120397012047462446">"Het proces <xliff:g id="PROCESS">%1$s</xliff:g> heeft het zelf afgedwongen StrictMode-beleid geschonden."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> wordt uitgevoerd"</string>
@@ -919,40 +913,26 @@
<item quantity="one" msgid="1634101450343277345">"Open Wi-Fi-netwerk beschikbaar"</item>
<item quantity="other" msgid="7915895323644292768">"Open Wi-Fi-netwerken beschikbaar"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Een Wi-Fi-netwerk is uitgeschakeld"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Een Wi-Fi-netwerk werd wegens slechte connectiviteit tijdelijk uitgeschakeld."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Bewerking van Wi-Fi Direct starten. Hierdoor wordt de bewerking van Wi-Fi-client/hotspot uitgeschakeld."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Wi-Fi Direct starten is mislukt"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Configuratieverzoek voor verbinding met Wi-Fi Direct van <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Klik op \'OK\' om te accepteren."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Configuratieverzoek van <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g> voor verbinding met Wi-Fi Direct. Geef de pincode op om door te gaan."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"WPS-pincode <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> moet worden ingevoerd op peerapparaat <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g>, zodat het instellen van de verbinding kan worden voortgezet"</string>
<string name="select_character" msgid="3365550120617701745">"Teken invoegen"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Onbekende app"</string>
<string name="sms_control_title" msgid="7296612781128917719">"SMS-berichten verzenden"</string>
<string name="sms_control_message" msgid="1289331457999236205">"Er wordt een groot aantal SMS-berichten verzonden. Selecteer \'OK\' om door te gaan of \'Annuleren\' om de verzending te stoppen."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Annuleren"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"Simkaart verwijderd"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Het mobiele netwerk is niet beschikbaar totdat u de simkaart vervangt."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Gereed"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"Simkaart aangesloten"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"U moet uw apparaat opnieuw starten voor toegang tot het mobiele netwerk."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Opnieuw starten"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Tijd instellen"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Datum instellen"</string>
<string name="date_time_set" msgid="5777075614321087758">"Instellen"</string>
@@ -983,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Gekoppeld als media-apparaat"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Gekoppeld als camera"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Gekoppeld als installatieprogramma"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Aangesloten op een USB-accessoire"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Raak aan voor andere USB-opties"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"USB-opslag formatt."</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"SD-kaart formatteren"</string>
@@ -1104,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Selecteer een account"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Hoger"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Lager"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Navigeren naar startpositie"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Omhoog navigeren"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Meer opties"</string>
@@ -1117,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G-gegevens uitgeschakeld"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobiele gegevens uitgeschakeld"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"tik om in te schakelen"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Beveiligingscertificaat"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Dit certificaat is geldig."</string>
<string name="issued_to" msgid="454239480274921032">"Uitgegeven voor:"</string>
@@ -1134,6 +1137,5 @@
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Alle bekijken..."</string>
<string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Activiteit selecteren"</string>
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Delen met..."</string>
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Apparaat vergrendeld."</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index eedf51a..2d99ef0 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Pozwala aplikacjom na śledzenie naciskanych klawiszy, nawet podczas pracy z innym programem (na przykład podczas wpisywania hasła). Nigdy nie powinno być potrzebne normalnym aplikacjom."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"powiązanie ze sposobem wprowadzania tekstu"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Pozwala na powiązanie wybranego sposobu wprowadzania tekstu z interfejsem najwyższego poziomu. To uprawnienie nie powinno być nigdy wymagane przez zwykłe aplikacje."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"powiąż z usługą SMS"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Zezwala posiadaczowi na utworzenie powiązania z interfejsem najwyższego poziomu usługi tekstowej (np. SpellCheckerService). Opcja nie powinna być nigdy potrzebna w przypadku zwykłych aplikacji."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"powiązanie z tapetą"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Umożliwia posiadaczowi powiązać interfejs najwyższego poziomu dla tapety. Nie powinno być nigdy potrzebne w przypadku zwykłych aplikacji."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"powiązanie z usługą widżetów"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Umożliwia aplikacji modyfikowanie historii lub zakładek przeglądarki zapisanych w telefonie. Złośliwe aplikacje mogą używać tej opcji do usuwania lub modyfikowania danych przeglądarki."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"ustaw alarm w budziku"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Umożliwia aplikacji ustawienie alarmu w zainstalowanej aplikacji budzika. W niektórych aplikacjach budzika funkcja ta może nie być zaimplementowana."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Dostęp do wiadomości głosowych zarządzanych przez tę aplikację"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Zezwala aplikacji na przechowywanie i pobieranie tylko tych wiadomości głosowych, do których ma dostęp powiązana z nią usługa."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Modyfikowanie uprawnień przeglądarki dotyczących lokalizacji geograficznej"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Zezwala aplikacji na modyfikowanie uprawnień przeglądarki dotyczących lokalizacji geograficznej. Złośliwe aplikacje mogą używać tej opcji do wysyłania informacji o lokalizacji do dowolnych witryn internetowych."</string>
<string name="save_password_message" msgid="767344687139195790">"Czy chcesz, aby zapamiętać to hasło w przeglądarce?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Wytnij"</string>
<string name="copy" msgid="2681946229533511987">"Kopiuj"</string>
<string name="paste" msgid="5629880836805036433">"Wklej"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Schowek jest pusty"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Kopiuj adres URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Zaznacz tekst"</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Zaznaczanie tekstu"</string>
@@ -880,12 +877,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Aplikacja przekierowana"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest uruchomiona."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> została pierwotnie uruchomiona."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Skala"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Zawsze pokazuj"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Aby włączyć ponownie, skorzystaj z opcji Ustawienia > Aplikacje > Zarządzaj aplikacjami."</string>
<string name="smv_application" msgid="295583804361236288">"Aplikacja <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) naruszyła wymuszone przez siebie zasady StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> naruszył wymuszone przez siebie zasady StrictMode."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Działa <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -919,40 +913,26 @@
<item quantity="one" msgid="1634101450343277345">"Otwórz dostępne sieci Wi-Fi"</item>
<item quantity="other" msgid="7915895323644292768">"Otwórz dostępne sieci Wi-Fi"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Sieć Wi-Fi została wyłączona."</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Sieć Wi-Fi została tymczasowo wyłączona z powodu niskiej jakości połączenia."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Rozpocznij pracę w trybie Wi-Fi Direct. Spowoduje to wyłączenie trybu klienta lub punktu dostępu Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Nie można uruchomić Wi-Fi Direct."</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Odebrano żądanie konfiguracji połączenia Wi-Fi Direct z urządzenia <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Kliknij przycisk OK, aby zaakceptować."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Otrzymano żądanie konfiguracji połączenia Wi-Fi Direct z urządzenia <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Wprowadź kod PIN, aby kontynuować."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"Aby kontynuować konfigurowanie połączenia, na drugim urządzeniu <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> należy wpisać kod PIN WPS <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g>."</string>
<string name="select_character" msgid="3365550120617701745">"Wstaw znak"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Nieznana aplikacja"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Wysyłanie wiadomości SMS"</string>
<string name="sms_control_message" msgid="1289331457999236205">"Wysyłana jest duża liczba wiadomości SMS. Wybierz „OK”, aby kontynuować, lub „Anuluj”, aby zatrzymać wysyłanie."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Anuluj"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"Karta SIM wyjęta"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Sieć komórkowa będzie niedostępna, dopóki nie włożysz w powrotem karty SIM."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Gotowe"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"Dodano kartę SIM"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Musisz ponownie uruchomić urządzenie, aby korzystać z sieci komórkowej."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Uruchom ponownie"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Ustaw godzinę"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Ustaw datę"</string>
<string name="date_time_set" msgid="5777075614321087758">"Ustaw"</string>
@@ -983,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Podłączono jako urządzenie multimedialne."</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Podłączono jako aparat."</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Podłączono jako nośnik instalacyjny."</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Podłączono akcesorium USB"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Dotknij, aby wyświetlić inne opcje USB."</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Formatuj nośnik USB"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"Formatuj kartę SD"</string>
@@ -1104,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Wybierz konto"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Zwiększ"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Zmniejsz"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Przejdź do strony głównej"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Przejdź wyżej"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Więcej opcji"</string>
@@ -1117,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Wyłączono transmisję danych 4G"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Wyłączono komórkową transm. danych"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"dotknij, aby włączyć"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Certyfikat zabezpieczeń"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Certyfikat jest ważny."</string>
<string name="issued_to" msgid="454239480274921032">"Wystawiony dla:"</string>
@@ -1134,6 +1137,5 @@
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Pokaż wszystkie"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Wybierz czynność"</string>
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Udostępnij..."</string>
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Urządzenie zablokowane."</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index c89577d..cae3318 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"Cortar"</string>
<string name="copy" msgid="2681946229533511987">"Copiar"</string>
<string name="paste" msgid="5629880836805036433">"Colar"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Nada para colar"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Seleccionar texto..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Selecção de texto"</string>
@@ -880,12 +881,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Aplicação redireccionada"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> está agora a ser executado."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> foi originalmente iniciado."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Escala"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Mostrar sempre"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Reativar modo através das Definições > Aplicações > Gerir aplicações."</string>
<string name="smv_application" msgid="295583804361236288">"A aplicação <xliff:g id="APPLICATION">%1$s</xliff:g> (processo <xliff:g id="PROCESS">%2$s</xliff:g>) violou a política StrictMode auto-imposta."</string>
<string name="smv_process" msgid="5120397012047462446">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> violou a política StrictMode auto-imposta."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> em execução"</string>
@@ -941,18 +939,12 @@
<string name="sms_control_message" msgid="1289331457999236205">"Está a ser enviado um grande número de mensagens SMS. Seleccione \"OK\" para continuar ou \"Cancelar\" para parar o envio."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Cancelar"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"Cartão SIM removido"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"A rede de telemóvel só estará disponível quando substituir o cartão SIM."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Concluído"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"Cartão SIM adicionado"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"É necessário reiniciar o aparelho para aceder à rede de telemóvel."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Reiniciar"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Definir hora"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Definir data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
@@ -1104,6 +1096,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Seleccionar conta"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Aumentar"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Diminuir"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Navegar para página inicial"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navegar para cima"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Mais opções"</string>
@@ -1117,6 +1125,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Os dados 4G estão desativados"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Os dados móveis estão desativados"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"toque para ativar"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Certificado de segurança"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Este certificado é válido."</string>
<string name="issued_to" msgid="454239480274921032">"Emitido para:"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 1a7e0a8..8f130a6 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Permite que os aplicativos vejam as teclas que você pressiona, mesmo quando estiver interagindo com outro aplicativo (como ao digitar uma senha). Aplicativos normais não devem precisar disso em momento algum."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"vincular a um método de entrada"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Permite que o detentor se sujeite à interface de nível superior de um método de entrada. Aplicativos normais não devem precisar disso em momento algum."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"sujeitar-se a um serviço de texto"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Permite que o titular se sujeite à interface de nível superior de um serviço de texto (por exemplo, SpellCheckerService). Não deve ser necessário para aplicativos normais."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"sujeitar-se a um plano de fundo"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Permite que o detentor se sujeite à interface de nível superior de um plano de fundo. Aplicativos normais não devem precisar disso em momento algum."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"sujeitar-se a um serviço de widget"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Permite que um aplicativo modifique o histórico ou os favoritos do Navegador armazenados no seu telefone. Aplicativos maliciosos podem usar isso para apagar ou modificar os dados do seu Navegador."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"definir alarme no despertador"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Permite que o aplicativo defina um alarme em um aplicativo de despertador instalado. Talvez alguns aplicativos de despertador não implementem esse recurso."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Acessar mensagens de voz gerenciadas por este aplicativo"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Permite que o aplicativo armazene e recupere somente mensagens de voz que seu serviço associado acessa."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Modifique as permissões de geolocalização do seu navegador"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Permite que um aplicativo modifique as permissões de geolocalização do navegador. Aplicativos maliciosos podem usar isso para permitir o envio de informações de localização a sites arbitrários."</string>
<string name="save_password_message" msgid="767344687139195790">"Deseja que o navegador lembre desta senha?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Recortar"</string>
<string name="copy" msgid="2681946229533511987">"Copiar"</string>
<string name="paste" msgid="5629880836805036433">"Colar"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Nada para colar"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Selecionar texto..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Seleção de texto"</string>
@@ -880,12 +877,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Aplicativo redirecionado"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> não está em execução."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> foi iniciado."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Escala"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Mostrar sempre"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Reativar em Configurações > Aplicativos > Gerenciar aplicativos."</string>
<string name="smv_application" msgid="295583804361236288">"O aplicativo <xliff:g id="APPLICATION">%1$s</xliff:g> (processo <xliff:g id="PROCESS">%2$s</xliff:g>) violou a política StrictMode imposta automaticamente."</string>
<string name="smv_process" msgid="5120397012047462446">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> violou a política StrictMode imposta automaticamente."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> em execução"</string>
@@ -919,40 +913,26 @@
<item quantity="one" msgid="1634101450343277345">"Rede Wi-Fi aberta disponível"</item>
<item quantity="other" msgid="7915895323644292768">"Redes Wi-Fi abertas disponíveis"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Uma rede WiFi foi desativada"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Uma rede WiFi foi temporariamente desativada devido a conectividade ruim."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"WiFi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Iniciar a operação do WiFi Direct. Isso desligará a operação do ponto de acesso/cliente WiFi."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Falha ao iniciar o WiFi Direct"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Solicitação de configuração da conexão do WiFi Direct de <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Clique em OK para aceitar."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Solicitação de configuração da conexão do WiFi Direct de <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Digite o pin para prosseguir."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"É necessário inserir o pin WPS <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> no dispositivo pareado <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> para prosseguir com a configuração da conexão"</string>
<string name="select_character" msgid="3365550120617701745">"Inserir caractere"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Aplicativo desconhecido"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Enviando mensagens SMS"</string>
<string name="sms_control_message" msgid="1289331457999236205">"Muitas mensagens SMS estão sendo enviadas. Selecione \"OK\" para continuar ou \"Cancelar\" para interromper o envio."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Cancelar"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"Cartão SIM removido"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"A rede móvel estará indisponível até que você substitua o cartão SIM."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Concluído"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"Cartão SIM adicionado"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Reinicie o dispositivo para acessar a rede móvel."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Reiniciar"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Definir hora"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Definir data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
@@ -983,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Conectado como um dispositivo de mídia"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Conectadas como uma câmera"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Conectados como um instalador"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a um acessório USB"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Toque para obter outras opções USB"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Formatar armaz. USB"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"Formatar cartão SD"</string>
@@ -1104,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Selecione uma conta"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Incremento"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Redução"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Navegar na página inicial"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navegar para cima"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Mais opções"</string>
@@ -1117,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Dados 4G desativados"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Dados móveis desativados"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"toque para ativar"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Certificado de segurança"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Este certificado é válido."</string>
<string name="issued_to" msgid="454239480274921032">"Emitido para:"</string>
@@ -1132,10 +1135,7 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"Impressão digital SHA-256"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"Impressão digital SHA-1"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Ver todos..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Selecionar atividade"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Compartilhar com..."</string>
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloqueado."</string>
</resources>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 4f0e385..8e9b711 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -937,7 +937,7 @@
<string name="cut" msgid="3092569408438626261">"Tagliar ora"</string>
<string name="copy" msgid="2681946229533511987">"Copiar"</string>
<string name="paste" msgid="5629880836805036433">"Encollar"</string>
- <!-- no translation found for pasteDisabled (7259254654641456570) -->
+ <!-- no translation found for replace (8333608224471746584) -->
<skip />
<string name="copyUrl" msgid="2538211579596067402">"Copiar l\'URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Selecziunar text…"</string>
@@ -1245,6 +1245,22 @@
<skip />
<!-- no translation found for number_picker_decrement_button (2576606679160067262) -->
<skip />
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<!-- no translation found for action_bar_home_description (5293600496601490216) -->
<skip />
<!-- no translation found for action_bar_up_description (2237496562952152589) -->
@@ -1271,6 +1287,14 @@
<skip />
<!-- no translation found for data_usage_limit_body (2182247539226163759) -->
<skip />
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<!-- no translation found for ssl_certificate (6510040486049237639) -->
<skip />
<!-- no translation found for ssl_certificate_is_valid (6825263250774569373) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 61a0d7b..cec0e69 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"Decupaţi"</string>
<string name="copy" msgid="2681946229533511987">"Copiaţi"</string>
<string name="paste" msgid="5629880836805036433">"Inseraţi"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Nimic de inserat"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Copiaţi adresa URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Selectaţi text..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Selectare text"</string>
@@ -880,12 +881,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Aplicaţie redirecţionată"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> funcţionează acum."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> a fost lansată iniţial."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Scară"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Afişaţi întotdeauna"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Reactivaţi această funcţie din Setări > Aplicaţii > Gestionaţi aplicaţii."</string>
<string name="smv_application" msgid="295583804361236288">"Aplicaţia <xliff:g id="APPLICATION">%1$s</xliff:g> (procesul <xliff:g id="PROCESS">%2$s</xliff:g>) a încălcat propria politică StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Procesul <xliff:g id="PROCESS">%1$s</xliff:g> a încălcat propria politică StrictMode."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Rulează <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -941,18 +939,12 @@
<string name="sms_control_message" msgid="1289331457999236205">"În acest moment se trimit multe mesaje SMS. Selectaţi „OK” pentru a continua sau „Anulaţi” pentru a opri trimiterea."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Anulaţi"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"Card SIM eliminat"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Reţea mobilă va fi indisponibilă până la înlocuirea cardului SIM."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Terminat"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"Card SIM adăugat"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Trebuie să reporniţi dispozitivul pentru a accesa reţeaua de telefonie mobilă."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Reporniţi"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Setaţi ora"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Setaţi data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Setaţi"</string>
@@ -1104,6 +1096,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Selectaţi un cont"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Incrementaţi"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Decrementaţi"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Navigaţi la ecranul de pornire"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navigaţi în sus"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Mai multe opţiuni"</string>
@@ -1117,6 +1125,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Datele 4G au fost dezactivate"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Datele mobile au fost dezactiv."</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"atingeţi pentru activare"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Certificat de securitate"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Certificatul este valid."</string>
<string name="issued_to" msgid="454239480274921032">"Emis către:"</string>
@@ -1132,10 +1148,8 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"Amprentă SHA-256:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"Amprentă SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Afişaţi-le pe toate..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Selectaţi o activitate"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Distribuiţi cu..."</string>
<!-- no translation found for status_bar_device_locked (3092703448690669768) -->
<skip />
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index d2907ae..e05039c 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"Вырезать"</string>
<string name="copy" msgid="2681946229533511987">"Копировать"</string>
<string name="paste" msgid="5629880836805036433">"Вставить"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Текст для вставки отсутствует"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Копировать URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Выбрать текст..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Выбор текста"</string>
@@ -880,12 +881,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Приложение перенаправлено"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Приложение <xliff:g id="APP_NAME">%1$s</xliff:g> выполняется."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Изначально было запущено приложение <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Масштаб"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Всегда показывать"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Включите еще раз в меню \"Настройки > Приложения > Управление приложениями\"."</string>
<string name="smv_application" msgid="295583804361236288">"Приложение <xliff:g id="APPLICATION">%1$s</xliff:g> (процесс <xliff:g id="PROCESS">%2$s</xliff:g>) нарушило собственную политику StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Процесс <xliff:g id="PROCESS">%1$s</xliff:g> нарушил собственную политику StrictMode."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Приложение <xliff:g id="APP">%1$s</xliff:g> запущено"</string>
@@ -941,18 +939,12 @@
<string name="sms_control_message" msgid="1289331457999236205">"Отправляется большое количество SMS-сообщений. Нажмите \"ОК\" для продолжения или \"Отмена\" для прекращения отправки."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"ОК"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Отмена"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"SIM-карта удалена"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Мобильная сеть будет недоступна, пока вы не замените SIM-карту."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"SIM-карта добавлена"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Для доступа к мобильной сети необходимо перезагрузить устройство."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Перезапуск"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Настройка времени"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Настройка даты"</string>
<string name="date_time_set" msgid="5777075614321087758">"Установить"</string>
@@ -1104,6 +1096,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Выберите аккаунт"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Увеличить"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Уменьшить"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Перейти на главную"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Перейти вверх"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Ещё"</string>
@@ -1117,6 +1125,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Передача данных 4G отключена"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Мобильный Интернет отключен"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"Нажмите, чтобы снова включить."</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Сертификат безопасности"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Этот сертификат действителен."</string>
<string name="issued_to" msgid="454239480274921032">"Кому выдан:"</string>
@@ -1132,10 +1148,8 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"Отпечаток SHA-256:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"Отпечаток SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Просмотреть все"</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Выбор действия"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Поделиться с..."</string>
<!-- no translation found for status_bar_device_locked (3092703448690669768) -->
<skip />
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 4af1a79..ccd0d56 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"Vystrihnúť"</string>
<string name="copy" msgid="2681946229533511987">"Kopírovať"</string>
<string name="paste" msgid="5629880836805036433">"Prilepiť"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Nie je čo vložiť"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Skopírovať adresu URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Vybrať text..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Výber textu"</string>
@@ -880,12 +881,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Aplikácia bola presmerov."</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Je spustená aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Pôvodne bola spustená aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Prispôsobiť veľkosť"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Vždy zobraziť"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Toto nastavenie je možné znova povoliť v sekcii Nastavenia > Aplikácie > Správa aplikácií."</string>
<string name="smv_application" msgid="295583804361236288">"Aplikácia <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) porušila svoje vlastné vynútené pravidlá StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> porušil svoje vlastné vynútené pravidlá StrictMode."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Spustená aplikácia: <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -941,18 +939,12 @@
<string name="sms_control_message" msgid="1289331457999236205">"Odosiela sa veľký počet správ SMS. Ak chcete pokračovať, vyberte OK. Ak chcete odosielanie ukončiť, vyberte Zrušiť."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Zrušiť"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"Karta SIM bola odobraná"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Mobilná sieť bude k dispozícii až keď vymeníte kartu SIM."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Hotovo"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"Bola pridaná karta SIM"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Ak chcete získať prístup k mobilnej sieti, musíte zariadenie reštartovať."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Reštartovať"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Nastaviť čas"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastaviť dátum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Nastaviť"</string>
@@ -1104,6 +1096,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Vybrať účet"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Zvýšenie"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Zníženie"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Prejsť na plochu"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Prejsť na"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Viac možností"</string>
@@ -1117,6 +1125,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Dátové prenosy 4G zakázané"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobilné dátové prenosy zakázané"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"klepnutím povolíte"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Certifikát zabezpečenia"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Certifikát je platný."</string>
<string name="issued_to" msgid="454239480274921032">"Vydané pre:"</string>
@@ -1132,10 +1148,8 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"Digitálny odtlačok SHA-256:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"Digitálny odtlačok SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Zobraziť všetko..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Vybrať aktivitu"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Zdieľať s..."</string>
<!-- no translation found for status_bar_device_locked (3092703448690669768) -->
<skip />
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 9b45470..40a1118 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Programu dovoljuje spremljanje tipk, ki jih pritisnete med interakcijo z drugim programom (na primer vnos gesla). Navadni programi tega nikoli ne potrebujejo."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"povezovanje z načinom vnosa"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Dovoljuje lastniku, da se poveže z vmesnikom načina vnosa najvišje ravni. Tega nikoli ni treba uporabiti za navadne programe."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"poveži z besedilno storitvijo"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Dovoljuje, da se lastnik poveže z vmesnikom besedilne storitve najvišje ravni (npr. SpellCheckerService). Tega nikoli ni treba uporabiti za navadne programe."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"povezovanje z ozadjem"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Dovoljuje, da se lastnik poveže z vmesnikom ozadja najvišje ravni. Tega nikoli ni treba uporabiti za navadne programe."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"poveži s storitvijo pripomočka"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Programu dovoljuje spreminjanje zgodovine brskalnika ali zaznamkov, shranjenih v telefonu. Zlonamerni programi lahko to uporabijo za brisanje ali spreminjanje podatkov brskalnika."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"nastavitev alarma budilke"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Programu omogoča nastavitev alarma v nameščeni budilki. Nekatere budilke morda ne bodo uporabile te funkcije."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Dostop do glasovne pošte, ki jo upravlja ta program"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Programu omogoča shranjevanje in prejemanje glasovne pošte, do katere lahko dostopa povezana storitev."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Spreminjanje dovoljenj za geolokacijo brskalnika"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Programu dovoljuje spreminjanje dovoljenja brskalnika za geografske lokacije. Zlonamerni programi lahko s tem dovoljenjem dovolijo pošiljanje podatkov o lokaciji poljubnim spletnim mestom."</string>
<string name="save_password_message" msgid="767344687139195790">"Ali želite, da si brskalnik zapomni to geslo?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Izreži"</string>
<string name="copy" msgid="2681946229533511987">"Kopiraj"</string>
<string name="paste" msgid="5629880836805036433">"Prilepi"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Ni elementov za lepljenje"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Kopiraj URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Izbiranje besedila ..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Izbrano besedilo"</string>
@@ -880,12 +877,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Preusmeritev programa"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> se izvaja."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Prvotno je bil zagnan program <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Lestvica"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Vedno pokaži"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Znova omogočite pri možnosti Nastavitve > Programi > Upravljanje programov."</string>
<string name="smv_application" msgid="295583804361236288">"Program <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) krši svoj samoizvedljivi pravilnik o strogem načinu."</string>
<string name="smv_process" msgid="5120397012047462446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> krši svoj samoizvedljivi pravilnik o strogem načinu."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> se izvaja"</string>
@@ -919,40 +913,26 @@
<item quantity="one" msgid="1634101450343277345">"Odpiranje razpoložljivega brezžičnega omrežja"</item>
<item quantity="other" msgid="7915895323644292768">"Odpiranje razpoložljivih brezžičnih omrežij"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Omrežje Wi-Fi je bilo onemogočeno"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Omrežje Wi-Fi je bilo začasno onemogočeno zaradi slabe povezljivosti."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Začnite s postopkom Wi-Fi Direct. S tem bo izklopljen postopek odjemalca/dostopne točke Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Napaka pri zagonu Wi-Fi Direct"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Zahteva za nastavitev povezave Wi-Fi Direct z naslova <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Če želite sprejeti, kliknite V redu."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Zahteva za nastavitev povezave Wi-Fi Direct z naslova <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Če želite nadaljevati, vnesite PIN."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"Pred začetkom nastavitve povezave morate PIN WPS <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> vnesti v enakovredno napravo <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g>"</string>
<string name="select_character" msgid="3365550120617701745">"Vstavljanje znaka"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Neznan program"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Pošiljanje sporočil SMS"</string>
<string name="sms_control_message" msgid="1289331457999236205">"V pošiljanju je veliko sporočil SMS. Če želite nadaljevati, izberite »V redu«. Če želite pošiljanje ustaviti, izberite »Prekliči«."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"V redu"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Prekliči"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"Kartica SIM odstranjena"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Mobilno omrežje ne bo na voljo, dokler ne zamenjate kartice SIM."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Dokončano"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"Kartica SIM dodana"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Če želite dostopati do mobilnega omrežja, morate znova zagnati napravo."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Vnovičen zagon"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Nastavi uro"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastavi datum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Nastavi"</string>
@@ -983,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Povezan kot predstavnostna naprava"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Povezan kot fotoaparat"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Povezan kot namestitveni program"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Priključen na dodatek USB"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Dotaknite se, če želite izbrati druge možnosti za USB"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Formatiranje pomnilnika USB"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"Formatiraj kartico SD"</string>
@@ -1104,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Izberite račun"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Povečaj"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Zmanjšaj"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Krmarjenje domov"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Krmarjenje navzgor"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Več možnosti"</string>
@@ -1117,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Podatki 4G so onemogočeni"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobilni podatki so onemogočeni"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"tapnite, če želite omogočiti"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Varnostno potrdilo"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"To potrdilo je veljavno."</string>
<string name="issued_to" msgid="454239480274921032">"Izdano za:"</string>
@@ -1134,6 +1137,5 @@
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Prikaži vse ..."</string>
<string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Izberite dejavnost"</string>
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Skupna raba z ..."</string>
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Naprava zaklenjena."</string>
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 4d25343..41ee753 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"Исеци"</string>
<string name="copy" msgid="2681946229533511987">"Копирај"</string>
<string name="paste" msgid="5629880836805036433">"Налепи"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Ништа није копирано"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Копирај URL адресу"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Изабери текст..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Избор текста"</string>
@@ -880,12 +881,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Апликација је преусмерена"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је сада покренута."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Првобитно је покренута апликација <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Размера"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Увек приказуј"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Поново ово омогућите у оквиру Подешавања > Апликације > Управљање апликацијама."</string>
<string name="smv_application" msgid="295583804361236288">"Апликација <xliff:g id="APPLICATION">%1$s</xliff:g> (процес <xliff:g id="PROCESS">%2$s</xliff:g>) је прекршила самонаметнуте StrictMode смернице."</string>
<string name="smv_process" msgid="5120397012047462446">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> је прекршио самонаметнуте StrictMode смернице."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Апликација <xliff:g id="APP">%1$s</xliff:g> је покренута"</string>
@@ -941,18 +939,12 @@
<string name="sms_control_message" msgid="1289331457999236205">"Шаље се велики број SMS порука. Кликните на „Потврди“ да бисте наставили или на „Откажи“ да бисте зауставили слање."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"Потврди"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Откажи"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"SIM картица је уклоњена"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Мобилна мрежа ће бити недоступна док не замените SIM картицу."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"SIM картица је додата"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Морате поново да покренете уређај да бисте могли да приступите мобилној мрежи."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Поново покрени"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Подешавање времена"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Подешавање датума"</string>
<string name="date_time_set" msgid="5777075614321087758">"Подеси"</string>
@@ -1104,6 +1096,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Избор налога"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Повећање"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Смањење"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Кретање до Почетне"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Кретање нагоре"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Још опција"</string>
@@ -1117,6 +1125,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G подаци су онемогућени"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Подаци мобилне мреже су онемогућени"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"додирните да бисте омогућили"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Безбедносни сертификат"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Овај сертификат је важећи."</string>
<string name="issued_to" msgid="454239480274921032">"Издато за:"</string>
@@ -1132,10 +1148,8 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 дигитални отисак:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 дигитални отисак:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Прикажи све..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Избор активности"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Дељење са..."</string>
<!-- no translation found for status_bar_device_locked (3092703448690669768) -->
<skip />
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 3de0006b..b65ab58 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"Klipp ut"</string>
<string name="copy" msgid="2681946229533511987">"Kopiera"</string>
<string name="paste" msgid="5629880836805036433">"Klistra in"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Inget att klistra in"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Kopiera webbadress"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Markera text..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Textmarkering"</string>
@@ -880,12 +881,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Programmet omdirigerades"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> körs."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> startades först."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Anpassning"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Visa alltid"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Aktivera igen under Inställningar > Appar > Hantera appar."</string>
<string name="smv_application" msgid="295583804361236288">"Programmet <xliff:g id="APPLICATION">%1$s</xliff:g> (processen <xliff:g id="PROCESS">%2$s</xliff:g>) har brutit mot sin egen StrictMode-policy."</string>
<string name="smv_process" msgid="5120397012047462446">"Processen <xliff:g id="PROCESS">%1$s</xliff:g> har brutit mot sin egen StrictMode-policy."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> körs"</string>
@@ -941,18 +939,12 @@
<string name="sms_control_message" msgid="1289331457999236205">"Flera SMS-meddelanden skickas. Tryck på OK om du vill fortsätta eller på Avbryt om du vill avsluta sändningen."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Avbryt"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"SIM-kortet togs bort"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Det mobila nätverket kommer inte bli tillgängligt förrän du byter SIM-kortet."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Klar"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"SIM-kort lades till"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Du måste starta om enheten för att ansluta till mobilnätet."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Starta om"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Ange tid"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Ange datum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Ställ in"</string>
@@ -1104,6 +1096,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Välj ett konto"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Öka"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Minska"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Visa startsidan"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navigera uppåt"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Fler alternativ"</string>
@@ -1117,6 +1125,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Data via 4G har inaktiverats"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobildata har inaktiverats"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"knacka lätt om du vill aktivera"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Säkerhetscertifikat"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Certifikatet är giltigt."</string>
<string name="issued_to" msgid="454239480274921032">"Utfärdad till:"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index d2c62bf..d329f24 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1117,7 +1117,8 @@
<skip />
<!-- no translation found for paste (5629880836805036433) -->
<skip />
- <string name="pasteDisabled" msgid="7259254654641456570">"Hakuna cha kubandika"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<!-- no translation found for copyUrl (2538211579596067402) -->
<skip />
<string name="selectTextMode" msgid="6738556348861347240">"Chagua maandishi"</string>
@@ -1431,6 +1432,22 @@
<skip />
<!-- no translation found for number_picker_decrement_button (2576606679160067262) -->
<skip />
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<!-- no translation found for action_bar_home_description (5293600496601490216) -->
<skip />
<!-- no translation found for action_bar_up_description (2237496562952152589) -->
@@ -1457,6 +1474,14 @@
<skip />
<!-- no translation found for data_usage_limit_body (2182247539226163759) -->
<skip />
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<!-- no translation found for ssl_certificate (6510040486049237639) -->
<skip />
<!-- no translation found for ssl_certificate_is_valid (6825263250774569373) -->
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 0e1e8c1..dfdf1f4 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"อนุญาตให้แอปพลิเคชันดูปุ่มที่คุณกดแม้ในระหว่างที่ทำงานร่วมกับแอปพลิเคชันอื่น (เช่น ป้อนรหัสผ่าน) ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"เชื่อมโยงกับวิธีป้อนข้อมูล"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"อนุญาตให้ผู้ถือเชื่อมโยงกับอินเทอร์เฟซระดับสูงสุดของวิธีป้อนข้อมูล ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"เชื่อมโยงกับบริการข้อความ"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"อนุญาตให้ผู้ถือเชื่อมโยงกับอินเทอร์เฟซระดับสูงสุดของบริการข้อความ (เช่น บริการเครื่องตรวจตัวสะกด) ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"เชื่อมโยงกับวอลเปเปอร์"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"อนุญาตให้ผู้ถือเชื่อมโยงกับอินเทอร์เฟซระดับสูงสุดของวอลเปเปอร์ ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"เชื่อมโยงกับบริการวิดเจ็ต"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"อนุญาตให้แอปพลิเคชันแก้ไขประวัติหรือบุ๊กมาร์กของเบราว์เซอร์ที่จัดเก็บบนโทรศัพท์ของคุณ แอปพลิเคชันที่เป็นอันตรายอาจใช้วิธีนี้ลบหรือแก้ไขข้อมูลเบราว์เซอร์ของคุณได้"</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"ตั้งเวลาปลุกในนาฬิกาปลุก"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"อนุญาตให้แอปพลิเคชันนี้ตั้งเวลาปลุกในแอปพลิเคชันนาฬิกาปลุกที่ติดตั้งไว้ แอปพลิเคชันนาฬิกาปลุกบางประเภทอาจไม่ใช้คุณลักษณะนี้"</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"เข้าถึงข้อความเสียงที่จัดการโดยแอปพลิเคชันนี้"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"อนุญาตให้แอปพลิเคชันจัดเก็บและเรียกเฉพาะข้อมูลเสียงซึ่งบริการที่เกี่ยวข้องของข้อมูลเสียงสามารถเข้าถึงได้เท่านั้น"</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"แก้ไขการอนุญาตเกี่ยวกับการระบุตำแหน่งทางภูมิศาสตร์ของเบราว์เซอร์"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"อนุญาตให้แอปพลิเคชันแก้ไขการอนุญาตเกี่ยวกับการระบุตำแหน่งทางภูมิศาสตร์ของเบราว์เซอร์ แอปพลิเคชันที่เป็นอันตรายอาจใช้วิธีนี้อนุญาตให้ส่งข้อมูลตำแหน่งไปที่เว็บไซต์อื่นได้โดยพลการ"</string>
<string name="save_password_message" msgid="767344687139195790">"คุณต้องการให้เบราว์เซอร์จำรหัสผ่านนี้หรือไม่"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"ตัด"</string>
<string name="copy" msgid="2681946229533511987">"คัดลอก"</string>
<string name="paste" msgid="5629880836805036433">"วาง"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"ไม่มีสิ่งที่จะวาง"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"คัดลอก URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"เลือกข้อความ..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"การเลือกข้อความ"</string>
@@ -880,12 +877,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"เปลี่ยนเส้นทางแอปพลิเคชัน"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังทำงานอยู่ในขณะนี้"</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> เปิดใช้ไว้แล้ว"</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"สเกล"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"แสดงเสมอ"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"เปิดใช้งานอีกครั้งด้วยการไปที่การตั้งค่า > แอปพลิเคชัน > จัดการแอปพลิเคชัน"</string>
<string name="smv_application" msgid="295583804361236288">"แอปพลิเคชัน <xliff:g id="APPLICATION">%1$s</xliff:g> (กระบวนการ <xliff:g id="PROCESS">%2$s</xliff:g>) ละเมิดนโยบาย StrictMode ที่บังคับใช้ด้วยตัวเอง"</string>
<string name="smv_process" msgid="5120397012047462446">"กระบวนการ <xliff:g id="PROCESS">%1$s</xliff:g> ละเมิดนโยบาย StrictMode ที่บังคับใช้ด้วยตัวเอง"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> กำลังทำงาน"</string>
@@ -919,40 +913,26 @@
<item quantity="one" msgid="1634101450343277345">"เปิดเครือข่าย Wi-Fi ที่ใช้งานได้"</item>
<item quantity="other" msgid="7915895323644292768">"เปิดเครือข่าย Wi-Fi ที่ใช้งานได้"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"เครือข่าย Wi-Fi ถูกปิดใช้งาน"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"เครือข่าย Wi-Fi ถูกปิดใช้งานชั่วคราวเนื่องจากปัญหาการเชื่อมต่อ"</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"เริ่มการทำงาน Wi-Fi Direct ซึ่งจะเป็นการปิดการทำงาน Wi-Fi ไคลเอ็นต์/ฮอตสปอต"</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"ไม่สามารถเริ่ม Wi-Fi Direct ได้"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"คำขอการตั้งค่าการเชื่อมต่อ Wi-Fi Direct จาก <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g> คลิก \"ตกลง\" เพื่อยอมรับ"</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"คำขอการตั้งค่าการเชื่อมต่อ Wi-Fi Direct จาก <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g> ป้อน PIN เพื่อดำเนินการต่อ"</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"ต้องป้อน PIN WPS <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> บนอุปกรณ์เพียร์ <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> เพื่อให้การตั้งค่าการเชื่อมต่อดำเนินการต่อ"</string>
<string name="select_character" msgid="3365550120617701745">"ใส่อักขระ"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"ไม่ทราบแอปพลิเคชัน"</string>
<string name="sms_control_title" msgid="7296612781128917719">"กำลังส่งข้อความ SMS"</string>
<string name="sms_control_message" msgid="1289331457999236205">"กำลังส่งข้อความ SMS จำนวนมาก เลือก \"ตกลง\" เพื่อทำงานต่อหรือ \"ยกเลิก\" เพื่อหยุดส่ง"</string>
<string name="sms_control_yes" msgid="2532062172402615953">"ตกลง"</string>
<string name="sms_control_no" msgid="1715320703137199869">"ยกเลิก"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"นำซิมการ์ดออกแล้ว"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"ไม่สามารถใช้เครือข่ายมือถือได้จนกว่าคุณจะเปลี่ยนซิมการ์ด"</string>
+ <string name="sim_done_button" msgid="827949989369963775">"เสร็จสิ้น"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"เพิ่มซิมการ์ดแล้ว"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"คุณต้องรีสตาร์ทอุปกรณ์ของคุณเพื่อเข้าถึงเครือข่ายมือถือ"</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"รีสตาร์ท"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"ตั้งเวลา"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"ตั้งวันที่"</string>
<string name="date_time_set" msgid="5777075614321087758">"ตั้งค่า"</string>
@@ -983,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"เชื่อมต่อเป็นอุปกรณ์สื่อ"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"เชื่อมต่อเป็นกล้องถ่ายรูป"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"เชื่อมต่อเป็นตัวติดตั้ง"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"เชื่อมต่อกับอุปกรณ์ USB"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"แตะสำหรับตัวเลือก USB อื่นๆ"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"ฟอร์แมตที่เก็บข้อมูล USB"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"ฟอร์แมตการ์ด SD"</string>
@@ -1104,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"เลือกบัญชี"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"การเพิ่ม"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"การลด"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"นำทางไปหน้าแรก"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"นำทางขึ้น"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"ตัวเลือกเพิ่มเติม"</string>
@@ -1117,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"ปิดใช้งานข้อมูล 4G"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"ปิดใช้งานข้อมูลมือถือ"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"แตะเพื่อเปิดใช้งาน"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"ใบรับรองความปลอดภัย"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"ใบรับรองนี้ใช้งานได้"</string>
<string name="issued_to" msgid="454239480274921032">"ออกให้แก่:"</string>
@@ -1134,6 +1137,5 @@
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"ดูทั้งหมด..."</string>
<string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"เลือกกิจกรรม"</string>
<string name="share_action_provider_share_with" msgid="1791316789651185229">"แบ่งปันกับ..."</string>
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"ล็อกอุปกรณ์อยู่"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 12c14c3..ef32418 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Pinapayagan ang mga application na panoorin ang mga pinipindot mong key maging kapag nakikipag-ugnay sa isa pang application (gaya ng pagpasok ng password). Hindi dapat na kailanganin kailanman para sa mga normal na application."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"sumailalim sa isang pamamaraan ng pag-input"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Pinapayagan ang holder na sumailalim sa nangungunang antas na interface ng pamamaraan ng pag-input. Hindi dapat kailanmang kailanganin para sa mga normal na application."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"sumailalim sa serbisyo ng teksto"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Binibigyang-daan ang may-ari upang sumailalim sa interface sa nangungunang antas(hal. SpellCheckerService). Hindi dapat kailanman kakailanganin para sa mga normal na application."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"sumailalim sa wallpaper"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Pinapayagan ang holder na sumailalim sa interface na nasa nangungunang antas ng wallpaper. Hindi kailanman dapat na kailanganin para sa mga normal na application."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"itali sa serbisyo ng widget"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Pinapayagan ang isang application na baguhin ang kasaysayan o mga bookmark ng Browser na nakaimbak sa iyong telepono. Magagamit ito ng mga nakakahamak na application upang burahin o baguhin ang iyong data ng Browser."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"itakda ang alarm sa alarm clock"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Pinapayagan ang application na magtakda ng alarm sa isang naka-install na application ng alarm clock. Maaaring hindi ipatupad ng ilang application ng alarm clock ang tampok na ito."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"I-access ang mga voicemail na pinapamahalaan ng application na ito"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Binibigyang-daan ang application upang mag-imbak at bumawi ng mga voicemail na maa-access ng nauugnay na serbisyo nito lamang."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Baguhin ang mga pahintulot ng Browser geolocation"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Pinapayagan ang isang application na baguhin ang mga pahintulot sa geolocation ng Browser. Magagamit ito ng mga nakakahamak na application upang payagan ang pagpapadala ng impormasyon ng lokasyon sa mga hindi saklaw na web site."</string>
<string name="save_password_message" msgid="767344687139195790">"Gusto mo bang tandaan ng browser ang password na ito?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"I-cut"</string>
<string name="copy" msgid="2681946229533511987">"Kopyahin"</string>
<string name="paste" msgid="5629880836805036433">"I-paste"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Walang ipe-paste"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Kopyahin ang URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Pumili ng teksto..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Pagpili ng teksto"</string>
@@ -880,12 +877,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Ni-redirect application"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Tumatakbo na ngayon ang <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Orihinal na nalunsad ang <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Sukat"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Palaging ipakita"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Muling paganahin ang Mga Setting > Mga Application > Pamahalaan ang mga application."</string>
<string name="smv_application" msgid="295583804361236288">"Ang application na <xliff:g id="APPLICATION">%1$s</xliff:g> (prosesong <xliff:g id="PROCESS">%2$s</xliff:g>) ay lumabag sa sarili nitong ipinapatupad na patakarang StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Ang prosesong <xliff:g id="PROCESS">%1$s</xliff:g> ay lumabag sa sarili nitong ipinapatupad na patakarang StrictMode."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Tumatakbo ang <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -919,40 +913,26 @@
<item quantity="one" msgid="1634101450343277345">"Available ang bukas na Wi-Fi network"</item>
<item quantity="other" msgid="7915895323644292768">"Buksan ang mga available na Wi-Fi network"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Hindi pinagana ang isang Wi-Fi network"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Pansamantalang hindi pinagana ang Wi-Fi network dahil sa hindi mahusay na connectivity."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Simulan ang pagpapatakbo ng Wi-Fi Direct. I-o-off nito ang pagpapatakbo ng client/hotspot ng Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Nabigong simulan ang Wi-Fi Direct"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Kahilingan sa pag-setup ng koneksyon ng Wi-Fi Direct mula sa <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. I-click ang OK upang tanggapin."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Kahilingan sa pag-setup ng koneksyon ng Wi-Fi Direct ng <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Ilagay ang pin upang magpatuloy."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"Kailangang mailagay ang WPS pin <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> sa peer device <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> para magpatuloy ang setup ng koneksyon"</string>
<string name="select_character" msgid="3365550120617701745">"Magpasok ng character"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Hindi kilalang application"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Nagpapadala ng mga SMS na mensahe"</string>
<string name="sms_control_message" msgid="1289331457999236205">"Pinapadala ang malaking bilang ng mga SMS na mensahe. Piliin ang \"OK\" upang magpatuloy, o \"Kanselahin\" upang itigil ang pagpapadala."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Kanselahin"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"Naalis ang SIM card"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Hindi magiging available ang mobile network hanggang palitan mo ang SIM card."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Tapos na"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"Idinagdag ang SIM card"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Dapat mong i-restart ang iyong device upang ma-access ang mobile network."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"I-restart"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Magtakda ng oras"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Itakda ang petsa"</string>
<string name="date_time_set" msgid="5777075614321087758">"Itakda"</string>
@@ -983,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Nakakonekta bilang isang media device"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Nakakonekta bilang isang camera"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Nakakonekta bilang isang installer"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Nakakonekta sa isang USB accessory"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"I-touch para sa mga ibang pagpipilian sa USB"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"I-format USB storage"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"I-format ang SD card"</string>
@@ -1104,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Pumili ng account"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Taasan"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Babaan"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Magnabiga sa home"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Magnabiga pataas"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Higit pang mga pagpipilian"</string>
@@ -1117,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Di pinagana ang data ng 4G"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Di pinagana ang data ng mobile"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"tapikin upang paganahin"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Certificate ng seguridad"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"May-bisa ang certificate na ito."</string>
<string name="issued_to" msgid="454239480274921032">"Ibinigay kay:"</string>
@@ -1133,7 +1136,6 @@
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 na fingerprint:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Tingnan lahat..."</string>
<string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Pumili ng aktibidad"</string>
- <string name="share_action_provider_share_with" msgid="1791316789651185229">"Ibahagi sa..."</string>
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Ibahagi kay..."</string>
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Naka-lock ang device."</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index ca29d65..1b5ea9a 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Uygulamaların, başka bir uygulama ile etkileşim halindeyken (örneğin bir şifre girerken) bile bastığınız tuşları izlemesine izin verir. Normal uygulamalarda hiçbir zaman gerek duyulmamalıdır."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"bir giriş yöntemine bağla"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Tutucunun bir giriş yönteminin en üst düzey arayüzüne bağlanmasına izin verir. Normal uygulamalarda hiçbir zaman gerek duyulmamalıdır."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"kısa mesaj hizmetine bağla"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Sahibine, bir metin hizmetinin (ör. SpellCheckerService) en üst düzey arayüzüne bağlama izni verir. Normal uygulamalarda hiçbir zaman gerekmez."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"bir duvar kağıdına tabi kıl"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Hesap sahibine bir duvar kağıdının en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmamalıdır."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bir widget hizmetine bağla"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Uygulamaya telefonunuzda depolanan Tarayıcı geçmişini veya favorileri değiştirme izni verir. Kötü amaçlı uygulamalar bunu Tarayıcı verilerinizi silmek veya değiştirmek için kullanabilir."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"çalar saatte alarm ayarla"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Uygulamanın yüklü bir çalar saat uygulamasında bir alarm ayarlamasına izin verir. Bazı çalar saat uygulamaları bu özelliği kullanmayabilir."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Bu uygulamanın yönettiği sesli mesajlara eriş"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Uygulamaya, yalnızca, ilgili hizmetin erişebildiği sesli mesajları depolama ve alma izni verir."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Tarayıcı\'nın coğrafi konum izinlerini değiştir"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Bir uygulamanın, Tarayıcı\'nın coğrafi konum izinlerini değiştirmesine izin verir. Kötü amaçlı uygulamalar, bu özelliği konum bilgilerini rastgele web sitelerine göndermek için kullanabilir."</string>
<string name="save_password_message" msgid="767344687139195790">"Tarayıcının bu şifreyi anımsamasını istiyor musunuz?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Kes"</string>
<string name="copy" msgid="2681946229533511987">"Kopyala"</string>
<string name="paste" msgid="5629880836805036433">"Yapıştır"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Yapştrlck bir şy yok"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"URL\'yi kopyala"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Metin seç..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Metin seçimi"</string>
@@ -880,12 +877,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Uygulama yönlendirildi"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> şimdi çalışıyor."</string>
<string name="launch_warning_original" msgid="188102023021668683">"İlk olarak <xliff:g id="APP_NAME">%1$s</xliff:g> başlatıldı."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Ölçek"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Her zaman göster"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Bunu Ayarlar > Uygulamalar > Uygulamaları yönet bölümünden yeniden etkinleştirebilirsiniz."</string>
<string name="smv_application" msgid="295583804361236288">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulaması (<xliff:g id="PROCESS">%2$s</xliff:g> işlemi) kendiliğinden uyguladığı StrictMode politikasını ihlal etti."</string>
<string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> işlemi kendiliğinden uyguladığı StrictMode politikasını ihlal etti."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> çalışıyor"</string>
@@ -919,40 +913,26 @@
<item quantity="one" msgid="1634101450343277345">"Kullanılabilir kablosuz ağı aç"</item>
<item quantity="other" msgid="7915895323644292768">"Kullanılabilir kablosuz ağları aç"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Kablosuz ağ devre dışı bırakıldı."</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Kötü bağlantı nedeniyle Kablosuz ağ geçici olarak devre dışı bırakıldı."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Kablosuz Doğrudan Bağlantı"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Kablosuz Doğrudan Bağlantı işlemini başlat. Bu durumda Kablosuz istemci/hotspot işlemi kapatılacak."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Kablosuz Doğrudan Bağlantı başlatılamadı"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"<xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g> tarafından gelen Kablosuz Doğrudan Bağlantı kurulum isteği. Kabul etmek için TAMAM\'ı tıklayın."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"<xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g> tarafından gelen Kablosuz Doğrudan Bağlantı kurulumu isteği. Devam etmek için pin girin."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"Bağlantı kurulum işleminin devamı için <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> eş cihazında WPS pin <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> girilmelidir."</string>
<string name="select_character" msgid="3365550120617701745">"Karakter ekle"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Bilinmeyen uygulama"</string>
<string name="sms_control_title" msgid="7296612781128917719">"SMS mesajları gönderiliyor"</string>
<string name="sms_control_message" msgid="1289331457999236205">"Çok sayıda SMS mesajı gönderiliyor. Devam etmek için \"Tamam\"ı, göndermeyi durdurmak için \"İptal\"i seçin."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"Tamam"</string>
<string name="sms_control_no" msgid="1715320703137199869">"İptal"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"SIM card çıkarıldı"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"SIM kartı değiştirinceye kadar mobil ağ kullanılamayacak."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Tamamlandı"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"SIM kart eklendi"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Mobil ağa erişmek için cihazınızı yeniden başlatmanız gerekir."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Yeniden başlat"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Saati ayarla"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Tarihi ayarla"</string>
<string name="date_time_set" msgid="5777075614321087758">"Ayarla"</string>
@@ -983,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Medya cihazı olarak bağlandı"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Kamera olarak bağlandı"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Yükleyici olarak bağlandı"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB aksesuarına bağlandı"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Diğer USB seçenekleri için dokunun"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"USB\'yi biçimlendir"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"SD kartı biçimlendir"</string>
@@ -1104,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Bir hesap seçin"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Artır"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Azalt"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Ana sayfaya git"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Yukarı git"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Diğer seçenekler"</string>
@@ -1117,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G verileri devre dışı"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobil veriler devre dışı"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"etkinleştirmek içn hafifçe vurun"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Güvenlik sertifikası"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Bu sertifika geçerli."</string>
<string name="issued_to" msgid="454239480274921032">"Verilen:"</string>
@@ -1132,10 +1135,7 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 parmak izi:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 parmak izi:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Tümünü göster..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Etkinlik seçin"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"Şununla paylaş..."</string>
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Cihaz kilitli."</string>
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 5a4a34c..91bd1c4 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Дозволяє програмі переглядати клавіші, які ви натискаєте, навіть під час роботи з іншою програмою (наприклад, під час вводу пароля). Ніколи не потрібний для звичайних програм."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"прив\'яз. до методу введ."</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Дозволяє власнику прив\'язувати до інтерфейсу верхнього рівня методу введення. Ніколи не потрібний для звичайних програм."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"прив’язати до текстової служби"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Дозволяє власникові прив’язувати до інтерфейсу верхнього рівня текстової служби (напр. SpellCheckerService). Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"прив\'зати до фон. мал."</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Дозволяє власнику прив\'язувати до інтерфейсу верхнього рівня фон. малюнка. Ніколи не потрібний для звичайних програм."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"прив\'язувати до служби віджетів"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Дозволяє програмі змінювати історію чи закладки переглядача, збережені у вашому тел. Шкідливі програми можуть викор. це, щоб видаляти чи змінювати дані переглядача."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"налашт. сигнал у будильн."</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Дозволяє програмі налаштовувати сигнал у встановленій програмі будильника. У деяких програмах будильника ця функція може не застосовуватися."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Доступ до голосової пошти, якою керує ця програма"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Дозволяє програмі зберігати та відновлювати лише голосову пошту, доступ до якої має пов’язана з нею служба."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Змін. дозволи геогр. місцезн. перегладача"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Дозволяє програмі змін. дозволи географ. місцезн. переглядача. Шкідливі програми можуть використ. це, щоб дозволяти надсилати інф-ю про місцезн. випадковим веб-сайтам."</string>
<string name="save_password_message" msgid="767344687139195790">"Хочете, щоб переглядач запам\'ятав цей пароль?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Виріз."</string>
<string name="copy" msgid="2681946229533511987">"Копіюв."</string>
<string name="paste" msgid="5629880836805036433">"Вставити"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Немає що вставити"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Копіюв. URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Вибрати текст..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Вибір тексту"</string>
@@ -880,12 +877,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Програму переадресовано"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Зараз працює <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Спочатку було запущено <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Масштаб"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Завжди показувати"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Знову ввімкнути це в розділі Налаштування > Програми > Керування програмами."</string>
<string name="smv_application" msgid="295583804361236288">"Програма <xliff:g id="APPLICATION">%1$s</xliff:g> (процес <xliff:g id="PROCESS">%2$s</xliff:g>) порушила свою самозастосовну політику StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> порушив свою самозастосовну політику StrictMode."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Працює <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -919,40 +913,26 @@
<item quantity="one" msgid="1634101450343277345">"Відкрита Wi-Fi мережа доступна"</item>
<item quantity="other" msgid="7915895323644292768">"Відкриті Wi-Fi мережі доступні"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Мережа Wi-Fi була вимкнена"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Мережа Wi-Fi була тимчасово вимкнена через погане з’єднання."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Почати операцію Wi-Fi Direct. Це вимкне Wi-Fi-операцію клієнт/точка доступу."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Не вдалося запустити Wi-Fi Direct"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Запит на налаштування з’єднання Wi-Fi Direct від пристрою <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Натисніть ОК, щоб прийняти."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Запит на налаштування з’єднання Wi-Fi Direct від пристрою <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Введіть PIN-код, щоб продовжити."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"Щоб продовжити процес налаштування з’днання, потрібно ввести PIN-код WPS <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> на пристрої однорангової мережі <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g>."</string>
<string name="select_character" msgid="3365550120617701745">"Вставл-ня символу"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Невідома програма"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Надсил. SMS повідомлень"</string>
<string name="sms_control_message" msgid="1289331457999236205">"Надсил-ся завелика к-сть SMS повідомл. Натисн. \"OK\", щоб продовж, або \"Скасувати\", щоб припин. надсил."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Скасувати"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"SIM-карту вилучено"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Мобільна мережа буде недоступною, поки ви не заміните SIM-карту."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"SIM-карту додано"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Щоб отримати доступ до мобільної мережі, потрібно перезапустити пристрій."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Перезапуск"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Установити час"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Установити дату"</string>
<string name="date_time_set" msgid="5777075614321087758">"Устан."</string>
@@ -983,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Під’єднано як носій"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Під’єднано як камеру"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Під’єднано як програму встановлення"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Під’єднано до аксесуара USB"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Торкніться, щоб побачити інші параметри USB"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Форматув. носій USB"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"Формат. карти SD"</string>
@@ -1104,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Вибрати обліковий запис"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Додати"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Відняти"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Перейти на головну"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Перейти вгору"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Інші варіанти"</string>
@@ -1117,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Дані 4G вимкнено"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Мобільне передав. даних вимкнено"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"торкніться, щоб увімкнути"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Сертифікат безпеки"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Цей сертифікат дійсний."</string>
<string name="issued_to" msgid="454239480274921032">"Кому видано:"</string>
@@ -1134,6 +1137,5 @@
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Показати всі..."</string>
<string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Вибрати дію"</string>
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Надіслати..."</string>
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Пристрій заблоковано."</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index a754a5c..4205041 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_readInputState" msgid="5132879321450325445">"Cho phép ứng dụng xem các phím bạn nhấn ngay cả khi tương tác với ứng dụng khác (chẳng hạn như nhập mật khẩu). Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"liên kết với phương thức nhập"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Cho phép chủ nhân ràng buộc với giao diện cấp cao nhất của phương thức nhập. Không cần thiết cho các ứng dụng thông thường."</string>
- <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
- <skip />
- <!-- no translation found for permdesc_bindTextService (172508880651909350) -->
- <skip />
+ <string name="permlab_bindTextService" msgid="7358378401915287938">"liên kết với dịch vụ văn bản"</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Cho phép chủ sở hữu nối kết với giao diện cấp cao nhất của dịch vụ văn bản (ví dụ: SpellCheckerService). Không nên sử dụng cho các ứng dụng thông thường."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"liên kết với hình nền"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Cho phép chủ nhân ràng buộc với giao diện cấp cao nhất của hình nền. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"liên kết với dịch vụ tiện ích con"</string>
@@ -724,10 +722,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Cho phép ứng dụng sửa đổi lịch sử hoặc dấu trang của Trình duyệt được lưu trữ trên điện thoại của bạn. Các ứng dụng độc hại có thể sử dụng quyền này để xoá hoặc sửa đổi dữ liệu Trình duyệt của bạn."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"đặt báo thức trong đồng hồ báo thức"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Cho phép ứng dụng đặt báo thức trong ứng dụng đồng hồ báo thức được cài đặt. Một số ứng dụng đồng hồ báo thức có thể không sử dụng tính năng này."</string>
- <!-- no translation found for permlab_readWriteOwnVoicemail (8861946090046059697) -->
- <skip />
- <!-- no translation found for permdesc_readWriteOwnVoicemail (7343490168272921274) -->
- <skip />
+ <string name="permlab_readWriteOwnVoicemail" msgid="8861946090046059697">"Truy cập thư thoại do ứng dụng này quản lý"</string>
+ <string name="permdesc_readWriteOwnVoicemail" msgid="7343490168272921274">"Cho phép ứng dụng lưu trữ và truy xuất chỉ các thư thoại mà dịch vụ liên quan của nó có thể truy cập."</string>
<string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Sửa đổi quyền về vị trí địa lý của Trình duyệt"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Cho phép ứng dụng sửa đổi các quyền về vị trí địa lý của Trình duyệt. Các ứng dụng độc hại có thể sử dụng quyền này để cho phép gửi thông tin vị trí đến trang web bất kỳ."</string>
<string name="save_password_message" msgid="767344687139195790">"Bạn có muốn trình duyệt nhớ mật khẩu này không?"</string>
@@ -843,7 +839,8 @@
<string name="cut" msgid="3092569408438626261">"Cắt"</string>
<string name="copy" msgid="2681946229533511987">"Sao chép"</string>
<string name="paste" msgid="5629880836805036433">"Dán"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"Không có gì để dán"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"Sao chép URL"</string>
<string name="selectTextMode" msgid="6738556348861347240">"Chọn văn bản..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Lựa chọn văn bản"</string>
@@ -880,12 +877,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"Ứng dụng đã được chuyển hướng"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> hiện đang chạy."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> được khởi chạy trước tiên."</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Tỷ lệ"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Luôn hiển thị"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"Bật lại hộp thoại này bằng Cài đặt > Ứng dụng > Quản lý ứng dụng."</string>
<string name="smv_application" msgid="295583804361236288">"Ứng dụng <xliff:g id="APPLICATION">%1$s</xliff:g> (quá trình <xliff:g id="PROCESS">%2$s</xliff:g>) đã vi phạm chính sách StrictMode tự thi hành của mình."</string>
<string name="smv_process" msgid="5120397012047462446">"Quá trình <xliff:g id="PROCESS">%1$s</xliff:g> đã vi phạm chính sách StrictMode tự thi hành của mình."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> đang hoạt động"</string>
@@ -919,40 +913,26 @@
<item quantity="one" msgid="1634101450343277345">"Mở mạng Wi-Fi khả dụng"</item>
<item quantity="other" msgid="7915895323644292768">"Mở mạng Wi-Fi khả dụng"</item>
</plurals>
- <!-- no translation found for wifi_watchdog_network_disabled (6398650124751302012) -->
- <skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4659127251774069612) -->
- <skip />
- <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
- <skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
- <skip />
- <!-- no translation found for wifi_p2p_failed_message (6467545523417622335) -->
- <skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
- <skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
- <skip />
+ <string name="wifi_watchdog_network_disabled" msgid="6398650124751302012">"Mạng Wi-Fi đã bị vô hiệu"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="4659127251774069612">"Mạng Wi-Fi đã tạm thời bị vô hiệu do kết nối lỗi."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Bắt đầu hoạt động Wi-Fi Direct. Điều này sẽ tắt hoạt động của ứng dụng khách/điểm phát sóng Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="6467545523417622335">"Không thể khởi động Wi-Fi Direct"</string>
+ <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Yêu cầu thiết lập kết nối Wi-Fi Direct từ <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Nhấp vào OK để chấp nhận."</string>
+ <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Yêu cầu thiết lập Wi-Fi Direct từ <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Nhập pin để tiếp tục."</string>
+ <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"Cần nhập pin WPS <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> vào thiết bị ngang hàng <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> để tiếp tục thiết lập kết nối"</string>
<string name="select_character" msgid="3365550120617701745">"Chèn ký tự"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Ứng dụng không xác định"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Đang gửi tin nhắn SMS"</string>
<string name="sms_control_message" msgid="1289331457999236205">"Một số lượng lớn các tin nhắn SMS đang được gửi. Chọn \"OK\" để tiếp tục hoặc \"Hủy\" để dừng gửi."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Hủy"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"Đã xóa thẻ SIM"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"Mạng di động sẽ không khả dụng cho đến khi bạn thay thế thẻ SIM."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Xong"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"Đã thêm thẻ SIM"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"Bạn phải khởi động lại thiết bị của mình để truy cập mạng di động."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Khởi động lại"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Đặt giờ"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Đặt ngày"</string>
<string name="date_time_set" msgid="5777075614321087758">"Đặt"</string>
@@ -983,8 +963,7 @@
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Đã kết nối là thiết bị truyền thông"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Đã kết nối như máy ảnh"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Được kết nối như trình cài đặt"</string>
- <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
- <skip />
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Đã kết nối với phụ kiện USB"</string>
<string name="usb_notification_message" msgid="4447869605109736382">"Chạm để có các tùy chọn USB khác"</string>
<string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Định dạng b.nhớ USB"</string>
<string name="extmedia_format_title" product="default" msgid="8663247929551095854">"Định dạng thẻ SD"</string>
@@ -1104,6 +1083,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"Chọn tài khoản"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Tăng dần"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Giảm dần"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"Điều hướng về trang chủ"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Điều hướng lên trên"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Tùy chọn khác"</string>
@@ -1117,6 +1112,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G dữ liệu bị vô hiệu hóa"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Dữ liệu di động bị vô hiệu hóa"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"chạm để bật"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"Chứng chỉ bảo mật"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Chứng chỉ này hợp lệ."</string>
<string name="issued_to" msgid="454239480274921032">"Cấp cho:"</string>
@@ -1134,6 +1137,5 @@
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"Xem tất cả..."</string>
<string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"Chọn hoạt động"</string>
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Chia sẻ với..."</string>
- <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
- <skip />
+ <string name="status_bar_device_locked" msgid="3092703448690669768">"Thiết bị đã bị khóa."</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 6daa793..f7e9b6f 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"剪切"</string>
<string name="copy" msgid="2681946229533511987">"复制"</string>
<string name="paste" msgid="5629880836805036433">"粘贴"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"剪贴板无内容"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"复制网址"</string>
<string name="selectTextMode" msgid="6738556348861347240">"选择文字..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"文字选择"</string>
@@ -1104,6 +1105,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"选择帐户"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"增加"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"减少"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"导航首页"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"向上导航"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"更多选项"</string>
@@ -1117,6 +1134,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G 数据已停用"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"移动数据已停用"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"点按即可启用"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"安全证书"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"该证书有效。"</string>
<string name="issued_to" msgid="454239480274921032">"颁发给:"</string>
@@ -1132,10 +1157,8 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 指纹:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 指纹:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"查看全部..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"选择活动"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"分享活动…"</string>
<!-- no translation found for status_bar_device_locked (3092703448690669768) -->
<skip />
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 411b24f..bc3817b 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -843,7 +843,8 @@
<string name="cut" msgid="3092569408438626261">"剪下"</string>
<string name="copy" msgid="2681946229533511987">"複製"</string>
<string name="paste" msgid="5629880836805036433">"貼上"</string>
- <string name="pasteDisabled" msgid="7259254654641456570">"沒有可貼上的內容"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<string name="copyUrl" msgid="2538211579596067402">"複製網址"</string>
<string name="selectTextMode" msgid="6738556348861347240">"選取文字..."</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"選取文字"</string>
@@ -880,12 +881,9 @@
<string name="launch_warning_title" msgid="8323761616052121936">"應用程式已重新導向"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」現在正在執行。"</string>
<string name="launch_warning_original" msgid="188102023021668683">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」原先已啟動。"</string>
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
- <!-- no translation found for screen_compat_mode_hint (2953716574198046484) -->
- <skip />
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"比例"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"一律顯示"</string>
+ <string name="screen_compat_mode_hint" msgid="2953716574198046484">"如要重新啟用這個模式,請至 [設定] > [應用程式] > [管理應用程式]。"</string>
<string name="smv_application" msgid="295583804361236288">"應用程式 <xliff:g id="APPLICATION">%1$s</xliff:g> (處理程序 <xliff:g id="PROCESS">%2$s</xliff:g>) 已違反其自行強制實施的嚴格模式 (StrictMode) 政策。"</string>
<string name="smv_process" msgid="5120397012047462446">"處理程序 <xliff:g id="PROCESS">%1$s</xliff:g> 已違反其自行強制實施的嚴格模式 (StrictMode) 政策。"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> 執行中"</string>
@@ -941,18 +939,12 @@
<string name="sms_control_message" msgid="1289331457999236205">"即將傳送大量 SMS 簡訊。選取 [確定] 繼續或 [取消] 停止傳送。"</string>
<string name="sms_control_yes" msgid="2532062172402615953">"確定"</string>
<string name="sms_control_no" msgid="1715320703137199869">"取消"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
- <!-- no translation found for sim_removed_message (2064255102770489459) -->
- <skip />
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
- <skip />
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"SIM 卡已移除"</string>
+ <string name="sim_removed_message" msgid="2064255102770489459">"您必須更換 SIM 卡,否則無法使用行動網路。"</string>
+ <string name="sim_done_button" msgid="827949989369963775">"完成"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"SIM 卡已新增"</string>
+ <string name="sim_added_message" msgid="1209265974048554242">"您必須重新啟動裝置,才能使用行動網路。"</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"重新啟動"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"設定時間"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"日期設定"</string>
<string name="date_time_set" msgid="5777075614321087758">"設定"</string>
@@ -1104,6 +1096,22 @@
<string name="choose_account_label" msgid="4191313562041125787">"選取帳戶"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"增加"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"減少"</string>
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<string name="action_bar_home_description" msgid="5293600496601490216">"瀏覽首頁"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"向上瀏覽"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"更多選項"</string>
@@ -1117,6 +1125,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"已停用 4G 數據"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"已停用行動數據"</string>
<string name="data_usage_limit_body" msgid="2182247539226163759">"輕按一下即可啟用"</string>
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<string name="ssl_certificate" msgid="6510040486049237639">"安全性憑證"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"憑證有效。"</string>
<string name="issued_to" msgid="454239480274921032">"發佈至:"</string>
@@ -1132,10 +1148,8 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 指紋"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 指紋"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"查看所有活動..."</string>
- <!-- no translation found for activity_chooser_view_dialog_title_default (3325054276356556835) -->
- <skip />
- <!-- no translation found for share_action_provider_share_with (1791316789651185229) -->
- <skip />
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"選取活動"</string>
+ <string name="share_action_provider_share_with" msgid="1791316789651185229">"分享活動..."</string>
<!-- no translation found for status_bar_device_locked (3092703448690669768) -->
<skip />
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index f224e63..3430057 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1117,7 +1117,8 @@
<skip />
<!-- no translation found for paste (5629880836805036433) -->
<skip />
- <string name="pasteDisabled" msgid="7259254654641456570">"Ayikho into yokunamathiselwa"</string>
+ <!-- no translation found for replace (8333608224471746584) -->
+ <skip />
<!-- no translation found for copyUrl (2538211579596067402) -->
<skip />
<string name="selectTextMode" msgid="6738556348861347240">"Khetha umbhalo..."</string>
@@ -1431,6 +1432,22 @@
<skip />
<!-- no translation found for number_picker_decrement_button (2576606679160067262) -->
<skip />
+ <!-- no translation found for checkbox_checked (7222044992652711167) -->
+ <skip />
+ <!-- no translation found for checkbox_not_checked (5174639551134444056) -->
+ <skip />
+ <!-- no translation found for radiobutton_selected (8603599808486581511) -->
+ <skip />
+ <!-- no translation found for radiobutton_not_selected (2908760184307722393) -->
+ <skip />
+ <!-- no translation found for switch_on (551417728476977311) -->
+ <skip />
+ <!-- no translation found for switch_off (7249798614327155088) -->
+ <skip />
+ <!-- no translation found for togglebutton_pressed (4180411746647422233) -->
+ <skip />
+ <!-- no translation found for togglebutton_not_pressed (4495147725636134425) -->
+ <skip />
<!-- no translation found for action_bar_home_description (5293600496601490216) -->
<skip />
<!-- no translation found for action_bar_up_description (2237496562952152589) -->
@@ -1457,6 +1474,14 @@
<skip />
<!-- no translation found for data_usage_limit_body (2182247539226163759) -->
<skip />
+ <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
+ <skip />
+ <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
+ <skip />
+ <!-- no translation found for data_usage_mobile_limit_snoozed_title (279240572165412168) -->
+ <skip />
+ <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <skip />
<!-- no translation found for ssl_certificate (6510040486049237639) -->
<skip />
<!-- no translation found for ssl_certificate_is_valid (6825263250774569373) -->
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index bcf1991..753e4ac 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -89,20 +89,10 @@
<item>@drawable/btn_radio_off</item>
<item>@drawable/btn_default_transparent_normal</item>
<item>@drawable/btn_default_small_selected</item>
- <item>@drawable/btn_default_small_pressed_holo_light</item>
- <item>@drawable/btn_default_small_pressed_holo_dark</item>
<item>@drawable/btn_default_small_pressed</item>
- <item>@drawable/btn_default_small_normal_holo_light</item>
- <item>@drawable/btn_default_small_normal_holo_dark</item>
<item>@drawable/btn_default_small_normal_disable_focused</item>
<item>@drawable/btn_default_small_normal_disable</item>
<item>@drawable/btn_default_small_normal</item>
- <item>@drawable/btn_default_small_focused_holo_light</item>
- <item>@drawable/btn_default_small_focused_holo_dark</item>
- <item>@drawable/btn_default_small_disabled_holo_light</item>
- <item>@drawable/btn_default_small_disabled_holo_dark</item>
- <item>@drawable/btn_default_small_disabled_focused_holo_light</item>
- <item>@drawable/btn_default_small_disabled_focused_holo_dark</item>
<item>@drawable/btn_default_selected</item>
<item>@drawable/btn_default_pressed_holo_light</item>
<item>@drawable/btn_default_pressed_holo_dark</item>
@@ -227,14 +217,18 @@
<item>@drawable/scrollbar_handle_vertical</item>
<item>@drawable/spinner_background_holo_dark</item>
<item>@drawable/spinner_background_holo_light</item>
- <item>@drawable/spinner_cab_default_holo_dark</item>
- <item>@drawable/spinner_cab_default_holo_light</item>
- <item>@drawable/spinner_cab_disabled_holo_dark</item>
- <item>@drawable/spinner_cab_disabled_holo_light</item>
- <item>@drawable/spinner_cab_focused_holo_dark</item>
- <item>@drawable/spinner_cab_focused_holo_light</item>
- <item>@drawable/spinner_cab_pressed_holo_dark</item>
- <item>@drawable/spinner_cab_pressed_holo_light</item>
+ <item>@drawable/spinner_ab_default_holo_dark</item>
+ <item>@drawable/spinner_ab_default_holo_light</item>
+ <item>@drawable/spinner_ab_disabled_holo_dark</item>
+ <item>@drawable/spinner_ab_disabled_holo_light</item>
+ <item>@drawable/spinner_ab_focused_holo_dark</item>
+ <item>@drawable/spinner_ab_focused_holo_light</item>
+ <item>@drawable/spinner_ab_pressed_holo_dark</item>
+ <item>@drawable/spinner_ab_pressed_holo_light</item>
+ <item>@drawable/spinner_ab_activated_holo_dark</item>
+ <item>@drawable/spinner_ab_activated_holo_light</item>
+ <item>@drawable/spinner_ab_holo_dark</item>
+ <item>@drawable/spinner_ab_holo_light</item>
<item>@drawable/spinner_default_holo_dark</item>
<item>@drawable/spinner_default_holo_light</item>
<item>@drawable/spinner_disabled_holo_dark</item>
@@ -368,4 +362,11 @@
<item>@null</item>"
</array>
+ <array name="lockscreen_targets_with_camera">
+ <item>@drawable/ic_lockscreen_unlock</item>
+ <item>@null</item>
+ <item>@drawable/ic_lockscreen_camera</item>
+ <item>@null</item>"
+ </array>
+
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index f80f27d..f70319b 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2632,12 +2632,12 @@
<attr name="alignmentMode" />
<!-- When set to true, forces row boundaries to appear in the same order
as row indices.
- The default is false.
+ The default is true.
See {@link android.widget.GridLayout#setRowOrderPreserved(boolean)}.-->
<attr name="rowOrderPreserved" format="boolean" />
<!-- When set to true, forces column boundaries to appear in the same order
as column indices.
- The default is false.
+ The default is true.
See {@link android.widget.GridLayout#setColumnOrderPreserved(boolean)}.-->
<attr name="columnOrderPreserved" format="boolean" />
</declare-styleable>
@@ -3363,18 +3363,6 @@
The default is LEFT | BASELINE.
See {@link android.widget.GridLayout.LayoutParams#setGravity(int)}. -->
<attr name="layout_gravity" />
- <!-- {@deprecated To make a column group lexible, ensure that every component in the
- group defines a horizontal gravity.} -->
- <attr name="layout_columnFlexibility" >
- <enum name="inflexible" value="0" />
- <enum name="canStretch" value="2" />
- </attr>
- <!-- {@deprecated To make a row group flexible, ensure that every component in the
- group defines a vertical gravity.} -->
- <attr name="layout_rowFlexibility" >
- <enum name="inflexible" value="0" />
- <enum name="canStretch" value="2" />
- </attr>
</declare-styleable>
<declare-styleable name="FrameLayout_Layout">
<attr name="layout_gravity" />
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index dd16bd0..847afa0 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -710,6 +710,22 @@
<enum name="preferExternal" value="2" />
</attr>
+ <!-- Extra options for an activity's UI. If specified on the application
+ tag these will be considered defaults for all activities in the
+ application. -->
+ <attr name="uiOptions">
+ <!-- No extra UI options. -->
+ <flag name="none" value="0" />
+ <!-- Split the options menu into a separate bar at the bottom of
+ the screen when severely constrained for horizontal space.
+ (e.g. portrait mode on a phone.) Instead of a small number
+ of action buttons appearing in the action bar at the top
+ of the screen, the action bar will split into the top navigation
+ section and the bottom menu section. Menu items will not be
+ split across the two bars; they will always appear together. -->
+ <flag name="splitActionBarWhenNarrow" value="1" />
+ </attr>
+
<!-- The <code>manifest</code> tag is the root of an
<code>AndroidManifest.xml</code> file,
describing the contents of an Android package (.apk) file. One
@@ -812,6 +828,7 @@
application is running, the user will be informed of this.
@hide -->
<attr name="cantSaveState" format="boolean" />
+ <attr name="uiOptions" />
</declare-styleable>
<!-- The <code>permission</code> tag declares a security permission that can be
@@ -1302,6 +1319,7 @@
<attr name="windowSoftInputMode" />
<attr name="immersive" />
<attr name="hardwareAccelerated" />
+ <attr name="uiOptions" />
</declare-styleable>
<!-- The <code>activity-alias</code> tag declares a new
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 65dce49..73443a0 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -84,6 +84,9 @@
specified for -large and -xlarge configurations. -->
<dimen name="config_prefDialogWidth">320dp</dimen>
+ <!-- Enables or disables fading edges when marquee is enabled in TextView. -->
+ <bool name="config_ui_enableFadingMarquee">true</bool>
+
<!-- Whether dialogs should close automatically when the user touches outside
of them. This should not normally be modified. -->
<bool name="config_closeDialogWhenTouchOutside">false</bool>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index b3e50ea..e534e9b 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -50,12 +50,17 @@
<dimen name="fastscroll_thumb_height">52dp</dimen>
<!-- Min width for a tablet device -->
<dimen name="min_xlarge_screen_width">800dp</dimen>
- <!-- Default height of a key in the password keyboard for alpha -->
+
+ <!-- Default height of a key in the password keyboard for alpha (used by keyguard) -->
<dimen name="password_keyboard_key_height_alpha">56dip</dimen>
- <!-- Default height of a key in the password keyboard for numeric -->
+ <!-- Default height of a key in the password keyboard for numeric (used by keyguard) -->
<dimen name="password_keyboard_key_height_numeric">56dip</dimen>
- <!-- Default correction for the space key in the password keyboard -->
+ <!-- Default correction for the space key in the password keyboard (used by keyguard) -->
<dimen name="password_keyboard_spacebar_vertical_correction">4dip</dimen>
+ <!-- Default horizontal gap between keys in the password keyboard (used by keyguard) -->
+ <dimen name="password_keyboard_horizontalGap">3dip</dimen>
+ <!-- Default vertical gap between keys in the password keyboard (used by keyguard) -->
+ <dimen name="password_keyboard_verticalGap">9dip</dimen>
<!-- Default target placement radius for MultiWaveView -->
<dimen name="multiwaveview_target_placement_radius">135dip</dimen>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 0555d10..f85dd85 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1728,10 +1728,8 @@
<public type="attr" name="layout_row" />
<public type="attr" name="layout_rowSpan" />
- <public type="attr" name="layout_rowFlexibility" />
<public type="attr" name="layout_columnSpan" />
- <public type="attr" name="layout_columnFlexibility" />
<public type="attr" name="actionModeSelectAllDrawable" />
@@ -1785,11 +1783,11 @@
<public type="attr" name="minResizeHeight" />
<public type="attr" name="actionBarWidgetTheme" />
+ <public type="attr" name="uiOptions" />
<public type="style" name="TextAppearance.SuggestionHighlight" />
- <public type="style" name="Theme.Holo.SplitActionBarWhenNarrow" />
- <public type="style" name="Theme.Holo.Light.SplitActionBarWhenNarrow" />
+ <public type="style" name="Theme.Holo.Light.DarkActionBar" />
<public type="style" name="Widget.Holo.Button.Borderless.Small" />
<public type="style" name="Widget.Holo.Light.Button.Borderless.Small" />
<public type="style" name="TextAppearance.Holo.Widget.ActionBar.Title.Inverse" />
@@ -1804,12 +1802,183 @@
<public type="style" name="Widget.Holo.Light.ActionBar.TabView.Inverse" />
<public type="style" name="Widget.Holo.Light.ActionBar.TabText.Inverse" />
<public type="style" name="Widget.Holo.Light.ActionMode.Inverse" />
- <public type="style" name="Theme.Holo.SolidActionBar" />
- <public type="style" name="Theme.Holo.Light.SolidActionBar" />
- <public type="style" name="Theme.Holo.Light.SolidActionBar.Inverse" />
- <public type="style" name="Theme.Holo.SolidActionBar.SplitActionBarWhenNarrow" />
- <public type="style" name="Theme.Holo.Light.SolidActionBar.SplitActionBarWhenNarrow" />
- <public type="style" name="Theme.Holo.Light.SolidActionBar.Inverse.SplitActionBarWhenNarrow" />
+
+ <public type="style" name="Theme.DeviceDefault" />
+ <public type="style" name="Theme.DeviceDefault.NoActionBar" />
+ <public type="style" name="Theme.DeviceDefault.NoActionBar.Fullscreen" />
+ <public type="style" name="Theme.DeviceDefault.Light" />
+ <public type="style" name="Theme.DeviceDefault.Light.NoActionBar" />
+ <public type="style" name="Theme.DeviceDefault.Light.NoActionBar.Fullscreen" />
+ <public type="style" name="Theme.DeviceDefault.Dialog" />
+ <public type="style" name="Theme.DeviceDefault.Dialog.MinWidth" />
+ <public type="style" name="Theme.DeviceDefault.Dialog.NoActionBar" />
+ <public type="style" name="Theme.DeviceDefault.Dialog.NoActionBar.MinWidth" />
+ <public type="style" name="Theme.DeviceDefault.Light.Dialog" />
+ <public type="style" name="Theme.DeviceDefault.Light.Dialog.MinWidth" />
+ <public type="style" name="Theme.DeviceDefault.Light.Dialog.NoActionBar" />
+ <public type="style" name="Theme.DeviceDefault.Light.Dialog.NoActionBar.MinWidth" />
+ <public type="style" name="Theme.DeviceDefault.DialogWhenLarge" />
+ <public type="style" name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar" />
+ <public type="style" name="Theme.DeviceDefault.Light.DialogWhenLarge" />
+ <public type="style" name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar" />
+ <public type="style" name="Theme.DeviceDefault.Panel" />
+ <public type="style" name="Theme.DeviceDefault.Light.Panel" />
+ <public type="style" name="Theme.DeviceDefault.Wallpaper" />
+ <public type="style" name="Theme.DeviceDefault.Wallpaper.NoTitleBar" />
+ <public type="style" name="Theme.DeviceDefault.InputMethod" />
+ <public type="style" name="Theme.DeviceDefault.Light.DarkActionBar" />
+
+ <public type="style" name="Widget.DeviceDefault" />
+ <public type="style" name="Widget.DeviceDefault.Button" />
+ <public type="style" name="Widget.DeviceDefault.Button.Small" />
+ <public type="style" name="Widget.DeviceDefault.Button.Inset" />
+ <public type="style" name="Widget.DeviceDefault.Button.Toggle" />
+ <public type="style" name="Widget.DeviceDefault.Button.Borderless.Small" />
+ <public type="style" name="Widget.DeviceDefault.TextView" />
+ <public type="style" name="Widget.DeviceDefault.AutoCompleteTextView" />
+ <public type="style" name="Widget.DeviceDefault.CompoundButton.CheckBox" />
+ <public type="style" name="Widget.DeviceDefault.ListView.DropDown" />
+ <public type="style" name="Widget.DeviceDefault.EditText" />
+ <public type="style" name="Widget.DeviceDefault.ExpandableListView" />
+ <public type="style" name="Widget.DeviceDefault.GridView" />
+ <public type="style" name="Widget.DeviceDefault.ImageButton" />
+ <public type="style" name="Widget.DeviceDefault.ListView" />
+ <public type="style" name="Widget.DeviceDefault.PopupWindow" />
+ <public type="style" name="Widget.DeviceDefault.ProgressBar" />
+ <public type="style" name="Widget.DeviceDefault.ProgressBar.Horizontal" />
+ <public type="style" name="Widget.DeviceDefault.ProgressBar.Small" />
+ <public type="style" name="Widget.DeviceDefault.ProgressBar.Small.Title" />
+ <public type="style" name="Widget.DeviceDefault.ProgressBar.Large" />
+ <public type="style" name="Widget.DeviceDefault.SeekBar" />
+ <public type="style" name="Widget.DeviceDefault.RatingBar" />
+ <public type="style" name="Widget.DeviceDefault.RatingBar.Indicator" />
+ <public type="style" name="Widget.DeviceDefault.RatingBar.Small" />
+ <public type="style" name="Widget.DeviceDefault.CompoundButton.RadioButton" />
+ <public type="style" name="Widget.DeviceDefault.ScrollView" />
+ <public type="style" name="Widget.DeviceDefault.HorizontalScrollView" />
+ <public type="style" name="Widget.DeviceDefault.Spinner" />
+ <public type="style" name="Widget.DeviceDefault.CompoundButton.Star" />
+ <public type="style" name="Widget.DeviceDefault.TabWidget" />
+ <public type="style" name="Widget.DeviceDefault.WebTextView" />
+ <public type="style" name="Widget.DeviceDefault.WebView" />
+ <public type="style" name="Widget.DeviceDefault.DropDownItem" />
+ <public type="style" name="Widget.DeviceDefault.DropDownItem.Spinner" />
+ <public type="style" name="Widget.DeviceDefault.TextView.SpinnerItem" />
+ <public type="style" name="Widget.DeviceDefault.ListPopupWindow" />
+ <public type="style" name="Widget.DeviceDefault.PopupMenu" />
+ <public type="style" name="Widget.DeviceDefault.ActionButton" />
+ <public type="style" name="Widget.DeviceDefault.ActionButton.Overflow" />
+ <public type="style" name="Widget.DeviceDefault.ActionButton.TextButton" />
+ <public type="style" name="Widget.DeviceDefault.ActionMode" />
+ <public type="style" name="Widget.DeviceDefault.ActionButton.CloseMode" />
+ <public type="style" name="Widget.DeviceDefault.ActionBar" />
+ <public type="style" name="Widget.DeviceDefault.Button.Borderless" />
+ <public type="style" name="Widget.DeviceDefault.Tab" />
+ <public type="style" name="Widget.DeviceDefault.CalendarView" />
+ <public type="style" name="Widget.DeviceDefault.DatePicker" />
+ <public type="style" name="Widget.DeviceDefault.ActionBar.TabView" />
+ <public type="style" name="Widget.DeviceDefault.ActionBar.TabText" />
+ <public type="style" name="Widget.DeviceDefault.ActionBar.TabBar" />
+ <public type="style" name="Widget.DeviceDefault.ActionBar.Solid" />
+ <public type="style" name="Widget.DeviceDefault.Light" />
+ <public type="style" name="Widget.DeviceDefault.Light.Button" />
+ <public type="style" name="Widget.DeviceDefault.Light.Button.Small" />
+ <public type="style" name="Widget.DeviceDefault.Light.Button.Inset" />
+ <public type="style" name="Widget.DeviceDefault.Light.Button.Toggle" />
+ <public type="style" name="Widget.DeviceDefault.Light.Button.Borderless.Small" />
+ <public type="style" name="Widget.DeviceDefault.Light.TextView" />
+ <public type="style" name="Widget.DeviceDefault.Light.AutoCompleteTextView" />
+ <public type="style" name="Widget.DeviceDefault.Light.CompoundButton.CheckBox" />
+ <public type="style" name="Widget.DeviceDefault.Light.ListView.DropDown" />
+ <public type="style" name="Widget.DeviceDefault.Light.EditText" />
+ <public type="style" name="Widget.DeviceDefault.Light.ExpandableListView" />
+ <public type="style" name="Widget.DeviceDefault.Light.GridView" />
+ <public type="style" name="Widget.DeviceDefault.Light.ImageButton" />
+ <public type="style" name="Widget.DeviceDefault.Light.ListView" />
+ <public type="style" name="Widget.DeviceDefault.Light.PopupWindow" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar.Horizontal" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar.Small" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar.Small.Title" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar.Large" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar.Inverse" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar.Small.Inverse" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar.Large.Inverse" />
+ <public type="style" name="Widget.DeviceDefault.Light.SeekBar" />
+ <public type="style" name="Widget.DeviceDefault.Light.RatingBar" />
+ <public type="style" name="Widget.DeviceDefault.Light.RatingBar.Indicator" />
+ <public type="style" name="Widget.DeviceDefault.Light.RatingBar.Small" />
+ <public type="style" name="Widget.DeviceDefault.Light.CompoundButton.RadioButton" />
+ <public type="style" name="Widget.DeviceDefault.Light.ScrollView" />
+ <public type="style" name="Widget.DeviceDefault.Light.HorizontalScrollView" />
+ <public type="style" name="Widget.DeviceDefault.Light.Spinner" />
+ <public type="style" name="Widget.DeviceDefault.Light.CompoundButton.Star" />
+ <public type="style" name="Widget.DeviceDefault.Light.TabWidget" />
+ <public type="style" name="Widget.DeviceDefault.Light.WebTextView" />
+ <public type="style" name="Widget.DeviceDefault.Light.WebView" />
+ <public type="style" name="Widget.DeviceDefault.Light.DropDownItem" />
+ <public type="style" name="Widget.DeviceDefault.Light.DropDownItem.Spinner" />
+ <public type="style" name="Widget.DeviceDefault.Light.TextView.SpinnerItem" />
+ <public type="style" name="Widget.DeviceDefault.Light.ListPopupWindow" />
+ <public type="style" name="Widget.DeviceDefault.Light.PopupMenu" />
+ <public type="style" name="Widget.DeviceDefault.Light.Tab" />
+ <public type="style" name="Widget.DeviceDefault.Light.CalendarView" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionButton" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionButton.Overflow" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionMode" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionButton.CloseMode" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.TabView" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.TabText" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.TabBar" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.Solid" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.Solid.Inverse" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.TabBar.Inverse" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.TabView.Inverse" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.TabText.Inverse" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionMode.Inverse" />
+
+ <public type="style" name="TextAppearance.DeviceDefault" />
+ <public type="style" name="TextAppearance.DeviceDefault.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.Large" />
+ <public type="style" name="TextAppearance.DeviceDefault.Large.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.Medium" />
+ <public type="style" name="TextAppearance.DeviceDefault.Medium.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.Small" />
+ <public type="style" name="TextAppearance.DeviceDefault.Small.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.SearchResult.Title" />
+ <public type="style" name="TextAppearance.DeviceDefault.SearchResult.Subtitle" />
+ <public type="style" name="TextAppearance.DeviceDefault.WindowTitle" />
+ <public type="style" name="TextAppearance.DeviceDefault.DialogWindowTitle" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.Button" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.IconMenu.Item" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.TabWidget" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.TextView" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.TextView.PopupMenu" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.DropDownHint" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.DropDownItem" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.TextView.SpinnerItem" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.EditText" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.PopupMenu" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.PopupMenu.Large" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.PopupMenu.Small" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionBar.Title" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionMode.Title" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionBar.Title.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionMode.Title.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionBar.Menu" />
+
+ <public type="style" name="DeviceDefault.ButtonBar" />
+ <public type="style" name="DeviceDefault.ButtonBar.AlertDialog" />
+ <public type="style" name="DeviceDefault.SegmentedButton" />
+ <public type="style" name="DeviceDefault.Light.ButtonBar" />
+ <public type="style" name="DeviceDefault.Light.ButtonBar.AlertDialog" />
+ <public type="style" name="DeviceDefault.Light.SegmentedButton" />
<public type="integer" name="status_bar_notification_info_maxnum" />
<public type="string" name="status_bar_notification_info_overflow" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 147fff0..afd8908 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -212,8 +212,8 @@
<!-- android.net.http Error strings --> <skip />
<!-- Displayed when a web request was successful. -->
<string name="httpErrorOk">OK</string>
- <!-- Displayed when a web request failed because we don't know the exact reason. -->
- <string name="httpError">The Web page contains an error.</string>
+ <!-- Displayed when a web request failed with a generic network error. -->
+ <string name="httpError">A network error occurred.</string>
<!-- Displayed when a web request failed because the URL could not be found. -->
<string name="httpErrorLookup">The URL could not be found.</string>
<!-- Displayed when a web request failed because the site's authentication scheme is not supported by us. -->
@@ -1358,14 +1358,6 @@
with Near Field Communication (NFC) tags, cards, and readers.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_vpn">intercept and modify all network traffic</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_vpn">Allows an application to intercept and
- inspect all network traffic to establish a VPN connection.
- Malicious applications may monitor, redirect, or modify network packets
- without your knowledge.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_disableKeyguard">disable keylock</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_disableKeyguard">Allows an application to disable
@@ -2159,11 +2151,11 @@
<!-- Title of an application permission, listed so the user can choose whether
they want to allow the application to do this. [CHAR LIMIT=NONE] -->
- <string name="permlab_readWriteOwnVoicemail">Access voicemails managed by this application</string>
+ <string name="permlab_addVoicemail">add voicemail</string>
<!-- Description of an application permission, listed so the user can choose whether
they want to allow the application to do this. [CHAR LIMIT=NONE] -->
- <string name="permdesc_readWriteOwnVoicemail">Allows the application to store and retrieve only
- voicemails that its associated service can access.</string>
+ <string name="permdesc_addVoicemail">Allows the application to add messages
+ to your voicemail inbox.</string>
<!-- Title of an application permission, listed so the user can choose whether
they want to allow the application to do this. -->
@@ -2405,6 +2397,9 @@
<!-- Item on EditText context menu. This action is used to paste from the clipboard into the eidt field -->
<string name="paste">Paste</string>
+ <!-- Text displayed in a popup dialog in TextEdit when the clipboard is empty. 'paste' is used otherwise. [CHAR LIMIT=20] -->
+ <string name="pasteDisabled">Nothing to paste</string>
+
<!-- Item on EditText context menu. This action is used to replace the current word by other suggested words, suggested by the IME or the spell checker -->
<string name="replace">Replace</string>
@@ -2552,6 +2547,19 @@
<!-- Title of the dialog where the user is adjusting the general audio volume -->
<string name="volume_unknown">Volume</string>
+ <!-- Content description for bluetooth volume icon [CHAR LIMIT=100] -->
+ <string name="volume_icon_description_bluetooth">Bluetooth volume. Tap to toggle silent mode.</string>
+ <!-- Content description for ringer volume icon [CHAR LIMIT=100] -->
+ <string name="volume_icon_description_ringer">Ringtone volume. Tap to toggle silent mode.</string>
+ <!-- Content description for in-call volume icon [CHAR LIMIT=100] -->
+ <string name="volume_icon_description_incall">Call volume. Tap to toggle silent mode.</string>
+ <!-- Content description for media volume icon [CHAR LIMIT=100] -->
+ <string name="volume_icon_description_media">Media volume. Tap to toggle silent mode.</string>
+ <!-- Content description for notification volume icon [CHAR LIMIT=100] -->
+ <string name="volume_icon_description_notification">Notification volume. Tap to toggle silent mode.</string>
+ <!-- Content description for volume settings expansion button [CHAR LIMIT=100] -->
+ <string name="volume_panel_more_description">Tap to show more audio stream volumes.</string>
+
<!-- Ringtone picker strings --> <skip />
<!-- Choice in the ringtone picker. If chosen, the default ringtone will be used. -->
<string name="ringtone_default">Default ringtone</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 5aa47b7..0c6e20f 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -14,6 +14,20 @@
limitations under the License.
-->
+<!--
+===============================================================
+ PLEASE READ
+===============================================================
+
+The Holo themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+ PLEASE READ
+===============================================================
+ -->
<resources>
<!-- Global Theme Styles -->
<eat-comment />
@@ -95,19 +109,6 @@
<item name="windowExitAnimation">@anim/dialog_exit</item>
</style>
- <!-- Standard animations for hiding and showing the status bar. -->
- <style name="Animation.StatusBar">
- <item name="windowEnterAnimation">@anim/status_bar_enter</item>
- <item name="windowExitAnimation">@anim/status_bar_exit</item>
- </style>
-
- <!-- {@hide} -->
- <style name="Animation.StatusBar.IntruderAlert"
- parent="@android:style/Animation.StatusBar">
- <item name="android:windowEnterAnimation">@anim/priority_alert_enter</item>
- <item name="android:windowExitAnimation">@anim/priority_alert_exit</item>
- </style>
-
<!-- Standard animations for a translucent window or activity. This
style is <em>not<em> used by default for the translucent theme
(since translucent activities are a special case that have no
@@ -1743,6 +1744,7 @@
</style>
<style name="Widget.Holo.Spinner.DropDown.ActionBar">
+ <item name="android:background">@android:drawable/spinner_ab_holo_dark</item>
</style>
<style name="Widget.Holo.CompoundButton.Star" parent="Widget.CompoundButton.Star">
@@ -2130,6 +2132,7 @@
</style>
<style name="Widget.Holo.Light.Spinner.DropDown.ActionBar">
+ <item name="android:background">@android:drawable/spinner_ab_holo_light</item>
</style>
<style name="Widget.Holo.Light.CompoundButton.Star" parent="Widget.CompoundButton.Star">
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
new file mode 100644
index 0000000..7f1891e
--- /dev/null
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -0,0 +1,741 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+===============================================================
+ PLEASE READ
+===============================================================
+This file contains the themes that are the Device Defaults.
+If you want to edit styles to skin your device, do it here.
+We recommend that you do not edit styles.xml and instead edit
+this file.
+
+Editing this file instead of styles.xml will greatly simplify
+merges for future platform versions and CTS compliance will be
+easier.
+===============================================================
+ PLEASE READ
+===============================================================
+ -->
+<resources>
+ <!-- Widget Styles -->
+ <style name="Widget.DeviceDefault" parent="Widget.Holo" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Button" parent="Widget.Holo.Button" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Button.Small" parent="Widget.Holo.Button.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Button.Inset" parent="Widget.Holo.Button.Inset" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Button.Toggle" parent="Widget.Holo.Button.Toggle" >
+
+ </style>
+ <style name="Widget.DeviceDefault.TextView" parent="Widget.Holo.TextView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.AutoCompleteTextView" parent="Widget.Holo.AutoCompleteTextView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.CompoundButton.CheckBox" parent="Widget.Holo.CompoundButton.CheckBox" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ListView.DropDown" parent="Widget.Holo.ListView.DropDown" >
+
+ </style>
+ <style name="Widget.DeviceDefault.EditText" parent="Widget.Holo.EditText" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ExpandableListView" parent="Widget.Holo.ExpandableListView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.GridView" parent="Widget.Holo.GridView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ImageButton" parent="Widget.Holo.ImageButton" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ListView" parent="Widget.Holo.ListView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.PopupWindow" parent="Widget.Holo.PopupWindow" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar" parent="Widget.Holo.ProgressBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar.Horizontal" parent="Widget.Holo.ProgressBar.Horizontal" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar.Small" parent="Widget.Holo.ProgressBar.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar.Small.Title" parent="Widget.Holo.ProgressBar.Small.Title" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar.Large" parent="Widget.Holo.ProgressBar.Large" >
+
+ </style>
+ <style name="Widget.DeviceDefault.SeekBar" parent="Widget.Holo.SeekBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.RatingBar" parent="Widget.Holo.RatingBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.RatingBar.Indicator" parent="Widget.Holo.RatingBar.Indicator" >
+
+ </style>
+ <style name="Widget.DeviceDefault.RatingBar.Small" parent="Widget.Holo.RatingBar.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.CompoundButton.RadioButton" parent="Widget.Holo.CompoundButton.RadioButton" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ScrollView" parent="Widget.Holo.ScrollView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.HorizontalScrollView" parent="Widget.Holo.HorizontalScrollView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Spinner" parent="Widget.Holo.Spinner" >
+
+ </style>
+ <style name="Widget.DeviceDefault.CompoundButton.Star" parent="Widget.Holo.CompoundButton.Star" >
+
+ </style>
+ <style name="Widget.DeviceDefault.TabWidget" parent="Widget.Holo.TabWidget" >
+
+ </style>
+ <style name="Widget.DeviceDefault.WebTextView" parent="Widget.Holo.WebTextView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.WebView" parent="Widget.Holo.WebView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.DropDownItem" parent="Widget.Holo.DropDownItem" >
+
+ </style>
+ <style name="Widget.DeviceDefault.DropDownItem.Spinner" parent="Widget.Holo.DropDownItem.Spinner" >
+
+ </style>
+ <style name="Widget.DeviceDefault.TextView.SpinnerItem" parent="Widget.Holo.TextView.SpinnerItem" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ListPopupWindow" parent="Widget.Holo.ListPopupWindow" >
+
+ </style>
+ <style name="Widget.DeviceDefault.PopupMenu" parent="Widget.Holo.PopupMenu" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionButton" parent="Widget.Holo.ActionButton" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionButton.Overflow" parent="Widget.Holo.ActionButton.Overflow" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionButton.TextButton" parent="Widget.Holo.ActionButton.TextButton" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionMode" parent="Widget.Holo.ActionMode" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionButton.CloseMode" parent="Widget.Holo.ActionButton.CloseMode" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionBar" parent="Widget.Holo.ActionBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Button.Borderless" parent="Widget.Holo.Button.Borderless" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Tab" parent="Widget.Holo.Tab" >
+
+ </style>
+ <style name="Widget.DeviceDefault.CalendarView" parent="Widget.Holo.CalendarView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.DatePicker" parent="Widget.Holo.DatePicker" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionBar.TabView" parent="Widget.Holo.ActionBar.TabView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionBar.TabText" parent="Widget.Holo.ActionBar.TabText" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionBar.TabBar" parent="Widget.Holo.ActionBar.TabBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionBar.Solid" parent="Widget.Holo.ActionBar.Solid" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Button.Borderless.Small" parent="Widget.Holo.Button.Borderless.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.AbsListView" parent="Widget.Holo.AbsListView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Spinner.DropDown.ActionBar" parent="Widget.Holo.Spinner.DropDown.ActionBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.PopupWindow.ActionMode" parent="Widget.Holo.PopupWindow.ActionMode" >
+
+ </style>
+ <style name="Widget.DeviceDefault.CompoundButton.Switch" parent="Widget.Holo.CompoundButton.Switch">
+
+ </style>
+ <style name="Widget.DeviceDefault.EditText.NumberPickerInputText" parent="Widget.Holo.EditText.NumberPickerInputText">
+
+ </style>
+ <style name="Widget.DeviceDefault.ExpandableListView.White" parent="Widget.Holo.ExpandableListView.White">
+
+ </style>
+ <style name="Widget.DeviceDefault.Gallery" parent="Widget.Holo.Gallery">
+
+ </style>
+ <style name="Widget.DeviceDefault.GestureOverlayView" parent="Widget.Holo.GestureOverlayView">
+
+ </style>
+ <style name="Widget.DeviceDefault.ImageButton.NumberPickerDownButton" parent="Widget.Holo.ImageButton.NumberPickerDownButton">
+
+ </style>
+ <style name="Widget.DeviceDefault.ImageButton.NumberPickerUpButton" parent="Widget.Holo.ImageButton.NumberPickerUpButton">
+
+ </style>
+ <style name="Widget.DeviceDefault.ImageWell" parent="Widget.Holo.ImageWell">
+
+ </style>
+ <style name="Widget.DeviceDefault.KeyboardView" parent="Widget.Holo.KeyboardView">
+
+ </style>
+ <style name="Widget.DeviceDefault.ListView.White" parent="Widget.Holo.ListView.White">
+
+ </style>
+ <style name="Widget.DeviceDefault.NumberPicker" parent="Widget.Holo.NumberPicker">
+
+ </style>
+ <style name="Widget.DeviceDefault.PreferenceFrameLayout" parent="Widget.Holo.PreferenceFrameLayout">
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar.Inverse" parent="Widget.Holo.ProgressBar.Inverse">
+
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar.Large.Inverse" parent="Widget.Holo.ProgressBar.Large.Inverse">
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar.Small.Inverse" parent="Widget.Holo.ProgressBar.Small.Inverse">
+
+ </style>
+ <style name="Widget.DeviceDefault.QuickContactBadge.WindowLarge" parent="Widget.Holo.QuickContactBadge.WindowLarge">
+
+ </style>
+ <style name="Widget.DeviceDefault.QuickContactBadge.WindowMedium" parent="Widget.Holo.QuickContactBadge.WindowMedium">
+
+ </style>
+ <style name="Widget.DeviceDefault.QuickContactBadge.WindowSmall" parent="Widget.Holo.QuickContactBadge.WindowSmall">
+
+ </style>
+ <style name="Widget.DeviceDefault.QuickContactBadgeSmall.WindowLarge" parent="Widget.Holo.QuickContactBadgeSmall.WindowLarge">
+
+ </style>
+ <style name="Widget.DeviceDefault.QuickContactBadgeSmall.WindowMedium" parent="Widget.Holo.QuickContactBadgeSmall.WindowMedium">
+
+ </style>
+ <style name="Widget.DeviceDefault.QuickContactBadgeSmall.WindowSmall" parent="Widget.Holo.QuickContactBadgeSmall.WindowSmall">
+
+ </style>
+ <style name="Widget.DeviceDefault.Spinner.DropDown" parent="Widget.Holo.Spinner.DropDown">
+
+ </style>
+ <style name="Widget.DeviceDefault.StackView" parent="Widget.Holo.StackView">
+
+ </style>
+ <style name="Widget.DeviceDefault.TextSelectHandle" parent="Widget.Holo.TextSelectHandle">
+
+ </style>
+ <style name="Widget.DeviceDefault.TextSuggestionsPopupWindow" parent="Widget.Holo.TextSuggestionsPopupWindow">
+
+ </style>
+ <style name="Widget.DeviceDefault.TextView.ListSeparator" parent="Widget.Holo.TextView.ListSeparator">
+
+ </style>
+ <style name="Widget.DeviceDefault.TimePicker" parent="Widget.Holo.TimePicker">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light" parent="Widget.Holo.Light" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Button" parent="Widget.Holo.Light.Button" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Button.Small" parent="Widget.Holo.Light.Button.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Button.Inset" parent="Widget.Holo.Light.Button.Inset" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Button.Toggle" parent="Widget.Holo.Light.Button.Toggle" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.TextView" parent="Widget.Holo.Light.TextView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.AutoCompleteTextView" parent="Widget.Holo.Light.AutoCompleteTextView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.CompoundButton.CheckBox" parent="Widget.Holo.Light.CompoundButton.CheckBox" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ListView.DropDown" parent="Widget.Holo.Light.ListView.DropDown" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.EditText" parent="Widget.Holo.Light.EditText" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ExpandableListView" parent="Widget.Holo.Light.ExpandableListView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.GridView" parent="Widget.Holo.Light.GridView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ImageButton" parent="Widget.Holo.Light.ImageButton" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ListView" parent="Widget.Holo.Light.ListView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.PopupWindow" parent="Widget.Holo.Light.PopupWindow" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar" parent="Widget.Holo.Light.ProgressBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar.Horizontal" parent="Widget.Holo.Light.ProgressBar.Horizontal" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar.Small" parent="Widget.Holo.Light.ProgressBar.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar.Small.Title" parent="Widget.Holo.Light.ProgressBar.Small.Title" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar.Large" parent="Widget.Holo.Light.ProgressBar.Large" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar.Inverse" parent="Widget.Holo.Light.ProgressBar.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar.Small.Inverse" parent="Widget.Holo.Light.ProgressBar.Small.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar.Large.Inverse" parent="Widget.Holo.Light.ProgressBar.Large.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.SeekBar" parent="Widget.Holo.Light.SeekBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.RatingBar" parent="Widget.Holo.Light.RatingBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.RatingBar.Indicator" parent="Widget.Holo.Light.RatingBar.Indicator" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.RatingBar.Small" parent="Widget.Holo.Light.RatingBar.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.CompoundButton.RadioButton" parent="Widget.Holo.Light.CompoundButton.RadioButton" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ScrollView" parent="Widget.Holo.Light.ScrollView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.HorizontalScrollView" parent="Widget.Holo.Light.HorizontalScrollView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Spinner" parent="Widget.Holo.Light.Spinner" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.CompoundButton.Star" parent="Widget.Holo.Light.CompoundButton.Star" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.TabWidget" parent="Widget.Holo.Light.TabWidget" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.WebTextView" parent="Widget.Holo.Light.WebTextView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.WebView" parent="Widget.Holo.Light.WebView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.DropDownItem" parent="Widget.Holo.Light.DropDownItem" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.DropDownItem.Spinner" parent="Widget.Holo.Light.DropDownItem.Spinner" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.TextView.SpinnerItem" parent="Widget.Holo.Light.TextView.SpinnerItem" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ListPopupWindow" parent="Widget.Holo.Light.ListPopupWindow" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.PopupMenu" parent="Widget.Holo.Light.PopupMenu" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Tab" parent="Widget.Holo.Light.Tab" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.CalendarView" parent="Widget.Holo.Light.CalendarView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Button.Borderless.Small" parent="Widget.Holo.Light.Button.Borderless.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionButton" parent="Widget.Holo.Light.ActionButton" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionButton.Overflow" parent="Widget.Holo.Light.ActionButton.Overflow" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionMode" parent="Widget.Holo.Light.ActionMode" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionButton.CloseMode" parent="Widget.Holo.Light.ActionButton.CloseMode" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar" parent="Widget.Holo.Light.ActionBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.TabView" parent="Widget.Holo.Light.ActionBar.TabView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.TabText" parent="Widget.Holo.Light.ActionBar.TabText" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.TabBar" parent="Widget.Holo.Light.ActionBar.TabBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.Solid" parent="Widget.Holo.Light.ActionBar.Solid" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.Solid.Inverse" parent="Widget.Holo.Light.ActionBar.Solid.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.TabBar.Inverse" parent="Widget.Holo.Light.ActionBar.TabBar.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.TabView.Inverse" parent="Widget.Holo.Light.ActionBar.TabView.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.TabText.Inverse" parent="Widget.Holo.Light.ActionBar.TabText.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionMode.Inverse" parent="Widget.Holo.Light.ActionMode.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.AbsListView" parent="Widget.Holo.Light.AbsListView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Spinner.DropDown.ActionBar" parent="Widget.Holo.Light.Spinner.DropDown.ActionBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.PopupWindow.ActionMode" parent="Widget.Holo.Light.PopupWindow.ActionMode" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Button.Borderless" parent="Widget.Holo.Light.Button.Borderless">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.DatePicker" parent="Widget.Holo.Light.DatePicker">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.EditText.NumberPickerInputText" parent="Widget.Holo.Light.EditText.NumberPickerInputText">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ExpandableListView.White" parent="Widget.Holo.Light.ExpandableListView.White">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Gallery" parent="Widget.Holo.Light.Gallery">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.GestureOverlayView" parent="Widget.Holo.Light.GestureOverlayView">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ImageButton.NumberPickerDownButton" parent="Widget.Holo.Light.ImageButton.NumberPickerDownButton">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ImageButton.NumberPickerUpButton" parent="Widget.Holo.Light.ImageButton.NumberPickerUpButton">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ImageWell" parent="Widget.Holo.Light.ImageWell">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ListView.White" parent="Widget.Holo.Light.ListView.White">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.NumberPicker" parent="Widget.Holo.Light.NumberPicker">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Spinner.DropDown" parent="Widget.Holo.Light.Spinner.DropDown">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.TextView.ListSeparator" parent="Widget.Holo.Light.TextView.ListSeparator">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.TimePicker" parent="Widget.Holo.Light.TimePicker">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.TextSuggestionsPopupWindow" parent="Widget.Holo.Light.TextSuggestionsPopupWindow">
+
+ </style>
+
+
+ <!-- Text Appearance Styles -->
+ <style name="TextAppearance.DeviceDefault" parent="TextAppearance.Holo" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Inverse" parent="TextAppearance.Holo.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Large" parent="TextAppearance.Holo.Large" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Large.Inverse" parent="TextAppearance.Holo.Large.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Medium" parent="TextAppearance.Holo.Medium" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Medium.Inverse" parent="TextAppearance.Holo.Medium.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Small" parent="TextAppearance.Holo.Small" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Small.Inverse" parent="TextAppearance.Holo.Small.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.SearchResult.Title" parent="TextAppearance.Holo.SearchResult.Title" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.SearchResult.Subtitle" parent="TextAppearance.Holo.SearchResult.Subtitle" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget" parent="TextAppearance.Holo.Widget" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.Button" parent="TextAppearance.Holo.Widget.Button" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.IconMenu.Item" parent="TextAppearance.Holo.Widget.IconMenu.Item" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.TabWidget" parent="TextAppearance.Holo.Widget.TabWidget" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.TextView" parent="TextAppearance.Holo.Widget.TextView" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.TextView.PopupMenu" parent="TextAppearance.Holo.Widget.TextView.PopupMenu" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.DropDownHint" parent="TextAppearance.Holo.Widget.DropDownHint" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.DropDownItem" parent="TextAppearance.Holo.Widget.DropDownItem" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.TextView.SpinnerItem" parent="TextAppearance.Holo.Widget.TextView.SpinnerItem" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.EditText" parent="TextAppearance.Holo.Widget.EditText" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.PopupMenu" parent="TextAppearance.Holo.Widget.PopupMenu" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.PopupMenu.Large" parent="TextAppearance.Holo.Widget.PopupMenu.Large" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.PopupMenu.Small" parent="TextAppearance.Holo.Widget.PopupMenu.Small" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Title" parent="TextAppearance.Holo.Widget.ActionBar.Title" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle" parent="TextAppearance.Holo.Widget.ActionBar.Subtitle" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Title" parent="TextAppearance.Holo.Widget.ActionMode.Title" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle" parent="TextAppearance.Holo.Widget.ActionMode.Subtitle" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.WindowTitle" parent="TextAppearance.Holo.WindowTitle" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.DialogWindowTitle" parent="TextAppearance.Holo.DialogWindowTitle" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Title.Inverse" parent="TextAppearance.Holo.Widget.ActionBar.Title.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle.Inverse" parent="TextAppearance.Holo.Widget.ActionBar.Subtitle.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Title.Inverse" parent="TextAppearance.Holo.Widget.ActionMode.Title.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle.Inverse" parent="TextAppearance.Holo.Widget.ActionMode.Subtitle.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Menu" parent="TextAppearance.Holo.Widget.ActionBar.Menu" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light" parent="TextAppearance.Holo.Light">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Inverse" parent="TextAppearance.Holo.Light.Inverse">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Large" parent="TextAppearance.Holo.Light.Large">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Large.Inverse" parent="TextAppearance.Holo.Light.Large.Inverse">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Medium" parent="TextAppearance.Holo.Light.Medium">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Medium.Inverse" parent="TextAppearance.Holo.Light.Medium.Inverse">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.SearchResult.Subtitle" parent="TextAppearance.Holo.Light.SearchResult.Subtitle">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.SearchResult.Title" parent="TextAppearance.Holo.Light.SearchResult.Title">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Small" parent="TextAppearance.Holo.Light.Small">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Small.Inverse" parent="TextAppearance.Holo.Light.Small.Inverse">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Widget.Button" parent="TextAppearance.Holo.Light.Widget.Button">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Widget.PopupMenu.Large" parent="TextAppearance.Holo.Light.Widget.PopupMenu.Large">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Widget.PopupMenu.Small" parent="TextAppearance.Holo.Light.Widget.PopupMenu.Small">
+
+ </style>
+
+
+ <!-- Preference Styles -->
+ <style name="Preference.DeviceDefault" parent="Preference.Holo">
+
+ </style>
+ <style name="Preference.DeviceDefault.Category" parent="Preference.Holo.Category">
+
+ </style>
+ <style name="Preference.DeviceDefault.CheckBoxPreference" parent="Preference.Holo.CheckBoxPreference">
+
+ </style>
+ <style name="Preference.DeviceDefault.DialogPreference" parent="Preference.Holo.DialogPreference">
+
+ </style>
+ <style name="Preference.DeviceDefault.DialogPreference.EditTextPreference" parent="Preference.Holo.DialogPreference.EditTextPreference">
+
+ </style>
+ <style name="Preference.DeviceDefault.DialogPreference.YesNoPreference" parent="Preference.Holo.DialogPreference.YesNoPreference">
+
+ </style>
+ <style name="Preference.DeviceDefault.Information" parent="Preference.Holo.Information">
+
+ </style>
+ <style name="Preference.DeviceDefault.PreferenceScreen" parent="Preference.Holo.PreferenceScreen">
+
+ </style>
+ <style name="Preference.DeviceDefault.RingtonePreference" parent="Preference.Holo.RingtonePreference">
+
+ </style>
+ <style name="Preference.DeviceDefault.SwitchPreference" parent="Preference.Holo.SwitchPreference">
+
+ </style>
+
+
+ <!-- AlertDialog Styles -->
+ <style name="AlertDialog.DeviceDefault" parent="AlertDialog.Holo">
+
+ </style>
+ <style name="AlertDialog.DeviceDefault.Light" parent="AlertDialog.DeviceDefault.Light" >
+
+ </style>
+
+
+ <!-- Animation Styles -->
+ <style name="Animation.DeviceDefault.Activity" parent="Animation.Holo.Activity">
+
+ </style>
+ <style name="Animation.DeviceDefault.Dialog" parent="Animation.Holo.Dialog">
+
+ </style>
+
+
+ <!-- DialogWindowTitle Styles -->
+ <style name="DialogWindowTitle.DeviceDefault" parent="DialogWindowTitle.Holo">
+
+ </style>
+ <style name="DialogWindowTitle.DeviceDefault.Light" parent="DialogWindowTitle.Holo.Light">
+
+ </style>
+
+
+ <!-- WindowTitle Styles -->
+ <style name="WindowTitle.DeviceDefault" parent="WindowTitle.Holo">
+
+ </style>
+ <style name="WindowTitleBackground.DeviceDefault" parent="WindowTitleBackground.Holo">
+
+ </style>
+
+
+ <!-- Other Styles -->
+ <style name="DeviceDefault.ButtonBar" parent="Holo.ButtonBar" >
+
+ </style>
+ <style name="DeviceDefault.ButtonBar.AlertDialog" parent="Holo.ButtonBar.AlertDialog" >
+
+ </style>
+ <style name="DeviceDefault.SegmentedButton" parent="Holo.SegmentedButton" >
+
+ </style>
+ <style name="DeviceDefault.Light.ButtonBar" parent="Holo.Light.ButtonBar" >
+
+ </style>
+ <style name="DeviceDefault.Light.ButtonBar.AlertDialog" parent="Holo.Light.ButtonBar.AlertDialog" >
+
+ </style>
+ <style name="DeviceDefault.Light.SegmentedButton" parent="Holo.Light.SegmentedButton" >
+
+ </style>
+</resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 3e7c5ca..615a37d 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -14,6 +14,20 @@
limitations under the License.
-->
+<!--
+===============================================================
+ PLEASE READ
+===============================================================
+
+The Holo themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see themes_device_defaults.xml.
+
+===============================================================
+ PLEASE READ
+===============================================================
+ -->
<resources>
<!-- The default system theme. This is the theme used for activities
that have not explicitly set their own theme.
@@ -1207,7 +1221,7 @@
<item name="windowNoTitle">false</item>
<item name="windowFullscreen">false</item>
<item name="windowIsFloating">false</item>
- <item name="windowContentOverlay">@null</item>
+ <item name="android:windowContentOverlay">@android:drawable/ab_solid_shadow_holo</item>
<item name="windowShowWallpaper">false</item>
<item name="windowTitleStyle">@android:style/WindowTitle.Holo</item>
<item name="windowTitleSize">25dip</item>
@@ -1337,7 +1351,7 @@
<item name="actionBarTabTextStyle">@style/Widget.Holo.Light.ActionBar.TabText</item>
<item name="actionModeStyle">@style/Widget.Holo.Light.ActionMode</item>
<item name="actionModeCloseButtonStyle">@style/Widget.Holo.Light.ActionButton.CloseMode</item>
- <item name="actionBarStyle">@android:style/Widget.Holo.Light.ActionBar</item>
+ <item name="android:actionBarStyle">@android:style/Widget.Holo.Light.ActionBar.Solid</item>
<item name="actionBarSize">@dimen/action_bar_default_height</item>
<item name="actionModePopupWindowStyle">@android:style/Widget.Holo.Light.PopupWindow.ActionMode</item>
<item name="actionBarWidgetTheme">@null</item>
@@ -1384,22 +1398,10 @@
</style>
- <!-- Variant of the holographic (dark) theme that has a solid (opaque) action bar. -->
- <style name="Theme.Holo.SolidActionBar">
- <item name="android:actionBarStyle">@android:style/Widget.Holo.ActionBar.Solid</item>
- <item name="android:windowContentOverlay">@android:drawable/ab_solid_shadow_holo</item>
- </style>
-
- <!-- Variant of the holographic (light) theme that has a solid (opaque) action bar. -->
- <style name="Theme.Holo.Light.SolidActionBar">
- <item name="android:actionBarStyle">@android:style/Widget.Holo.Light.ActionBar.Solid</item>
- <item name="android:windowContentOverlay">@android:drawable/ab_solid_shadow_holo</item>
- </style>
-
<!-- Variant of the holographic (light) theme that has a solid (opaque) action bar
with an inverse color profile. The dark action bar sharply stands out against
the light content. -->
- <style name="Theme.Holo.Light.SolidActionBar.Inverse">
+ <style name="Theme.Holo.Light.DarkActionBar">
<item name="android:windowContentOverlay">@android:drawable/title_bar_shadow</item>
<item name="android:actionBarStyle">@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse</item>
<item name="actionBarWidgetTheme">@android:style/Theme.Holo</item>
@@ -1427,30 +1429,6 @@
<item name="actionModeWebSearchDrawable">@android:drawable/ic_menu_search_holo_dark</item>
</style>
- <!-- Variant of the holographic (dark) theme that has a solid
- (opaque) action bar. The action bar will split across both
- the top and bottom of the screen when the screen is
- especially constrained for horizontal space. -->
- <style name="Theme.Holo.SolidActionBar.SplitActionBarWhenNarrow">
- <item name="android:windowSplitActionBar">@android:bool/split_action_bar_is_narrow</item>
- </style>
-
- <!-- Variant of the holographic (light) theme that has a solid
- (opaque) action bar. The action bar will split across both
- the top and bottom of the screen when the screen is
- especially constrained for horizontal space. -->
- <style name="Theme.Holo.Light.SolidActionBar.SplitActionBarWhenNarrow">
- <item name="android:windowSplitActionBar">@android:bool/split_action_bar_is_narrow</item>
- </style>
-
- <!-- Variant of the holographic (light) theme that has a solid (opaque) action bar
- with an inverse color profile. The dark action bar sharply stands out against
- the light content. The action bar will split across both the top and bottom of
- the screen when the screen is especially constrained for horizontal space. -->
- <style name="Theme.Holo.Light.SolidActionBar.Inverse.SplitActionBarWhenNarrow">
- <item name="android:windowSplitActionBar">@android:bool/split_action_bar_is_narrow</item>
- </style>
-
<!-- Variant of the holographic (dark) theme with no action bar. -->
<style name="Theme.Holo.NoActionBar">
<item name="android:windowActionBar">false</item>
@@ -1654,18 +1632,4 @@
<style name="Theme.Holo.Wallpaper.NoTitleBar">
<item name="android:windowNoTitle">true</item>
</style>
-
- <!-- Variant of the holographic (dark) theme with an action bar that
- splits across the top and bottom of the activity when constrained
- for horizontal space. -->
- <style name="Theme.Holo.SplitActionBarWhenNarrow">
- <item name="android:windowSplitActionBar">@android:bool/split_action_bar_is_narrow</item>
- </style>
-
- <!-- Variant of the holographic (light) theme with an action bar that
- splits across the top and bottom of the activity when constrained
- for horizontal space. -->
- <style name="Theme.Holo.Light.SplitActionBarWhenNarrow">
- <item name="android:windowSplitActionBar">@android:bool/split_action_bar_is_narrow</item>
- </style>
</resources>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
new file mode 100644
index 0000000..bf6329d
--- /dev/null
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -0,0 +1,423 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+===============================================================
+ PLEASE READ
+===============================================================
+This file contains the themes that are the Device Defaults.
+If you want to edit themes to skin your device, do it here.
+We recommend that you do not edit themes.xml and instead edit
+this file.
+
+Editing this file instead of themes.xml will greatly simplify
+merges for future platform versions and CTS compliance will be
+easier.
+===============================================================
+ PLEASE READ
+===============================================================
+ -->
+<resources>
+ <style name="Theme.DeviceDefault" parent="Theme.Holo" >
+ <!-- Text styles -->
+ <item name="textAppearance">@android:style/TextAppearance.DeviceDefault</item>
+ <item name="textAppearanceInverse">@android:style/TextAppearance.DeviceDefault.Inverse</item>
+
+ <item name="textAppearanceLarge">@android:style/TextAppearance.DeviceDefault.Large</item>
+ <item name="textAppearanceMedium">@android:style/TextAppearance.DeviceDefault.Medium</item>
+ <item name="textAppearanceSmall">@android:style/TextAppearance.DeviceDefault.Small</item>
+ <item name="textAppearanceLargeInverse">@android:style/TextAppearance.DeviceDefault.Large.Inverse</item>
+ <item name="textAppearanceMediumInverse">@android:style/TextAppearance.DeviceDefault.Medium.Inverse</item>
+ <item name="textAppearanceSmallInverse">@android:style/TextAppearance.DeviceDefault.Small.Inverse</item>
+ <item name="textAppearanceSearchResultTitle">@android:style/TextAppearance.DeviceDefault.SearchResult.Title</item>
+ <item name="textAppearanceSearchResultSubtitle">@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle</item>
+
+ <item name="textAppearanceButton">@android:style/TextAppearance.DeviceDefault.Widget.Button</item>
+
+ <item name="textAppearanceLargePopupMenu">@android:style/TextAppearance.DeviceDefault.Widget.PopupMenu.Large</item>
+ <item name="textAppearanceSmallPopupMenu">@android:style/TextAppearance.DeviceDefault.Widget.PopupMenu.Small</item>
+
+ <!-- Button styles -->
+ <item name="buttonStyle">@android:style/Widget.DeviceDefault.Button</item>
+
+ <item name="buttonStyleSmall">@android:style/Widget.DeviceDefault.Button.Small</item>
+ <item name="buttonStyleInset">@android:style/Widget.DeviceDefault.Button.Inset</item>
+
+ <item name="buttonStyleToggle">@android:style/Widget.DeviceDefault.Button.Toggle</item>
+ <item name="switchStyle">@android:style/Widget.DeviceDefault.CompoundButton.Switch</item>
+
+ <item name="borderlessButtonStyle">@android:style/Widget.DeviceDefault.Button.Borderless</item>
+
+ <item name="listSeparatorTextViewStyle">@android:style/Widget.DeviceDefault.TextView.ListSeparator</item>
+
+ <!-- Window attributes -->
+ <item name="windowTitleStyle">@android:style/WindowTitle.DeviceDefault</item>
+ <item name="windowTitleBackgroundStyle">@android:style/WindowTitleBackground.DeviceDefault</item>
+ <item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Activity</item>
+
+ <!-- Dialog attributes -->
+ <item name="alertDialogStyle">@android:style/AlertDialog.DeviceDefault</item>
+ <item name="dialogTheme">@android:style/Theme.DeviceDefault.Dialog</item>
+ <item name="alertDialogTheme">@android:style/Theme.DeviceDefault.Dialog.Alert</item>
+
+ <!-- Text selection handle attributes -->
+ <item name="textSelectHandleWindowStyle">@android:style/Widget.DeviceDefault.TextSelectHandle</item>
+ <item name="textSuggestionsWindowStyle">@android:style/Widget.DeviceDefault.TextSuggestionsPopupWindow</item>
+
+ <!-- Widget styles -->
+ <item name="absListViewStyle">@android:style/Widget.DeviceDefault.AbsListView</item>
+ <item name="autoCompleteTextViewStyle">@android:style/Widget.DeviceDefault.AutoCompleteTextView</item>
+ <item name="checkboxStyle">@android:style/Widget.DeviceDefault.CompoundButton.CheckBox</item>
+ <item name="dropDownListViewStyle">@android:style/Widget.DeviceDefault.ListView.DropDown</item>
+ <item name="editTextStyle">@android:style/Widget.DeviceDefault.EditText</item>
+ <item name="expandableListViewStyle">@android:style/Widget.DeviceDefault.ExpandableListView</item>
+ <item name="expandableListViewWhiteStyle">@android:style/Widget.DeviceDefault.ExpandableListView.White</item>
+ <item name="galleryStyle">@android:style/Widget.DeviceDefault.Gallery</item>
+ <item name="gestureOverlayViewStyle">@android:style/Widget.DeviceDefault.GestureOverlayView</item>
+ <item name="gridViewStyle">@android:style/Widget.DeviceDefault.GridView</item>
+ <item name="imageButtonStyle">@android:style/Widget.DeviceDefault.ImageButton</item>
+ <item name="imageWellStyle">@android:style/Widget.DeviceDefault.ImageWell</item>
+ <item name="listViewStyle">@android:style/Widget.DeviceDefault.ListView</item>
+ <item name="listViewWhiteStyle">@android:style/Widget.DeviceDefault.ListView.White</item>
+ <item name="popupWindowStyle">@android:style/Widget.DeviceDefault.PopupWindow</item>
+ <item name="progressBarStyle">@android:style/Widget.DeviceDefault.ProgressBar</item>
+ <item name="progressBarStyleHorizontal">@android:style/Widget.DeviceDefault.ProgressBar.Horizontal</item>
+ <item name="progressBarStyleSmall">@android:style/Widget.DeviceDefault.ProgressBar.Small</item>
+ <item name="progressBarStyleSmallTitle">@android:style/Widget.DeviceDefault.ProgressBar.Small.Title</item>
+ <item name="progressBarStyleLarge">@android:style/Widget.DeviceDefault.ProgressBar.Large</item>
+ <item name="progressBarStyleInverse">@android:style/Widget.DeviceDefault.ProgressBar.Inverse</item>
+ <item name="progressBarStyleSmallInverse">@android:style/Widget.DeviceDefault.ProgressBar.Small.Inverse</item>
+ <item name="progressBarStyleLargeInverse">@android:style/Widget.DeviceDefault.ProgressBar.Large.Inverse</item>
+ <item name="seekBarStyle">@android:style/Widget.DeviceDefault.SeekBar</item>
+ <item name="ratingBarStyle">@android:style/Widget.DeviceDefault.RatingBar</item>
+ <item name="ratingBarStyleIndicator">@android:style/Widget.DeviceDefault.RatingBar.Indicator</item>
+ <item name="ratingBarStyleSmall">@android:style/Widget.DeviceDefault.RatingBar.Small</item>
+ <item name="radioButtonStyle">@android:style/Widget.DeviceDefault.CompoundButton.RadioButton</item>
+ <item name="scrollViewStyle">@android:style/Widget.DeviceDefault.ScrollView</item>
+ <item name="horizontalScrollViewStyle">@android:style/Widget.DeviceDefault.HorizontalScrollView</item>
+ <item name="dropDownSpinnerStyle">@android:style/Widget.DeviceDefault.Spinner.DropDown</item>
+ <item name="starStyle">@android:style/Widget.DeviceDefault.CompoundButton.Star</item>
+ <item name="tabWidgetStyle">@android:style/Widget.DeviceDefault.TabWidget</item>
+ <item name="textViewStyle">@android:style/Widget.DeviceDefault.TextView</item>
+ <item name="webTextViewStyle">@android:style/Widget.DeviceDefault.WebTextView</item>
+ <item name="webViewStyle">@android:style/Widget.DeviceDefault.WebView</item>
+ <item name="dropDownItemStyle">@android:style/Widget.DeviceDefault.DropDownItem</item>
+ <item name="spinnerDropDownItemStyle">@android:style/Widget.DeviceDefault.DropDownItem.Spinner</item>
+ <item name="spinnerItemStyle">@android:style/Widget.DeviceDefault.TextView.SpinnerItem</item>
+ <item name="dropDownHintAppearance">@android:style/TextAppearance.DeviceDefault.Widget.DropDownHint</item>
+ <item name="keyboardViewStyle">@android:style/Widget.DeviceDefault.KeyboardView</item>
+ <item name="quickContactBadgeStyleWindowSmall">@android:style/Widget.DeviceDefault.QuickContactBadge.WindowSmall</item>
+ <item name="quickContactBadgeStyleWindowMedium">@android:style/Widget.DeviceDefault.QuickContactBadge.WindowMedium</item>
+ <item name="quickContactBadgeStyleWindowLarge">@android:style/Widget.DeviceDefault.QuickContactBadge.WindowLarge</item>
+ <item name="quickContactBadgeStyleSmallWindowSmall">@android:style/Widget.DeviceDefault.QuickContactBadgeSmall.WindowSmall</item>
+ <item name="quickContactBadgeStyleSmallWindowMedium">@android:style/Widget.DeviceDefault.QuickContactBadgeSmall.WindowMedium</item>
+ <item name="quickContactBadgeStyleSmallWindowLarge">@android:style/Widget.DeviceDefault.QuickContactBadgeSmall.WindowLarge</item>
+ <item name="listPopupWindowStyle">@android:style/Widget.DeviceDefault.ListPopupWindow</item>
+ <item name="popupMenuStyle">@android:style/Widget.DeviceDefault.PopupMenu</item>
+ <item name="stackViewStyle">@android:style/Widget.DeviceDefault.StackView</item>
+
+ <!-- Preference styles -->
+ <item name="preferenceScreenStyle">@android:style/Preference.DeviceDefault.PreferenceScreen</item>
+ <item name="preferenceCategoryStyle">@android:style/Preference.DeviceDefault.Category</item>
+ <item name="preferenceStyle">@android:style/Preference.DeviceDefault</item>
+ <item name="preferenceInformationStyle">@android:style/Preference.DeviceDefault.Information</item>
+ <item name="checkBoxPreferenceStyle">@android:style/Preference.DeviceDefault.CheckBoxPreference</item>
+ <item name="switchPreferenceStyle">@android:style/Preference.DeviceDefault.SwitchPreference</item>
+ <item name="yesNoPreferenceStyle">@android:style/Preference.DeviceDefault.DialogPreference.YesNoPreference</item>
+ <item name="dialogPreferenceStyle">@android:style/Preference.DeviceDefault.DialogPreference</item>
+ <item name="editTextPreferenceStyle">@android:style/Preference.DeviceDefault.DialogPreference.EditTextPreference</item>
+ <item name="ringtonePreferenceStyle">@android:style/Preference.DeviceDefault.RingtonePreference</item>
+
+ <!-- Action bar styles -->
+ <item name="actionDropDownStyle">@android:style/Widget.DeviceDefault.Spinner.DropDown.ActionBar</item>
+ <item name="actionButtonStyle">@android:style/Widget.DeviceDefault.ActionButton</item>
+ <item name="actionOverflowButtonStyle">@android:style/Widget.DeviceDefault.ActionButton.Overflow</item>
+ <item name="actionBarTabStyle">@style/Widget.DeviceDefault.ActionBar.TabView</item>
+ <item name="actionBarTabBarStyle">@style/Widget.DeviceDefault.ActionBar.TabBar</item>
+ <item name="actionBarTabTextStyle">@style/Widget.DeviceDefault.ActionBar.TabText</item>
+ <item name="actionModeStyle">@style/Widget.DeviceDefault.ActionMode</item>
+ <item name="actionModeCloseButtonStyle">@style/Widget.DeviceDefault.ActionButton.CloseMode</item>
+ <item name="actionBarStyle">@android:style/Widget.DeviceDefault.ActionBar</item>
+ <item name="actionModePopupWindowStyle">@android:style/Widget.DeviceDefault.PopupWindow.ActionMode</item>
+
+ <item name="buttonBarStyle">@android:style/DeviceDefault.ButtonBar</item>
+ <item name="segmentedButtonStyle">@android:style/DeviceDefault.SegmentedButton</item>
+
+ <item name="searchDialogTheme">@style/Theme.DeviceDefault.SearchBar</item>
+
+ <!-- PreferenceFrameLayout attributes -->
+ <item name="preferenceFrameLayoutStyle">@android:style/Widget.DeviceDefault.PreferenceFrameLayout</item>
+
+ <!-- NumberPicker styles-->
+ <item name="numberPickerUpButtonStyle">@style/Widget.DeviceDefault.ImageButton.NumberPickerUpButton</item>
+ <item name="numberPickerDownButtonStyle">@style/Widget.DeviceDefault.ImageButton.NumberPickerDownButton</item>
+ <item name="numberPickerInputTextStyle">@style/Widget.DeviceDefault.EditText.NumberPickerInputText</item>
+ <item name="numberPickerStyle">@style/Widget.DeviceDefault.NumberPicker</item>
+
+ <!-- CalendarView style-->
+ <item name="calendarViewStyle">@style/Widget.DeviceDefault.CalendarView</item>
+
+ <!-- TimePicker style -->
+ <item name="timePickerStyle">@style/Widget.DeviceDefault.TimePicker</item>
+
+ <!-- DatePicker style -->
+ <item name="datePickerStyle">@style/Widget.DeviceDefault.DatePicker</item>
+ </style>
+ <style name="Theme.DeviceDefault.NoActionBar" parent="Theme.Holo.NoActionBar" >
+
+ </style>
+ <style name="Theme.DeviceDefault.NoActionBar.Fullscreen" parent="Theme.Holo.NoActionBar.Fullscreen" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light" parent="Theme.Holo.Light" >
+ <!-- Text styles -->
+ <item name="textAppearance">@android:style/TextAppearance.DeviceDefault.Light</item>
+ <item name="textAppearanceInverse">@android:style/TextAppearance.DeviceDefault.Light.Inverse</item>
+
+ <item name="textAppearanceLarge">@android:style/TextAppearance.DeviceDefault.Light.Large</item>
+ <item name="textAppearanceMedium">@android:style/TextAppearance.DeviceDefault.Light.Medium</item>
+ <item name="textAppearanceSmall">@android:style/TextAppearance.DeviceDefault.Light.Small</item>
+ <item name="textAppearanceLargeInverse">@android:style/TextAppearance.DeviceDefault.Light.Large.Inverse</item>
+ <item name="textAppearanceMediumInverse">@android:style/TextAppearance.DeviceDefault.Light.Medium.Inverse</item>
+ <item name="textAppearanceSmallInverse">@android:style/TextAppearance.DeviceDefault.Light.Small.Inverse</item>
+ <item name="textAppearanceSearchResultTitle">@android:style/TextAppearance.DeviceDefault.Light.SearchResult.Title</item>
+ <item name="textAppearanceSearchResultSubtitle">@android:style/TextAppearance.DeviceDefault.Light.SearchResult.Subtitle</item>
+
+ <item name="textAppearanceButton">@android:style/TextAppearance.DeviceDefault.Light.Widget.Button</item>
+
+ <item name="textAppearanceLargePopupMenu">@android:style/TextAppearance.DeviceDefault.Light.Widget.PopupMenu.Large</item>
+ <item name="textAppearanceSmallPopupMenu">@android:style/TextAppearance.DeviceDefault.Light.Widget.PopupMenu.Small</item>
+
+ <!-- Button styles -->
+ <item name="buttonStyle">@android:style/Widget.DeviceDefault.Light.Button</item>
+
+ <item name="buttonStyleSmall">@android:style/Widget.DeviceDefault.Light.Button.Small</item>
+ <item name="buttonStyleInset">@android:style/Widget.DeviceDefault.Light.Button.Inset</item>
+
+ <item name="buttonStyleToggle">@android:style/Widget.DeviceDefault.Light.Button.Toggle</item>
+
+ <item name="borderlessButtonStyle">@android:style/Widget.DeviceDefault.Light.Button.Borderless</item>
+
+ <item name="listSeparatorTextViewStyle">@android:style/Widget.DeviceDefault.Light.TextView.ListSeparator</item>
+
+ <item name="windowTitleStyle">@android:style/WindowTitle.DeviceDefault</item>
+ <item name="windowTitleBackgroundStyle">@android:style/WindowTitleBackground.DeviceDefault</item>
+ <item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Activity</item>
+
+ <!-- Dialog attributes -->
+ <item name="alertDialogStyle">@android:style/AlertDialog.DeviceDefault.Light</item>
+ <item name="dialogTheme">@android:style/Theme.DeviceDefault.Light.Dialog</item>
+ <item name="alertDialogTheme">@android:style/Theme.DeviceDefault.Light.Dialog.Alert</item>
+
+ <!-- Text selection handle attributes -->
+ <item name="textSelectHandleWindowStyle">@android:style/Widget.DeviceDefault.TextSelectHandle</item>
+ <item name="textSuggestionsWindowStyle">@android:style/Widget.DeviceDefault.Light.TextSuggestionsPopupWindow</item>
+
+ <!-- Widget styles -->
+ <item name="absListViewStyle">@android:style/Widget.DeviceDefault.Light.AbsListView</item>
+ <item name="autoCompleteTextViewStyle">@android:style/Widget.DeviceDefault.Light.AutoCompleteTextView</item>
+ <item name="checkboxStyle">@android:style/Widget.DeviceDefault.Light.CompoundButton.CheckBox</item>
+ <item name="dropDownListViewStyle">@android:style/Widget.DeviceDefault.ListView.DropDown</item>
+ <item name="editTextStyle">@android:style/Widget.DeviceDefault.Light.EditText</item>
+ <item name="expandableListViewStyle">@android:style/Widget.DeviceDefault.Light.ExpandableListView</item>
+ <item name="expandableListViewWhiteStyle">@android:style/Widget.DeviceDefault.Light.ExpandableListView.White</item>
+ <item name="galleryStyle">@android:style/Widget.DeviceDefault.Light.Gallery</item>
+ <item name="gestureOverlayViewStyle">@android:style/Widget.DeviceDefault.Light.GestureOverlayView</item>
+ <item name="gridViewStyle">@android:style/Widget.DeviceDefault.Light.GridView</item>
+ <item name="imageButtonStyle">@android:style/Widget.DeviceDefault.Light.ImageButton</item>
+ <item name="imageWellStyle">@android:style/Widget.DeviceDefault.Light.ImageWell</item>
+ <item name="listViewStyle">@android:style/Widget.DeviceDefault.Light.ListView</item>
+ <item name="listViewWhiteStyle">@android:style/Widget.DeviceDefault.Light.ListView.White</item>
+ <item name="popupWindowStyle">@android:style/Widget.DeviceDefault.Light.PopupWindow</item>
+ <item name="progressBarStyle">@android:style/Widget.DeviceDefault.Light.ProgressBar</item>
+ <item name="progressBarStyleHorizontal">@android:style/Widget.DeviceDefault.Light.ProgressBar.Horizontal</item>
+ <item name="progressBarStyleSmall">@android:style/Widget.DeviceDefault.Light.ProgressBar.Small</item>
+ <item name="progressBarStyleSmallTitle">@android:style/Widget.DeviceDefault.Light.ProgressBar.Small.Title</item>
+ <item name="progressBarStyleLarge">@android:style/Widget.DeviceDefault.Light.ProgressBar.Large</item>
+ <item name="progressBarStyleInverse">@android:style/Widget.DeviceDefault.Light.ProgressBar.Inverse</item>
+ <item name="progressBarStyleSmallInverse">@android:style/Widget.DeviceDefault.Light.ProgressBar.Small.Inverse</item>
+ <item name="progressBarStyleLargeInverse">@android:style/Widget.DeviceDefault.Light.ProgressBar.Large.Inverse</item>
+ <item name="seekBarStyle">@android:style/Widget.DeviceDefault.Light.SeekBar</item>
+ <item name="ratingBarStyle">@android:style/Widget.DeviceDefault.Light.RatingBar</item>
+ <item name="ratingBarStyleIndicator">@android:style/Widget.DeviceDefault.Light.RatingBar.Indicator</item>
+ <item name="ratingBarStyleSmall">@android:style/Widget.DeviceDefault.Light.RatingBar.Small</item>
+ <item name="radioButtonStyle">@android:style/Widget.DeviceDefault.Light.CompoundButton.RadioButton</item>
+ <item name="scrollViewStyle">@android:style/Widget.DeviceDefault.Light.ScrollView</item>
+ <item name="horizontalScrollViewStyle">@android:style/Widget.DeviceDefault.Light.HorizontalScrollView</item>
+ <item name="dropDownSpinnerStyle">@android:style/Widget.DeviceDefault.Light.Spinner.DropDown</item>
+ <item name="starStyle">@android:style/Widget.DeviceDefault.Light.CompoundButton.Star</item>
+ <item name="tabWidgetStyle">@android:style/Widget.DeviceDefault.Light.TabWidget</item>
+ <item name="textViewStyle">@android:style/Widget.DeviceDefault.Light.TextView</item>
+ <item name="webTextViewStyle">@android:style/Widget.DeviceDefault.Light.WebTextView</item>
+ <item name="webViewStyle">@android:style/Widget.DeviceDefault.Light.WebView</item>
+ <item name="dropDownItemStyle">@android:style/Widget.DeviceDefault.Light.DropDownItem</item>
+ <item name="spinnerDropDownItemStyle">@android:style/Widget.DeviceDefault.Light.DropDownItem.Spinner</item>
+ <item name="spinnerItemStyle">@android:style/Widget.DeviceDefault.TextView.SpinnerItem</item>
+ <item name="dropDownHintAppearance">@android:style/TextAppearance.DeviceDefault.Widget.DropDownHint</item>
+ <item name="keyboardViewStyle">@android:style/Widget.DeviceDefault.KeyboardView</item>
+ <item name="quickContactBadgeStyleWindowSmall">@android:style/Widget.DeviceDefault.QuickContactBadge.WindowSmall</item>
+ <item name="quickContactBadgeStyleWindowMedium">@android:style/Widget.DeviceDefault.QuickContactBadge.WindowMedium</item>
+ <item name="quickContactBadgeStyleWindowLarge">@android:style/Widget.DeviceDefault.QuickContactBadge.WindowLarge</item>
+ <item name="quickContactBadgeStyleSmallWindowSmall">@android:style/Widget.DeviceDefault.QuickContactBadgeSmall.WindowSmall</item>
+ <item name="quickContactBadgeStyleSmallWindowMedium">@android:style/Widget.DeviceDefault.QuickContactBadgeSmall.WindowMedium</item>
+ <item name="quickContactBadgeStyleSmallWindowLarge">@android:style/Widget.DeviceDefault.QuickContactBadgeSmall.WindowLarge</item>
+ <item name="listPopupWindowStyle">@android:style/Widget.DeviceDefault.Light.ListPopupWindow</item>
+ <item name="popupMenuStyle">@android:style/Widget.DeviceDefault.Light.PopupMenu</item>
+ <item name="stackViewStyle">@android:style/Widget.DeviceDefault.StackView</item>
+
+ <!-- Preference styles -->
+ <item name="preferenceScreenStyle">@android:style/Preference.DeviceDefault.PreferenceScreen</item>
+ <item name="preferenceCategoryStyle">@android:style/Preference.DeviceDefault.Category</item>
+ <item name="preferenceStyle">@android:style/Preference.DeviceDefault</item>
+ <item name="preferenceInformationStyle">@android:style/Preference.DeviceDefault.Information</item>
+ <item name="checkBoxPreferenceStyle">@android:style/Preference.DeviceDefault.CheckBoxPreference</item>
+ <item name="switchPreferenceStyle">@android:style/Preference.DeviceDefault.SwitchPreference</item>
+ <item name="yesNoPreferenceStyle">@android:style/Preference.DeviceDefault.DialogPreference.YesNoPreference</item>
+ <item name="dialogPreferenceStyle">@android:style/Preference.DeviceDefault.DialogPreference</item>
+ <item name="editTextPreferenceStyle">@android:style/Preference.DeviceDefault.DialogPreference.EditTextPreference</item>
+ <item name="ringtonePreferenceStyle">@android:style/Preference.DeviceDefault.RingtonePreference</item>
+
+ <!-- Action bar styles -->
+ <item name="actionDropDownStyle">@android:style/Widget.DeviceDefault.Light.Spinner.DropDown.ActionBar</item>
+ <item name="actionButtonStyle">@android:style/Widget.DeviceDefault.Light.ActionButton</item>
+ <item name="actionOverflowButtonStyle">@android:style/Widget.DeviceDefault.Light.ActionButton.Overflow</item>
+ <item name="actionBarTabStyle">@style/Widget.DeviceDefault.Light.ActionBar.TabView</item>
+ <item name="actionBarTabBarStyle">@style/Widget.DeviceDefault.Light.ActionBar.TabBar</item>
+ <item name="actionBarTabTextStyle">@style/Widget.DeviceDefault.Light.ActionBar.TabText</item>
+ <item name="actionModeStyle">@style/Widget.DeviceDefault.Light.ActionMode</item>
+ <item name="actionModeCloseButtonStyle">@style/Widget.DeviceDefault.Light.ActionButton.CloseMode</item>
+ <item name="actionBarStyle">@android:style/Widget.DeviceDefault.Light.ActionBar</item>
+ <item name="actionModePopupWindowStyle">@android:style/Widget.DeviceDefault.Light.PopupWindow.ActionMode</item>
+
+ <item name="buttonBarStyle">@android:style/DeviceDefault.Light.ButtonBar</item>
+ <item name="segmentedButtonStyle">@android:style/DeviceDefault.Light.SegmentedButton</item>
+
+ <item name="searchDialogTheme">@style/Theme.DeviceDefault.Light.SearchBar</item>
+
+ <!-- NumberPicker attributes and styles-->
+ <item name="numberPickerUpButtonStyle">@style/Widget.DeviceDefault.Light.ImageButton.NumberPickerUpButton</item>
+ <item name="numberPickerDownButtonStyle">@style/Widget.DeviceDefault.Light.ImageButton.NumberPickerDownButton</item>
+ <item name="numberPickerInputTextStyle">@style/Widget.DeviceDefault.Light.EditText.NumberPickerInputText</item>
+ <item name="numberPickerStyle">@style/Widget.DeviceDefault.Light.NumberPicker</item>
+
+ <!-- CalendarView style-->
+ <item name="calendarViewStyle">@style/Widget.DeviceDefault.Light.CalendarView</item>
+
+ <!-- TimePicker style -->
+ <item name="timePickerStyle">@style/Widget.DeviceDefault.Light.TimePicker</item>
+
+ <!-- DatePicker style -->
+ <item name="datePickerStyle">@style/Widget.DeviceDefault.Light.DatePicker</item>
+ </style>
+ <style name="Theme.DeviceDefault.Light.NoActionBar" parent="Theme.Holo.Light.NoActionBar" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.NoActionBar.Fullscreen" parent="Theme.Holo.Light.NoActionBar.Fullscreen" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Dialog" parent="Theme.Holo.Dialog" >
+ <item name="android:windowTitleStyle">@android:style/DialogWindowTitle.DeviceDefault</item>
+ <item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Dialog</item>
+
+ <item name="android:buttonBarStyle">@android:style/DeviceDefault.ButtonBar.AlertDialog</item>
+ <item name="borderlessButtonStyle">@android:style/Widget.DeviceDefault.Button.Borderless.Small</item>
+
+ <item name="textAppearance">@android:style/TextAppearance.DeviceDefault</item>
+ <item name="textAppearanceInverse">@android:style/TextAppearance.DeviceDefault.Inverse</item>
+ </style>
+ <style name="Theme.DeviceDefault.Dialog.MinWidth" parent="Theme.Holo.Dialog.MinWidth" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Dialog.NoActionBar" parent="Theme.Holo.Dialog.NoActionBar" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Dialog.NoActionBar.MinWidth" parent="Theme.Holo.Dialog.NoActionBar.MinWidth" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.Dialog" parent="Theme.Holo.Light.Dialog" >
+ <item name="android:windowTitleStyle">@android:style/DialogWindowTitle.DeviceDefault.Light</item>
+ <item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Dialog</item>
+
+ <item name="android:buttonBarStyle">@android:style/DeviceDefault.Light.ButtonBar.AlertDialog</item>
+ <item name="borderlessButtonStyle">@android:style/Widget.DeviceDefault.Light.Button.Borderless.Small</item>
+
+ <item name="textAppearance">@android:style/TextAppearance.DeviceDefault.Light</item>
+ <item name="textAppearanceInverse">@android:style/TextAppearance.DeviceDefault.Light.Inverse</item>
+ </style>
+ <style name="Theme.DeviceDefault.Light.Dialog.MinWidth" parent="Theme.Holo.Light.Dialog.MinWidth" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.Dialog.NoActionBar" parent="Theme.Holo.Light.Dialog.NoActionBar" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.Dialog.NoActionBar.MinWidth" parent="Theme.Holo.Light.Dialog.NoActionBar.MinWidth" >
+
+ </style>
+ <style name="Theme.DeviceDefault.DialogWhenLarge" parent="Theme.Holo.DialogWhenLarge" >
+
+ </style>
+ <style name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar" parent="Theme.Holo.DialogWhenLarge.NoActionBar" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.DialogWhenLarge" parent="Theme.Holo.Light.DialogWhenLarge" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar" parent="Theme.Holo.Light.DialogWhenLarge.NoActionBar" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Panel" parent="Theme.Holo.Panel" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.Panel" parent="Theme.Holo.Light.Panel" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Wallpaper" parent="Theme.Holo.Wallpaper" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Wallpaper.NoTitleBar" parent="Theme.Holo.Wallpaper.NoTitleBar" >
+
+ </style>
+ <style name="Theme.DeviceDefault.InputMethod" parent="Theme.Holo.InputMethod" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.DarkActionBar" parent="Theme.Holo.Light.DarkActionBar" >
+ <item name="android:actionBarStyle">@android:style/Widget.DeviceDefault.Light.ActionBar.Solid.Inverse</item>
+
+ <item name="actionDropDownStyle">@android:style/Widget.DeviceDefault.Spinner.DropDown.ActionBar</item>
+ <item name="actionButtonStyle">@android:style/Widget.DeviceDefault.ActionButton</item>
+ <item name="actionOverflowButtonStyle">@android:style/Widget.DeviceDefault.ActionButton.Overflow</item>
+ <item name="actionBarTabStyle">@style/Widget.DeviceDefault.Light.ActionBar.TabView.Inverse</item>
+ <item name="actionBarTabBarStyle">@style/Widget.DeviceDefault.Light.ActionBar.TabBar.Inverse</item>
+ <item name="actionBarTabTextStyle">@style/Widget.DeviceDefault.Light.ActionBar.TabText.Inverse</item>
+ <item name="actionModeStyle">@style/Widget.DeviceDefault.Light.ActionMode.Inverse</item>
+ <item name="actionModeCloseButtonStyle">@style/Widget.DeviceDefault.ActionButton.CloseMode</item>
+ <item name="actionModePopupWindowStyle">@android:style/Widget.DeviceDefault.PopupWindow.ActionMode</item>
+
+ </style>
+
+ <style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Holo.Dialog.Alert">
+ <item name="windowTitleStyle">@android:style/DialogWindowTitle.DeviceDefault</item>
+ </style>
+ <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.DeviceDefault.Light.Dialog.Alert">
+ <item name="windowTitleStyle">@android:style/DialogWindowTitle.DeviceDefault.Light</item>
+ </style>
+ <style name="Theme.DeviceDefault.SearchBar" parent="Theme.DeviceDefault.SearchBar">
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.SearchBar" parent="Theme.DeviceDefault.Light.SearchBar">
+
+ </style>
+</resources>
diff --git a/core/res/res/xml-land/password_kbd_qwerty.xml b/core/res/res/xml-land/password_kbd_qwerty.xml
index fd8bd49..988f9ff 100755
--- a/core/res/res/xml-land/password_kbd_qwerty.xml
+++ b/core/res/res/xml-land/password_kbd_qwerty.xml
@@ -20,8 +20,8 @@
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
diff --git a/core/res/res/xml-land/password_kbd_qwerty_shifted.xml b/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
index 9ff6fd7..4941946d 100755
--- a/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
@@ -20,8 +20,8 @@
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
diff --git a/core/res/res/xml-mdpi/password_kbd_qwerty.xml b/core/res/res/xml-mdpi/password_kbd_qwerty.xml
index 82a7c75..265d7dc 100755
--- a/core/res/res/xml-mdpi/password_kbd_qwerty.xml
+++ b/core/res/res/xml-mdpi/password_kbd_qwerty.xml
@@ -20,8 +20,8 @@
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
diff --git a/core/res/res/xml-mdpi/password_kbd_qwerty_shifted.xml b/core/res/res/xml-mdpi/password_kbd_qwerty_shifted.xml
index 9fff3cc..7379f69 100755
--- a/core/res/res/xml-mdpi/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml-mdpi/password_kbd_qwerty_shifted.xml
@@ -20,8 +20,8 @@
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
diff --git a/core/res/res/xml-xlarge/password_kbd_numeric.xml b/core/res/res/xml-xlarge/password_kbd_numeric.xml
index 0253122..3745672 100755
--- a/core/res/res/xml-xlarge/password_kbd_numeric.xml
+++ b/core/res/res/xml-xlarge/password_kbd_numeric.xml
@@ -19,7 +19,8 @@
-->
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="33.33%p"
- android:verticalGap="0px"
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap"
android:keyHeight="@dimen/password_keyboard_key_height_numeric"
>
diff --git a/core/res/res/xml-xlarge/password_kbd_qwerty.xml b/core/res/res/xml-xlarge/password_kbd_qwerty.xml
index 1009c9a..76b6019 100755
--- a/core/res/res/xml-xlarge/password_kbd_qwerty.xml
+++ b/core/res/res/xml-xlarge/password_kbd_qwerty.xml
@@ -22,8 +22,8 @@
android:keyWidth="8.272%p"
keyboardHeight="@dimen/password_keyboard_height"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
- android:horizontalGap="0px"
- android:verticalGap="0px">
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap">
<Row android:keyWidth="8.272%p">
<Key android:keyLabel="Tab"
diff --git a/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml b/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml
index cbf17c3..35c3142 100755
--- a/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml
@@ -22,8 +22,8 @@
android:keyWidth="8.272%p"
keyboardHeight="@dimen/password_keyboard_height"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
- android:horizontalGap="0px"
- android:verticalGap="0px">
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap">
<Row android:keyWidth="8.272%p">
<Key android:keyLabel="Tab"
diff --git a/core/res/res/xml-xlarge/password_kbd_symbols.xml b/core/res/res/xml-xlarge/password_kbd_symbols.xml
index a58a023..106dd6e 100755
--- a/core/res/res/xml-xlarge/password_kbd_symbols.xml
+++ b/core/res/res/xml-xlarge/password_kbd_symbols.xml
@@ -22,8 +22,8 @@
android:keyWidth="8.272%p"
keyboardHeight="@dimen/password_keyboard_height"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
- android:horizontalGap="0px"
- android:verticalGap="0px">
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap">
<Row android:keyWidth="8.272%p">
<Key android:keyLabel="Tab"
diff --git a/core/res/res/xml-xlarge/password_kbd_symbols_shift.xml b/core/res/res/xml-xlarge/password_kbd_symbols_shift.xml
index 9d9acf5..1233f78 100755
--- a/core/res/res/xml-xlarge/password_kbd_symbols_shift.xml
+++ b/core/res/res/xml-xlarge/password_kbd_symbols_shift.xml
@@ -20,8 +20,8 @@
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap"
android:keyHeight="@dimen/password_keyboard_key_height_alpha">
<Row android:keyWidth="8.272%p"
diff --git a/core/res/res/xml/password_kbd_extension.xml b/core/res/res/xml/password_kbd_extension.xml
index f3fa57b..e8d61fe 100755
--- a/core/res/res/xml/password_kbd_extension.xml
+++ b/core/res/res/xml/password_kbd_extension.xml
@@ -20,8 +20,8 @@
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
diff --git a/core/res/res/xml/password_kbd_numeric.xml b/core/res/res/xml/password_kbd_numeric.xml
index 2270b8a..2fd5aa0 100755
--- a/core/res/res/xml/password_kbd_numeric.xml
+++ b/core/res/res/xml/password_kbd_numeric.xml
@@ -19,7 +19,8 @@
-->
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="33.33%p"
- android:verticalGap="0px"
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap"
android:keyHeight="@dimen/password_keyboard_key_height_numeric"
>
diff --git a/core/res/res/xml/password_kbd_popup_template.xml b/core/res/res/xml/password_kbd_popup_template.xml
index 9b853e2..9fcac2c 100644
--- a/core/res/res/xml/password_kbd_popup_template.xml
+++ b/core/res/res/xml/password_kbd_popup_template.xml
@@ -20,8 +20,8 @@
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
</Keyboard>
diff --git a/core/res/res/xml/password_kbd_qwerty.xml b/core/res/res/xml/password_kbd_qwerty.xml
index 0a35040..dfe581e 100755
--- a/core/res/res/xml/password_kbd_qwerty.xml
+++ b/core/res/res/xml/password_kbd_qwerty.xml
@@ -20,8 +20,8 @@
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
diff --git a/core/res/res/xml/password_kbd_qwerty_shifted.xml b/core/res/res/xml/password_kbd_qwerty_shifted.xml
index 9e9db81..1366c58 100755
--- a/core/res/res/xml/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml/password_kbd_qwerty_shifted.xml
@@ -20,8 +20,8 @@
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
diff --git a/core/res/res/xml/password_kbd_symbols.xml b/core/res/res/xml/password_kbd_symbols.xml
index 9a94930..5876b0d 100755
--- a/core/res/res/xml/password_kbd_symbols.xml
+++ b/core/res/res/xml/password_kbd_symbols.xml
@@ -20,8 +20,8 @@
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
diff --git a/core/res/res/xml/password_kbd_symbols_shift.xml b/core/res/res/xml/password_kbd_symbols_shift.xml
index a972eb2..ee83544 100755
--- a/core/res/res/xml/password_kbd_symbols_shift.xml
+++ b/core/res/res/xml/password_kbd_symbols_shift.xml
@@ -20,8 +20,8 @@
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:horizontalGap="@dimen/password_keyboard_horizontalGap"
+ android:verticalGap="@dimen/password_keyboard_verticalGap"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
diff --git a/core/tests/bandwidthtests/Android.mk b/core/tests/bandwidthtests/Android.mk
new file mode 100644
index 0000000..3d56141
--- /dev/null
+++ b/core/tests/bandwidthtests/Android.mk
@@ -0,0 +1,30 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+# Include all test java files.
+LOCAL_SRC_FILES := \
+ $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_PACKAGE_NAME := BandwidthTests
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/core/tests/bandwidthtests/AndroidManifest.xml b/core/tests/bandwidthtests/AndroidManifest.xml
new file mode 100644
index 0000000..24221bc
--- /dev/null
+++ b/core/tests/bandwidthtests/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.bandwidth.tests" >
+
+ <application >
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="com.android.bandwidthtest.BandwidthTestRunner"
+ android:targetPackage="com.android.bandwidth.tests"
+ android:label="Bandwidth Tests" />
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+ <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.DEVICE_POWER" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+</manifest>
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
new file mode 100644
index 0000000..73c92b0
--- /dev/null
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.bandwidthtest;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo.State;
+import android.net.NetworkStats;
+import android.net.TrafficStats;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Process;
+import android.os.SystemClock;
+import android.telephony.TelephonyManager;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+import com.android.bandwidthtest.util.BandwidthTestUtil;
+import com.android.bandwidthtest.util.ConnectionUtil;
+
+import java.io.File;
+
+/**
+ * Test that downloads files from a test server and reports the bandwidth metrics collected.
+ */
+public class BandwidthTest extends InstrumentationTestCase {
+
+ private static final String LOG_TAG = "BandwidthTest";
+ private final static String PROF_LABEL = "PROF_";
+ private final static String PROC_LABEL = "PROC_";
+ private final static int INSTRUMENTATION_IN_PROGRESS = 2;
+
+ private final static String BASE_DIR =
+ Environment.getExternalStorageDirectory().getAbsolutePath();
+ private final static String TMP_FILENAME = "tmp.dat";
+ // Download 10.486 * 106 bytes (+ headers) from app engine test server.
+ private final int FILE_SIZE = 10485613;
+ private Context mContext;
+ private ConnectionUtil mConnectionUtil;
+ private TelephonyManager mTManager;
+ private int mUid;
+ private String mSsid;
+ private String mTestServer;
+ private String mDeviceId;
+ private BandwidthTestRunner mRunner;
+
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mRunner = (BandwidthTestRunner) getInstrumentation();
+ mSsid = mRunner.mSsid;
+ mTestServer = mRunner.mTestServer;
+ mContext = mRunner.getTargetContext();
+ mConnectionUtil = new ConnectionUtil(mContext);
+ mConnectionUtil.initialize();
+ Log.v(LOG_TAG, "Initialized mConnectionUtil");
+ mUid = Process.myUid();
+ mTManager = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ mDeviceId = mTManager.getDeviceId();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mConnectionUtil.cleanUp();
+ super.tearDown();
+ }
+
+ /**
+ * Ensure that downloading on wifi reports reasonable stats.
+ */
+ @LargeTest
+ public void testWifiDownload() {
+ assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
+ NetworkStats pre_test_stats = fetchDataFromProc(mUid);
+ String ts = Long.toString(System.currentTimeMillis());
+
+ String targetUrl = BandwidthTestUtil.buildDownloadUrl(
+ mTestServer, FILE_SIZE, mDeviceId, ts);
+ TrafficStats.startDataProfiling(mContext);
+ File tmpSaveFile = new File(BASE_DIR + File.separator + TMP_FILENAME);
+ assertTrue(BandwidthTestUtil.DownloadFromUrl(targetUrl, tmpSaveFile));
+ NetworkStats prof_stats = TrafficStats.stopDataProfiling(mContext);
+
+ NetworkStats post_test_stats = fetchDataFromProc(mUid);
+ NetworkStats proc_stats = post_test_stats.subtract(pre_test_stats);
+
+ // Output measurements to instrumentation out, so that it can be compared to that of
+ // the server.
+ Bundle results = new Bundle();
+ results.putString("device_id", mDeviceId);
+ results.putString("timestamp", ts);
+ results.putInt("size", FILE_SIZE);
+ AddStatsToResults(PROF_LABEL, prof_stats, results);
+ AddStatsToResults(PROC_LABEL, proc_stats, results);
+ getInstrumentation().sendStatus(INSTRUMENTATION_IN_PROGRESS, results);
+
+ // Clean up.
+ assertTrue(cleanUpFile(tmpSaveFile));
+ }
+
+ /**
+ * We want to make sure that if we use the Download Manager to download stuff,
+ * accounting still goes to the app making the call and that the numbers still make sense.
+ */
+ @LargeTest
+ public void testWifiDownloadWithDownloadManager() {
+ assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
+ // If we are using the download manager, then the data that is written to /proc/uid_stat/
+ // is accounted against download manager's uid, since it uses pre-ICS API.
+ int downloadManagerUid = mConnectionUtil.downloadManagerUid();
+ assertTrue(downloadManagerUid >= 0);
+ NetworkStats pre_test_stats = fetchDataFromProc(downloadManagerUid);
+ // start profiling
+ TrafficStats.startDataProfiling(mContext);
+ String ts = Long.toString(System.currentTimeMillis());
+ String targetUrl = BandwidthTestUtil.buildDownloadUrl(
+ mTestServer, FILE_SIZE, mDeviceId, ts);
+ Log.v(LOG_TAG, "Download url: " + targetUrl);
+ File tmpSaveFile = new File(BASE_DIR + File.separator + TMP_FILENAME);
+ assertTrue(mConnectionUtil.startDownloadAndWait(targetUrl, 500000));
+ NetworkStats prof_stats = TrafficStats.stopDataProfiling(mContext);
+ NetworkStats post_test_stats = fetchDataFromProc(downloadManagerUid);
+ NetworkStats proc_stats = post_test_stats.subtract(pre_test_stats);
+
+ // Output measurements to instrumentation out, so that it can be compared to that of
+ // the server.
+ Bundle results = new Bundle();
+ results.putString("device_id", mDeviceId);
+ results.putString("timestamp", ts);
+ results.putInt("size", FILE_SIZE);
+ AddStatsToResults(PROF_LABEL, prof_stats, results);
+ AddStatsToResults(PROC_LABEL, proc_stats, results);
+ getInstrumentation().sendStatus(INSTRUMENTATION_IN_PROGRESS, results);
+
+ // Clean up.
+ assertTrue(cleanUpFile(tmpSaveFile));
+ }
+
+ /**
+ * Fetch network data from /proc/uid_stat/uid
+ * @return populated {@link NetworkStats}
+ */
+ public NetworkStats fetchDataFromProc(int uid) {
+ String root_filepath = "/proc/uid_stat/" + uid + "/";
+ File rcv_stat = new File (root_filepath + "tcp_rcv");
+ int rx = BandwidthTestUtil.parseIntValueFromFile(rcv_stat);
+ File snd_stat = new File (root_filepath + "tcp_snd");
+ int tx = BandwidthTestUtil.parseIntValueFromFile(snd_stat);
+ NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
+ stats.addValues(NetworkStats.IFACE_ALL, uid, NetworkStats.TAG_NONE, rx, 0, tx, 0);
+ return stats;
+ }
+
+ /**
+ * Turn on Airplane mode and connect to the wifi
+ * @param ssid of the wifi to connect to
+ * @return true if we successfully connected to a given network.
+ */
+ public boolean setDeviceWifiAndAirplaneMode(String ssid) {
+ mConnectionUtil.setAirplaneMode(mContext, true);
+ assertTrue(mConnectionUtil.connectToWifi(ssid));
+ assertTrue(mConnectionUtil.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
+ ConnectionUtil.LONG_TIMEOUT));
+ return mConnectionUtil.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+ ConnectionUtil.LONG_TIMEOUT);
+ }
+
+ /**
+ * Output the {@link NetworkStats} to Instrumentation out.
+ * @param label to attach to this given stats.
+ * @param stats {@link NetworkStats} to add.
+ * @param results {@link Bundle} to be added to.
+ */
+ public void AddStatsToResults(String label, NetworkStats stats, Bundle results){
+ if (results == null || results.isEmpty()) {
+ Log.e(LOG_TAG, "Empty bundle provided.");
+ return;
+ }
+ for (int i = 0; i < stats.size(); ++i) {
+ android.net.NetworkStats.Entry entry = stats.getValues(i, null);
+ results.putInt(label + "uid", entry.uid);
+ results.putString(label + "iface", entry.iface);
+ results.putInt(label + "tag", entry.tag);
+ results.putLong(label + "tx", entry.txBytes);
+ results.putLong(label + "rx", entry.rxBytes);
+ }
+ }
+
+ /**
+ * Remove file if it exists.
+ * @param file {@link File} to delete.
+ * @return true if successfully deleted the file.
+ */
+ private boolean cleanUpFile(File file) {
+ if (file.exists()) {
+ return file.delete();
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTestRunner.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTestRunner.java
new file mode 100644
index 0000000..290ccee
--- /dev/null
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTestRunner.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.bandwidthtest;
+
+import android.os.Bundle;
+import android.test.InstrumentationTestRunner;
+
+public class BandwidthTestRunner extends InstrumentationTestRunner {
+ public String mSsid = "wifi-ssid";
+ public String mTestServer = "http://www.sometestserver.com";
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ String ssidStr= (String) icicle.get("ssid");
+ if (ssidStr != null) {
+ mSsid = ssidStr;
+ }
+ String serverStr = (String) icicle.get("server");
+ if (serverStr != null) {
+ mTestServer = serverStr;
+ }
+ }
+}
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/NetworkState.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/NetworkState.java
new file mode 100644
index 0000000..fae0e76
--- /dev/null
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/NetworkState.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.bandwidthtest;
+
+import android.net.NetworkInfo.State;
+import android.util.Log;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Data structure to keep track of the network state transitions.
+ */
+public class NetworkState {
+ /**
+ * Desired direction of state transition.
+ */
+ public enum StateTransitionDirection {
+ TO_DISCONNECTION, TO_CONNECTION, DO_NOTHING
+ }
+ private final String LOG_TAG = "NetworkState";
+ private List<State> mStateDepository;
+ private State mTransitionTarget;
+ private StateTransitionDirection mTransitionDirection;
+ private String mReason = null; // record mReason of state transition failure
+
+ public NetworkState() {
+ mStateDepository = new ArrayList<State>();
+ mTransitionDirection = StateTransitionDirection.DO_NOTHING;
+ mTransitionTarget = State.UNKNOWN;
+ }
+
+ public NetworkState(State currentState) {
+ mStateDepository = new ArrayList<State>();
+ mStateDepository.add(currentState);
+ mTransitionDirection = StateTransitionDirection.DO_NOTHING;
+ mTransitionTarget = State.UNKNOWN;
+ }
+
+ /**
+ * Reinitialize the network state
+ */
+ public void resetNetworkState() {
+ mStateDepository.clear();
+ mTransitionDirection = StateTransitionDirection.DO_NOTHING;
+ mTransitionTarget = State.UNKNOWN;
+ }
+
+ /**
+ * Set the transition criteria
+ * @param initState initial {@link State}
+ * @param transitionDir explicit {@link StateTransitionDirection}
+ * @param targetState desired {@link State}
+ */
+ public void setStateTransitionCriteria(State initState, StateTransitionDirection transitionDir,
+ State targetState) {
+ if (!mStateDepository.isEmpty()) {
+ mStateDepository.clear();
+ }
+ mStateDepository.add(initState);
+ mTransitionDirection = transitionDir;
+ mTransitionTarget = targetState;
+ Log.v(LOG_TAG, "setStateTransitionCriteria: " + printStates());
+ }
+
+ /**
+ * Record the current state of the network
+ * @param currentState the current {@link State}
+ */
+ public void recordState(State currentState) {
+ mStateDepository.add(currentState);
+ }
+
+ /**
+ * Verify the state transition
+ * @return true if the requested transition completed successfully.
+ */
+ public boolean validateStateTransition() {
+ Log.v(LOG_TAG, String.format("Print state depository: %s", printStates()));
+ switch (mTransitionDirection) {
+ case DO_NOTHING:
+ Log.v(LOG_TAG, "No direction requested, verifying network states");
+ return validateNetworkStates();
+ case TO_CONNECTION:
+ Log.v(LOG_TAG, "Transition to CONNECTED");
+ return validateNetworkConnection();
+ case TO_DISCONNECTION:
+ Log.v(LOG_TAG, "Transition to DISCONNECTED");
+ return validateNetworkDisconnection();
+ default:
+ Log.e(LOG_TAG, "Invalid transition direction.");
+ return false;
+ }
+ }
+
+ /**
+ * Verify that network states are valid
+ * @return false if any of the states are invalid
+ */
+ private boolean validateNetworkStates() {
+ if (mStateDepository.isEmpty()) {
+ Log.v(LOG_TAG, "no state is recorded");
+ mReason = "no state is recorded.";
+ return false;
+ } else if (mStateDepository.size() > 1) {
+ Log.v(LOG_TAG, "no broadcast is expected, instead broadcast is probably received");
+ mReason = "no broadcast is expected, instead broadcast is probably received";
+ return false;
+ } else if (mStateDepository.get(0) != mTransitionTarget) {
+ Log.v(LOG_TAG, String.format("%s is expected, but it is %s",
+ mTransitionTarget.toString(),
+ mStateDepository.get(0).toString()));
+ mReason = String.format("%s is expected, but it is %s",
+ mTransitionTarget.toString(),
+ mStateDepository.get(0).toString());
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Verify the network state to disconnection
+ * @return false if any of the state transitions were not valid
+ */
+ private boolean validateNetworkDisconnection() {
+ // Transition from CONNECTED -> DISCONNECTED: CONNECTED->DISCONNECTING->DISCONNECTED
+ StringBuffer str = new StringBuffer ("States: ");
+ str.append(printStates());
+ if (mStateDepository.get(0) != State.CONNECTED) {
+ str.append(String.format(" Initial state should be CONNECTED, but it is %s.",
+ mStateDepository.get(0)));
+ mReason = str.toString();
+ return false;
+ }
+ State lastState = mStateDepository.get(mStateDepository.size() - 1);
+ if ( lastState != mTransitionTarget) {
+ str.append(String.format(" Last state should be DISCONNECTED, but it is %s",
+ lastState));
+ mReason = str.toString();
+ return false;
+ }
+ for (int i = 1; i < mStateDepository.size() - 1; i++) {
+ State preState = mStateDepository.get(i-1);
+ State curState = mStateDepository.get(i);
+ if ((preState == State.CONNECTED) && ((curState == State.DISCONNECTING) ||
+ (curState == State.DISCONNECTED))) {
+ continue;
+ } else if ((preState == State.DISCONNECTING) && (curState == State.DISCONNECTED)) {
+ continue;
+ } else if ((preState == State.DISCONNECTED) && (curState == State.DISCONNECTED)) {
+ continue;
+ } else {
+ str.append(String.format(" Transition state from %s to %s is not valid",
+ preState.toString(), curState.toString()));
+ mReason = str.toString();
+ return false;
+ }
+ }
+ mReason = str.toString();
+ return true;
+ }
+
+ /**
+ * Verify the network state to connection
+ * @return false if any of the state transitions were not valid
+ */
+ private boolean validateNetworkConnection() {
+ StringBuffer str = new StringBuffer("States ");
+ str.append(printStates());
+ if (mStateDepository.get(0) != State.DISCONNECTED) {
+ str.append(String.format(" Initial state should be DISCONNECTED, but it is %s.",
+ mStateDepository.get(0)));
+ mReason = str.toString();
+ return false;
+ }
+ State lastState = mStateDepository.get(mStateDepository.size() - 1);
+ if ( lastState != mTransitionTarget) {
+ str.append(String.format(" Last state should be %s, but it is %s", mTransitionTarget,
+ lastState));
+ mReason = str.toString();
+ return false;
+ }
+ for (int i = 1; i < mStateDepository.size(); i++) {
+ State preState = mStateDepository.get(i-1);
+ State curState = mStateDepository.get(i);
+ if ((preState == State.DISCONNECTED) && ((curState == State.CONNECTING) ||
+ (curState == State.CONNECTED) || (curState == State.DISCONNECTED))) {
+ continue;
+ } else if ((preState == State.CONNECTING) && (curState == State.CONNECTED)) {
+ continue;
+ } else if ((preState == State.CONNECTED) && (curState == State.CONNECTED)) {
+ continue;
+ } else {
+ str.append(String.format(" Transition state from %s to %s is not valid.",
+ preState.toString(), curState.toString()));
+ mReason = str.toString();
+ return false;
+ }
+ }
+ mReason = str.toString();
+ return true;
+ }
+
+ /**
+ * Fetch the different network state transitions
+ * @return {@link List} of {@link State}
+ */
+ public List<State> getTransitionStates() {
+ return mStateDepository;
+ }
+
+ /**
+ * Fetch the reason for network state transition failure
+ * @return the {@link String} for the failure
+ */
+ public String getFailureReason() {
+ return mReason;
+ }
+
+ /**
+ * Print the network state
+ * @return {@link String} representation of the network state
+ */
+ public String printStates() {
+ StringBuilder stateBuilder = new StringBuilder();
+ for (int i = 0; i < mStateDepository.size(); i++) {
+ stateBuilder.append(" ").append(mStateDepository.get(i).toString()).append("->");
+ }
+ return stateBuilder.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("mTransitionDirection: ").append(mTransitionDirection.toString()).
+ append("; ").append("states:").
+ append(printStates()).append("; ");
+ return builder.toString();
+ }
+}
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/BandwidthTestUtil.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/BandwidthTestUtil.java
new file mode 100644
index 0000000..d850169
--- /dev/null
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/BandwidthTestUtil.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.bandwidthtest.util;
+
+import android.util.Log;
+
+import org.apache.http.util.ByteArrayBuffer;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+
+public class BandwidthTestUtil {
+ private static final String LOG_TAG = "BandwidthTestUtil";
+ /**
+ * Parses the first line in a file if exists.
+ *
+ * @param file {@link File} the input
+ * @return the integer value of the first line of the file.
+ */
+ public static int parseIntValueFromFile(File file) {
+ int value = 0;
+ if (file.exists()) {
+ try {
+ FileInputStream fstream = new FileInputStream(file);
+ DataInputStream in = new DataInputStream(fstream);
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
+ String strLine = br.readLine();
+ if (strLine != null) {
+ value = Integer.parseInt(strLine);
+ }
+ // Close the input stream
+ in.close();
+ } catch (Exception e) {
+ System.err.println("Error: " + e.getMessage());
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Creates the Download string for the test server.
+ *
+ * @param server url of the test server
+ * @param size in bytes of the file to download
+ * @param deviceId the device id that is downloading
+ * @param timestamp
+ * @return download url
+ */
+ public static String buildDownloadUrl(String server, int size, String deviceId,
+ String timestamp) {
+ String downloadUrl = server + "/download?size=" + size + "&device_id=" + deviceId +
+ "×tamp=" + timestamp;
+ return downloadUrl;
+ }
+
+ /**
+ * Download a given file from a target url to a given destination file.
+ * @param targetUrl the url to download
+ * @param file the {@link File} location where to save to
+ * @return true if it succeeded.
+ */
+ public static boolean DownloadFromUrl(String targetUrl, File file) {
+ try {
+ URL url = new URL(targetUrl);
+ Log.d(LOG_TAG, "Download begining");
+ Log.d(LOG_TAG, "Download url:" + url);
+ Log.d(LOG_TAG, "Downloaded file name:" + file.getAbsolutePath());
+ URLConnection ucon = url.openConnection();
+ InputStream is = ucon.getInputStream();
+ BufferedInputStream bis = new BufferedInputStream(is);
+ ByteArrayBuffer baf = new ByteArrayBuffer(50);
+ int current = 0;
+ while ((current = bis.read()) != -1) {
+ baf.append((byte) current);
+ }
+ FileOutputStream fos = new FileOutputStream(file);
+ fos.write(baf.toByteArray());
+ fos.close();
+ } catch (IOException e) {
+ Log.d(LOG_TAG, "Failed to download file with error: " + e);
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
new file mode 100644
index 0000000..d663aad
--- /dev/null
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
@@ -0,0 +1,684 @@
+/*
+ * Copyright (C) 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.bandwidthtest.util;
+
+import android.app.DownloadManager;
+import android.app.DownloadManager.Query;
+import android.app.DownloadManager.Request;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.Cursor;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.NetworkInfo.State;
+import android.net.Uri;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.Message;
+import android.provider.Settings;
+import android.util.Log;
+
+import com.android.bandwidthtest.NetworkState;
+import com.android.bandwidthtest.NetworkState.StateTransitionDirection;
+import com.android.internal.util.AsyncChannel;
+
+import java.util.List;
+
+/*
+ * Utility class used to set the connectivity of the device and to download files.
+ */
+public class ConnectionUtil {
+ private static final String LOG_TAG = "ConnectionUtil";
+ private static final String DOWNLOAD_MANAGER_PKG_NAME = "com.android.providers.downloads";
+ private static final int WAIT_FOR_SCAN_RESULT = 10 * 1000; // 10 seconds
+ private static final int WIFI_SCAN_TIMEOUT = 50 * 1000;
+ public static final int SHORT_TIMEOUT = 5 * 1000;
+ public static final int LONG_TIMEOUT = 10 * 1000;
+ private ConnectivityReceiver mConnectivityReceiver = null;
+ private WifiReceiver mWifiReceiver = null;
+ private DownloadReceiver mDownloadReceiver = null;
+ private DownloadManager mDownloadManager;
+ private NetworkInfo mNetworkInfo;
+ private NetworkInfo mOtherNetworkInfo;
+ private boolean mScanResultIsAvailable = false;
+ private ConnectivityManager mCM;
+ private Object mWifiMonitor = new Object();
+ private Object mConnectivityMonitor = new Object();
+ private Object mDownloadMonitor = new Object();
+ private int mWifiState;
+ private NetworkInfo mWifiNetworkInfo;
+ private WifiManager mWifiManager;
+ private Context mContext;
+ // Verify connectivity state
+ private static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1;
+ private NetworkState[] mConnectivityState = new NetworkState[NUM_NETWORK_TYPES];
+
+ public ConnectionUtil(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Initialize the class. Needs to be called before any other methods in {@link ConnectionUtil}
+ *
+ * @throws Exception
+ */
+ public void initialize() throws Exception {
+ // Register a connectivity receiver for CONNECTIVITY_ACTION
+ mConnectivityReceiver = new ConnectivityReceiver();
+ mContext.registerReceiver(mConnectivityReceiver,
+ new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
+
+ // Register a download receiver for ACTION_DOWNLOAD_COMPLETE
+ mDownloadReceiver = new DownloadReceiver();
+ mContext.registerReceiver(mDownloadReceiver,
+ new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
+
+ // Register a wifi receiver
+ mWifiReceiver = new WifiReceiver();
+ IntentFilter mIntentFilter = new IntentFilter();
+ mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+ mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+ mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+ mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
+ mIntentFilter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
+ mContext.registerReceiver(mWifiReceiver, mIntentFilter);
+
+ // Get an instance of ConnectivityManager
+ mCM = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ // Get an instance of WifiManager
+ mWifiManager =(WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
+ mWifiManager.asyncConnect(mContext, new WifiServiceHandler());
+
+ mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE);
+
+ initializeNetworkStates();
+
+ mWifiManager.setWifiEnabled(true);
+
+ Log.v(LOG_TAG, "Clear Wifi before we start the test.");
+ sleep(SHORT_TIMEOUT);
+ removeConfiguredNetworksAndDisableWifi();
+ }
+
+
+ /**
+ * A wrapper of a broadcast receiver which provides network connectivity information
+ * for all kinds of network: wifi, mobile, etc.
+ */
+ private class ConnectivityReceiver extends BroadcastReceiver {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (isInitialStickyBroadcast()) {
+ Log.d(LOG_TAG, "This is a sticky broadcast don't do anything.");
+ return;
+ }
+ Log.v(LOG_TAG, "ConnectivityReceiver: onReceive() is called with " + intent);
+ String action = intent.getAction();
+ if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
+ Log.v("ConnectivityReceiver", "onReceive() called with " + intent);
+ return;
+ }
+ if (intent.hasExtra(ConnectivityManager.EXTRA_NETWORK_INFO)) {
+ mNetworkInfo = (NetworkInfo)
+ intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
+ }
+
+ if (intent.hasExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO)) {
+ mOtherNetworkInfo = (NetworkInfo)
+ intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
+ }
+
+ Log.v(LOG_TAG, "mNetworkInfo: " + mNetworkInfo.toString());
+ recordNetworkState(mNetworkInfo.getType(), mNetworkInfo.getState());
+ if (mOtherNetworkInfo != null) {
+ Log.v(LOG_TAG, "mOtherNetworkInfo: " + mOtherNetworkInfo.toString());
+ recordNetworkState(mOtherNetworkInfo.getType(), mOtherNetworkInfo.getState());
+ }
+ notifyNetworkConnectivityChange();
+ }
+ }
+
+ /**
+ * A wrapper of a broadcast receiver which provides wifi information.
+ */
+ private class WifiReceiver extends BroadcastReceiver {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ Log.v("WifiReceiver", "onReceive() is calleld with " + intent);
+ if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
+ Log.v(LOG_TAG, "Scan results are available");
+ notifyScanResult();
+ } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+ mWifiNetworkInfo =
+ (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+ Log.v(LOG_TAG, "mWifiNetworkInfo: " + mWifiNetworkInfo.toString());
+ if (mWifiNetworkInfo.getState() == State.CONNECTED) {
+ intent.getStringExtra(WifiManager.EXTRA_BSSID);
+ }
+ notifyWifiState();
+ } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
+ mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+ WifiManager.WIFI_STATE_UNKNOWN);
+ notifyWifiState();
+ } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
+ notifyWifiAPState();
+ } else {
+ return;
+ }
+ }
+ }
+
+ /**
+ * A wrapper of a broadcast receiver which provides download manager information.
+ */
+ private class DownloadReceiver extends BroadcastReceiver {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ Log.v("DownloadReceiver", "onReceive() is called with " + intent);
+ // Download complete
+ if (action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
+ notifiyDownloadState();
+ }
+ }
+ }
+
+ private class WifiServiceHandler extends Handler {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+ if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
+ // AsyncChannel in msg.obj
+ } else {
+ Log.v(LOG_TAG, "Failed to establish AsyncChannel connection");
+ }
+ break;
+ default:
+ // Ignore
+ break;
+ }
+ }
+ }
+
+ /**
+ * Initialize all the network states.
+ */
+ public void initializeNetworkStates() {
+ // For each network type, initialize network states to UNKNOWN, and no verification
+ // flag is set.
+ for (int networkType = NUM_NETWORK_TYPES - 1; networkType >= 0; networkType--) {
+ mConnectivityState[networkType] = new NetworkState();
+ Log.v(LOG_TAG, "Initialize network state for " + networkType + ": " +
+ mConnectivityState[networkType].toString());
+ }
+ }
+
+ public void recordNetworkState(int networkType, State networkState) {
+ // deposit a network state
+ Log.v(LOG_TAG, "record network state for network " + networkType +
+ ", state is " + networkState);
+ mConnectivityState[networkType].recordState(networkState);
+ }
+
+ /**
+ * Set the state transition criteria
+ *
+ * @param networkType
+ * @param initState
+ * @param transitionDir
+ * @param targetState
+ */
+ public void setStateTransitionCriteria(int networkType, State initState,
+ StateTransitionDirection transitionDir, State targetState) {
+ mConnectivityState[networkType].setStateTransitionCriteria(
+ initState, transitionDir, targetState);
+ }
+
+ /**
+ * Validate the states recorded.
+ * @param networkType
+ * @return
+ */
+ public boolean validateNetworkStates(int networkType) {
+ Log.v(LOG_TAG, "validate network state for " + networkType + ": ");
+ return mConnectivityState[networkType].validateStateTransition();
+ }
+
+ /**
+ * Fetch the failure reason for the transition.
+ * @param networkType
+ * @return result from network state validation
+ */
+ public String getTransitionFailureReason(int networkType) {
+ Log.v(LOG_TAG, "get network state transition failure reason for " + networkType + ": " +
+ mConnectivityState[networkType].toString());
+ return mConnectivityState[networkType].getFailureReason();
+ }
+
+ /**
+ * Send a notification via the mConnectivityMonitor when the network connectivity changes.
+ */
+ private void notifyNetworkConnectivityChange() {
+ synchronized(mConnectivityMonitor) {
+ Log.v(LOG_TAG, "notify network connectivity changed");
+ mConnectivityMonitor.notifyAll();
+ }
+ }
+
+ /**
+ * Send a notification when a scan for the wifi network is done.
+ */
+ private void notifyScanResult() {
+ synchronized (this) {
+ Log.v(LOG_TAG, "notify that scan results are available");
+ this.notify();
+ }
+ }
+
+ /**
+ * Send a notification via the mWifiMonitor when the wifi state changes.
+ */
+ private void notifyWifiState() {
+ synchronized (mWifiMonitor) {
+ Log.v(LOG_TAG, "notify wifi state changed.");
+ mWifiMonitor.notify();
+ }
+ }
+
+ /**
+ * Send a notification via the mDownloadMonitor when a download is complete.
+ */
+ private void notifiyDownloadState() {
+ synchronized (mDownloadMonitor) {
+ Log.v(LOG_TAG, "notifiy download manager state changed.");
+ mDownloadMonitor.notify();
+ }
+ }
+
+ /**
+ * Send a notification when the wifi ap state changes.
+ */
+ private void notifyWifiAPState() {
+ synchronized (this) {
+ Log.v(LOG_TAG, "notify wifi AP state changed.");
+ this.notify();
+ }
+ }
+
+ /**
+ * Start a download on a given url and wait for completion.
+ *
+ * @param targetUrl the target to download.x
+ * @param timeout to wait for download to finish
+ * @return true if we successfully downloaded the requestedUrl, false otherwise.
+ */
+ public boolean startDownloadAndWait(String targetUrl, long timeout) {
+ if (targetUrl.length() == 0 || targetUrl == null) {
+ Log.v(LOG_TAG, "Empty or Null target url requested to DownloadManager");
+ return true;
+ }
+ Request request = new Request(Uri.parse(targetUrl));
+ long enqueue = mDownloadManager.enqueue(request);
+ Log.v(LOG_TAG, "Sending download request of " + targetUrl + " to DownloadManager");
+ long startTime = System.currentTimeMillis();
+ while (true) {
+ if ((System.currentTimeMillis() - startTime) > timeout) {
+ Log.v(LOG_TAG, "startDownloadAndWait timed out, failed to fetch " + targetUrl +
+ " within " + timeout);
+ return downloadSuccessful(enqueue);
+ }
+ Log.v(LOG_TAG, "Waiting for the download to finish " + targetUrl);
+ synchronized (mDownloadMonitor) {
+ try {
+ mDownloadMonitor.wait(SHORT_TIMEOUT);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ if (!downloadSuccessful(enqueue)) {
+ continue;
+ }
+ return true;
+ }
+ }
+ }
+
+ /**
+ * Fetch the Download Manager's UID.
+ * @return the Download Manager's UID
+ */
+ public int downloadManagerUid() {
+ try {
+ PackageManager pm = mContext.getPackageManager();
+ ApplicationInfo appInfo = pm.getApplicationInfo(DOWNLOAD_MANAGER_PKG_NAME,
+ PackageManager.GET_META_DATA);
+ return appInfo.uid;
+ } catch (NameNotFoundException e) {
+ Log.d(LOG_TAG, "Did not find the package for the download service.");
+ return -1;
+ }
+ }
+
+ /**
+ * Determines if a given download was successful by querying the DownloadManager.
+ *
+ * @param enqueue the id used to identify/query the DownloadManager with.
+ * @return true if download was successful, false otherwise.
+ */
+ private boolean downloadSuccessful(long enqueue) {
+ Query query = new Query();
+ query.setFilterById(enqueue);
+ Cursor c = mDownloadManager.query(query);
+ if (c.moveToFirst()) {
+ int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
+ if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
+ Log.v(LOG_TAG, "Successfully downloaded file!");
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Wait for network connectivity state.
+ * @param networkType the network to check for
+ * @param expectedState the desired state
+ * @param timeout in milliseconds
+ * @return true if the network connectivity state matched what was expected
+ */
+ public boolean waitForNetworkState(int networkType, State expectedState, long timeout) {
+ long startTime = System.currentTimeMillis();
+ while (true) {
+ if ((System.currentTimeMillis() - startTime) > timeout) {
+ Log.v(LOG_TAG, "waitForNetworkState time out, the state of network type " + networkType +
+ " is: " + mCM.getNetworkInfo(networkType).getState());
+ if (mCM.getNetworkInfo(networkType).getState() != expectedState) {
+ return false;
+ } else {
+ // the broadcast has been sent out. the state has been changed.
+ Log.v(LOG_TAG, "networktype: " + networkType + " state: " +
+ mCM.getNetworkInfo(networkType));
+ return true;
+ }
+ }
+ Log.v(LOG_TAG, "Wait for the connectivity state for network: " + networkType +
+ " to be " + expectedState.toString());
+ synchronized (mConnectivityMonitor) {
+ try {
+ mConnectivityMonitor.wait(SHORT_TIMEOUT);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ if ((mNetworkInfo.getType() != networkType) ||
+ (mNetworkInfo.getState() != expectedState)) {
+ Log.v(LOG_TAG, "network state for " + mNetworkInfo.getType() +
+ "is: " + mNetworkInfo.getState());
+ continue;
+ }
+ return true;
+ }
+ }
+ }
+
+ /**
+ * Wait for a given wifi state to occur within a given timeout.
+ * @param expectedState the expected wifi state.
+ * @param timeout for the state to be set in milliseconds.
+ * @return true if the state was achieved within the timeout, false otherwise.
+ */
+ public boolean waitForWifiState(int expectedState, long timeout) {
+ // Wait for Wifi state: WIFI_STATE_DISABLED, WIFI_STATE_DISABLING, WIFI_STATE_ENABLED,
+ // WIFI_STATE_ENALBING, WIFI_STATE_UNKNOWN
+ long startTime = System.currentTimeMillis();
+ while (true) {
+ if ((System.currentTimeMillis() - startTime) > timeout) {
+ if (mWifiState != expectedState) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ Log.v(LOG_TAG, "Wait for wifi state to be: " + expectedState);
+ synchronized (mWifiMonitor) {
+ try {
+ mWifiMonitor.wait(SHORT_TIMEOUT);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ if (mWifiState != expectedState) {
+ Log.v(LOG_TAG, "Wifi state is: " + mWifiState);
+ continue;
+ }
+ return true;
+ }
+ }
+ }
+
+ /**
+ * Convenience method to determine if we are connected to a mobile network.
+ * @return true if connected to a mobile network, false otherwise.
+ */
+ public boolean isConnectedToMobile() {
+ return (mNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE);
+ }
+
+ /**
+ * Convenience method to determine if we are connected to wifi.
+ * @return true if connected to wifi, false otherwise.
+ */
+ public boolean isConnectedToWifi() {
+ return (mNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI);
+ }
+
+
+ /**
+ * Associate the device to given SSID
+ * If the device is already associated with a WiFi, disconnect and forget it,
+ * We don't verify whether the connection is successful or not, leave this to the test
+ */
+ public boolean connectToWifi(String knownSSID) {
+ WifiConfiguration config = new WifiConfiguration();
+ config.SSID = knownSSID;
+ config.allowedKeyManagement.set(KeyMgmt.NONE);
+ return connectToWifiWithConfiguration(config);
+ }
+
+ /**
+ * Connect to Wi-Fi with the given configuration.
+ * @param config
+ * @return true if we ar connected to a given
+ */
+ public boolean connectToWifiWithConfiguration(WifiConfiguration config) {
+ // The SSID in the configuration is a pure string, need to convert it to a quoted string.
+ String ssid = config.SSID;
+ config.SSID = convertToQuotedString(ssid);
+
+ // If wifi is not enabled, enable it
+ if (!mWifiManager.isWifiEnabled()) {
+ Log.v(LOG_TAG, "Wifi is not enabled, enable it");
+ mWifiManager.setWifiEnabled(true);
+ // wait for the wifi state change before start scanning.
+ if (!waitForWifiState(WifiManager.WIFI_STATE_ENABLED, 2 * SHORT_TIMEOUT)) {
+ Log.v(LOG_TAG, "Wait for WIFI_STATE_ENABLED failed");
+ return false;
+ }
+ }
+
+ boolean foundApInScanResults = false;
+ for (int retry = 0; retry < 5; retry++) {
+ List<ScanResult> netList = mWifiManager.getScanResults();
+ if (netList != null) {
+ Log.v(LOG_TAG, "size of scan result list: " + netList.size());
+ for (int i = 0; i < netList.size(); i++) {
+ ScanResult sr= netList.get(i);
+ if (sr.SSID.equals(ssid)) {
+ Log.v(LOG_TAG, "Found " + ssid + " in the scan result list.");
+ Log.v(LOG_TAG, "Retry: " + retry);
+ foundApInScanResults = true;
+ mWifiManager.connectNetwork(config);
+ break;
+ }
+ }
+ }
+ if (foundApInScanResults) {
+ return true;
+ } else {
+ // Start an active scan
+ mWifiManager.startScanActive();
+ mScanResultIsAvailable = false;
+ long startTime = System.currentTimeMillis();
+ while (!mScanResultIsAvailable) {
+ if ((System.currentTimeMillis() - startTime) > WIFI_SCAN_TIMEOUT) {
+ Log.v(LOG_TAG, "wait for scan results timeout");
+ return false;
+ }
+ // wait for the scan results to be available
+ synchronized (this) {
+ // wait for the scan result to be available
+ try {
+ this.wait(WAIT_FOR_SCAN_RESULT);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ if ((mWifiManager.getScanResults() == null) ||
+ (mWifiManager.getScanResults().size() <= 0)) {
+ continue;
+ }
+ mScanResultIsAvailable = true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /*
+ * Disconnect from the current AP and remove configured networks.
+ */
+ public boolean disconnectAP() {
+ // remove saved networks
+ List<WifiConfiguration> wifiConfigList = mWifiManager.getConfiguredNetworks();
+ Log.v(LOG_TAG, "size of wifiConfigList: " + wifiConfigList.size());
+ for (WifiConfiguration wifiConfig: wifiConfigList) {
+ Log.v(LOG_TAG, "Remove wifi configuration: " + wifiConfig.networkId);
+ int netId = wifiConfig.networkId;
+ mWifiManager.forgetNetwork(netId);
+ }
+ return true;
+ }
+
+ /**
+ * Enable Wifi
+ * @return true if Wifi is enabled successfully
+ */
+ public boolean enableWifi() {
+ return mWifiManager.setWifiEnabled(true);
+ }
+
+ /**
+ * Disable Wifi
+ * @return true if Wifi is disabled successfully
+ */
+ public boolean disableWifi() {
+ return mWifiManager.setWifiEnabled(false);
+ }
+
+ /**
+ * Remove configured networks and disable wifi
+ */
+ public boolean removeConfiguredNetworksAndDisableWifi() {
+ if (!disconnectAP()) {
+ return false;
+ }
+ sleep(SHORT_TIMEOUT);
+ if (!mWifiManager.setWifiEnabled(false)) {
+ return false;
+ }
+ sleep(SHORT_TIMEOUT);
+ return true;
+ }
+
+ /**
+ * Make the current thread sleep.
+ * @param sleeptime the time to sleep in milliseconds
+ */
+ private void sleep(long sleeptime) {
+ try {
+ Thread.sleep(sleeptime);
+ } catch (InterruptedException e) {}
+ }
+
+ /**
+ * Set airplane mode on device, caller is responsible to ensuring correct state.
+ * @param context {@link Context}
+ * @param enableAM to enable or disable airplane mode.
+ */
+ public void setAirplaneMode(Context context, boolean enableAM) {
+ //set the airplane mode
+ Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
+ enableAM ? 1 : 0);
+ // Post the intent
+ Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ intent.putExtra("state", enableAM);
+ context.sendBroadcast(intent);
+ }
+
+ /**
+ * Add quotes around the string.
+ * @param string to convert
+ * @return string with quotes around it
+ */
+ protected static String convertToQuotedString(String string) {
+ return "\"" + string + "\"";
+ }
+
+ public void cleanUp() {
+ // Unregister receivers if defined.
+ if (mConnectivityReceiver != null) {
+ mContext.unregisterReceiver(mConnectivityReceiver);
+ }
+ if (mWifiReceiver != null) {
+ mContext.unregisterReceiver(mWifiReceiver);
+ }
+ if (mDownloadReceiver != null) {
+ mContext.unregisterReceiver(mDownloadReceiver);
+ }
+ Log.v(LOG_TAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
+ }
+}
\ No newline at end of file
diff --git a/core/tests/coretests/res/raw/history_v1 b/core/tests/coretests/res/raw/history_v1
new file mode 100644
index 0000000..de79491
--- /dev/null
+++ b/core/tests/coretests/res/raw/history_v1
Binary files differ
diff --git a/core/tests/coretests/src/android/animation/EventsTest.java b/core/tests/coretests/src/android/animation/EventsTest.java
index f970ffc..6ea2845 100644
--- a/core/tests/coretests/src/android/animation/EventsTest.java
+++ b/core/tests/coretests/src/android/animation/EventsTest.java
@@ -21,6 +21,8 @@
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
+import java.util.concurrent.TimeUnit;
+
/**
* Tests for the various lifecycle events of Animators. This abstract class is subclassed by
* concrete implementations that provide the actual Animator objects being tested. All of the
@@ -40,7 +42,10 @@
private static final int ANIM_DELAY = 100;
private static final int ANIM_MID_DURATION = ANIM_DURATION / 2;
private static final int ANIM_MID_DELAY = ANIM_DELAY / 2;
+ private static final int FUTURE_RELEASE_DELAY = 50;
+ private static final int TIMEOUT = ANIM_DURATION + ANIM_DELAY + FUTURE_RELEASE_DELAY;
+ private boolean mStarted; // tracks whether we've received the onAnimationStart() callback
private boolean mRunning; // tracks whether we've started the animator
private boolean mCanceled; // trackes whether we've canceled the animator
private Animator.AnimatorListener mFutureListener; // mechanism for delaying the end of the test
@@ -51,17 +56,44 @@
// setup() method prior to calling the superclass setup()
/**
- * Cancels the given animator. Used to delay cancelation until some later time (after the
+ * Cancels the given animator. Used to delay cancellation until some later time (after the
* animator has started playing).
*/
static class Canceler implements Runnable {
Animator mAnim;
- public Canceler(Animator anim) {
+ FutureWaiter mFuture;
+ public Canceler(Animator anim, FutureWaiter future) {
mAnim = anim;
+ mFuture = future;
}
@Override
public void run() {
- mAnim.cancel();
+ try {
+ mAnim.cancel();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
+ }
+ }
+ };
+
+ /**
+ * Ends the given animator. Used to delay ending until some later time (after the
+ * animator has started playing).
+ */
+ static class Ender implements Runnable {
+ Animator mAnim;
+ FutureWaiter mFuture;
+ public Ender(Animator anim, FutureWaiter future) {
+ mAnim = anim;
+ mFuture = future;
+ }
+ @Override
+ public void run() {
+ try {
+ mAnim.end();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
+ }
}
};
@@ -76,6 +108,23 @@
public FutureReleaseListener(FutureWaiter future) {
mFuture = future;
}
+
+ /**
+ * Variant constructor that auto-releases the FutureWaiter after the specified timeout.
+ * @param future
+ * @param timeout
+ */
+ public FutureReleaseListener(FutureWaiter future, long timeout) {
+ mFuture = future;
+ Handler handler = new Handler();
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mFuture.release();
+ }
+ }, timeout);
+ }
+
@Override
public void onAnimationEnd(Animator animation) {
Handler handler = new Handler();
@@ -84,7 +133,7 @@
public void run() {
mFuture.release();
}
- }, ANIM_MID_DURATION);
+ }, FUTURE_RELEASE_DELAY);
}
};
@@ -92,7 +141,6 @@
super(BasicAnimatorActivity.class);
}
-
/**
* Sets up the fields used by each test. Subclasses must override this method to create
* the protected mAnimator object used in all tests. Overrides must create that animator
@@ -107,11 +155,20 @@
// are embedded in the listener callbacks that it implements.
mListener = new AnimatorListenerAdapter() {
@Override
+ public void onAnimationStart(Animator animation) {
+ // This should only be called on an animation that has not yet been started
+ assertFalse(mStarted);
+ assertTrue(mRunning);
+ mStarted = true;
+ }
+
+ @Override
public void onAnimationCancel(Animator animation) {
// This should only be called on an animation that has been started and not
// yet canceled or ended
assertFalse(mCanceled);
assertTrue(mRunning);
+ assertTrue(mStarted);
mCanceled = true;
}
@@ -120,7 +177,9 @@
// This should only be called on an animation that has been started and not
// yet ended
assertTrue(mRunning);
+ assertTrue(mStarted);
mRunning = false;
+ mStarted = false;
super.onAnimationEnd(animation);
}
};
@@ -132,6 +191,7 @@
mRunning = false;
mCanceled = false;
+ mStarted = false;
}
/**
@@ -144,26 +204,104 @@
}
/**
+ * Verify that calling end on an unstarted animator does nothing.
+ */
+ @UiThreadTest
+ @SmallTest
+ public void testEnd() throws Exception {
+ mAnimator.end();
+ }
+
+ /**
* Verify that calling cancel on a started animator does the right thing.
*/
@UiThreadTest
@SmallTest
public void testStartCancel() throws Exception {
- mRunning = true;
- mAnimator.start();
- mAnimator.cancel();
+ mFutureListener = new FutureReleaseListener(mFuture);
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.cancel();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
+ }
+ }
+ });
+ mFuture.get(TIMEOUT, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Verify that calling end on a started animator does the right thing.
+ */
+ @UiThreadTest
+ @SmallTest
+ public void testStartEnd() throws Exception {
+ mFutureListener = new FutureReleaseListener(mFuture);
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.end();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
+ }
+ }
+ });
+ mFuture.get(TIMEOUT, TimeUnit.MILLISECONDS);
}
/**
* Same as testStartCancel, but with a startDelayed animator
*/
- @UiThreadTest
@SmallTest
public void testStartDelayedCancel() throws Exception {
+ mFutureListener = new FutureReleaseListener(mFuture);
mAnimator.setStartDelay(ANIM_DELAY);
- mRunning = true;
- mAnimator.start();
- mAnimator.cancel();
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.cancel();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
+ }
+ }
+ });
+ mFuture.get(TIMEOUT, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Same as testStartEnd, but with a startDelayed animator
+ */
+ @SmallTest
+ public void testStartDelayedEnd() throws Exception {
+ mFutureListener = new FutureReleaseListener(mFuture);
+ mAnimator.setStartDelay(ANIM_DELAY);
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.end();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
+ }
+ }
+ });
+ mFuture.get(TIMEOUT, TimeUnit.MILLISECONDS);
}
/**
@@ -180,13 +318,36 @@
mAnimator.addListener(mFutureListener);
mRunning = true;
mAnimator.start();
- handler.postDelayed(new Canceler(mAnimator), ANIM_MID_DURATION);
+ handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DURATION);
} catch (junit.framework.AssertionFailedError e) {
mFuture.setException(new RuntimeException(e));
}
}
});
- mFuture.get();
+ mFuture.get(TIMEOUT, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Verify that ending an animator that is playing does the right thing.
+ */
+ @MediumTest
+ public void testPlayingEnd() throws Exception {
+ mFutureListener = new FutureReleaseListener(mFuture);
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Handler handler = new Handler();
+ mAnimator.addListener(mFutureListener);
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Ender(mAnimator, mFuture), ANIM_MID_DURATION);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
+ }
+ }
+ });
+ mFuture.get(TIMEOUT, TimeUnit.MILLISECONDS);
}
/**
@@ -204,13 +365,91 @@
mAnimator.addListener(mFutureListener);
mRunning = true;
mAnimator.start();
- handler.postDelayed(new Canceler(mAnimator), ANIM_MID_DURATION);
+ handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DURATION);
} catch (junit.framework.AssertionFailedError e) {
mFuture.setException(new RuntimeException(e));
}
}
});
- mFuture.get();
+ mFuture.get(TIMEOUT, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Same as testPlayingEnd, but with a startDelayed animator
+ */
+ @MediumTest
+ public void testPlayingDelayedEnd() throws Exception {
+ mAnimator.setStartDelay(ANIM_DELAY);
+ mFutureListener = new FutureReleaseListener(mFuture);
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Handler handler = new Handler();
+ mAnimator.addListener(mFutureListener);
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Ender(mAnimator, mFuture), ANIM_MID_DURATION);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
+ }
+ }
+ });
+ mFuture.get(TIMEOUT, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Same as testPlayingDelayedCancel, but cancel during the startDelay period
+ */
+ @MediumTest
+ public void testPlayingDelayedCancelMidDelay() throws Exception {
+ mAnimator.setStartDelay(ANIM_DELAY);
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ // Set the listener to automatically timeout after an uncanceled animation
+ // would have finished. This tests to make sure that we're not calling
+ // the listeners with cancel/end callbacks since they won't be called
+ // with the start event.
+ mFutureListener = new FutureReleaseListener(mFuture, TIMEOUT);
+ Handler handler = new Handler();
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DELAY);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
+ }
+ }
+ });
+ mFuture.get(TIMEOUT + 100, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Same as testPlayingDelayedEnd, but end during the startDelay period
+ */
+ @MediumTest
+ public void testPlayingDelayedEndMidDelay() throws Exception {
+ mAnimator.setStartDelay(ANIM_DELAY);
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ // Set the listener to automatically timeout after an uncanceled animation
+ // would have finished. This tests to make sure that we're not calling
+ // the listeners with cancel/end callbacks since they won't be called
+ // with the start event.
+ mFutureListener = new FutureReleaseListener(mFuture, TIMEOUT);
+ Handler handler = new Handler();
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Ender(mAnimator, mFuture), ANIM_MID_DELAY);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
+ }
+ }
+ });
+ mFuture.get(TIMEOUT + 100, TimeUnit.MILLISECONDS);
}
/**
@@ -234,7 +473,31 @@
}
}
});
- mFuture.get();
+ mFuture.get(TIMEOUT, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Verifies that ending a started animation after it has already been ended
+ * does nothing.
+ */
+ @MediumTest
+ public void testStartDoubleEnd() throws Exception {
+ mFutureListener = new FutureReleaseListener(mFuture);
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.end();
+ mAnimator.end();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
+ }
+ }
+ });
+ mFuture.get(TIMEOUT, TimeUnit.MILLISECONDS);
}
/**
@@ -258,8 +521,31 @@
}
}
});
- mFuture.get();
- }
+ mFuture.get(TIMEOUT, TimeUnit.MILLISECONDS);
+ }
+ /**
+ * Same as testStartDoubleEnd, but with a startDelayed animator
+ */
+ @MediumTest
+ public void testStartDelayedDoubleEnd() throws Exception {
+ mAnimator.setStartDelay(ANIM_DELAY);
+ mFutureListener = new FutureReleaseListener(mFuture);
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.end();
+ mAnimator.end();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
+ }
+ }
+ });
+ mFuture.get(TIMEOUT, TimeUnit.MILLISECONDS);
+ }
}
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 5d28ef7..6c87c3b 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -3114,6 +3114,13 @@
PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
}
+ @LargeTest
+ public void testInstallNonexistentFile() {
+ int retCode = PackageManager.INSTALL_FAILED_INVALID_URI;
+ File invalidFile = new File("/nonexistent-file.apk");
+ invokeInstallPackageFail(Uri.fromFile(invalidFile), 0, retCode);
+ }
+
/*---------- Recommended install location tests ----*/
/*
* TODO's
diff --git a/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java b/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
index 9403d95..4db4ea5 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
@@ -16,6 +16,14 @@
package android.net;
+import static android.net.NetworkStatsHistory.FIELD_ALL;
+import static android.net.NetworkStatsHistory.FIELD_OPERATIONS;
+import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
+import static android.net.NetworkStatsHistory.FIELD_RX_PACKETS;
+import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
+import static android.net.NetworkStatsHistory.DataStreamUtils.readVarLong;
+import static android.net.NetworkStatsHistory.DataStreamUtils.writeVarLong;
+import static android.net.NetworkStatsHistory.Entry.UNKNOWN;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
@@ -23,20 +31,29 @@
import static android.text.format.DateUtils.WEEK_IN_MILLIS;
import static android.text.format.DateUtils.YEAR_IN_MILLIS;
+import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
-import junit.framework.TestCase;
+import com.android.frameworks.coretests.R;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
import java.util.Random;
@SmallTest
-public class NetworkStatsHistoryTest extends TestCase {
+public class NetworkStatsHistoryTest extends AndroidTestCase {
private static final String TAG = "NetworkStatsHistoryTest";
private static final long TEST_START = 1194220800000L;
+ private static final long KB_IN_BYTES = 1024;
+ private static final long MB_IN_BYTES = KB_IN_BYTES * 1024;
+ private static final long GB_IN_BYTES = MB_IN_BYTES * 1024;
+
private NetworkStatsHistory stats;
@Override
@@ -47,15 +64,42 @@
}
}
+ public void testReadOriginalVersion() throws Exception {
+ final DataInputStream in = new DataInputStream(
+ getContext().getResources().openRawResource(R.raw.history_v1));
+
+ NetworkStatsHistory.Entry entry = null;
+ try {
+ final NetworkStatsHistory history = new NetworkStatsHistory(in);
+ assertEquals(15 * SECOND_IN_MILLIS, history.getBucketDuration());
+
+ entry = history.getValues(0, entry);
+ assertEquals(29143L, entry.rxBytes);
+ assertEquals(6223L, entry.txBytes);
+
+ entry = history.getValues(history.size() - 1, entry);
+ assertEquals(1476L, entry.rxBytes);
+ assertEquals(838L, entry.txBytes);
+
+ entry = history.getValues(Long.MIN_VALUE, Long.MAX_VALUE, entry);
+ assertEquals(332401L, entry.rxBytes);
+ assertEquals(64314L, entry.txBytes);
+
+ } finally {
+ in.close();
+ }
+ }
+
public void testRecordSingleBucket() throws Exception {
final long BUCKET_SIZE = HOUR_IN_MILLIS;
stats = new NetworkStatsHistory(BUCKET_SIZE);
// record data into narrow window to get single bucket
- stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS, 1024L, 2048L);
+ stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS,
+ new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
assertEquals(1, stats.size());
- assertValues(stats, 0, 1024L, 2048L);
+ assertValues(stats, 0, 1024L, 10L, 2048L, 20L, 2L);
}
public void testRecordEqualBuckets() throws Exception {
@@ -64,11 +108,12 @@
// split equally across two buckets
final long recordStart = TEST_START + (bucketDuration / 2);
- stats.recordData(recordStart, recordStart + bucketDuration, 1024L, 128L);
+ stats.recordData(recordStart, recordStart + bucketDuration,
+ new NetworkStats.Entry(1024L, 10L, 128L, 2L, 2L));
assertEquals(2, stats.size());
- assertValues(stats, 0, 512L, 64L);
- assertValues(stats, 1, 512L, 64L);
+ assertValues(stats, 0, 512L, 5L, 64L, 1L, 1L);
+ assertValues(stats, 1, 512L, 5L, 64L, 1L, 1L);
}
public void testRecordTouchingBuckets() throws Exception {
@@ -79,15 +124,16 @@
// overlap into neighboring buckets. total record is 20 minutes.
final long recordStart = (TEST_START + BUCKET_SIZE) - MINUTE_IN_MILLIS;
final long recordEnd = (TEST_START + (BUCKET_SIZE * 2)) + (MINUTE_IN_MILLIS * 4);
- stats.recordData(recordStart, recordEnd, 1000L, 5000L);
+ stats.recordData(recordStart, recordEnd,
+ new NetworkStats.Entry(1000L, 2000L, 5000L, 10000L, 100L));
assertEquals(3, stats.size());
// first bucket should have (1/20 of value)
- assertValues(stats, 0, 50L, 250L);
+ assertValues(stats, 0, 50L, 100L, 250L, 500L, 5L);
// second bucket should have (15/20 of value)
- assertValues(stats, 1, 750L, 3750L);
+ assertValues(stats, 1, 750L, 1500L, 3750L, 7500L, 75L);
// final bucket should have (4/20 of value)
- assertValues(stats, 2, 200L, 1000L);
+ assertValues(stats, 2, 200L, 400L, 1000L, 2000L, 20L);
}
public void testRecordGapBuckets() throws Exception {
@@ -97,25 +143,28 @@
// record some data today and next week with large gap
final long firstStart = TEST_START;
final long lastStart = TEST_START + WEEK_IN_MILLIS;
- stats.recordData(firstStart, firstStart + SECOND_IN_MILLIS, 128L, 256L);
- stats.recordData(lastStart, lastStart + SECOND_IN_MILLIS, 64L, 512L);
+ stats.recordData(firstStart, firstStart + SECOND_IN_MILLIS,
+ new NetworkStats.Entry(128L, 2L, 256L, 4L, 1L));
+ stats.recordData(lastStart, lastStart + SECOND_IN_MILLIS,
+ new NetworkStats.Entry(64L, 1L, 512L, 8L, 2L));
// we should have two buckets, far apart from each other
assertEquals(2, stats.size());
- assertValues(stats, 0, 128L, 256L);
- assertValues(stats, 1, 64L, 512L);
+ assertValues(stats, 0, 128L, 2L, 256L, 4L, 1L);
+ assertValues(stats, 1, 64L, 1L, 512L, 8L, 2L);
// now record something in middle, spread across two buckets
final long middleStart = TEST_START + DAY_IN_MILLIS;
final long middleEnd = middleStart + (HOUR_IN_MILLIS * 2);
- stats.recordData(middleStart, middleEnd, 2048L, 2048L);
+ stats.recordData(middleStart, middleEnd,
+ new NetworkStats.Entry(2048L, 4L, 2048L, 4L, 2L));
// now should have four buckets, with new record in middle two buckets
assertEquals(4, stats.size());
- assertValues(stats, 0, 128L, 256L);
- assertValues(stats, 1, 1024L, 1024L);
- assertValues(stats, 2, 1024L, 1024L);
- assertValues(stats, 3, 64L, 512L);
+ assertValues(stats, 0, 128L, 2L, 256L, 4L, 1L);
+ assertValues(stats, 1, 1024L, 2L, 1024L, 2L, 1L);
+ assertValues(stats, 2, 1024L, 2L, 1024L, 2L, 1L);
+ assertValues(stats, 3, 64L, 1L, 512L, 8L, 2L);
}
public void testRecordOverlapBuckets() throws Exception {
@@ -123,14 +172,16 @@
stats = new NetworkStatsHistory(BUCKET_SIZE);
// record some data in one bucket, and another overlapping buckets
- stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS, 256L, 256L);
+ stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS,
+ new NetworkStats.Entry(256L, 2L, 256L, 2L, 1L));
final long midStart = TEST_START + (HOUR_IN_MILLIS / 2);
- stats.recordData(midStart, midStart + HOUR_IN_MILLIS, 1024L, 1024L);
+ stats.recordData(midStart, midStart + HOUR_IN_MILLIS,
+ new NetworkStats.Entry(1024L, 10L, 1024L, 10L, 10L));
// should have two buckets, with some data mixed together
assertEquals(2, stats.size());
- assertValues(stats, 0, 768L, 768L);
- assertValues(stats, 1, 512L, 512L);
+ assertValues(stats, 0, 768L, 7L, 768L, 7L, 6L);
+ assertValues(stats, 1, 512L, 5L, 512L, 5L, 5L);
}
public void testRecordEntireGapIdentical() throws Exception {
@@ -255,6 +306,7 @@
public void testFuzzing() throws Exception {
try {
// fuzzing with random events, looking for crashes
+ final NetworkStats.Entry entry = new NetworkStats.Entry();
final Random r = new Random();
for (int i = 0; i < 500; i++) {
stats = new NetworkStatsHistory(r.nextLong());
@@ -263,7 +315,12 @@
// add range
final long start = r.nextLong();
final long end = start + r.nextInt();
- stats.recordData(start, end, r.nextLong(), r.nextLong());
+ entry.rxBytes = nextPositiveLong(r);
+ entry.rxPackets = nextPositiveLong(r);
+ entry.txBytes = nextPositiveLong(r);
+ entry.txPackets = nextPositiveLong(r);
+ entry.operations = nextPositiveLong(r);
+ stats.recordData(start, end, entry);
} else {
// trim something
stats.removeBucketsBefore(r.nextLong());
@@ -277,6 +334,88 @@
}
}
+ private static long nextPositiveLong(Random r) {
+ final long value = r.nextLong();
+ return value < 0 ? -value : value;
+ }
+
+ public void testIgnoreFields() throws Exception {
+ final NetworkStatsHistory history = new NetworkStatsHistory(
+ MINUTE_IN_MILLIS, 0, FIELD_RX_BYTES | FIELD_TX_BYTES);
+
+ history.recordData(0, MINUTE_IN_MILLIS,
+ new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L));
+ history.recordData(0, MINUTE_IN_MILLIS * 2,
+ new NetworkStats.Entry(2L, 2L, 2L, 2L, 2L));
+
+ assertValues(
+ history, Long.MIN_VALUE, Long.MAX_VALUE, 1026L, UNKNOWN, 2050L, UNKNOWN, UNKNOWN);
+ }
+
+ public void testIgnoreFieldsRecordIn() throws Exception {
+ final NetworkStatsHistory full = new NetworkStatsHistory(MINUTE_IN_MILLIS, 0, FIELD_ALL);
+ final NetworkStatsHistory partial = new NetworkStatsHistory(
+ MINUTE_IN_MILLIS, 0, FIELD_RX_PACKETS | FIELD_OPERATIONS);
+
+ full.recordData(0, MINUTE_IN_MILLIS,
+ new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L));
+ partial.recordEntireHistory(full);
+
+ assertValues(partial, Long.MIN_VALUE, Long.MAX_VALUE, UNKNOWN, 10L, UNKNOWN, UNKNOWN, 4L);
+ }
+
+ public void testIgnoreFieldsRecordOut() throws Exception {
+ final NetworkStatsHistory full = new NetworkStatsHistory(MINUTE_IN_MILLIS, 0, FIELD_ALL);
+ final NetworkStatsHistory partial = new NetworkStatsHistory(
+ MINUTE_IN_MILLIS, 0, FIELD_RX_PACKETS | FIELD_OPERATIONS);
+
+ partial.recordData(0, MINUTE_IN_MILLIS,
+ new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L));
+ full.recordEntireHistory(partial);
+
+ assertValues(full, Long.MIN_VALUE, Long.MAX_VALUE, 0L, 10L, 0L, 0L, 4L);
+ }
+
+ public void testSerialize() throws Exception {
+ final NetworkStatsHistory before = new NetworkStatsHistory(MINUTE_IN_MILLIS, 40, FIELD_ALL);
+ before.recordData(0, MINUTE_IN_MILLIS * 4,
+ new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L));
+ before.recordData(DAY_IN_MILLIS, DAY_IN_MILLIS + MINUTE_IN_MILLIS,
+ new NetworkStats.Entry(10L, 20L, 30L, 40L, 50L));
+
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ before.writeToStream(new DataOutputStream(out));
+ out.close();
+
+ final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ final NetworkStatsHistory after = new NetworkStatsHistory(new DataInputStream(in));
+
+ // must have identical totals before and after
+ assertValues(before, Long.MIN_VALUE, Long.MAX_VALUE, 1034L, 30L, 2078L, 60L, 54L);
+ assertValues(after, Long.MIN_VALUE, Long.MAX_VALUE, 1034L, 30L, 2078L, 60L, 54L);
+ }
+
+ public void testVarLong() throws Exception {
+ assertEquals(0L, performVarLong(0L));
+ assertEquals(-1L, performVarLong(-1L));
+ assertEquals(1024L, performVarLong(1024L));
+ assertEquals(-1024L, performVarLong(-1024L));
+ assertEquals(40 * MB_IN_BYTES, performVarLong(40 * MB_IN_BYTES));
+ assertEquals(512 * GB_IN_BYTES, performVarLong(512 * GB_IN_BYTES));
+ assertEquals(Long.MIN_VALUE, performVarLong(Long.MIN_VALUE));
+ assertEquals(Long.MAX_VALUE, performVarLong(Long.MAX_VALUE));
+ assertEquals(Long.MIN_VALUE + 40, performVarLong(Long.MIN_VALUE + 40));
+ assertEquals(Long.MAX_VALUE - 40, performVarLong(Long.MAX_VALUE - 40));
+ }
+
+ private static long performVarLong(long before) throws Exception {
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ writeVarLong(new DataOutputStream(out), before);
+
+ final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ return readVarLong(new DataInputStream(in));
+ }
+
private static void assertConsistent(NetworkStatsHistory stats) {
// verify timestamps are monotonic
long lastStart = Long.MIN_VALUE;
@@ -302,4 +441,23 @@
assertEquals("unexpected txBytes", txBytes, entry.txBytes);
}
+ private static void assertValues(NetworkStatsHistory stats, int index, long rxBytes,
+ long rxPackets, long txBytes, long txPackets, long operations) {
+ final NetworkStatsHistory.Entry entry = stats.getValues(index, null);
+ assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
+ assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
+ assertEquals("unexpected txBytes", txBytes, entry.txBytes);
+ assertEquals("unexpected txPackets", txPackets, entry.txPackets);
+ assertEquals("unexpected operations", operations, entry.operations);
+ }
+
+ private static void assertValues(NetworkStatsHistory stats, long start, long end, long rxBytes,
+ long rxPackets, long txBytes, long txPackets, long operations) {
+ final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
+ assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
+ assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
+ assertEquals("unexpected txBytes", txBytes, entry.txBytes);
+ assertEquals("unexpected txPackets", txPackets, entry.txPackets);
+ assertEquals("unexpected operations", operations, entry.operations);
+ }
}
diff --git a/core/tests/coretests/src/android/net/NetworkStatsTest.java b/core/tests/coretests/src/android/net/NetworkStatsTest.java
index 2434e9f..69ad0f4 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsTest.java
@@ -31,9 +31,9 @@
public void testFindIndex() throws Exception {
final NetworkStats stats = new NetworkStats(TEST_START, 3)
- .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L)
- .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L)
- .addValues(TEST_IFACE, 102, TAG_NONE, 1024L, 8L, 1024L, 8L);
+ .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 10)
+ .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 11)
+ .addValues(TEST_IFACE, 102, TAG_NONE, 1024L, 8L, 1024L, 8L, 12);
assertEquals(2, stats.findIndex(TEST_IFACE, 102, TAG_NONE));
assertEquals(2, stats.findIndex(TEST_IFACE, 102, TAG_NONE));
@@ -47,95 +47,95 @@
assertEquals(0, stats.size());
assertEquals(2, stats.internalSize());
- stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 1L, 1L, 2L, 2L);
- stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 2L, 2L, 2L, 2L);
+ stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 1L, 1L, 2L, 2L, 3);
+ stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 2L, 2L, 2L, 2L, 4);
assertEquals(2, stats.size());
assertEquals(2, stats.internalSize());
- stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 3L, 30L, 4L, 40L);
- stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 4L, 40L, 4L, 40L);
- stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 5L, 50L, 5L, 50L);
+ stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 3L, 30L, 4L, 40L, 7);
+ stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 4L, 40L, 4L, 40L, 8);
+ stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 5L, 50L, 5L, 50L, 10);
assertEquals(5, stats.size());
assertTrue(stats.internalSize() >= 5);
- assertEntry(stats, 0, TEST_IFACE, TEST_UID, TAG_NONE, 1L, 1L, 2L, 2L);
- assertEntry(stats, 1, TEST_IFACE, TEST_UID, TAG_NONE, 2L, 2L, 2L, 2L);
- assertEntry(stats, 2, TEST_IFACE, TEST_UID, TAG_NONE, 3L, 30L, 4L, 40L);
- assertEntry(stats, 3, TEST_IFACE, TEST_UID, TAG_NONE, 4L, 40L, 4L, 40L);
- assertEntry(stats, 4, TEST_IFACE, TEST_UID, TAG_NONE, 5L, 50L, 5L, 50L);
+ assertValues(stats, 0, TEST_IFACE, TEST_UID, TAG_NONE, 1L, 1L, 2L, 2L, 3);
+ assertValues(stats, 1, TEST_IFACE, TEST_UID, TAG_NONE, 2L, 2L, 2L, 2L, 4);
+ assertValues(stats, 2, TEST_IFACE, TEST_UID, TAG_NONE, 3L, 30L, 4L, 40L, 7);
+ assertValues(stats, 3, TEST_IFACE, TEST_UID, TAG_NONE, 4L, 40L, 4L, 40L, 8);
+ assertValues(stats, 4, TEST_IFACE, TEST_UID, TAG_NONE, 5L, 50L, 5L, 50L, 10);
}
public void testCombineExisting() throws Exception {
final NetworkStats stats = new NetworkStats(TEST_START, 10);
- stats.addValues(TEST_IFACE, 1001, TAG_NONE, 512L, 4L, 256L, 2L);
- stats.addValues(TEST_IFACE, 1001, 0xff, 128L, 1L, 128L, 1L);
- stats.combineValues(TEST_IFACE, 1001, TAG_NONE, -128L, -1L, -128L, -1L);
+ stats.addValues(TEST_IFACE, 1001, TAG_NONE, 512L, 4L, 256L, 2L, 10);
+ stats.addValues(TEST_IFACE, 1001, 0xff, 128L, 1L, 128L, 1L, 2);
+ stats.combineValues(TEST_IFACE, 1001, TAG_NONE, -128L, -1L, -128L, -1L, -1);
- assertEntry(stats, 0, TEST_IFACE, 1001, TAG_NONE, 384L, 3L, 128L, 1L);
- assertEntry(stats, 1, TEST_IFACE, 1001, 0xff, 128L, 1L, 128L, 1L);
+ assertValues(stats, 0, TEST_IFACE, 1001, TAG_NONE, 384L, 3L, 128L, 1L, 9);
+ assertValues(stats, 1, TEST_IFACE, 1001, 0xff, 128L, 1L, 128L, 1L, 2);
// now try combining that should create row
- stats.combineValues(TEST_IFACE, 5005, TAG_NONE, 128L, 1L, 128L, 1L);
- assertEntry(stats, 2, TEST_IFACE, 5005, TAG_NONE, 128L, 1L, 128L, 1L);
- stats.combineValues(TEST_IFACE, 5005, TAG_NONE, 128L, 1L, 128L, 1L);
- assertEntry(stats, 2, TEST_IFACE, 5005, TAG_NONE, 256L, 2L, 256L, 2L);
+ stats.combineValues(TEST_IFACE, 5005, TAG_NONE, 128L, 1L, 128L, 1L, 3);
+ assertValues(stats, 2, TEST_IFACE, 5005, TAG_NONE, 128L, 1L, 128L, 1L, 3);
+ stats.combineValues(TEST_IFACE, 5005, TAG_NONE, 128L, 1L, 128L, 1L, 3);
+ assertValues(stats, 2, TEST_IFACE, 5005, TAG_NONE, 256L, 2L, 256L, 2L, 6);
}
public void testSubtractIdenticalData() throws Exception {
final NetworkStats before = new NetworkStats(TEST_START, 2)
- .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L)
- .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L);
+ .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+ .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
final NetworkStats after = new NetworkStats(TEST_START, 2)
- .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L)
- .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L);
+ .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+ .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
final NetworkStats result = after.subtract(before);
// identical data should result in zero delta
- assertEntry(result, 0, TEST_IFACE, 100, TAG_NONE, 0L, 0L, 0L, 0L);
- assertEntry(result, 1, TEST_IFACE, 101, TAG_NONE, 0L, 0L, 0L, 0L);
+ assertValues(result, 0, TEST_IFACE, 100, TAG_NONE, 0L, 0L, 0L, 0L, 0);
+ assertValues(result, 1, TEST_IFACE, 101, TAG_NONE, 0L, 0L, 0L, 0L, 0);
}
public void testSubtractIdenticalRows() throws Exception {
final NetworkStats before = new NetworkStats(TEST_START, 2)
- .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L)
- .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L);
+ .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+ .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
final NetworkStats after = new NetworkStats(TEST_START, 2)
- .addValues(TEST_IFACE, 100, TAG_NONE, 1025L, 9L, 2L, 1L)
- .addValues(TEST_IFACE, 101, TAG_NONE, 3L, 1L, 1028L, 9L);
+ .addValues(TEST_IFACE, 100, TAG_NONE, 1025L, 9L, 2L, 1L, 15)
+ .addValues(TEST_IFACE, 101, TAG_NONE, 3L, 1L, 1028L, 9L, 20);
final NetworkStats result = after.subtract(before);
// expect delta between measurements
- assertEntry(result, 0, TEST_IFACE, 100, TAG_NONE, 1L, 1L, 2L, 1L);
- assertEntry(result, 1, TEST_IFACE, 101, TAG_NONE, 3L, 1L, 4L, 1L);
+ assertValues(result, 0, TEST_IFACE, 100, TAG_NONE, 1L, 1L, 2L, 1L, 4);
+ assertValues(result, 1, TEST_IFACE, 101, TAG_NONE, 3L, 1L, 4L, 1L, 8);
}
public void testSubtractNewRows() throws Exception {
final NetworkStats before = new NetworkStats(TEST_START, 2)
- .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L)
- .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L);
+ .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+ .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
final NetworkStats after = new NetworkStats(TEST_START, 3)
- .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L)
- .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L)
- .addValues(TEST_IFACE, 102, TAG_NONE, 1024L, 8L, 1024L, 8L);
+ .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+ .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 12)
+ .addValues(TEST_IFACE, 102, TAG_NONE, 1024L, 8L, 1024L, 8L, 20);
final NetworkStats result = after.subtract(before);
// its okay to have new rows
- assertEntry(result, 0, TEST_IFACE, 100, TAG_NONE, 0L, 0L, 0L, 0L);
- assertEntry(result, 1, TEST_IFACE, 101, TAG_NONE, 0L, 0L, 0L, 0L);
- assertEntry(result, 2, TEST_IFACE, 102, TAG_NONE, 1024L, 8L, 1024L, 8L);
+ assertValues(result, 0, TEST_IFACE, 100, TAG_NONE, 0L, 0L, 0L, 0L, 0);
+ assertValues(result, 1, TEST_IFACE, 101, TAG_NONE, 0L, 0L, 0L, 0L, 0);
+ assertValues(result, 2, TEST_IFACE, 102, TAG_NONE, 1024L, 8L, 1024L, 8L, 20);
}
- private static void assertEntry(NetworkStats stats, int index, String iface, int uid, int tag,
- long rxBytes, long rxPackets, long txBytes, long txPackets) {
+ private static void assertValues(NetworkStats stats, int index, String iface, int uid, int tag,
+ long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) {
final NetworkStats.Entry entry = stats.getValues(index, null);
assertEquals(iface, entry.iface);
assertEquals(uid, entry.uid);
@@ -144,6 +144,7 @@
assertEquals(rxPackets, entry.rxPackets);
assertEquals(txBytes, entry.txBytes);
assertEquals(txPackets, entry.txPackets);
+ assertEquals(operations, entry.operations);
}
}
diff --git a/docs/html/guide/developing/tools/draw9patch.jd b/docs/html/guide/developing/tools/draw9patch.jd
index 1d9de4f..7cf0e4b 100644
--- a/docs/html/guide/developing/tools/draw9patch.jd
+++ b/docs/html/guide/developing/tools/draw9patch.jd
@@ -41,7 +41,7 @@
A previously saved 9-patch file (<code>*.9.png</code>) will be loaded as-is,
with no drawing area added, because it already exists.</p>
-<img src="{@docRoot}images/draw9patch-bad.png" style="float:right" alt="" height="300" width="341"
+<img src="{@docRoot}images/draw9patch-bad.png" style="float:right;clear:both" alt="" height="300" width="341"
/>
<p>Optional controls include:</p>
diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd
index ef98a6a..49d6b62 100644
--- a/docs/html/guide/topics/manifest/uses-feature-element.jd
+++ b/docs/html/guide/topics/manifest/uses-feature-element.jd
@@ -677,20 +677,36 @@
<td>The application uses basic touch interaction events, such as "click down", "click
up", and drag.</td>
<td>When declared, this indicates that the application is compatible with a device that offers an
-emulated touchscreen (or better). A device that offers an emulated touchscreen provides a user input
-system that can emulate a subset of touchscreen capabilities. An example of such an input system is
-a mouse or remote control that drives an on-screen cursor. If your application does not require
-complicated gestures and you want your application available to devices that use an on-screen
-cursor to emulate touch events, you should declare this feature.</td>
+emulated touchscreen ("fake touch" interface), or better. A device that offers a fake touch
+interface provides a user input system that emulates a subset of touchscreen capabilities. For
+example, a mouse or remote control that drives an on-screen cursor provides a fake touch interface.
+If your application requires only basic point and click interaction, you should declare this
+feature. Because this is the minimum level of touch interaction, your app will also be compatible
+with devices that offer more complex touch interfaces.
+ <p class="note"><strong>Note:</strong> Because applications require the {@code
+android.hardware.touchscreen} feature by default, if you want your application to be available to
+devices that provide a fake touch interface, you must also explicitly declare that a touch screen is
+<em>not</em> required by declaring {@code <uses-feature
+android:name="android.hardware.touchscreen" <strong>android:required="false"</strong>
+/>}</p></td>
</tr>
<tr>
<td><code>android.hardware.touchscreen</code></td>
- <td>The application uses touchscreen capabilities, for gestures more interactive
-than basic touches, such as a fling. This is a superset of the faketouch features.</td>
- <td>By default, this is assumed to be required, unless you declare
-<code>android.hardware.faketouch</code> (the subset touch mode). As such, your application is
-<em>not</em> available to devices that provide only an emulated touch interface ("fake touch") by
-default.</td>
+ <td>The application uses touchscreen capabilities for gestures that are more interactive
+than basic touch events, such as a fling. This is a superset of the faketouch features.</td>
+ <td>By default, your application requires this. As such, your application is
+<em>not</em> available to devices that provide only an emulated touch interface ("fake touch"), by
+default. If you want your application available to devices that provide a fake touch interface,
+you must explicitly declare that a touch screen is not required, by
+declaring {@code android.hardware.touchscreen} with {@code android:required="false"}. You should
+do so even if your application uses—but does not <em>require</em>—a real touch screen
+interface.
+<p>If your application <em>does require</em> a basic touch interface (in order to perform touch
+gestures such as a fling), then you don't need to do anything, because this is required by default.
+However, it's best if you explicitly declare all features used by your application, so you should
+still declare this if your app uses it.</p>
+ <p>If you require more complex touch interaction, such as multi-finger gestures, you
+should declare the advanced touch screen features below.</p></td>
</tr>
<tr>
<td><code>android.hardware.touchscreen.multitouch</code></td>
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index 986f32c..0b76a36 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -808,7 +808,9 @@
LOGV("BnDrmManagerService::onTransact :INSTALL_DRM_ENGINE");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- status_t status = installDrmEngine(data.readInt32(), data.readString8());
+ const int uniqueId = data.readInt32();
+ const String8 engineFile = data.readString8();
+ status_t status = installDrmEngine(uniqueId, engineFile);
reply->writeInt32(status);
return DRM_NO_ERROR;
@@ -822,7 +824,8 @@
const int uniqueId = data.readInt32();
const String8 path = data.readString8();
- DrmConstraints* drmConstraints = getConstraints(uniqueId, &path, data.readInt32());
+ DrmConstraints* drmConstraints
+ = getConstraints(uniqueId, &path, data.readInt32());
if (NULL != drmConstraints) {
//Filling DRM Constraints contents
@@ -948,7 +951,9 @@
const int uniqueId = data.readInt32();
//Filling DRM info Request
- DrmInfoRequest* drmInfoRequest = new DrmInfoRequest(data.readInt32(), data.readString8());
+ const int infoType = data.readInt32();
+ const String8 mimeType = data.readString8();
+ DrmInfoRequest* drmInfoRequest = new DrmInfoRequest(infoType, mimeType);
const int size = data.readInt32();
for (int index = 0; index < size; ++index) {
@@ -1021,7 +1026,9 @@
LOGV("BnDrmManagerService::onTransact :GET_ORIGINAL_MIMETYPE");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- const String8 originalMimeType = getOriginalMimeType(data.readInt32(), data.readString8());
+ const int uniqueId = data.readInt32();
+ const String8 path = data.readString8();
+ const String8 originalMimeType = getOriginalMimeType(uniqueId, path);
reply->writeString8(originalMimeType);
return DRM_NO_ERROR;
@@ -1032,8 +1039,10 @@
LOGV("BnDrmManagerService::onTransact :GET_DRM_OBJECT_TYPE");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- const int drmObjectType
- = getDrmObjectType(data.readInt32(), data.readString8(), data.readString8());
+ const int uniqueId = data.readInt32();
+ const String8 path = data.readString8();
+ const String8 mimeType = data.readString8();
+ const int drmObjectType = getDrmObjectType(uniqueId, path, mimeType);
reply->writeInt32(drmObjectType);
return DRM_NO_ERROR;
@@ -1044,8 +1053,10 @@
LOGV("BnDrmManagerService::onTransact :CHECK_RIGHTS_STATUS");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- const int result
- = checkRightsStatus(data.readInt32(), data.readString8(), data.readInt32());
+ const int uniqueId = data.readInt32();
+ const String8 path = data.readString8();
+ const int action = data.readInt32();
+ const int result = checkRightsStatus(uniqueId, path, action);
reply->writeInt32(result);
return DRM_NO_ERROR;
@@ -1061,9 +1072,10 @@
DecryptHandle handle;
readDecryptHandleFromParcelData(&handle, data);
+ const int action = data.readInt32();
+ const bool reserve = static_cast<bool>(data.readInt32());
const status_t status
- = consumeRights(uniqueId, &handle, data.readInt32(),
- static_cast<bool>(data.readInt32()));
+ = consumeRights(uniqueId, &handle, action, reserve);
reply->writeInt32(status);
clearDecryptHandle(&handle);
@@ -1080,8 +1092,10 @@
DecryptHandle handle;
readDecryptHandleFromParcelData(&handle, data);
+ const int playbackStatus = data.readInt32();
+ const int64_t position = data.readInt64();
const status_t status
- = setPlaybackStatus(uniqueId, &handle, data.readInt32(), data.readInt64());
+ = setPlaybackStatus(uniqueId, &handle, playbackStatus, position);
reply->writeInt32(status);
clearDecryptHandle(&handle);
@@ -1093,11 +1107,13 @@
LOGV("BnDrmManagerService::onTransact :VALIDATE_ACTION");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- bool result = validateAction(
- data.readInt32(),
- data.readString8(),
- data.readInt32(),
- ActionDescription(data.readInt32(), data.readInt32()));
+ const int uniqueId = data.readInt32();
+ const String8 path = data.readString8();
+ const int action = data.readInt32();
+ const int outputType = data.readInt32();
+ const int configuration = data.readInt32();
+ bool result = validateAction(uniqueId, path, action,
+ ActionDescription(outputType, configuration));
reply->writeInt32(result);
return DRM_NO_ERROR;
@@ -1108,7 +1124,9 @@
LOGV("BnDrmManagerService::onTransact :REMOVE_RIGHTS");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- const status_t status = removeRights(data.readInt32(), data.readString8());
+ int uniqueId = data.readInt32();
+ String8 path = data.readString8();
+ const status_t status = removeRights(uniqueId, path);
reply->writeInt32(status);
return DRM_NO_ERROR;
@@ -1130,7 +1148,9 @@
LOGV("BnDrmManagerService::onTransact :OPEN_CONVERT_SESSION");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- const int convertId = openConvertSession(data.readInt32(), data.readString8());
+ const int uniqueId = data.readInt32();
+ const String8 mimeType = data.readString8();
+ const int convertId = openConvertSession(uniqueId, mimeType);
reply->writeInt32(convertId);
return DRM_NO_ERROR;
@@ -1176,8 +1196,10 @@
LOGV("BnDrmManagerService::onTransact :CLOSE_CONVERT_SESSION");
CHECK_INTERFACE(IDrmManagerService, data, reply);
- DrmConvertedStatus* drmConvertedStatus
- = closeConvertSession(data.readInt32(), data.readInt32());
+ const int uniqueId = data.readInt32();
+ const int convertId = data.readInt32();
+ DrmConvertedStatus* drmConvertedStatus
+ = closeConvertSession(uniqueId, convertId);
if (NULL != drmConvertedStatus) {
//Filling Drm Converted Ststus
@@ -1241,8 +1263,10 @@
const int uniqueId = data.readInt32();
const int fd = data.readFileDescriptor();
+ const off64_t offset = data.readInt64();
+ const off64_t length = data.readInt64();
DecryptHandle* handle
- = openDecryptSession(uniqueId, fd, data.readInt64(), data.readInt64());
+ = openDecryptSession(uniqueId, fd, offset, length);
if (NULL != handle) {
writeDecryptHandleToParcelData(handle, reply);
diff --git a/drm/libdrmframework/plugins/common/util/include/SessionMap.h b/drm/libdrmframework/plugins/common/util/include/SessionMap.h
index 3dff58c..e563894 100644
--- a/drm/libdrmframework/plugins/common/util/include/SessionMap.h
+++ b/drm/libdrmframework/plugins/common/util/include/SessionMap.h
@@ -13,141 +13,175 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
#ifndef __SESSIONMAP_H__
#define __SESSIONMAP_H__
#include <utils/KeyedVector.h>
+#include <utils/threads.h>
namespace android {
/**
- * A wrapper template class for handling DRM Engine sessions.
+ * A thread safe wrapper template class for session handlings for Drm Engines. It wraps a
+ * pointer type over KeyedVector. It keeps pointer as data in the vector and free up memory
+ * allocated pointer can be of any type of structure/class meant for keeping session data.
+ * so session object here means pointer to the session data.
*/
-template <typename NODE>
+template <typename TValue>
class SessionMap {
public:
- KeyedVector<int, NODE> map;
-
SessionMap() {}
virtual ~SessionMap() {
+ Mutex::Autolock lock(mLock);
destroyMap();
}
-/**
- * Adds a new value in the session map table. It expects memory to be allocated already
- * for the session object
- *
- * @param key - key or Session ID
- * @param value - session object to add
- *
- * @return boolean result of adding value. returns false if key is already exist.
- */
-bool addValue(int key, NODE value) {
- bool result = false;
-
- if (!isCreated(key)) {
- map.add(key, value);
- result = true;
+ /**
+ * Adds a new value in the session map table. It expects memory to be allocated already
+ * for the session object
+ *
+ * @param key - key or Session ID
+ * @param value - session object to add
+ *
+ * @return boolean result of adding value. returns false if key is already exist.
+ */
+ bool addValue(int key, TValue value) {
+ Mutex::Autolock lock(mLock);
+ if (!isCreatedInternal(key)) {
+ map.add(key, value);
+ return true;
+ }
+ return false;
}
- return result;
-}
-
-
-/**
- * returns the session object by the key
- *
- * @param key - key or Session ID
- *
- * @return session object as per the key
- */
-NODE getValue(int key) {
- NODE value = NULL;
-
- if (isCreated(key)) {
- value = (NODE) map.valueFor(key);
+ /**
+ * returns the session object by the key
+ *
+ * @param key - key or Session ID
+ *
+ * @return session object as per the key
+ */
+ TValue getValue(int key) {
+ Mutex::Autolock lock(mLock);
+ return getValueInternal(key);
}
- return value;
-}
-
-/**
- * returns the number of objects in the session map table
- *
- * @return count of number of session objects.
- */
-int getSize() {
- return map.size();
-}
-
-/**
- * returns the session object by the index in the session map table
- *
- * @param index - index of the value required
- *
- * @return session object as per the index
- */
-NODE getValueAt(unsigned int index) {
- NODE value = NULL;
-
- if (map.size() > index) {
- value = map.valueAt(index);
+ /**
+ * returns the number of objects in the session map table
+ *
+ * @return count of number of session objects.
+ */
+ int getSize() {
+ Mutex::Autolock lock(mLock);
+ return map.size();
}
- return value;
-}
+ /**
+ * returns the session object by the index in the session map table
+ *
+ * @param index - index of the value required
+ *
+ * @return session object as per the index
+ */
+ TValue getValueAt(unsigned int index) {
+ TValue value = NULL;
+ Mutex::Autolock lock(mLock);
-/**
- * deletes the object from session map. It also frees up memory for the session object.
- *
- * @param key - key of the value to be deleted
- *
- */
-void removeValue(int key) {
- deleteValue(getValue(key));
- map.removeItem(key);
-}
-
-/**
- * decides if session is already created.
- *
- * @param key - key of the value for the session
- *
- * @return boolean result of whether session is created
- */
-bool isCreated(int key) {
- return (0 <= map.indexOfKey(key));
-}
-
-/**
- * empty the entire session table. It releases all the memory for session objects.
- */
-void destroyMap() {
- int size = map.size();
- int i = 0;
-
- for (i = 0; i < size; i++) {
- deleteValue(map.valueAt(i));
+ if (map.size() > index) {
+ value = map.valueAt(index);
+ }
+ return value;
}
- map.clear();
-}
+ /**
+ * deletes the object from session map. It also frees up memory for the session object.
+ *
+ * @param key - key of the value to be deleted
+ *
+ */
+ void removeValue(int key) {
+ Mutex::Autolock lock(mLock);
+ deleteValue(getValueInternal(key));
+ map.removeItem(key);
+ }
-/**
- * free up the memory for the session object.
- * Make sure if any reference to the session object anywhere, otherwise it will be a
- * dangle pointer after this call.
- *
- * @param value - session object to free
- *
- */
-void deleteValue(NODE value) {
- delete value;
-}
+ /**
+ * decides if session is already created.
+ *
+ * @param key - key of the value for the session
+ *
+ * @return boolean result of whether session is created
+ */
+ bool isCreated(int key) {
+ Mutex::Autolock lock(mLock);
+ return isCreatedInternal(key);
+ }
+ SessionMap<TValue> & operator=(const SessionMap<TValue> & objectCopy) {
+ Mutex::Autolock lock(mLock);
+
+ destroyMap();
+ map = objectCopy.map;
+ return *this;
+ }
+
+private:
+ KeyedVector<int, TValue> map;
+ Mutex mLock;
+
+ /**
+ * free up the memory for the session object.
+ * Make sure if any reference to the session object anywhere, otherwise it will be a
+ * dangle pointer after this call.
+ *
+ * @param value - session object to free
+ *
+ */
+ void deleteValue(TValue value) {
+ delete value;
+ }
+
+ /**
+ * free up the memory for the entire map.
+ * free up any resources in the sessions before calling this funtion.
+ *
+ */
+ void destroyMap() {
+ int size = map.size();
+
+ for (int i = 0; i < size; i++) {
+ deleteValue(map.valueAt(i));
+ }
+ map.clear();
+ }
+
+ /**
+ * decides if session is already created.
+ *
+ * @param key - key of the value for the session
+ *
+ * @return boolean result of whether session is created
+ */
+ bool isCreatedInternal(int key) {
+ return(0 <= map.indexOfKey(key));
+ }
+
+ /**
+ * returns the session object by the key
+ *
+ * @param key - key or Session ID
+ *
+ * @return session object as per the key
+ */
+ TValue getValueInternal(int key) {
+ TValue value = NULL;
+ if (isCreatedInternal(key)) {
+ value = (TValue) map.valueFor(key);
+ }
+ return value;
+ }
};
};
diff --git a/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp b/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp
index 4ee903e..57ef799 100644
--- a/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp
+++ b/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp
@@ -22,6 +22,13 @@
#undef LOG_TAG
#define LOG_TAG "MimeTypeUtil"
+#ifdef DRM_OMA_FL_ENGINE_DEBUG
+#define LOG_NDEBUG 0
+#define LOG_DEBUG(...) LOGD(__VA_ARGS__)
+#else
+#define LOG_DEBUG(...)
+#endif
+
enum {
MIMETYPE_AUDIO = 0,
MIMETYPE_APPLICATION = 1,
@@ -59,6 +66,7 @@
static const char mime_group_application[] = "application/";
static const char mime_group_image[] = "image/";
static const char mime_group_video[] = "video/";
+static const char mime_type_unsupported[] = "unsupported/drm.mimetype";
static struct MimeGroup mimeGroup[] = {
{MIMETYPE_AUDIO, mime_group_audio, sizeof(mime_group_audio)-1},
@@ -107,48 +115,52 @@
* replacement mimetype otherwise the original mimetype
* is returned.
*
+ * If the mimetype is of unsupported group i.e. application/*
+ * then "unsupported/drm.mimetype" will be returned.
+ *
* @param mimeType - mimetype in lower case to convert.
*
- * @return mimetype or null.
+ * @return mimetype or "unsupported/drm.mimetype".
*/
String8 MimeTypeUtil::convertMimeType(String8& mimeType) {
String8 result = mimeType;
- const char* pTmp;
const char* pMimeType;
struct MimeGroup* pGroup;
struct MimeTypeList* pMimeItem;
int len;
-
pMimeType = mimeType.string();
if (NULL != pMimeType) {
- /* Check which group the mimetype is */
- pGroup = mimeGroup;
-
- while (MIMETYPE_LAST != pGroup->type) {
- if (0 == strncmp(pMimeType, pGroup->pGroup, pGroup->size)) {
- break;
- }
- pGroup++;
- }
-
- /* Go through the mimetype list. Only check items of the correct group */
- if (MIMETYPE_LAST != pGroup->type) {
- pMimeItem = mimeTypeList;
- len = strlen (pMimeType+pGroup->size);
-
- while (MIMETYPE_LAST != pMimeItem->type) {
- if ((len == pMimeItem->size) &&
- (0 == strcmp(pMimeType+pGroup->size, pMimeItem->pMimeExt))) {
- result = String8(pMimeItem->pMimeType);
+ if ((0 == strncmp(pMimeType, mime_group_audio, (sizeof mime_group_audio) - 1)) ||
+ (0 == strncmp(pMimeType, mime_group_video, (sizeof mime_group_video) - 1))) {
+ /* Check which group the mimetype is */
+ pGroup = mimeGroup;
+ while (MIMETYPE_LAST != pGroup->type) {
+ if (0 == strncmp(pMimeType, pGroup->pGroup, pGroup->size)) {
break;
}
- pMimeItem++;
+ pGroup++;
}
- }
- LOGI("convertMimeType got mimetype %s, converted into mimetype %s",
- pMimeType, result.string());
- }
+ /* Go through the mimetype list. Only check items of the correct group */
+ if (MIMETYPE_LAST != pGroup->type) {
+ pMimeItem = mimeTypeList;
+ len = strlen (pMimeType+pGroup->size);
+ while (MIMETYPE_LAST != pMimeItem->type) {
+ if ((pGroup->type == pMimeItem->type) &&
+ (len == pMimeItem->size) &&
+ (0 == strcmp(pMimeType+pGroup->size, pMimeItem->pMimeExt))) {
+ result = String8(pMimeItem->pMimeType);
+ break;
+ }
+ pMimeItem++;
+ }
+ }
+ } else {
+ result = String8(mime_type_unsupported);
+ }
+ LOG_DEBUG("convertMimeType got mimetype %s, converted into mimetype %s",
+ pMimeType, result.string());
+ }
return result;
}
};
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk
index 9805a40..e359dbd 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk
@@ -17,6 +17,9 @@
include $(CLEAR_VARS)
+# The flag below turns on local debug printouts
+#LOCAL_CFLAGS += -DDRM_OMA_FL_ENGINE_DEBUG
+
base := frameworks/base
# Determine whether the DRM framework uses 64-bit data types for file offsets and do the same.
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
index 31c3c14..e184545 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
@@ -41,6 +41,13 @@
#undef LOG_TAG
#define LOG_TAG "FwdLockEngine"
+#ifdef DRM_OMA_FL_ENGINE_DEBUG
+#define LOG_NDEBUG 0
+#define LOG_VERBOSE(...) LOGV(__VA_ARGS__)
+#else
+#define LOG_VERBOSE(...)
+#endif
+
using namespace android;
// This extern "C" is mandatory to be managed by TPlugInManager
extern "C" IDrmEngine* create() {
@@ -53,14 +60,25 @@
}
FwdLockEngine::FwdLockEngine() {
- LOGV("FwdLockEngine Construction");
+ LOG_VERBOSE("FwdLockEngine Construction");
}
FwdLockEngine::~FwdLockEngine() {
- LOGV("FwdLockEngine Destruction");
+ LOG_VERBOSE("FwdLockEngine Destruction");
- convertSessionMap.destroyMap();
- decodeSessionMap.destroyMap();
+ int size = decodeSessionMap.getSize();
+
+ for (int i = 0; i < size; i++) {
+ DecodeSession *session = (DecodeSession*) decodeSessionMap.getValueAt(i);
+ FwdLockFile_detach(session->fileDesc);
+ ::close(session->fileDesc);
+ }
+
+ size = convertSessionMap.getSize();
+ for (int i = 0; i < size; i++) {
+ ConvertSession *convSession = (ConvertSession*) convertSessionMap.getValueAt(i);
+ FwdLockConv_CloseSession(convSession->uniqueId, &(convSession->output));
+ }
}
int FwdLockEngine::getConvertedStatus(FwdLockConv_Status_t status) {
@@ -74,12 +92,12 @@
case FwdLockConv_Status_InvalidArgument:
case FwdLockConv_Status_UnsupportedFileFormat:
case FwdLockConv_Status_UnsupportedContentTransferEncoding:
- LOGD("FwdLockEngine getConvertedStatus: file conversion Error %d. " \
+ LOGE("FwdLockEngine getConvertedStatus: file conversion Error %d. "
"Returning STATUS_INPUTDATA_ERROR", status);
retStatus = DrmConvertedStatus::STATUS_INPUTDATA_ERROR;
break;
default:
- LOGD("FwdLockEngine getConvertedStatus: file conversion Error %d. " \
+ LOGE("FwdLockEngine getConvertedStatus: file conversion Error %d. "
"Returning STATUS_ERROR", status);
retStatus = DrmConvertedStatus::STATUS_ERROR;
break;
@@ -91,7 +109,7 @@
DrmConstraints* FwdLockEngine::onGetConstraints(int uniqueId, const String8* path, int action) {
DrmConstraints* drmConstraints = NULL;
- LOGV("FwdLockEngine::onGetConstraints");
+ LOG_VERBOSE("FwdLockEngine::onGetConstraints");
if (NULL != path &&
(RightsStatus::RIGHTS_VALID == onCheckRightsStatus(uniqueId, *path, action))) {
@@ -105,7 +123,7 @@
DrmMetadata* FwdLockEngine::onGetMetadata(int uniqueId, const String8* path) {
DrmMetadata* drmMetadata = NULL;
- LOGV("FwdLockEngine::onGetMetadata");
+ LOG_VERBOSE("FwdLockEngine::onGetMetadata");
if (NULL != path) {
// Returns empty metadata to show no error condition.
@@ -116,13 +134,12 @@
}
android::status_t FwdLockEngine::onInitialize(int uniqueId) {
- LOGV("FwdLockEngine::onInitialize");
-
+ LOG_VERBOSE("FwdLockEngine::onInitialize");
if (FwdLockGlue_InitializeKeyEncryption()) {
- LOGV("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption succeeded");
+ LOG_VERBOSE("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption succeeded");
} else {
- LOGD("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption failed:"
+ LOGE("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption failed:"
"errno = %d", errno);
}
@@ -132,13 +149,13 @@
android::status_t
FwdLockEngine::onSetOnInfoListener(int uniqueId, const IDrmEngine::OnInfoListener* infoListener) {
// Not used
- LOGV("FwdLockEngine::onSetOnInfoListener");
+ LOG_VERBOSE("FwdLockEngine::onSetOnInfoListener");
return DRM_NO_ERROR;
}
android::status_t FwdLockEngine::onTerminate(int uniqueId) {
- LOGV("FwdLockEngine::onTerminate");
+ LOG_VERBOSE("FwdLockEngine::onTerminate");
return DRM_NO_ERROR;
}
@@ -146,7 +163,7 @@
DrmSupportInfo* FwdLockEngine::onGetSupportInfo(int uniqueId) {
DrmSupportInfo* pSupportInfo = new DrmSupportInfo();
- LOGV("FwdLockEngine::onGetSupportInfo");
+ LOG_VERBOSE("FwdLockEngine::onGetSupportInfo");
// fill all Forward Lock mimetypes and extensions
if (NULL != pSupportInfo) {
@@ -182,7 +199,7 @@
drmInfoStatus = new DrmInfoStatus((int)DrmInfoStatus::STATUS_OK, 0, NULL, String8(""));
- LOGV("FwdLockEngine::onProcessDrmInfo");
+ LOG_VERBOSE("FwdLockEngine::onProcessDrmInfo");
return drmInfoStatus;
}
@@ -193,7 +210,7 @@
const String8& rightsPath,
const String8& contentPath) {
// No rights to save. Return
- LOGV("FwdLockEngine::onSaveRights");
+ LOG_VERBOSE("FwdLockEngine::onSaveRights");
return DRM_ERROR_UNKNOWN;
}
@@ -201,7 +218,7 @@
DrmInfo* drmInfo = NULL;
// Nothing to be done for Forward Lock file
- LOGV("FwdLockEngine::onAcquireDrmInfo");
+ LOG_VERBOSE("FwdLockEngine::onAcquireDrmInfo");
return drmInfo;
}
@@ -211,7 +228,7 @@
int action) {
int result = RightsStatus::RIGHTS_INVALID;
- LOGV("FwdLockEngine::onCheckRightsStatus");
+ LOG_VERBOSE("FwdLockEngine::onCheckRightsStatus");
// Only Transfer action is not allowed for forward Lock files.
if (onCanHandle(uniqueId, path)) {
@@ -241,7 +258,7 @@
int action,
bool reserve) {
// No rights consumption
- LOGV("FwdLockEngine::onConsumeRights");
+ LOG_VERBOSE("FwdLockEngine::onConsumeRights");
return DRM_NO_ERROR;
}
@@ -249,14 +266,14 @@
const String8& path,
int action,
const ActionDescription& description) {
- LOGV("FwdLockEngine::onValidateAction");
+ LOG_VERBOSE("FwdLockEngine::onValidateAction");
// For the forwardlock engine checkRights and ValidateAction are the same.
return (onCheckRightsStatus(uniqueId, path, action) == RightsStatus::RIGHTS_VALID);
}
String8 FwdLockEngine::onGetOriginalMimeType(int uniqueId, const String8& path) {
- LOGV("FwdLockEngine::onGetOriginalMimeType");
+ LOG_VERBOSE("FwdLockEngine::onGetOriginalMimeType");
String8 mimeString = String8("");
int fileDesc = FwdLockFile_open(path.string());
@@ -280,7 +297,7 @@
const String8& mimeType) {
String8 mimeStr = String8(mimeType);
- LOGV("FwdLockEngine::onGetDrmObjectType");
+ LOG_VERBOSE("FwdLockEngine::onGetDrmObjectType");
mimeStr.toLower();
@@ -301,13 +318,13 @@
status_t FwdLockEngine::onRemoveRights(int uniqueId, const String8& path) {
// No Rights to remove
- LOGV("FwdLockEngine::onRemoveRights");
+ LOG_VERBOSE("FwdLockEngine::onRemoveRights");
return DRM_NO_ERROR;
}
status_t FwdLockEngine::onRemoveAllRights(int uniqueId) {
// No rights to remove
- LOGV("FwdLockEngine::onRemoveAllRights");
+ LOG_VERBOSE("FwdLockEngine::onRemoveAllRights");
return DRM_NO_ERROR;
}
@@ -319,14 +336,14 @@
int playbackStatus, int position) {
#endif
// Not used
- LOGV("FwdLockEngine::onSetPlaybackStatus");
+ LOG_VERBOSE("FwdLockEngine::onSetPlaybackStatus");
return DRM_NO_ERROR;
}
status_t FwdLockEngine::onOpenConvertSession(int uniqueId,
int convertId) {
status_t result = DRM_ERROR_UNKNOWN;
- LOGV("FwdLockEngine::onOpenConvertSession");
+ LOG_VERBOSE("FwdLockEngine::onOpenConvertSession");
if (!convertSessionMap.isCreated(convertId)) {
ConvertSession *newSession = new ConvertSession();
if (FwdLockConv_Status_OK ==
@@ -334,7 +351,7 @@
convertSessionMap.addValue(convertId, newSession);
result = DRM_NO_ERROR;
} else {
- LOGD("FwdLockEngine::onOpenConvertSession -- FwdLockConv_OpenSession failed.");
+ LOGE("FwdLockEngine::onOpenConvertSession -- FwdLockConv_OpenSession failed.");
delete newSession;
}
}
@@ -383,7 +400,7 @@
DrmBuffer *convResult = new DrmBuffer(NULL, 0);
int offset = -1;
- LOGV("FwdLockEngine::onCloseConvertSession");
+ LOG_VERBOSE("FwdLockEngine::onCloseConvertSession");
if (convertSessionMap.isCreated(convertId)) {
ConvertSession *convSession = convertSessionMap.getValue(convertId);
@@ -424,14 +441,14 @@
status_t result = DRM_ERROR_CANNOT_HANDLE;
int fileDesc = -1;
- LOGV("FwdLockEngine::onOpenDecryptSession");
+ LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession");
if ((-1 < fd) &&
(NULL != decryptHandle) &&
(!decodeSessionMap.isCreated(decryptHandle->decryptId))) {
fileDesc = dup(fd);
} else {
- LOGD("FwdLockEngine::onOpenDecryptSession parameter error");
+ LOGE("FwdLockEngine::onOpenDecryptSession parameter error");
return result;
}
@@ -453,7 +470,7 @@
decryptHandle->decryptInfo = NULL;
result = DRM_NO_ERROR;
} else {
- LOGD("FwdLockEngine::onOpenDecryptSession Integrity Check failed for the fd");
+ LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession Integrity Check failed for the fd");
FwdLockFile_detach(fileDesc);
delete decodeSession;
}
@@ -463,7 +480,7 @@
::close(fileDesc);
}
- LOGV("FwdLockEngine::onOpenDecryptSession Exit. result = %d", result);
+ LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession Exit. result = %d", result);
return result;
}
@@ -500,7 +517,7 @@
status_t FwdLockEngine::onCloseDecryptSession(int uniqueId,
DecryptHandle* decryptHandle) {
status_t result = DRM_ERROR_UNKNOWN;
- LOGV("FwdLockEngine::onCloseDecryptSession");
+ LOG_VERBOSE("FwdLockEngine::onCloseDecryptSession");
if (NULL != decryptHandle && decodeSessionMap.isCreated(decryptHandle->decryptId)) {
DecodeSession* session = decodeSessionMap.getValue(decryptHandle->decryptId);
@@ -525,7 +542,7 @@
decryptHandle = NULL;
}
- LOGV("FwdLockEngine::onCloseDecryptSession Exit");
+ LOG_VERBOSE("FwdLockEngine::onCloseDecryptSession Exit");
return result;
}
@@ -533,13 +550,13 @@
DecryptHandle* decryptHandle,
int decryptUnitId,
const DrmBuffer* headerInfo) {
- LOGV("FwdLockEngine::onInitializeDecryptUnit");
+ LOGE("FwdLockEngine::onInitializeDecryptUnit is not supported for this DRM scheme");
return DRM_ERROR_UNKNOWN;
}
status_t FwdLockEngine::onDecrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
- LOGV("FwdLockEngine::onDecrypt");
+ LOGE("FwdLockEngine::onDecrypt is not supported for this DRM scheme");
return DRM_ERROR_UNKNOWN;
}
@@ -548,14 +565,14 @@
int decryptUnitId,
const DrmBuffer* encBuffer,
DrmBuffer** decBuffer) {
- LOGV("FwdLockEngine::onDecrypt");
+ LOGE("FwdLockEngine::onDecrypt is not supported for this DRM scheme");
return DRM_ERROR_UNKNOWN;
}
status_t FwdLockEngine::onFinalizeDecryptUnit(int uniqueId,
DecryptHandle* decryptHandle,
int decryptUnitId) {
- LOGV("FwdLockEngine::onFinalizeDecryptUnit");
+ LOGE("FwdLockEngine::onFinalizeDecryptUnit is not supported for this DRM scheme");
return DRM_ERROR_UNKNOWN;
}
@@ -633,11 +650,11 @@
if (((off_t)-1) != decoderSession->offset) {
bytesRead = onRead(uniqueId, decryptHandle, buffer, numBytes);
if (bytesRead < 0) {
- LOGD("FwdLockEngine::onPread error reading");
+ LOGE("FwdLockEngine::onPread error reading");
}
}
} else {
- LOGD("FwdLockEngine::onPread decryptId not found");
+ LOGE("FwdLockEngine::onPread decryptId not found");
}
return bytesRead;
diff --git a/drm/libdrmframework/plugins/forward-lock/internal-format/converter/FwdLockConv.c b/drm/libdrmframework/plugins/forward-lock/internal-format/converter/FwdLockConv.c
index 14ea9e9..299116d 100644
--- a/drm/libdrmframework/plugins/forward-lock/internal-format/converter/FwdLockConv.c
+++ b/drm/libdrmframework/plugins/forward-lock/internal-format/converter/FwdLockConv.c
@@ -275,17 +275,18 @@
}
/**
- * Checks whether a given character is valid in a boundary. Note that the boundary may contain
- * leading and internal spaces.
+ * Checks whether a given character is valid in a boundary. Allows some non-standard characters that
+ * are invalid according to RFC 2046 but nevertheless used by one vendor's DRM packager. Note that
+ * the boundary may contain leading and internal spaces.
*
* @param[in] ch The character to check.
*
* @return A Boolean value indicating whether the given character is valid in a boundary.
*/
static int FwdLockConv_IsBoundaryChar(int ch) {
- return isalnum(ch) || ch == '\'' ||
- ch == '(' || ch == ')' || ch == '+' || ch == '_' || ch == ',' || ch == '-' ||
- ch == '.' || ch == '/' || ch == ':' || ch == '=' || ch == '?' || ch == ' ';
+ return isalnum(ch) || ch == '\'' || ch == '(' || ch == ')' || ch == '+' || ch == '_' ||
+ ch == ',' || ch == '-' || ch == '.' || ch == '/' || ch == ':' || ch == '=' ||
+ ch == '?' || ch == ' ' || ch == '%' || ch == '[' || ch == '&' || ch == '*' || ch == '^';
}
/**
@@ -1085,6 +1086,13 @@
status = FwdLockConv_MatchBinaryEncodedData(pSession, ch, pOutput);
break;
case FwdLockConv_ParserState_WantsBase64EncodedData:
+ if (ch == '\n' && pSession->scannerState != FwdLockConv_ScannerState_WantsLF) {
+ // Repair base64-encoded data that doesn't have carriage returns in its line breaks.
+ status = FwdLockConv_MatchBase64EncodedData(pSession, '\r', pOutput);
+ if (status != FwdLockConv_Status_OK) {
+ break;
+ }
+ }
status = FwdLockConv_MatchBase64EncodedData(pSession, ch, pOutput);
break;
case FwdLockConv_ParserState_Done:
@@ -1199,7 +1207,7 @@
status = FwdLockConv_Status_SyntaxError;
} else {
// Finalize the data signature.
- size_t signatureSize;
+ unsigned int signatureSize = SHA1_HASH_SIZE;
HMAC_Final(&pSession->signingContext, pOutput->fromCloseSession.signatures,
&signatureSize);
if (signatureSize != SHA1_HASH_SIZE) {
@@ -1214,9 +1222,9 @@
HMAC_Update(&pSession->signingContext, pSession->pEncryptedSessionKey,
pSession->encryptedSessionKeyLength);
HMAC_Update(&pSession->signingContext, pOutput->fromCloseSession.signatures,
- signatureSize);
- HMAC_Final(&pSession->signingContext, &pOutput->fromCloseSession.
- signatures[signatureSize], &signatureSize);
+ SHA1_HASH_SIZE);
+ HMAC_Final(&pSession->signingContext,
+ &pOutput->fromCloseSession.signatures[SHA1_HASH_SIZE], &signatureSize);
if (signatureSize != SHA1_HASH_SIZE) {
status = FwdLockConv_Status_ProgramError;
} else {
diff --git a/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/FwdLockFile.c b/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/FwdLockFile.c
index 98284e72..dacf00e 100644
--- a/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/FwdLockFile.c
+++ b/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/FwdLockFile.c
@@ -114,7 +114,7 @@
}
/**
- * Finds the file session associated to the given file descriptor.
+ * Finds the file session associated with the given file descriptor.
*
* @param[in] fileDesc A file descriptor.
*
@@ -389,7 +389,7 @@
result = FALSE;
} else {
ssize_t numBytesRead;
- size_t signatureSize = SHA1_HASH_SIZE;
+ unsigned int signatureSize = SHA1_HASH_SIZE;
while ((numBytesRead =
read(pSession->fileDesc, pData->buffer, SIG_CALC_BUFFER_SIZE)) > 0) {
HMAC_Update(&pSession->signingContext, pData->buffer, (size_t)numBytesRead);
@@ -399,7 +399,7 @@
} else {
HMAC_Final(&pSession->signingContext, pData->signature, &signatureSize);
assert(signatureSize == SHA1_HASH_SIZE);
- result = memcmp(pData->signature, pSession->dataSignature, signatureSize) == 0;
+ result = memcmp(pData->signature, pSession->dataSignature, SHA1_HASH_SIZE) == 0;
}
HMAC_Init_ex(&pSession->signingContext, NULL, KEY_SIZE, NULL, NULL);
(void)lseek64(pSession->fileDesc, pSession->dataOffset + pSession->filePos,
@@ -419,16 +419,16 @@
} else {
FwdLockFile_Session_t *pSession = sessionPtrs[sessionId];
unsigned char signature[SHA1_HASH_SIZE];
- size_t signatureSize = SHA1_HASH_SIZE;
+ unsigned int signatureSize = SHA1_HASH_SIZE;
HMAC_Update(&pSession->signingContext, pSession->topHeader, TOP_HEADER_SIZE);
HMAC_Update(&pSession->signingContext, (unsigned char *)pSession->pContentType,
pSession->contentTypeLength);
HMAC_Update(&pSession->signingContext, pSession->pEncryptedSessionKey,
pSession->encryptedSessionKeyLength);
- HMAC_Update(&pSession->signingContext, pSession->dataSignature, signatureSize);
+ HMAC_Update(&pSession->signingContext, pSession->dataSignature, SHA1_HASH_SIZE);
HMAC_Final(&pSession->signingContext, signature, &signatureSize);
assert(signatureSize == SHA1_HASH_SIZE);
- result = memcmp(signature, pSession->headerSignature, signatureSize) == 0;
+ result = memcmp(signature, pSession->headerSignature, SHA1_HASH_SIZE) == 0;
HMAC_Init_ex(&pSession->signingContext, NULL, KEY_SIZE, NULL, NULL);
}
return result;
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 40d54bb..3fc6463 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -567,6 +567,7 @@
canvas.setBitmap(bitmap);
canvas.drawBitmap(source, srcR, dstR, paint);
+ canvas.setBitmap(null);
return bitmap;
}
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 35ed4d2..6ae8c9b 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -178,17 +178,22 @@
* @see #getDensity()
*/
public void setBitmap(Bitmap bitmap) {
- if (!bitmap.isMutable()) {
- throw new IllegalStateException();
- }
if (isHardwareAccelerated()) {
throw new RuntimeException("Can't set a bitmap device on a GL canvas");
}
- throwIfRecycled(bitmap);
- native_setBitmap(mNativeCanvas, bitmap.ni());
+ int pointer = 0;
+ if (bitmap != null) {
+ if (!bitmap.isMutable()) {
+ throw new IllegalStateException();
+ }
+ throwIfRecycled(bitmap);
+ mDensity = bitmap.mDensity;
+ pointer = bitmap.ni();
+ }
+
+ native_setBitmap(mNativeCanvas, pointer);
mBitmap = bitmap;
- mDensity = bitmap.mDensity;
}
/**
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index b8e9384..7269a71 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -84,9 +84,19 @@
public static final int JPEG = 0x100;
/**
+ * Raw bayer format used for images, which is 10 bit precision samples
+ * stored in 16 bit words. The filter pattern is RGGB. Whether this format
+ * is supported by the camera hardware can be determined by
+ * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
+ *
+ * @hide
+ */
+ public static final int BAYER_RGGB = 0x200;
+
+ /**
* Use this function to retrieve the number of bits per pixel of an
* ImageFormat.
- *
+ *
* @param format
* @return the number of bits per pixel of the given format or -1 if the
* format doesn't exist or is not supported.
@@ -103,6 +113,8 @@
return 12;
case NV21:
return 12;
+ case BAYER_RGGB:
+ return 16;
}
return -1;
}
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 962f22c..163bd4a 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -349,6 +349,18 @@
mCompatScaling = paint.mCompatScaling;
mInvCompatScaling = paint.mInvCompatScaling;
mBidiFlags = paint.mBidiFlags;
+ hasShadow = paint.hasShadow;
+ mColorFilter = paint.mColorFilter;
+ mMaskFilter = paint.mMaskFilter;
+ mPathEffect = paint.mPathEffect;
+ mRasterizer = paint.mRasterizer;
+ mShader = paint.mShader;
+ mTypeface = paint.mTypeface;
+ mXfermode = paint.mXfermode;
+ shadowColor = paint.shadowColor;
+ shadowDx = paint.shadowDx;
+ shadowDy = paint.shadowDy;
+ shadowRadius = paint.shadowRadius;
}
/** Restores the paint to its default settings. */
@@ -1932,7 +1944,11 @@
@Override
protected void finalize() throws Throwable {
- finalizer(mNativePaint);
+ try {
+ finalizer(mNativePaint);
+ } finally {
+ super.finalize();
+ }
}
private static native int native_init();
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 1647ff3..d62fd67 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -187,6 +187,25 @@
return nativeGetTimestamp();
}
+ /**
+ * release() frees all the buffers and puts the SurfaceTexture into the
+ * 'abandoned' state. Once put in this state the SurfaceTexture can never
+ * leave it. When in the 'abandoned' state, all methods of the
+ * ISurfaceTexture interface will fail with the NO_INIT error.
+ *
+ * Note that while calling this method causes all the buffers to be freed
+ * from the perspective of the the SurfaceTexture, if there are additional
+ * references on the buffers (e.g. if a buffer is referenced by a client or
+ * by OpenGL ES as a texture) then those buffer will remain allocated.
+ *
+ * Always call this method when you are done with SurfaceTexture. Failing
+ * to do so may delay resource deallocation for a significant amount of
+ * time.
+ */
+ public void release() {
+ nativeRelease();
+ }
+
protected void finalize() throws Throwable {
try {
nativeFinalize();
@@ -232,6 +251,7 @@
private native void nativeSetDefaultBufferSize(int width, int height);
private native void nativeUpdateTexImage();
private native int nativeGetQueuedCount();
+ private native void nativeRelease();
/*
* We use a class initializer to allow the native code to cache some
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 7e03e1c..87421b1 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -20,18 +20,16 @@
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Shader;
-import android.graphics.BitmapShader;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
-import android.view.View;
-
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index f701280..234e165 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -59,7 +59,8 @@
{
public:
virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
- virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr) = 0;
+ virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr,
+ camera_frame_metadata_t *metadata) = 0;
virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) = 0;
};
@@ -138,7 +139,8 @@
// ICameraClient interface
virtual void notifyCallback(int32_t msgType, int32_t ext, int32_t ext2);
- virtual void dataCallback(int32_t msgType, const sp<IMemory>& dataPtr);
+ virtual void dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
+ camera_frame_metadata_t *metadata);
virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
sp<ICamera> remote();
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index d2f398a..b661496 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -484,6 +484,17 @@
// Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read only.
static const char KEY_VIDEO_FRAME_FORMAT[];
+ // Sets the hint of the recording mode. If this is true, MediaRecorder.start
+ // may be faster or has less glitches. This should be called before starting
+ // the preview for the best result. But it is allowed to change the hint
+ // while the preview is active. The default value is false.
+ //
+ // The apps can still call Camera.takePicture when the hint is true. The
+ // apps can call MediaRecorder.start when the hint is false. But the
+ // performance may be worse.
+ // Example value: "true" or "false". Read/write.
+ static const char KEY_RECORDING_HINT[];
+
// Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED.
static const char TRUE[];
static const char FALSE[];
@@ -562,6 +573,9 @@
static const char PIXEL_FORMAT_RGB565[];
static const char PIXEL_FORMAT_RGBA8888[];
static const char PIXEL_FORMAT_JPEG[];
+ // Raw bayer format used for images, which is 10 bit precision samples
+ // stored in 16 bit words. The filter pattern is RGGB.
+ static const char PIXEL_FORMAT_BAYER_RGGB[];
// Values for focus mode settings.
// Auto-focus mode. Applications should call
diff --git a/include/camera/ICameraClient.h b/include/camera/ICameraClient.h
index 236d0f6..b30aa7a 100644
--- a/include/camera/ICameraClient.h
+++ b/include/camera/ICameraClient.h
@@ -22,6 +22,7 @@
#include <binder/Parcel.h>
#include <binder/IMemory.h>
#include <utils/Timers.h>
+#include <system/camera.h>
namespace android {
@@ -31,7 +32,8 @@
DECLARE_META_INTERFACE(CameraClient);
virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
- virtual void dataCallback(int32_t msgType, const sp<IMemory>& data) = 0;
+ virtual void dataCallback(int32_t msgType, const sp<IMemory>& data,
+ camera_frame_metadata_t *metadata) = 0;
virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& data) = 0;
};
diff --git a/include/media/stagefright/MediaBuffer.h b/include/media/stagefright/MediaBuffer.h
index c1c4f94..3d79596 100644
--- a/include/media/stagefright/MediaBuffer.h
+++ b/include/media/stagefright/MediaBuffer.h
@@ -25,6 +25,7 @@
namespace android {
+struct ABuffer;
class GraphicBuffer;
class MediaBuffer;
class MediaBufferObserver;
@@ -51,6 +52,8 @@
MediaBuffer(const sp<GraphicBuffer>& graphicBuffer);
+ MediaBuffer(const sp<ABuffer> &buffer);
+
// Decrements the reference count and returns the buffer to its
// associated MediaBufferGroup if the reference count drops to 0.
void release();
@@ -100,6 +103,7 @@
void *mData;
size_t mSize, mRangeOffset, mRangeLength;
sp<GraphicBuffer> mGraphicBuffer;
+ sp<ABuffer> mBuffer;
bool mOwnsData;
diff --git a/include/ui/Input.h b/include/ui/Input.h
index c9f694a..f1385a0 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -206,10 +206,17 @@
float getAxisValue(int32_t axis) const;
status_t setAxisValue(int32_t axis, float value);
- float* editAxisValue(int32_t axis);
void scale(float scale);
+ inline float getX() const {
+ return getAxisValue(AMOTION_EVENT_AXIS_X);
+ }
+
+ inline float getY() const {
+ return getAxisValue(AMOTION_EVENT_AXIS_Y);
+ }
+
#ifdef HAVE_ANDROID_OS
status_t readFromParcel(Parcel* parcel);
status_t writeToParcel(Parcel* parcel) const;
diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h
index 600017e..9452e86 100644
--- a/include/utils/BitSet.h
+++ b/include/utils/BitSet.h
@@ -68,6 +68,30 @@
// Result is undefined if all bits are unmarked.
inline uint32_t lastMarkedBit() const { return 31 - __builtin_ctz(value); }
+ // Finds the first marked bit in the set and clears it. Returns the bit index.
+ // Result is undefined if all bits are unmarked.
+ inline uint32_t clearFirstMarkedBit() {
+ uint32_t n = firstMarkedBit();
+ clearBit(n);
+ return n;
+ }
+
+ // Finds the first unmarked bit in the set and marks it. Returns the bit index.
+ // Result is undefined if all bits are marked.
+ inline uint32_t markFirstUnmarkedBit() {
+ uint32_t n = firstUnmarkedBit();
+ markBit(n);
+ return n;
+ }
+
+ // Finds the last marked bit in the set and clears it. Returns the bit index.
+ // Result is undefined if all bits are unmarked.
+ inline uint32_t clearLastMarkedBit() {
+ uint32_t n = lastMarkedBit();
+ clearBit(n);
+ return n;
+ }
+
// Gets the index of the specified bit in the set, which is the number of
// marked bits that appear before the specified bit.
inline uint32_t getIndexOfBit(uint32_t n) const {
diff --git a/libs/camera/Camera.cpp b/libs/camera/Camera.cpp
index 3c00db5..7ac3cc1 100644
--- a/libs/camera/Camera.cpp
+++ b/libs/camera/Camera.cpp
@@ -360,7 +360,8 @@
}
// callback from camera service when frame or image is ready
-void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
+void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
+ camera_frame_metadata_t *metadata)
{
sp<CameraListener> listener;
{
@@ -368,7 +369,7 @@
listener = mListener;
}
if (listener != NULL) {
- listener->postData(msgType, dataPtr);
+ listener->postData(msgType, dataPtr, metadata);
}
}
diff --git a/libs/camera/CameraParameters.cpp b/libs/camera/CameraParameters.cpp
index d8fef09..51b96c1 100644
--- a/libs/camera/CameraParameters.cpp
+++ b/libs/camera/CameraParameters.cpp
@@ -86,6 +86,7 @@
const char CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] = "preferred-preview-size-for-video";
const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW[] = "max-num-detected-faces-hw";
const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW[] = "max-num-detected-faces-sw";
+const char CameraParameters::KEY_RECORDING_HINT[] = "recording-hint";
const char CameraParameters::TRUE[] = "true";
const char CameraParameters::FALSE[] = "false";
@@ -150,6 +151,7 @@
const char CameraParameters::PIXEL_FORMAT_RGB565[] = "rgb565";
const char CameraParameters::PIXEL_FORMAT_RGBA8888[] = "rgba8888";
const char CameraParameters::PIXEL_FORMAT_JPEG[] = "jpeg";
+const char CameraParameters::PIXEL_FORMAT_BAYER_RGGB[] = "bayer-rggb";
// Values for focus mode settings.
const char CameraParameters::FOCUS_MODE_AUTO[] = "auto";
diff --git a/libs/camera/ICameraClient.cpp b/libs/camera/ICameraClient.cpp
index cb3bd0c..183429a 100644
--- a/libs/camera/ICameraClient.cpp
+++ b/libs/camera/ICameraClient.cpp
@@ -51,13 +51,18 @@
}
// generic data callback from camera service to app with image data
- void dataCallback(int32_t msgType, const sp<IMemory>& imageData)
+ void dataCallback(int32_t msgType, const sp<IMemory>& imageData,
+ camera_frame_metadata_t *metadata)
{
LOGV("dataCallback");
Parcel data, reply;
data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
data.writeInt32(msgType);
data.writeStrongBinder(imageData->asBinder());
+ if (metadata) {
+ data.writeInt32(metadata->number_of_faces);
+ data.write(metadata->faces, sizeof(camera_face_t) * metadata->number_of_faces);
+ }
remote()->transact(DATA_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
}
@@ -96,7 +101,15 @@
CHECK_INTERFACE(ICameraClient, data, reply);
int32_t msgType = data.readInt32();
sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
- dataCallback(msgType, imageData);
+ camera_frame_metadata_t *metadata = NULL;
+ if (data.dataAvail() > 0) {
+ metadata = new camera_frame_metadata_t;
+ metadata->number_of_faces = data.readInt32();
+ metadata->faces = (camera_face_t *) data.readInplace(
+ sizeof(camera_face_t) * metadata->number_of_faces);
+ }
+ dataCallback(msgType, imageData, metadata);
+ if (metadata) delete metadata;
return NO_ERROR;
} break;
case DATA_CALLBACK_TIMESTAMP: {
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 4f51f03..1a036ee 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -910,6 +910,7 @@
Mutex::Autolock lock(mMutex);
freeAllBuffers();
mAbandoned = true;
+ mCurrentTextureBuf.clear();
mDequeueCondition.signal();
}
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index e6837ea..d1037de 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -258,10 +258,10 @@
int res = NO_ERROR;
switch (operation) {
case NATIVE_WINDOW_CONNECT:
- res = dispatchConnect(args);
+ // deprecated. must return NO_ERROR.
break;
case NATIVE_WINDOW_DISCONNECT:
- res = dispatchDisconnect(args);
+ // deprecated. must return NO_ERROR.
break;
case NATIVE_WINDOW_SET_USAGE:
res = dispatchSetUsage(args);
@@ -296,6 +296,12 @@
case NATIVE_WINDOW_SET_SCALING_MODE:
res = dispatchSetScalingMode(args);
break;
+ case NATIVE_WINDOW_API_CONNECT:
+ res = dispatchConnect(args);
+ break;
+ case NATIVE_WINDOW_API_DISCONNECT:
+ res = dispatchDisconnect(args);
+ break;
default:
res = NAME_NOT_FOUND;
break;
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index c5858e9..24ec4e8 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -142,7 +142,6 @@
void Caches::clearGarbage() {
textureCache.clearGarbage();
- gradientCache.clearGarbage();
pathCache.clearGarbage();
Mutex::Autolock _l(mGarbageLock);
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index 5db73db..7cbb39d 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -20,6 +20,9 @@
// Turn on to check for OpenGL errors on each frame
#define DEBUG_OPENGL 1
+// Turn on to display informations about the GPU
+#define DEBUG_EXTENSIONS 0
+
// Turn on to enable initialization information
#define DEBUG_INIT 0
diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h
index eceb5c1c..38d1130 100644
--- a/libs/hwui/Extensions.h
+++ b/libs/hwui/Extensions.h
@@ -23,6 +23,8 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
+#include "Debug.h"
+
namespace android {
namespace uirenderer {
@@ -31,15 +33,20 @@
///////////////////////////////////////////////////////////////////////////////
// Debug
-#define DEBUG_EXTENSIONS 0
-
-// Debug
#if DEBUG_EXTENSIONS
#define EXT_LOGD(...) LOGD(__VA_ARGS__)
#else
#define EXT_LOGD(...)
#endif
+// Vendor strings
+
+#define VENDOR_IMG "Imagination Technologies"
+
+///////////////////////////////////////////////////////////////////////////////
+// Classes
+///////////////////////////////////////////////////////////////////////////////
+
class Extensions {
public:
Extensions() {
@@ -58,17 +65,21 @@
} while (head);
mHasNPot = hasExtension("GL_OES_texture_npot");
- mHasDrawPath = hasExtension("GL_NV_draw_path");
- mHasCoverageSample = hasExtension("GL_NV_coverage_sample");
mHasFramebufferFetch = hasExtension("GL_NV_shader_framebuffer_fetch");
+ const char* vendor = (const char*) glGetString(GL_VENDOR);
+ EXT_LOGD("Vendor: %s", vendor);
+ mNeedsHighpTexCoords = strcmp(vendor, VENDOR_IMG) == 0;
+
+ // We don't need to copy the string, the OpenGL ES spec
+ // guarantees the result of glGetString to point to a
+ // static string as long as our OpenGL context is valid
mExtensions = buffer;
}
inline bool hasNPot() const { return mHasNPot; }
- inline bool hasDrawPath() const { return mHasDrawPath; }
- inline bool hasCoverageSample() const { return mHasCoverageSample; }
inline bool hasFramebufferFetch() const { return mHasFramebufferFetch; }
+ inline bool needsHighpTexCoords() const { return mNeedsHighpTexCoords; }
bool hasExtension(const char* extension) const {
const String8 s(extension);
@@ -85,8 +96,7 @@
const char* mExtensions;
bool mHasNPot;
- bool mHasDrawPath;
- bool mHasCoverageSample;
+ bool mNeedsHighpTexCoords;
bool mHasFramebufferFetch;
}; // class Extensions
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 9bf3de8..9acf99b 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -44,9 +44,11 @@
///////////////////////////////////////////////////////////////////////////////
Font::Font(FontRenderer* state, uint32_t fontId, float fontSize,
- int flags, uint32_t italicStyle, uint32_t scaleX) :
+ int flags, uint32_t italicStyle, uint32_t scaleX,
+ SkPaint::Style style, uint32_t strokeWidth) :
mState(state), mFontId(fontId), mFontSize(fontSize),
- mFlags(flags), mItalicStyle(italicStyle), mScaleX(scaleX) {
+ mFlags(flags), mItalicStyle(italicStyle), mScaleX(scaleX),
+ mStyle(style), mStrokeWidth(mStrokeWidth) {
}
@@ -283,19 +285,22 @@
}
Font* Font::create(FontRenderer* state, uint32_t fontId, float fontSize,
- int flags, uint32_t italicStyle, uint32_t scaleX) {
+ int flags, uint32_t italicStyle, uint32_t scaleX,
+ SkPaint::Style style, uint32_t strokeWidth) {
Vector<Font*> &activeFonts = state->mActiveFonts;
for (uint32_t i = 0; i < activeFonts.size(); i++) {
Font* font = activeFonts[i];
if (font->mFontId == fontId && font->mFontSize == fontSize &&
font->mFlags == flags && font->mItalicStyle == italicStyle &&
- font->mScaleX == scaleX) {
+ font->mScaleX == scaleX && font->mStyle == style &&
+ (style == SkPaint::kFill_Style || font->mStrokeWidth == strokeWidth)) {
return font;
}
}
- Font* newFont = new Font(state, fontId, fontSize, flags, italicStyle, scaleX);
+ Font* newFont = new Font(state, fontId, fontSize, flags, italicStyle,
+ scaleX, style, strokeWidth);
activeFonts.push(newFont);
return newFont;
}
@@ -690,7 +695,11 @@
uint32_t italicStyle = *(uint32_t*) &skewX;
const float scaleXFloat = paint->getTextScaleX();
uint32_t scaleX = *(uint32_t*) &scaleXFloat;
- mCurrentFont = Font::create(this, fontId, fontSize, flags, italicStyle, scaleX);
+ SkPaint::Style style = paint->getStyle();
+ const float strokeWidthFloat = paint->getStrokeWidth();
+ uint32_t strokeWidth = *(uint32_t*) &strokeWidthFloat;
+ mCurrentFont = Font::create(this, fontId, fontSize, flags, italicStyle,
+ scaleX, style, strokeWidth);
const float maxPrecacheFontSize = 40.0f;
bool isNewFont = currentNumFonts != mActiveFonts.size();
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 24ed6fa..1922812 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -82,7 +82,8 @@
* Creates a new font associated with the specified font state.
*/
static Font* create(FontRenderer* state, uint32_t fontId, float fontSize,
- int flags, uint32_t italicStyle, uint32_t scaleX);
+ int flags, uint32_t italicStyle, uint32_t scaleX, SkPaint::Style style,
+ uint32_t strokeWidth);
protected:
friend class FontRenderer;
@@ -128,7 +129,7 @@
};
Font(FontRenderer* state, uint32_t fontId, float fontSize, int flags, uint32_t italicStyle,
- uint32_t scaleX);
+ uint32_t scaleX, SkPaint::Style style, uint32_t strokeWidth);
// Cache of glyphs
DefaultKeyedVector<glyph_t, CachedGlyphInfo*> mCachedGlyphs;
@@ -157,6 +158,8 @@
int mFlags;
uint32_t mItalicStyle;
uint32_t mScaleX;
+ SkPaint::Style mStyle;
+ uint32_t mStrokeWidth;
};
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 996acd5..aacf22a 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -35,7 +35,7 @@
///////////////////////////////////////////////////////////////////////////////
GradientCache::GradientCache():
- mCache(GenerationCache<SkShader*, Texture*>::kUnlimitedCapacity),
+ mCache(GenerationCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity),
mSize(0), mMaxSize(MB(DEFAULT_GRADIENT_CACHE_SIZE)) {
char property[PROPERTY_VALUE_MAX];
if (property_get(PROPERTY_GRADIENT_CACHE_SIZE, property, NULL) > 0) {
@@ -49,7 +49,7 @@
}
GradientCache::GradientCache(uint32_t maxByteSize):
- mCache(GenerationCache<SkShader*, Texture*>::kUnlimitedCapacity),
+ mCache(GenerationCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity),
mSize(0), mMaxSize(maxByteSize) {
mCache.setOnEntryRemovedListener(this);
}
@@ -81,9 +81,8 @@
// Callbacks
///////////////////////////////////////////////////////////////////////////////
-void GradientCache::operator()(SkShader*& shader, Texture*& texture) {
- // Already locked here
- if (shader) {
+void GradientCache::operator()(GradientCacheEntry& shader, Texture*& texture) {
+ if (texture) {
const uint32_t size = texture->width * texture->height * 4;
mSize -= size;
}
@@ -98,34 +97,25 @@
// Caching
///////////////////////////////////////////////////////////////////////////////
-Texture* GradientCache::get(SkShader* shader) {
- return mCache.get(shader);
-}
+Texture* GradientCache::get(uint32_t* colors, float* positions,
+ int count, SkShader::TileMode tileMode) {
-void GradientCache::remove(SkShader* shader) {
- mCache.remove(shader);
-}
+ GradientCacheEntry gradient(colors, positions, count, tileMode);
+ Texture* texture = mCache.get(gradient);
-void GradientCache::removeDeferred(SkShader* shader) {
- Mutex::Autolock _l(mLock);
- mGarbage.push(shader);
-}
-
-void GradientCache::clearGarbage() {
- Mutex::Autolock _l(mLock);
- size_t count = mGarbage.size();
- for (size_t i = 0; i < count; i++) {
- mCache.remove(mGarbage.itemAt(i));
+ if (!texture) {
+ texture = addLinearGradient(gradient, colors, positions, count, tileMode);
}
- mGarbage.clear();
+
+ return texture;
}
void GradientCache::clear() {
mCache.clear();
}
-Texture* GradientCache::addLinearGradient(SkShader* shader, uint32_t* colors,
- float* positions, int count, SkShader::TileMode tileMode) {
+Texture* GradientCache::addLinearGradient(GradientCacheEntry& gradient,
+ uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode) {
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1024, 1);
bitmap.allocPixels();
@@ -156,7 +146,7 @@
generateTexture(&bitmap, texture);
mSize += size;
- mCache.put(shader, texture);
+ mCache.put(gradient, texture);
return texture;
}
diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h
index 30da462..086921c 100644
--- a/libs/hwui/GradientCache.h
+++ b/libs/hwui/GradientCache.h
@@ -22,17 +22,74 @@
#include <utils/Vector.h>
#include "Texture.h"
+#include "utils/Compare.h"
#include "utils/GenerationCache.h"
namespace android {
namespace uirenderer {
+struct GradientCacheEntry {
+ GradientCacheEntry() {
+ count = 0;
+ colors = NULL;
+ positions = NULL;
+ tileMode = SkShader::kClamp_TileMode;
+ }
+
+ GradientCacheEntry(uint32_t* colors, float* positions, int count,
+ SkShader::TileMode tileMode) {
+ this->count = count;
+ this->colors = new uint32_t[count];
+ this->positions = new float[count];
+ this->tileMode = tileMode;
+
+ memcpy(this->colors, colors, count * sizeof(uint32_t));
+ memcpy(this->positions, positions, count * sizeof(float));
+ }
+
+ GradientCacheEntry(const GradientCacheEntry& entry) {
+ this->count = entry.count;
+ this->colors = new uint32_t[count];
+ this->positions = new float[count];
+ this->tileMode = entry.tileMode;
+
+ memcpy(this->colors, entry.colors, count * sizeof(uint32_t));
+ memcpy(this->positions, entry.positions, count * sizeof(float));
+ }
+
+ ~GradientCacheEntry() {
+ delete[] colors;
+ delete[] positions;
+ }
+
+ bool operator<(const GradientCacheEntry& r) const {
+ const GradientCacheEntry& rhs = (const GradientCacheEntry&) r;
+ LTE_INT(count) {
+ LTE_INT(tileMode) {
+ int result = memcmp(colors, rhs.colors, count * sizeof(uint32_t));
+ if (result< 0) return true;
+ else if (result == 0) {
+ result = memcmp(positions, rhs.positions, count * sizeof(float));
+ if (result < 0) return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ uint32_t* colors;
+ float* positions;
+ int count;
+ SkShader::TileMode tileMode;
+
+}; // GradientCacheEntry
+
/**
* A simple LRU gradient cache. The cache has a maximum size expressed in bytes.
* Any texture added to the cache causing the cache to grow beyond the maximum
* allowed size will also cause the oldest texture to be kicked out.
*/
-class GradientCache: public OnEntryRemoved<SkShader*, Texture*> {
+class GradientCache: public OnEntryRemoved<GradientCacheEntry, Texture*> {
public:
GradientCache();
GradientCache(uint32_t maxByteSize);
@@ -42,32 +99,13 @@
* Used as a callback when an entry is removed from the cache.
* Do not invoke directly.
*/
- void operator()(SkShader*& shader, Texture*& texture);
+ void operator()(GradientCacheEntry& shader, Texture*& texture);
/**
- * Adds a new linear gradient to the cache. The generated texture is
- * returned.
- */
- Texture* addLinearGradient(SkShader* shader, uint32_t* colors, float* positions,
- int count, SkShader::TileMode tileMode = SkShader::kClamp_TileMode);
- /**
* Returns the texture associated with the specified shader.
*/
- Texture* get(SkShader* shader);
- /**
- * Removes the texture associated with the specified shader.
- * Upon remove the texture is freed.
- */
- void remove(SkShader* shader);
- /**
- * Removes the texture associated with the specified shader. This is meant
- * to be called from threads that are not the EGL context thread.
- */
- void removeDeferred(SkShader* shader);
- /**
- * Process deferred removals.
- */
- void clearGarbage();
+ Texture* get(uint32_t* colors, float* positions,
+ int count, SkShader::TileMode tileMode = SkShader::kClamp_TileMode);
/**
* Clears the cache. This causes all textures to be deleted.
*/
@@ -87,9 +125,17 @@
uint32_t getSize();
private:
+ /**
+ * Adds a new linear gradient to the cache. The generated texture is
+ * returned.
+ */
+ Texture* addLinearGradient(GradientCacheEntry& gradient,
+ uint32_t* colors, float* positions, int count,
+ SkShader::TileMode tileMode = SkShader::kClamp_TileMode);
+
void generateTexture(SkBitmap* bitmap, Texture* texture);
- GenerationCache<SkShader*, Texture*> mCache;
+ GenerationCache<GradientCacheEntry, Texture*> mCache;
uint32_t mSize;
uint32_t mMaxSize;
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index d419e3e..c2383f4 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -18,6 +18,7 @@
#include <utils/String8.h>
+#include "Caches.h"
#include "ProgramCache.h"
namespace android {
@@ -64,10 +65,18 @@
const char* gVS_Header_Varyings_IsAA =
"varying float widthProportion;\n"
"varying float lengthProportion;\n";
-const char* gVS_Header_Varyings_HasBitmap =
- "varying vec2 outBitmapTexCoords;\n";
-const char* gVS_Header_Varyings_PointHasBitmap =
- "varying vec2 outPointBitmapTexCoords;\n";
+const char* gVS_Header_Varyings_HasBitmap[2] = {
+ // Default precision
+ "varying vec2 outBitmapTexCoords;\n",
+ // High precision
+ "varying highp vec2 outBitmapTexCoords;\n"
+};
+const char* gVS_Header_Varyings_PointHasBitmap[2] = {
+ // Default precision
+ "varying vec2 outPointBitmapTexCoords;\n",
+ // High precision
+ "varying highp vec2 outPointBitmapTexCoords;\n"
+};
const char* gVS_Header_Varyings_HasGradient[3] = {
// Linear
"varying vec2 linear;\n",
@@ -417,9 +426,10 @@
shader.append(gVS_Header_Varyings_HasGradient[description.gradientType]);
}
if (description.hasBitmap) {
+ int index = Caches::getInstance().extensions.needsHighpTexCoords() ? 1 : 0;
shader.append(description.isPoint ?
- gVS_Header_Varyings_PointHasBitmap :
- gVS_Header_Varyings_HasBitmap);
+ gVS_Header_Varyings_PointHasBitmap[index] :
+ gVS_Header_Varyings_HasBitmap[index]);
}
// Begin the shader
@@ -455,7 +465,6 @@
}
String8 ProgramCache::generateFragmentShader(const ProgramDescription& description) {
- // Set the default precision
String8 shader;
const bool blendFramebuffer = description.framebufferMode >= SkXfermode::kPlus_Mode;
@@ -479,9 +488,10 @@
shader.append(gVS_Header_Varyings_HasGradient[description.gradientType]);
}
if (description.hasBitmap) {
+ int index = Caches::getInstance().extensions.needsHighpTexCoords() ? 1 : 0;
shader.append(description.isPoint ?
- gVS_Header_Varyings_PointHasBitmap :
- gVS_Header_Varyings_HasBitmap);
+ gVS_Header_Varyings_PointHasBitmap[index] :
+ gVS_Header_Varyings_HasBitmap[index]);
}
// Uniforms
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index cd2c405..ee73983 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -166,9 +166,6 @@
ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
if (ref == NULL) {
// If we're not tracking this resource, just delete it
- if (Caches::hasInstance()) {
- Caches::getInstance().gradientCache.removeDeferred(resource->getSkShader());
- }
delete resource;
return;
}
@@ -220,9 +217,6 @@
break;
case kShader: {
SkiaShader* shader = (SkiaShader*) resource;
- if (Caches::hasInstance()) {
- Caches::getInstance().gradientCache.removeDeferred(shader->getSkShader());
- }
delete shader;
}
break;
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 06382f2..2428295 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -225,10 +225,7 @@
GLuint textureSlot = (*textureUnit)++;
glActiveTexture(gTextureUnitsMap[textureSlot]);
- Texture* texture = mGradientCache->get(mKey);
- if (!texture) {
- texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount, mTileX);
- }
+ Texture* texture = mGradientCache->get(mColors, mPositions, mCount, mTileX);
mat4 screenSpace;
computeScreenSpaceMatrix(screenSpace, modelView);
@@ -340,10 +337,7 @@
GLuint textureSlot = (*textureUnit)++;
glActiveTexture(gTextureUnitsMap[textureSlot]);
- Texture* texture = mGradientCache->get(mKey);
- if (!texture) {
- texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount);
- }
+ Texture* texture = mGradientCache->get(mColors, mPositions, mCount);
mat4 screenSpace;
computeScreenSpaceMatrix(screenSpace, modelView);
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index 807ed24..fb2df37 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -114,7 +114,7 @@
goto error;
}
- if (bccPrepareExecutableEx(drv->mBccScript, cacheDir, resName, 0) != 0) {
+ if (bccPrepareExecutable(drv->mBccScript, cacheDir, resName, 0) != 0) {
LOGE("bcc: FAILS to prepare executable");
goto error;
}
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 0e8ae61..8949730 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -317,6 +317,8 @@
case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
+ case NATIVE_WINDOW_API_CONNECT:
+ case NATIVE_WINDOW_API_DISCONNECT:
// TODO: we should implement these
return NO_ERROR;
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
index 0af7f80..688b998 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -280,6 +280,9 @@
uint64_t axisBit = 1LL << axis;
uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
if (!(bits & axisBit)) {
+ if (value == 0) {
+ return OK; // axes with value 0 do not need to be stored
+ }
uint32_t count = __builtin_popcountll(bits);
if (count >= MAX_AXES) {
tooManyAxes(axis);
@@ -294,23 +297,10 @@
return OK;
}
-float* PointerCoords::editAxisValue(int32_t axis) {
- if (axis < 0 || axis > 63) {
- return NULL;
- }
-
- uint64_t axisBit = 1LL << axis;
- if (!(bits & axisBit)) {
- return NULL;
- }
- uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
- return &values[index];
-}
-
static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
- float* value = c.editAxisValue(axis);
- if (value) {
- *value *= scaleFactor;
+ float value = c.getAxisValue(axis);
+ if (value != 0) {
+ c.setAxisValue(axis, value * scaleFactor);
}
}
@@ -574,20 +564,14 @@
size_t numSamples = mSamplePointerCoords.size();
for (size_t i = 0; i < numSamples; i++) {
PointerCoords& c = mSamplePointerCoords.editItemAt(i);
- float* xPtr = c.editAxisValue(AMOTION_EVENT_AXIS_X);
- float* yPtr = c.editAxisValue(AMOTION_EVENT_AXIS_Y);
- if (xPtr && yPtr) {
- float x = *xPtr + oldXOffset;
- float y = *yPtr + oldYOffset;
- matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), & point);
- *xPtr = SkScalarToFloat(point.fX) - newXOffset;
- *yPtr = SkScalarToFloat(point.fY) - newYOffset;
- }
+ float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
+ float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
+ matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point);
+ c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset);
+ c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset);
- float* orientationPtr = c.editAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
- if (orientationPtr) {
- *orientationPtr = transformAngle(matrix, *orientationPtr);
- }
+ float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
+ c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation));
}
}
@@ -727,7 +711,7 @@
}
while (idBits.count() > MAX_POINTERS) {
- idBits.clearBit(idBits.lastMarkedBit());
+ idBits.clearLastMarkedBit();
}
Movement& movement = mMovements[mIndex];
@@ -776,7 +760,7 @@
// We do this on down instead of on up because the client may want to query the
// final velocity for a pointer that just went up.
BitSet32 downIdBits;
- downIdBits.markBit(event->getActionIndex());
+ downIdBits.markBit(event->getPointerId(event->getActionIndex()));
clearPointers(downIdBits);
break;
}
diff --git a/libs/ui/tests/InputEvent_test.cpp b/libs/ui/tests/InputEvent_test.cpp
index e48d5b7..e21c464 100644
--- a/libs/ui/tests/InputEvent_test.cpp
+++ b/libs/ui/tests/InputEvent_test.cpp
@@ -52,9 +52,6 @@
ASSERT_EQ(0, coords.getAxisValue(1))
<< "getAxisValue should return zero because axis is not present";
- ASSERT_EQ(NULL, coords.editAxisValue(0))
- << "editAxisValue should return null because axis is not present";
-
// Set first axis.
ASSERT_EQ(OK, coords.setAxisValue(1, 5));
ASSERT_EQ(0x00000002ULL, coords.bits);
@@ -96,26 +93,17 @@
ASSERT_EQ(2, coords.getAxisValue(3))
<< "getAxisValue should return value of axis";
- // Edit an existing axis value in place.
- valuePtr = coords.editAxisValue(1);
- ASSERT_EQ(5, *valuePtr)
- << "editAxisValue should return pointer to axis value";
-
- *valuePtr = 7;
- ASSERT_EQ(7, coords.getAxisValue(1))
- << "getAxisValue should return value of axis";
-
// Set an axis with an id between the others. (inserting value in the middle)
ASSERT_EQ(OK, coords.setAxisValue(2, 1));
ASSERT_EQ(0x0000000fULL, coords.bits);
ASSERT_EQ(4, coords.values[0]);
- ASSERT_EQ(7, coords.values[1]);
+ ASSERT_EQ(5, coords.values[1]);
ASSERT_EQ(1, coords.values[2]);
ASSERT_EQ(2, coords.values[3]);
ASSERT_EQ(4, coords.getAxisValue(0))
<< "getAxisValue should return value of axis";
- ASSERT_EQ(7, coords.getAxisValue(1))
+ ASSERT_EQ(5, coords.getAxisValue(1))
<< "getAxisValue should return value of axis";
ASSERT_EQ(1, coords.getAxisValue(2))
<< "getAxisValue should return value of axis";
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 7258e11..e7a306b 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1646,7 +1646,8 @@
IAudioService service = getService();
try {
status = service.requestAudioFocus(streamType, durationHint, mICallBack,
- mAudioFocusDispatcher, getIdForAudioFocusListener(l));
+ mAudioFocusDispatcher, getIdForAudioFocusListener(l),
+ mContext.getPackageName() /* package name */);
} catch (RemoteException e) {
Log.e(TAG, "Can't call requestAudioFocus() from AudioService due to "+e);
}
@@ -1682,7 +1683,9 @@
* in the application manifest.
*/
public void registerMediaButtonEventReceiver(ComponentName eventReceiver) {
- //TODO enforce the rule about the receiver being declared in the manifest
+ if (eventReceiver == null) {
+ return;
+ }
IAudioService service = getService();
try {
service.registerMediaButtonEventReceiver(eventReceiver);
@@ -1697,6 +1700,9 @@
* that was registered with {@link #registerMediaButtonEventReceiver(ComponentName)}.
*/
public void unregisterMediaButtonEventReceiver(ComponentName eventReceiver) {
+ if (eventReceiver == null) {
+ return;
+ }
IAudioService service = getService();
try {
service.unregisterMediaButtonEventReceiver(eventReceiver);
@@ -1706,6 +1712,110 @@
}
/**
+ * @hide
+ * Registers the remote control client for providing information to display on the remotes.
+ * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver}
+ * that will receive the media button intent, and associated with the remote control
+ * client. This method has no effect if
+ * {@link #registerMediaButtonEventReceiver(ComponentName)} hasn't been called
+ * with the same eventReceiver, or if
+ * {@link #unregisterMediaButtonEventReceiver(ComponentName)} has been called.
+ * @param rcClient the client associated with the event receiver, responsible for providing
+ * the information to display on the remote control.
+ */
+ public void registerRemoteControlClient(ComponentName eventReceiver,
+ IRemoteControlClient rcClient) {
+ if (eventReceiver == null) {
+ return;
+ }
+ IAudioService service = getService();
+ try {
+ service.registerRemoteControlClient(eventReceiver, rcClient,
+ // used to match media button event receiver and audio focus
+ mContext.getPackageName());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Dead object in registerRemoteControlClient"+e);
+ }
+ }
+
+ /**
+ * @hide
+ * @param eventReceiver
+ */
+ public void unregisterRemoteControlClient(ComponentName eventReceiver) {
+ if (eventReceiver == null) {
+ return;
+ }
+ IAudioService service = getService();
+ try {
+ // unregistering a IRemoteControlClient is equivalent to setting it to null
+ service.registerRemoteControlClient(eventReceiver, null, mContext.getPackageName());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Dead object in unregisterRemoteControlClient"+e);
+ }
+ }
+
+ /**
+ * @hide
+ * Definitions of constants to be used in {@link android.media.IRemoteControlClient}.
+ */
+ public final class RemoteControlParameters {
+ public final static int PLAYSTATE_STOPPED = 1;
+ public final static int PLAYSTATE_PAUSED = 2;
+ public final static int PLAYSTATE_PLAYING = 3;
+ public final static int PLAYSTATE_FAST_FORWARDING = 4;
+ public final static int PLAYSTATE_REWINDING = 5;
+ public final static int PLAYSTATE_SKIPPING_FORWARDS = 6;
+ public final static int PLAYSTATE_SKIPPING_BACKWARDS = 7;
+ public final static int PLAYSTATE_BUFFERING = 8;
+
+ public final static int FLAG_KEY_MEDIA_PREVIOUS = 1 << 0;
+ public final static int FLAG_KEY_MEDIA_REWIND = 1 << 1;
+ public final static int FLAG_KEY_MEDIA_PLAY = 1 << 2;
+ public final static int FLAG_KEY_MEDIA_PLAY_PAUSE = 1 << 3;
+ public final static int FLAG_KEY_MEDIA_PAUSE = 1 << 4;
+ public final static int FLAG_KEY_MEDIA_STOP = 1 << 5;
+ public final static int FLAG_KEY_MEDIA_FAST_FORWARD = 1 << 6;
+ public final static int FLAG_KEY_MEDIA_NEXT = 1 << 7;
+ }
+
+ /**
+ * @hide
+ * Broadcast intent action indicating that the displays on the remote controls
+ * should be updated because a new remote control client is now active. If there is no
+ * {@link #EXTRA_REMOTE_CONTROL_CLIENT}, the remote control display should be cleared
+ * because there is no valid client to supply it with information.
+ *
+ * @see #EXTRA_REMOTE_CONTROL_CLIENT
+ */
+ public static final String REMOTE_CONTROL_CLIENT_CHANGED =
+ "android.media.REMOTE_CONTROL_CLIENT_CHANGED";
+
+ /**
+ * @hide
+ * The IRemoteControlClient monotonically increasing generation counter.
+ *
+ * @see #REMOTE_CONTROL_CLIENT_CHANGED_ACTION
+ */
+ public static final String EXTRA_REMOTE_CONTROL_CLIENT =
+ "android.media.EXTRA_REMOTE_CONTROL_CLIENT";
+
+ /**
+ * @hide
+ * Notifies the users of the associated remote control client that the information to display
+ * has changed.
+ * @param eventReceiver
+ */
+ public void notifyRemoteControlInformationChanged(ComponentName eventReceiver) {
+ IAudioService service = getService();
+ try {
+ service.notifyRemoteControlInformationChanged(eventReceiver);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Dead object in refreshRemoteControlDisplay"+e);
+ }
+ }
+
+ /**
* @hide
* Reload audio settings. This method is called by Settings backup
* agent when audio settings are restored and causes the AudioService
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 682560a..bf1585d 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -55,6 +55,7 @@
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
+import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -113,6 +114,8 @@
private static final int MSG_SET_FORCE_USE = 10;
private static final int MSG_PERSIST_MEDIABUTTONRECEIVER = 11;
private static final int MSG_BT_HEADSET_CNCT_FAILED = 12;
+ private static final int MSG_RCDISPLAY_CLEAR = 13;
+ private static final int MSG_RCDISPLAY_UPDATE = 14;
private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000;
// Timeout for connection to bluetooth headset service
@@ -184,7 +187,7 @@
AudioSystem.STREAM_RING, // STREAM_RING
AudioSystem.STREAM_MUSIC, // STREAM_MUSIC
AudioSystem.STREAM_ALARM, // STREAM_ALARM
- AudioSystem.STREAM_NOTIFICATION, // STREAM_NOTIFICATION
+ AudioSystem.STREAM_RING, // STREAM_NOTIFICATION
AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO
AudioSystem.STREAM_SYSTEM, // STREAM_SYSTEM_ENFORCED
AudioSystem.STREAM_VOICE_CALL, // STREAM_DTMF
@@ -239,9 +242,6 @@
*/
private int mVibrateSetting;
- /** @see System#NOTIFICATIONS_USE_RING_VOLUME */
- private int mNotificationsUseRingVolume;
-
// Broadcast receiver for device connections intent broadcasts
private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
@@ -371,7 +371,9 @@
// Register for media button intent broadcasts.
intentFilter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
- intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+ // Workaround for bug on priority setting
+ //intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+ intentFilter.setPriority(Integer.MAX_VALUE);
context.registerReceiver(mMediaButtonReceiver, intentFilter);
// Register for phone state monitoring
@@ -451,16 +453,6 @@
System.MUTE_STREAMS_AFFECTED,
((1 << AudioSystem.STREAM_MUSIC)|(1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_SYSTEM)));
- if (mVoiceCapable) {
- mNotificationsUseRingVolume = System.getInt(cr,
- Settings.System.NOTIFICATIONS_USE_RING_VOLUME, 1);
- } else {
- mNotificationsUseRingVolume = 1;
- }
-
- if (mNotificationsUseRingVolume == 1) {
- STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING;
- }
// Each stream will read its own persisted settings
// Broadcast the sticky intent
@@ -885,7 +877,8 @@
requestAudioFocus(AudioManager.STREAM_RING,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, cb,
null /* IAudioFocusDispatcher allowed to be null only for this clientId */,
- IN_VOICE_COMM_FOCUS_ID /*clientId*/);
+ IN_VOICE_COMM_FOCUS_ID /*clientId*/,
+ "system");
}
}
@@ -897,7 +890,8 @@
requestAudioFocus(AudioManager.STREAM_RING,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, cb,
null /* IAudioFocusDispatcher allowed to be null only for this clientId */,
- IN_VOICE_COMM_FOCUS_ID /*clientId*/);
+ IN_VOICE_COMM_FOCUS_ID /*clientId*/,
+ "system");
}
// if exiting call
else if (newMode == AudioSystem.MODE_NORMAL) {
@@ -2155,6 +2149,33 @@
persistMediaButtonReceiver( (ComponentName) msg.obj );
break;
+ case MSG_RCDISPLAY_CLEAR:
+ Log.i(TAG, "Clear remote control display");
+ Intent clearIntent = new Intent(AudioManager.REMOTE_CONTROL_CLIENT_CHANGED);
+ // no extra means no IRemoteControlClient, which is a request to clear
+ clearIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ mContext.sendBroadcast(clearIntent);
+ break;
+
+ case MSG_RCDISPLAY_UPDATE:
+ synchronized(mCurrentRcLock) {
+ if (mCurrentRcClientRef.get() == null) {
+ // the remote control display owner has changed between the
+ // the message to update the display was sent, and the time it
+ // gets to be processed (now)
+ } else {
+ mCurrentRcClientGen++;
+ Log.i(TAG, "Display/update remote control ");
+ Intent rcClientIntent = new Intent(
+ AudioManager.REMOTE_CONTROL_CLIENT_CHANGED);
+ rcClientIntent.putExtra(AudioManager.EXTRA_REMOTE_CONTROL_CLIENT,
+ mCurrentRcClientGen);
+ rcClientIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ mContext.sendBroadcast(rcClientIntent);
+ }
+ }
+ break;
+
case MSG_BT_HEADSET_CNCT_FAILED:
resetBluetoothSco();
break;
@@ -2168,8 +2189,6 @@
super(new Handler());
mContentResolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this);
- mContentResolver.registerContentObserver(Settings.System.getUriFor(
- Settings.System.NOTIFICATIONS_USE_RING_VOLUME), false, this);
}
@Override
@@ -2193,29 +2212,6 @@
mRingerModeAffectedStreams = ringerModeAffectedStreams;
setRingerModeInt(getRingerMode(), false);
}
-
- int notificationsUseRingVolume = Settings.System.getInt(mContentResolver,
- Settings.System.NOTIFICATIONS_USE_RING_VOLUME,
- 1);
- if (mVoiceCapable) {
- if (notificationsUseRingVolume != mNotificationsUseRingVolume) {
- mNotificationsUseRingVolume = notificationsUseRingVolume;
- if (mNotificationsUseRingVolume == 1) {
- STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING;
- mStreamStates[AudioSystem.STREAM_NOTIFICATION].setVolumeIndexSettingName(
- System.VOLUME_SETTINGS[AudioSystem.STREAM_RING]);
- } else {
- STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_NOTIFICATION;
- mStreamStates[AudioSystem.STREAM_NOTIFICATION].setVolumeIndexSettingName(
- System.VOLUME_SETTINGS[AudioSystem.STREAM_NOTIFICATION]);
- // Persist notification volume volume as it was not persisted while aliased to ring volume
- // and persist with no delay as there might be registered observers of the persisted
- // notification volume.
- sendMsg(mAudioHandler, MSG_PERSIST_VOLUME, AudioSystem.STREAM_NOTIFICATION,
- SENDMSG_REPLACE, 1, 1, mStreamStates[AudioSystem.STREAM_NOTIFICATION], 0);
- }
- }
- }
}
}
}
@@ -2567,23 +2563,25 @@
private static class FocusStackEntry {
public int mStreamType = -1;// no stream type
- public boolean mIsTransportControlReceiver = false;
public IAudioFocusDispatcher mFocusDispatcher = null;
public IBinder mSourceRef = null;
public String mClientId;
public int mFocusChangeType;
+ public String mPackageName;
+ public int mCallingUid;
public FocusStackEntry() {
}
- public FocusStackEntry(int streamType, int duration, boolean isTransportControlReceiver,
- IAudioFocusDispatcher afl, IBinder source, String id) {
+ public FocusStackEntry(int streamType, int duration,
+ IAudioFocusDispatcher afl, IBinder source, String id, String pn, int uid) {
mStreamType = streamType;
- mIsTransportControlReceiver = isTransportControlReceiver;
mFocusDispatcher = afl;
mSourceRef = source;
mClientId = id;
mFocusChangeType = duration;
+ mPackageName = pn;
+ mCallingUid = uid;
}
}
@@ -2600,13 +2598,15 @@
while(stackIterator.hasNext()) {
FocusStackEntry fse = stackIterator.next();
pw.println(" source:" + fse.mSourceRef + " -- client: " + fse.mClientId
- + " -- duration: " +fse.mFocusChangeType);
+ + " -- duration: " + fse.mFocusChangeType
+ + " -- uid: " + fse.mCallingUid);
}
}
}
/**
* Helper function:
+ * Called synchronized on mAudioFocusLock
* Remove a focus listener from the focus stack.
* @param focusListenerToRemove the focus listener
* @param signal if true and the listener was at the top of the focus stack, i.e. it was holding
@@ -2621,6 +2621,10 @@
if (signal) {
// notify the new top of the stack it gained focus
notifyTopOfAudioFocusStack();
+ // there's a new top of the stack, let the remote control know
+ synchronized(mRCStack) {
+ checkUpdateRemoteControlDisplay();
+ }
}
} else {
// focus is abandoned by a client that's not at the top of the stack,
@@ -2639,6 +2643,7 @@
/**
* Helper function:
+ * Called synchronized on mAudioFocusLock
* Remove focus listeners from the focus stack for a particular client.
*/
private void removeFocusStackEntryForClient(IBinder cb) {
@@ -2658,6 +2663,10 @@
// we removed an entry at the top of the stack:
// notify the new top of the stack it gained focus.
notifyTopOfAudioFocusStack();
+ // there's a new top of the stack, let the remote control know
+ synchronized(mRCStack) {
+ checkUpdateRemoteControlDisplay();
+ }
}
}
@@ -2700,7 +2709,7 @@
/** @see AudioManager#requestAudioFocus(IAudioFocusDispatcher, int, int) */
public int requestAudioFocus(int mainStreamType, int focusChangeHint, IBinder cb,
- IAudioFocusDispatcher fd, String clientId) {
+ IAudioFocusDispatcher fd, String clientId, String callingPackageName) {
Log.i(TAG, " AudioFocus requestAudioFocus() from " + clientId);
// the main stream type for the audio focus request is currently not used. It may
// potentially be used to handle multiple stream type-dependent audio focuses.
@@ -2743,8 +2752,13 @@
removeFocusStackEntry(clientId, false);
// push focus requester at the top of the audio focus stack
- mFocusStack.push(new FocusStackEntry(mainStreamType, focusChangeHint, false, fd, cb,
- clientId));
+ mFocusStack.push(new FocusStackEntry(mainStreamType, focusChangeHint, fd, cb,
+ clientId, callingPackageName, Binder.getCallingUid()));
+
+ // there's a new top of the stack, let the remote control know
+ synchronized(mRCStack) {
+ checkUpdateRemoteControlDisplay();
+ }
}//synchronized(mAudioFocusLock)
// handle the potential premature death of the new holder of the focus
@@ -2831,19 +2845,100 @@
}
}
- private static class RemoteControlStackEntry {
- public ComponentName mReceiverComponent;// always non null
- // TODO implement registration expiration?
- //public int mRegistrationTime;
+ private final static Object mCurrentRcLock = new Object();
+ /**
+ * The one remote control client to be polled for display information.
+ * This object is never null, but its reference might.
+ * Access protected by mCurrentRcLock.
+ */
+ private static SoftReference<IRemoteControlClient> mCurrentRcClientRef =
+ new SoftReference<IRemoteControlClient>(null);
- public RemoteControlStackEntry() {
- }
+ /**
+ * A monotonically increasing generation counter for mCurrentRcClientRef.
+ * Only accessed with a lock on mCurrentRcLock.
+ */
+ private static int mCurrentRcClientGen = 0;
- public RemoteControlStackEntry(ComponentName r) {
- mReceiverComponent = r;
+ /**
+ * Returns the current remote control client.
+ * @param rcClientId the counter value that matches the extra
+ * {@link AudioManager#EXTRA_REMOTE_CONTROL_CLIENT} in the
+ * {@link AudioManager#REMOTE_CONTROL_CLIENT_CHANGED} event
+ * @return the current IRemoteControlClient from which information to display on the remote
+ * control can be retrieved, or null if rcClientId doesn't match the current generation
+ * counter.
+ */
+ public static IRemoteControlClient getRemoteControlClient(int rcClientId) {
+ synchronized(mCurrentRcLock) {
+ if (rcClientId == mCurrentRcClientGen) {
+ return mCurrentRcClientRef.get();
+ } else {
+ return null;
+ }
}
}
+ /**
+ * Inner class to monitor remote control client deaths, and remove the client for the
+ * remote control stack if necessary.
+ */
+ private class RcClientDeathHandler implements IBinder.DeathRecipient {
+ private IBinder mCb; // To be notified of client's death
+ private ComponentName mRcEventReceiver;
+
+ RcClientDeathHandler(IBinder cb, ComponentName eventReceiver) {
+ mCb = cb;
+ mRcEventReceiver = eventReceiver;
+ }
+
+ public void binderDied() {
+ Log.w(TAG, " RemoteControlClient died");
+ // remote control client died, make sure the displays don't use it anymore
+ // by setting its remote control client to null
+ registerRemoteControlClient(mRcEventReceiver, null, null/*ignored*/);
+ }
+
+ public IBinder getBinder() {
+ return mCb;
+ }
+ }
+
+ private static class RemoteControlStackEntry {
+ /** the target for the ACTION_MEDIA_BUTTON events */
+ public ComponentName mReceiverComponent;// always non null
+ public String mCallingPackageName;
+ public int mCallingUid;
+
+ /** provides access to the information to display on the remote control */
+ public SoftReference<IRemoteControlClient> mRcClientRef;
+ public RcClientDeathHandler mRcClientDeathHandler;
+
+ public RemoteControlStackEntry(ComponentName r) {
+ mReceiverComponent = r;
+ mCallingUid = -1;
+ mRcClientRef = new SoftReference<IRemoteControlClient>(null);
+ }
+
+ public void unlinkToRcClientDeath() {
+ if ((mRcClientDeathHandler != null) && (mRcClientDeathHandler.mCb != null)) {
+ try {
+ mRcClientDeathHandler.mCb.unlinkToDeath(mRcClientDeathHandler, 0);
+ } catch (java.util.NoSuchElementException e) {
+ // not much we can do here
+ Log.e(TAG, "Encountered " + e + " in unlinkToRcClientDeath()");
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ /**
+ * The stack of remote control event receivers.
+ * Code sections and methods that modify the remote control event receiver stack are
+ * synchronized on mRCStack, but also BEFORE on mFocusLock as any change in either
+ * stack, audio focus or RC, can lead to a change in the remote control display
+ */
private Stack<RemoteControlStackEntry> mRCStack = new Stack<RemoteControlStackEntry>();
/**
@@ -2855,8 +2950,10 @@
synchronized(mRCStack) {
Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
while(stackIterator.hasNext()) {
- RemoteControlStackEntry fse = stackIterator.next();
- pw.println(" receiver:" + fse.mReceiverComponent);
+ RemoteControlStackEntry rcse = stackIterator.next();
+ pw.println(" receiver: " + rcse.mReceiverComponent +
+ " -- client: " + rcse.mRcClientRef.get() +
+ " -- uid: " + rcse.mCallingUid);
}
}
}
@@ -2909,6 +3006,7 @@
ComponentName receiverComponentName = ComponentName.unflattenFromString(receiverName);
registerMediaButtonEventReceiver(receiverComponentName);
}
+ // upon restoring (e.g. after boot), do we want to refresh all remotes?
}
/**
@@ -2921,14 +3019,20 @@
return;
}
Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+ RemoteControlStackEntry rcse = null;
+ boolean wasInsideStack = false;
while(stackIterator.hasNext()) {
- RemoteControlStackEntry rcse = (RemoteControlStackEntry)stackIterator.next();
+ rcse = (RemoteControlStackEntry)stackIterator.next();
if(rcse.mReceiverComponent.equals(newReceiver)) {
+ wasInsideStack = true;
stackIterator.remove();
break;
}
}
- mRCStack.push(new RemoteControlStackEntry(newReceiver));
+ if (!wasInsideStack) {
+ rcse = new RemoteControlStackEntry(newReceiver);
+ }
+ mRCStack.push(rcse);
// post message to persist the default media button receiver
mAudioHandler.sendMessage( mAudioHandler.obtainMessage(
@@ -2950,13 +3054,88 @@
}
}
+ /**
+ * Helper function:
+ * Called synchronized on mRCStack
+ */
+ private boolean isCurrentRcController(ComponentName eventReceiver) {
+ if (!mRCStack.empty() && mRCStack.peek().mReceiverComponent.equals(eventReceiver)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Helper function:
+ * Called synchronized on mRCStack
+ */
+ private void clearRemoteControlDisplay() {
+ synchronized(mCurrentRcLock) {
+ mCurrentRcClientRef.clear();
+ }
+ mAudioHandler.sendMessage( mAudioHandler.obtainMessage(MSG_RCDISPLAY_CLEAR) );
+ }
+
+ /**
+ * Helper function:
+ * Called synchronized on mRCStack
+ * mRCStack.empty() is false
+ */
+ private void updateRemoteControlDisplay() {
+ RemoteControlStackEntry rcse = mRCStack.peek();
+ // this is where we enforce opt-in for information display on the remote controls
+ // with the new AudioManager.registerRemoteControlClient() API
+ if (rcse.mRcClientRef.get() == null) {
+ // FIXME remove log before release: this warning will be displayed for every AF change
+ Log.w(TAG, "Can't update remote control display with null remote control client");
+ clearRemoteControlDisplay();
+ return;
+ }
+ synchronized(mCurrentRcLock) {
+ mCurrentRcClientRef = rcse.mRcClientRef;
+ }
+ mAudioHandler.sendMessage( mAudioHandler.obtainMessage(MSG_RCDISPLAY_UPDATE, 0, 0, rcse) );
+ }
+
+ /**
+ * Helper function:
+ * Called synchronized on mFocusLock, then mRCStack
+ * Check whether the remote control display should be updated, triggers the update if required
+ */
+ private void checkUpdateRemoteControlDisplay() {
+ // determine whether the remote control display should be refreshed
+ // if either stack is empty, there is a mismatch, so clear the RC display
+ if (mRCStack.isEmpty() || mFocusStack.isEmpty()) {
+ clearRemoteControlDisplay();
+ return;
+ }
+ // if the top of the two stacks belong to different packages, there is a mismatch, clear
+ if ((mRCStack.peek().mCallingPackageName != null)
+ && (mFocusStack.peek().mPackageName != null)
+ && !(mRCStack.peek().mCallingPackageName.compareTo(
+ mFocusStack.peek().mPackageName) == 0)) {
+ clearRemoteControlDisplay();
+ return;
+ }
+ // if the audio focus didn't originate from the same Uid as the one in which the remote
+ // control information will be retrieved, clear
+ if (mRCStack.peek().mCallingUid != mFocusStack.peek().mCallingUid) {
+ clearRemoteControlDisplay();
+ return;
+ }
+ // refresh conditions were verified: update the remote controls
+ updateRemoteControlDisplay();
+ }
/** see AudioManager.registerMediaButtonEventReceiver(ComponentName eventReceiver) */
public void registerMediaButtonEventReceiver(ComponentName eventReceiver) {
Log.i(TAG, " Remote Control registerMediaButtonEventReceiver() for " + eventReceiver);
- synchronized(mRCStack) {
- pushMediaButtonReceiver(eventReceiver);
+ synchronized(mAudioFocusLock) {
+ synchronized(mRCStack) {
+ pushMediaButtonReceiver(eventReceiver);
+ checkUpdateRemoteControlDisplay();
+ }
}
}
@@ -2964,11 +3143,74 @@
public void unregisterMediaButtonEventReceiver(ComponentName eventReceiver) {
Log.i(TAG, " Remote Control unregisterMediaButtonEventReceiver() for " + eventReceiver);
- synchronized(mRCStack) {
- removeMediaButtonReceiver(eventReceiver);
+ synchronized(mAudioFocusLock) {
+ synchronized(mRCStack) {
+ boolean topOfStackWillChange = isCurrentRcController(eventReceiver);
+ removeMediaButtonReceiver(eventReceiver);
+ if (topOfStackWillChange) {
+ checkUpdateRemoteControlDisplay();
+ }
+ }
}
}
+ /** see AudioManager.registerRemoteControlClient(ComponentName eventReceiver, ...) */
+ public void registerRemoteControlClient(ComponentName eventReceiver,
+ IRemoteControlClient rcClient, String callingPackageName) {
+ synchronized(mAudioFocusLock) {
+ synchronized(mRCStack) {
+ // store the new display information
+ Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+ while(stackIterator.hasNext()) {
+ RemoteControlStackEntry rcse = stackIterator.next();
+ if(rcse.mReceiverComponent.equals(eventReceiver)) {
+ // already had a remote control client?
+ if (rcse.mRcClientDeathHandler != null) {
+ // stop monitoring the old client's death
+ rcse.unlinkToRcClientDeath();
+ }
+ // save the new remote control client
+ rcse.mRcClientRef = new SoftReference<IRemoteControlClient>(rcClient);
+ rcse.mCallingPackageName = callingPackageName;
+ rcse.mCallingUid = Binder.getCallingUid();
+ if (rcClient == null) {
+ break;
+ }
+ // monitor the new client's death
+ IBinder b = rcClient.asBinder();
+ RcClientDeathHandler rcdh =
+ new RcClientDeathHandler(b, rcse.mReceiverComponent);
+ try {
+ b.linkToDeath(rcdh, 0);
+ } catch (RemoteException e) {
+ // remote control client is DOA, disqualify it
+ Log.w(TAG, "registerRemoteControlClient() has a dead client " + b);
+ rcse.mRcClientRef.clear();
+ }
+ rcse.mRcClientDeathHandler = rcdh;
+ break;
+ }
+ }
+ // if the eventReceiver is at the top of the stack
+ // then check for potential refresh of the remote controls
+ if (isCurrentRcController(eventReceiver)) {
+ checkUpdateRemoteControlDisplay();
+ }
+ }
+ }
+ }
+
+ /** see AudioManager.notifyRemoteControlInformationChanged(ComponentName er) */
+ public void notifyRemoteControlInformationChanged(ComponentName eventReceiver) {
+ synchronized(mAudioFocusLock) {
+ synchronized(mRCStack) {
+ // only refresh if the eventReceiver is at the top of the stack
+ if (isCurrentRcController(eventReceiver)) {
+ checkUpdateRemoteControlDisplay();
+ }
+ }
+ }
+ }
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index e3bd7b4..9afe553 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -18,6 +18,9 @@
import android.content.ComponentName;
import android.media.IAudioFocusDispatcher;
+import android.media.IRemoteControlClient;
+import android.net.Uri;
+import android.os.Bundle;
/**
* {@hide}
@@ -77,7 +80,7 @@
boolean isBluetoothScoOn();
int requestAudioFocus(int mainStreamType, int durationHint, IBinder cb, IAudioFocusDispatcher l,
- String clientId);
+ String clientId, String callingPackageName);
int abandonAudioFocus(IAudioFocusDispatcher l, String clientId);
@@ -87,6 +90,11 @@
void unregisterMediaButtonEventReceiver(in ComponentName eventReceiver);
+ void registerRemoteControlClient(in ComponentName eventReceiver,
+ in IRemoteControlClient rcClient, in String callingPackageName);
+
+ void notifyRemoteControlInformationChanged(in ComponentName eventReceiver);
+
void startBluetoothSco(IBinder cb);
void stopBluetoothSco(IBinder cb);
diff --git a/media/java/android/media/IRemoteControlClient.aidl b/media/java/android/media/IRemoteControlClient.aidl
new file mode 100644
index 0000000..a49371c
--- /dev/null
+++ b/media/java/android/media/IRemoteControlClient.aidl
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.media;
+
+import android.graphics.Bitmap;
+
+/**
+ * {@hide}
+ */
+interface IRemoteControlClient
+{
+ /**
+ * Called by a remote control to retrieve a String of information to display.
+ * @param field the identifier for a metadata field to retrieve. Valid values are
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUM},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ARTIST},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_AUTHOR},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPILATION},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPOSER},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DATE},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_GENRE},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}.
+ * @return null if the given field is not supported, or the String matching the metadata field.
+ */
+ String getMetadataString(int field);
+
+ /**
+ * Returns the current playback state.
+ * @return one of the following values:
+ * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_STOPPED},
+ * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_PAUSED},
+ * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_PLAYING},
+ * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_FAST_FORWARDING},
+ * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_REWINDING},
+ * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_SKIPPING_FORWARDS},
+ * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_SKIPPING_BACKWARDS},
+ * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_BUFFERING}.
+ */
+ int getPlaybackState();
+
+ /**
+ * Returns the flags for the media transport control buttons this client supports.
+ * @see {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_PREVIOUS},
+ * {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_REWIND},
+ * {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_PLAY},
+ * {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_PLAY_PAUSE},
+ * {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_PAUSE},
+ * {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_STOP},
+ * {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_FAST_FORWARD},
+ * {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_NEXT}
+ */
+ int getTransportControlFlags();
+
+ Bitmap getAlbumArt(int width, int height);
+}
diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java
index 7c181ee..078d4af 100644
--- a/media/java/android/media/ThumbnailUtils.java
+++ b/media/java/android/media/ThumbnailUtils.java
@@ -387,6 +387,7 @@
if (recycle) {
source.recycle();
}
+ c.setBitmap(null);
return b2;
}
float bitmapWidthF = source.getWidth();
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index 6b0fb12..5bfdcdb 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -3761,6 +3761,7 @@
final Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(tempBitmap, new Rect(0, 0, newWidth, newHeight),
new Rect(0, 0, width, height), sResizePaint);
+ canvas.setBitmap(null);
}
if (tempBitmap != null) {
@@ -3837,6 +3838,7 @@
final Canvas canvas = new Canvas(bitmaps[i]);
canvas.drawBitmap(tempBitmap, new Rect(0, 0, newWidth, newHeight),
new Rect(0, 0, width, height), sResizePaint);
+ canvas.setBitmap(null);
}
}
diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java
index 73cc7e2..f0cc1fe 100755
--- a/media/java/android/media/videoeditor/MediaImageItem.java
+++ b/media/java/android/media/videoeditor/MediaImageItem.java
@@ -1008,6 +1008,7 @@
srcBitmap.getHeight()),
new Rect(0, 0, (int)bitmapWidth,
(int)bitmapHeight), sResizePaint);
+ canvas.setBitmap(null);
/**
* Release the source bitmap
*/
diff --git a/media/java/android/media/videoeditor/OverlayFrame.java b/media/java/android/media/videoeditor/OverlayFrame.java
index 131f5f0..d159df2 100755
--- a/media/java/android/media/videoeditor/OverlayFrame.java
+++ b/media/java/android/media/videoeditor/OverlayFrame.java
@@ -420,6 +420,7 @@
}
overlayCanvas.drawBitmap(overlayBitmap, srcRect, destRect, sResizePaint);
+ overlayCanvas.setBitmap(null);
/*
* Write to the dest file
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index 76a8a91..52885d2 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -352,7 +352,9 @@
} break;
case SET_VOLUME: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
- reply->writeInt32(setVolume(data.readFloat(), data.readFloat()));
+ float leftVolume = data.readFloat();
+ float rightVolume = data.readFloat();
+ reply->writeInt32(setVolume(leftVolume, rightVolume));
return NO_ERROR;
} break;
case INVOKE: {
@@ -367,7 +369,9 @@
} break;
case GET_METADATA: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
- const status_t retcode = getMetadata(data.readInt32(), data.readInt32(), reply);
+ bool update_only = static_cast<bool>(data.readInt32());
+ bool apply_filter = static_cast<bool>(data.readInt32());
+ const status_t retcode = getMetadata(update_only, apply_filter, reply);
reply->setDataPosition(0);
reply->writeInt32(retcode);
reply->setDataPosition(0);
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index a11fb80..3dd9249 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -201,11 +201,11 @@
void MediaPlayer::disconnectNativeWindow() {
if (mConnectedWindow != NULL) {
- status_t err = native_window_disconnect(mConnectedWindow.get(),
+ status_t err = native_window_api_disconnect(mConnectedWindow.get(),
NATIVE_WINDOW_API_MEDIA);
if (err != OK) {
- LOGW("native_window_disconnect returned an error: %s (%d)",
+ LOGW("native_window_api_disconnect returned an error: %s (%d)",
strerror(-err), err);
}
}
@@ -224,7 +224,7 @@
}
if (surface != NULL) {
- status_t err = native_window_connect(surface.get(),
+ status_t err = native_window_api_connect(surface.get(),
NATIVE_WINDOW_API_MEDIA);
if (err != OK) {
@@ -274,7 +274,7 @@
sp<ANativeWindow> anw;
if (surfaceTexture != NULL) {
anw = new SurfaceTextureClient(surfaceTexture);
- status_t err = native_window_connect(anw.get(),
+ status_t err = native_window_api_connect(anw.get(),
NATIVE_WINDOW_API_MEDIA);
if (err != OK) {
diff --git a/media/libstagefright/AACExtractor.cpp b/media/libstagefright/AACExtractor.cpp
index 4203b6e..a5a6b64 100644
--- a/media/libstagefright/AACExtractor.cpp
+++ b/media/libstagefright/AACExtractor.cpp
@@ -92,7 +92,7 @@
size_t frameSize = 0;
uint8_t syncword[2];
- if (source->readAt(0, &syncword, 2) != 2) {
+ if (source->readAt(offset, &syncword, 2) != 2) {
return 0;
}
if ((syncword[0] != 0xff) || ((syncword[1] & 0xf6) != 0xf0)) {
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index de66d99..ea8eaa4 100755
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -37,7 +37,8 @@
CameraSourceListener(const sp<CameraSource> &source);
virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);
- virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr);
+ virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr,
+ camera_frame_metadata_t *metadata);
virtual void postDataTimestamp(
nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
@@ -63,7 +64,8 @@
LOGV("notify(%d, %d, %d)", msgType, ext1, ext2);
}
-void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr) {
+void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr,
+ camera_frame_metadata_t *metadata) {
LOGV("postData(%d, ptr:%p, size:%d)",
msgType, dataPtr->pointer(), dataPtr->size());
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 5bbed5d..92e84c2 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -407,6 +407,8 @@
int64_t seekTimeUs;
ReadOptions::SeekMode mode;
+ bool seekCBR = false;
+
if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) {
int64_t actualSeekTimeUs = seekTimeUs;
if (mSeeker == NULL
@@ -421,6 +423,7 @@
mCurrentTimeUs = seekTimeUs;
mCurrentPos = mFirstFramePos + seekTimeUs * bitrate / 8000000;
+ seekCBR = true;
} else {
mCurrentTimeUs = actualSeekTimeUs;
}
@@ -454,6 +457,13 @@
&& GetMPEGAudioFrameSize(
header, &frame_size, &sample_rate, NULL,
&bitrate, &num_samples)) {
+
+ // re-calculate mCurrentTimeUs because we might have called Resync()
+ if (seekCBR) {
+ mCurrentTimeUs = (mCurrentPos - mFirstFramePos) * 8000 / bitrate;
+ mBasisTimeUs = mCurrentTimeUs;
+ }
+
break;
}
diff --git a/media/libstagefright/MediaBuffer.cpp b/media/libstagefright/MediaBuffer.cpp
index a8fadf2..0b14f1e 100644
--- a/media/libstagefright/MediaBuffer.cpp
+++ b/media/libstagefright/MediaBuffer.cpp
@@ -21,6 +21,7 @@
#include <pthread.h>
#include <stdlib.h>
+#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MetaData.h>
@@ -70,6 +71,20 @@
mOriginal(NULL) {
}
+MediaBuffer::MediaBuffer(const sp<ABuffer> &buffer)
+ : mObserver(NULL),
+ mNextBuffer(NULL),
+ mRefCount(0),
+ mData(buffer->data()),
+ mSize(buffer->size()),
+ mRangeOffset(0),
+ mRangeLength(mSize),
+ mBuffer(buffer),
+ mOwnsData(false),
+ mMetaData(new MetaData),
+ mOriginal(NULL) {
+}
+
void MediaBuffer::release() {
if (mObserver == NULL) {
CHECK_EQ(mRefCount, 0);
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index ac73351..a4f3922 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -976,11 +976,6 @@
video_def->nFrameWidth = width;
video_def->nFrameHeight = height;
video_def->xFramerate = 0; // No need for output port
- // FIXME:
- // Revmoe this workaround after work is done.
- if (!strncmp(mComponentName, "OMX.TI.DUCATI1", 14)) {
- video_def->xFramerate = (frameRate << 16);
- }
video_def->nBitrate = bitRate; // Q16 format
video_def->eCompressionFormat = compressionFormat;
video_def->eColorFormat = OMX_COLOR_FormatUnused;
diff --git a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
index 07a9eb8..887fe7c 100644
--- a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
+++ b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
@@ -47,6 +47,8 @@
delete mDelegate;
mDelegate = NULL;
+ clearDRMState_l();
+
if (mDrmManagerClient != NULL) {
delete mDrmManagerClient;
mDrmManagerClient = NULL;
@@ -116,8 +118,6 @@
// mURI.clear();
mIOResult = err;
-
- clearDRMState_l();
}
void ChromiumHTTPDataSource::disconnect() {
@@ -251,8 +251,6 @@
// mURI.clear();
mCondition.broadcast();
-
- clearDRMState_l();
}
sp<DecryptHandle> ChromiumHTTPDataSource::DrmInitialization() {
diff --git a/media/libstagefright/chromium_http/support.cpp b/media/libstagefright/chromium_http/support.cpp
index eb10ab7..26c3eda 100644
--- a/media/libstagefright/chromium_http/support.cpp
+++ b/media/libstagefright/chromium_http/support.cpp
@@ -183,19 +183,19 @@
void SfDelegate::OnReceivedRedirect(
net::URLRequest *request, const GURL &new_url, bool *defer_redirect) {
- MY_LOGI("OnReceivedRedirect");
+ MY_LOGV("OnReceivedRedirect");
}
void SfDelegate::OnAuthRequired(
net::URLRequest *request, net::AuthChallengeInfo *auth_info) {
- MY_LOGI("OnAuthRequired");
+ MY_LOGV("OnAuthRequired");
inherited::OnAuthRequired(request, auth_info);
}
void SfDelegate::OnCertificateRequested(
net::URLRequest *request, net::SSLCertRequestInfo *cert_request_info) {
- MY_LOGI("OnCertificateRequested");
+ MY_LOGV("OnCertificateRequested");
inherited::OnCertificateRequested(request, cert_request_info);
}
@@ -208,7 +208,7 @@
}
void SfDelegate::OnGetCookies(net::URLRequest *request, bool blocked_by_policy) {
- MY_LOGI("OnGetCookies");
+ MY_LOGV("OnGetCookies");
}
void SfDelegate::OnSetCookie(
@@ -216,7 +216,7 @@
const std::string &cookie_line,
const net::CookieOptions &options,
bool blocked_by_policy) {
- MY_LOGI("OnSetCookie");
+ MY_LOGV("OnSetCookie");
}
void SfDelegate::OnResponseStarted(net::URLRequest *request) {
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 2578d2d..f67cdac 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -617,23 +617,32 @@
goto rinse_repeat;
}
- if (!mPlaylist->isComplete()
- && mSeqNumber > lastSeqNumberInPlaylist
- && mNumRetries < kMaxNumRetries) {
+ if (!mPlaylist->isComplete() && mNumRetries < kMaxNumRetries) {
++mNumRetries;
- mLastPlaylistFetchTimeUs = -1;
- postMonitorQueue(3000000ll);
+ if (mSeqNumber > lastSeqNumberInPlaylist) {
+ mLastPlaylistFetchTimeUs = -1;
+ postMonitorQueue(3000000ll);
+ return;
+ }
+
+ // we've missed the boat, let's start from the lowest sequence
+ // number available and signal a discontinuity.
+
+ LOGI("We've missed the boat, restarting playback.");
+ mSeqNumber = lastSeqNumberInPlaylist;
+ explicitDiscontinuity = true;
+
+ // fall through
+ } else {
+ LOGE("Cannot find sequence number %d in playlist "
+ "(contains %d - %d)",
+ mSeqNumber, firstSeqNumberInPlaylist,
+ firstSeqNumberInPlaylist + mPlaylist->size() - 1);
+
+ mDataSource->queueEOS(ERROR_END_OF_STREAM);
return;
}
-
- LOGE("Cannot find sequence number %d in playlist "
- "(contains %d - %d)",
- mSeqNumber, firstSeqNumberInPlaylist,
- firstSeqNumberInPlaylist + mPlaylist->size() - 1);
-
- mDataSource->queueEOS(ERROR_END_OF_STREAM);
- return;
}
mNumRetries = 0;
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index 59de17e..2e66a2c 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -105,12 +105,10 @@
int64_t timeUs;
CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
- MediaBuffer *mediaBuffer = new MediaBuffer(buffer->size());
+ MediaBuffer *mediaBuffer = new MediaBuffer(buffer);
+
mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
- // hexdump(buffer->data(), buffer->size());
-
- memcpy(mediaBuffer->data(), buffer->data(), buffer->size());
*out = mediaBuffer;
return OK;
}
diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp
index a02591f..4ecb92f 100644
--- a/media/libstagefright/rtsp/APacketSource.cpp
+++ b/media/libstagefright/rtsp/APacketSource.cpp
@@ -628,14 +628,12 @@
updateNormalPlayTime_l(buffer);
- MediaBuffer *mediaBuffer = new MediaBuffer(buffer->size());
-
int64_t timeUs;
CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
+ MediaBuffer *mediaBuffer = new MediaBuffer(buffer);
mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
- memcpy(mediaBuffer->data(), buffer->data(), buffer->size());
*out = mediaBuffer;
mBuffers.erase(mBuffers.begin());
diff --git a/media/libstagefright/tests/SurfaceMediaSource_test.cpp b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
index dc6f2c9..5b32b68 100644
--- a/media/libstagefright/tests/SurfaceMediaSource_test.cpp
+++ b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
@@ -57,6 +57,7 @@
protected:
virtual void SetUp() {
+ android::ProcessState::self()->startThreadPool();
mSMS = new SurfaceMediaSource(mYuvTexWidth, mYuvTexHeight);
mSMS->setSynchronousMode(true);
mSTC = new SurfaceTextureClient(mSMS);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java
index 0b0d0ce..369a067 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java
@@ -16,24 +16,33 @@
package com.android.mediaframeworktest;
+import android.media.EncoderCapabilities.AudioEncoderCap;
+import android.media.EncoderCapabilities.VideoEncoderCap;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
import com.android.mediaframeworktest.stress.MediaRecorderStressTest;
+import java.util.List;
import junit.framework.TestSuite;
public class MediaRecorderStressTestRunner extends InstrumentationTestRunner {
- // Default recorder settings
+ public static List<VideoEncoderCap> videoEncoders = MediaProfileReader.getVideoEncoders();
+ public static List<AudioEncoderCap> audioEncoders = MediaProfileReader.getAudioEncoders();
+
+ //Get the first capability as the default
+ public static VideoEncoderCap videoEncoder = videoEncoders.get(0);
+ public static AudioEncoderCap audioEncoder = audioEncoders.get(0);
+
public static int mIterations = 100;
- public static int mVideoEncoder = MediaRecorder.VideoEncoder.H263;
- public static int mAudioEncdoer = MediaRecorder.AudioEncoder.AMR_NB;
- public static int mFrameRate = 20;
- public static int mVideoWidth = 352;
- public static int mVideoHeight = 288;
- public static int mBitRate = 100;
+ public static int mVideoEncoder = videoEncoder.mCodec;
+ public static int mAudioEncdoer = audioEncoder.mCodec;
+ public static int mFrameRate = videoEncoder.mMaxFrameRate;
+ public static int mVideoWidth = videoEncoder.mMaxFrameWidth;
+ public static int mVideoHeight = videoEncoder.mMaxFrameHeight;
+ public static int mBitRate = audioEncoder.mMaxBitRate;
public static boolean mRemoveVideo = true;
public static int mDuration = 10000;
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 3f547fd..4c7f84e 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -1073,6 +1073,15 @@
return gl;
}
+ public void purgeBuffers() {
+ mEgl.eglMakeCurrent(mEglDisplay,
+ EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE,
+ EGL10.EGL_NO_CONTEXT);
+ mEgl.eglMakeCurrent(mEglDisplay,
+ mEglSurface, mEglSurface,
+ mEglContext);
+ }
+
/**
* Display the current render surface.
* @return false if the context has been lost.
@@ -1415,6 +1424,7 @@
if (LOG_RENDERER) {
Log.w("GLThread", "onSurfaceChanged(" + w + ", " + h + ")");
}
+ mEglHelper.purgeBuffers();
mRenderer.onSurfaceChanged(gl, w, h);
sizeChanged = false;
}
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index ba5d29a..10cea22 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -363,6 +363,12 @@
EGLConfig iConfig = dp->configs[intptr_t(config)].config;
EGLint format;
+ if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != OK) {
+ LOGE("EGLNativeWindowType %p already connected to another API",
+ window);
+ return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ }
+
// set the native window's buffers format to match this config
if (cnx->egl.eglGetConfigAttrib(iDpy,
iConfig, EGL_NATIVE_VISUAL_ID, &format)) {
@@ -371,6 +377,7 @@
if (err != 0) {
LOGE("error setting native window pixel format: %s (%d)",
strerror(-err), err);
+ native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
}
}
@@ -383,6 +390,10 @@
dp->configs[intptr_t(config)].impl, cnx);
return s;
}
+
+ // EGLSurface creation failed
+ native_window_set_buffers_format(window, 0);
+ native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
}
return EGL_NO_SURFACE;
}
@@ -443,8 +454,12 @@
EGLBoolean result = s->cnx->egl.eglDestroySurface(
dp->disp[s->impl].dpy, s->surface);
if (result == EGL_TRUE) {
- if (s->win != NULL) {
- native_window_set_buffers_geometry(s->win.get(), 0, 0, 0);
+ ANativeWindow* const window = s->win.get();
+ if (window != NULL) {
+ native_window_set_buffers_format(window, 0);
+ if (native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL)) {
+ LOGE("EGLNativeWindowType %p disconnected failed", window);
+ }
}
_s.terminate();
}
diff --git a/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml b/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
index 3668b8c..7dfa53e 100644
--- a/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
+++ b/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
@@ -18,10 +18,20 @@
*/
-->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="16dp" >
+
+ <ScrollView
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:layout_width="match_parent">
+ <LinearLayout
+ android:orientation="vertical"
android:layout_height="wrap_content"
- android:padding="16dp" >
+ android:layout_width="match_parent">
<TextView android:id="@+id/confirm_text"
android:layout_width="match_parent"
@@ -63,13 +73,21 @@
android:layout_marginLeft="30dp"
android:layout_below="@id/enc_password"
android:layout_marginBottom="30dp" />
+ </LinearLayout>
+ </ScrollView>
+
+ <LinearLayout android:orientation="horizontal"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_gravity="bottom">
<Button android:id="@+id/button_allow"
android:filterTouchesWhenObscured="true"
android:text="@string/allow_backup_button_label"
android:layout_below="@id/package_name"
android:layout_height="wrap_content"
- android:layout_width="wrap_content" />
+ android:layout_width="0dp"
+ android:layout_weight="1" />
<Button android:id="@+id/button_deny"
android:text="@string/deny_backup_button_label"
@@ -77,6 +95,9 @@
android:layout_toRightOf="@id/button_allow"
android:layout_alignTop="@id/button_allow"
android:layout_height="wrap_content"
- android:layout_width="wrap_content" />
+ android:layout_width="0dp"
+ android:layout_weight="1" />
-</RelativeLayout>
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml b/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
index 38fcc496..4927cbb 100644
--- a/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
+++ b/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
@@ -18,65 +18,86 @@
*/
-->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:padding="16dp" >
-
- <TextView android:id="@+id/confirm_text"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="30dp"
- android:text="@string/restore_confirm_text" />
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="16dp" >
- <TextView android:id="@+id/password_desc"
- android:layout_below="@id/confirm_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="10dp"
- android:text="@string/current_password_text" />
+ <ScrollView
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:layout_width="match_parent">
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent">
- <EditText android:id="@+id/password"
- android:layout_below="@id/password_desc"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="30dp"
- android:password="true" />
+ <TextView android:id="@+id/confirm_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="30dp"
+ android:text="@string/restore_confirm_text" />
- <TextView android:id="@+id/enc_password_desc"
- android:layout_below="@id/password"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="10dp"
- android:text="@string/restore_enc_password_text" />
+ <TextView android:id="@+id/password_desc"
+ android:layout_below="@id/confirm_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="10dp"
+ android:text="@string/current_password_text" />
- <EditText android:id="@+id/enc_password"
- android:layout_below="@id/enc_password_desc"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="30dp"
- android:password="true" />
+ <EditText android:id="@+id/password"
+ android:layout_below="@id/password_desc"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="30dp"
+ android:password="true" />
- <TextView android:id="@+id/package_name"
- android:layout_width="match_parent"
- android:layout_height="20dp"
- android:layout_marginLeft="30dp"
- android:layout_below="@id/enc_password"
- android:layout_marginBottom="30dp" />
+ <TextView android:id="@+id/enc_password_desc"
+ android:layout_below="@id/password"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="10dp"
+ android:text="@string/restore_enc_password_text" />
- <Button android:id="@+id/button_allow"
- android:filterTouchesWhenObscured="true"
- android:text="@string/allow_restore_button_label"
- android:layout_below="@id/package_name"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content" />
+ <EditText android:id="@+id/enc_password"
+ android:layout_below="@id/enc_password_desc"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="30dp"
+ android:password="true" />
- <Button android:id="@+id/button_deny"
- android:text="@string/deny_restore_button_label"
- android:layout_below="@id/package_name"
- android:layout_toRightOf="@id/button_allow"
- android:layout_alignTop="@id/button_allow"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content" />
+ <TextView android:id="@+id/package_name"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginLeft="30dp"
+ android:layout_below="@id/enc_password"
+ android:layout_marginBottom="10dp" />
+ </LinearLayout>
+ </ScrollView>
-</RelativeLayout>
+ <LinearLayout android:orientation="horizontal"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_gravity="bottom">
+
+ <Button android:id="@+id/button_allow"
+ android:filterTouchesWhenObscured="true"
+ android:text="@string/allow_restore_button_label"
+ android:layout_below="@id/package_name"
+ android:layout_height="wrap_content"
+ android:layout_width="0dp"
+ android:layout_weight="1" />
+
+ <Button android:id="@+id/button_deny"
+ android:text="@string/deny_restore_button_label"
+ android:layout_below="@id/package_name"
+ android:layout_toRightOf="@id/button_allow"
+ android:layout_alignTop="@id/button_allow"
+ android:layout_height="wrap_content"
+ android:layout_width="0dp"
+ android:layout_weight="1" />
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 626cc86..eae6112 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -38,8 +38,7 @@
import android.os.StatFs;
import android.app.IntentService;
import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.Pair;
+import android.util.Slog;
import java.io.File;
import java.io.FileInputStream;
@@ -47,11 +46,6 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
-import java.util.zip.ZipFile;
import android.os.FileUtils;
import android.provider.Settings;
@@ -120,29 +114,39 @@
public PackageInfoLite getMinimalPackageInfo(final Uri fileUri, int flags, long threshold) {
PackageInfoLite ret = new PackageInfoLite();
if (fileUri == null) {
- Log.i(TAG, "Invalid package uri " + fileUri);
+ Slog.i(TAG, "Invalid package uri " + fileUri);
ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_APK;
return ret;
}
String scheme = fileUri.getScheme();
if (scheme != null && !scheme.equals("file")) {
- Log.w(TAG, "Falling back to installing on internal storage only");
+ Slog.w(TAG, "Falling back to installing on internal storage only");
ret.recommendedInstallLocation = PackageHelper.RECOMMEND_INSTALL_INTERNAL;
return ret;
}
String archiveFilePath = fileUri.getPath();
DisplayMetrics metrics = new DisplayMetrics();
metrics.setToDefaults();
+
PackageParser.PackageLite pkg = PackageParser.parsePackageLite(archiveFilePath, 0);
if (pkg == null) {
- Log.w(TAG, "Failed to parse package");
- ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_APK;
+ Slog.w(TAG, "Failed to parse package");
+
+ final File apkFile = new File(archiveFilePath);
+ if (!apkFile.exists()) {
+ ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_URI;
+ } else {
+ ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_APK;
+ }
+
return ret;
}
ret.packageName = pkg.packageName;
ret.installLocation = pkg.installLocation;
+
ret.recommendedInstallLocation = recommendAppInstallLocation(pkg.installLocation,
archiveFilePath, flags, threshold);
+
return ret;
}
@@ -150,20 +154,28 @@
public boolean checkInternalFreeStorage(Uri packageUri, long threshold)
throws RemoteException {
final File apkFile = new File(packageUri.getPath());
- return isUnderInternalThreshold(apkFile, threshold);
+ try {
+ return isUnderInternalThreshold(apkFile, threshold);
+ } catch (FileNotFoundException e) {
+ return true;
+ }
}
@Override
public boolean checkExternalFreeStorage(Uri packageUri) throws RemoteException {
final File apkFile = new File(packageUri.getPath());
- return isUnderExternalThreshold(apkFile);
+ try {
+ return isUnderExternalThreshold(apkFile);
+ } catch (FileNotFoundException e) {
+ return true;
+ }
}
public ObbInfo getObbInfo(String filename) {
try {
return ObbScanner.getObbInfo(filename);
} catch (IOException e) {
- Log.d(TAG, "Couldn't get OBB info for " + filename);
+ Slog.d(TAG, "Couldn't get OBB info for " + filename);
return null;
}
}
@@ -221,7 +233,7 @@
// Make sure the sdcard is mounted.
String status = Environment.getExternalStorageState();
if (!status.equals(Environment.MEDIA_MOUNTED)) {
- Log.w(TAG, "Make sure sdcard is mounted.");
+ Slog.w(TAG, "Make sure sdcard is mounted.");
return null;
}
@@ -229,75 +241,81 @@
String codePath = packageURI.getPath();
File codeFile = new File(codePath);
- // Native files we need to copy to the container.
- List<Pair<ZipEntry, String>> nativeFiles = new ArrayList<Pair<ZipEntry, String>>();
-
// Calculate size of container needed to hold base APK.
- final int sizeMb = calculateContainerSize(codeFile, nativeFiles);
+ int sizeMb;
+ try {
+ sizeMb = calculateContainerSize(codeFile);
+ } catch (FileNotFoundException e) {
+ Slog.w(TAG, "File does not exist when trying to copy " + codeFile.getPath());
+ return null;
+ }
// Create new container
- String newCachePath = null;
+ final String newCachePath;
if ((newCachePath = PackageHelper.createSdDir(sizeMb, newCid, key, Process.myUid())) == null) {
- Log.e(TAG, "Failed to create container " + newCid);
- return null;
- }
- if (localLOGV)
- Log.i(TAG, "Created container for " + newCid + " at path : " + newCachePath);
- File resFile = new File(newCachePath, resFileName);
- if (!FileUtils.copyFile(new File(codePath), resFile)) {
- Log.e(TAG, "Failed to copy " + codePath + " to " + resFile);
- // Clean up container
- PackageHelper.destroySdDir(newCid);
+ Slog.e(TAG, "Failed to create container " + newCid);
return null;
}
- try {
- ZipFile zipFile = new ZipFile(codeFile);
+ if (localLOGV) {
+ Slog.i(TAG, "Created container for " + newCid + " at path : " + newCachePath);
+ }
- File sharedLibraryDir = new File(newCachePath, LIB_DIR_NAME);
- sharedLibraryDir.mkdir();
-
- final int N = nativeFiles.size();
- for (int i = 0; i < N; i++) {
- final Pair<ZipEntry, String> entry = nativeFiles.get(i);
-
- InputStream is = zipFile.getInputStream(entry.first);
- try {
- File destFile = new File(sharedLibraryDir, entry.second);
- if (!FileUtils.copyToFile(is, destFile)) {
- throw new IOException("Couldn't copy native binary "
- + entry.first.getName() + " to " + entry.second);
- }
- } finally {
- is.close();
- }
+ final File resFile = new File(newCachePath, resFileName);
+ if (FileUtils.copyFile(new File(codePath), resFile)) {
+ if (localLOGV) {
+ Slog.i(TAG, "Copied " + codePath + " to " + resFile);
}
- } catch (IOException e) {
- Log.e(TAG, "Couldn't copy native file to container", e);
+ } else {
+ Slog.e(TAG, "Failed to copy " + codePath + " to " + resFile);
+ // Clean up container
PackageHelper.destroySdDir(newCid);
return null;
}
- if (localLOGV) Log.i(TAG, "Copied " + codePath + " to " + resFile);
+ final File sharedLibraryDir = new File(newCachePath, LIB_DIR_NAME);
+ if (sharedLibraryDir.mkdir()) {
+ int ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(codeFile, sharedLibraryDir);
+ if (ret != PackageManager.INSTALL_SUCCEEDED) {
+ Slog.e(TAG, "Could not copy native libraries to " + sharedLibraryDir.getPath());
+ PackageHelper.destroySdDir(newCid);
+ return null;
+ }
+ } else {
+ Slog.e(TAG, "Could not create native lib directory: " + sharedLibraryDir.getPath());
+ PackageHelper.destroySdDir(newCid);
+ return null;
+ }
+
if (!PackageHelper.finalizeSdDir(newCid)) {
- Log.e(TAG, "Failed to finalize " + newCid + " at path " + newCachePath);
+ Slog.e(TAG, "Failed to finalize " + newCid + " at path " + newCachePath);
// Clean up container
PackageHelper.destroySdDir(newCid);
+ return null;
}
- if (localLOGV) Log.i(TAG, "Finalized container " + newCid);
+
+ if (localLOGV) {
+ Slog.i(TAG, "Finalized container " + newCid);
+ }
+
if (PackageHelper.isContainerMounted(newCid)) {
- if (localLOGV) Log.i(TAG, "Unmounting " + newCid +
- " at path " + newCachePath);
+ if (localLOGV) {
+ Slog.i(TAG, "Unmounting " + newCid + " at path " + newCachePath);
+ }
+
// Force a gc to avoid being killed.
Runtime.getRuntime().gc();
PackageHelper.unMountSdDir(newCid);
} else {
- if (localLOGV) Log.i(TAG, "Container " + newCid + " not mounted");
+ if (localLOGV) {
+ Slog.i(TAG, "Container " + newCid + " not mounted");
+ }
}
+
return newCachePath;
}
- public static boolean copyToFile(InputStream inputStream, FileOutputStream out) {
+ private static boolean copyToFile(InputStream inputStream, FileOutputStream out) {
try {
byte[] buffer = new byte[4096];
int bytesRead;
@@ -306,12 +324,12 @@
}
return true;
} catch (IOException e) {
- Log.i(TAG, "Exception : " + e + " when copying file");
+ Slog.i(TAG, "Exception : " + e + " when copying file");
return false;
}
}
- public static boolean copyToFile(File srcFile, FileOutputStream out) {
+ private static boolean copyToFile(File srcFile, FileOutputStream out) {
InputStream inputStream = null;
try {
inputStream = new FileInputStream(srcFile);
@@ -323,7 +341,7 @@
}
}
- private boolean copyFile(Uri pPackageURI, FileOutputStream outStream) {
+ private boolean copyFile(Uri pPackageURI, FileOutputStream outStream) {
String scheme = pPackageURI.getScheme();
if (scheme == null || scheme.equals("file")) {
final File srcPackageFile = new File(pPackageURI.getPath());
@@ -331,7 +349,7 @@
// destination file in order to eliminate a window where the package directory
// scanner notices the new package file but it's not completely copied yet.
if (!copyToFile(srcPackageFile, outStream)) {
- Log.e(TAG, "Couldn't copy file: " + srcPackageFile);
+ Slog.e(TAG, "Couldn't copy file: " + srcPackageFile);
return false;
}
} else if (scheme.equals("content")) {
@@ -339,28 +357,31 @@
try {
fd = getContentResolver().openFileDescriptor(pPackageURI, "r");
} catch (FileNotFoundException e) {
- Log.e(TAG, "Couldn't open file descriptor from download service. Failed with exception " + e);
+ Slog.e(TAG,
+ "Couldn't open file descriptor from download service. Failed with exception "
+ + e);
return false;
}
if (fd == null) {
- Log.e(TAG, "Couldn't open file descriptor from download service (null).");
+ Slog.e(TAG, "Couldn't open file descriptor from download service (null).");
return false;
} else {
if (localLOGV) {
- Log.v(TAG, "Opened file descriptor from download service.");
+ Slog.i(TAG, "Opened file descriptor from download service.");
}
ParcelFileDescriptor.AutoCloseInputStream
dlStream = new ParcelFileDescriptor.AutoCloseInputStream(fd);
// We copy the source package file to a temp file and then rename it to the
// destination file in order to eliminate a window where the package directory
- // scanner notices the new package file but it's not completely copied yet.
+ // scanner notices the new package file but it's not completely
+ // cop
if (!copyToFile(dlStream, outStream)) {
- Log.e(TAG, "Couldn't copy " + pPackageURI + " to temp file.");
+ Slog.e(TAG, "Couldn't copy " + pPackageURI + " to temp file.");
return false;
}
}
} else {
- Log.e(TAG, "Package URI is not 'file:' or 'content:' - " + pPackageURI);
+ Slog.e(TAG, "Package URI is not 'file:' or 'content:' - " + pPackageURI);
return false;
}
return true;
@@ -434,12 +455,20 @@
boolean fitsOnInternal = false;
if (checkBoth || prefer == PREFER_INTERNAL) {
- fitsOnInternal = isUnderInternalThreshold(apkFile, threshold);
+ try {
+ fitsOnInternal = isUnderInternalThreshold(apkFile, threshold);
+ } catch (FileNotFoundException e) {
+ return PackageHelper.RECOMMEND_FAILED_INVALID_URI;
+ }
}
boolean fitsOnSd = false;
if (!emulated && (checkBoth || prefer == PREFER_EXTERNAL)) {
- fitsOnSd = isUnderExternalThreshold(apkFile);
+ try {
+ fitsOnSd = isUnderExternalThreshold(apkFile);
+ } catch (FileNotFoundException e) {
+ return PackageHelper.RECOMMEND_FAILED_INVALID_URI;
+ }
}
if (prefer == PREFER_INTERNAL) {
@@ -473,8 +502,20 @@
}
}
- private boolean isUnderInternalThreshold(File apkFile, long threshold) {
+ /**
+ * Measure a file to see if it fits within the free space threshold.
+ *
+ * @param apkFile file to check
+ * @param threshold byte threshold to compare against
+ * @return true if file fits under threshold
+ * @throws FileNotFoundException when APK does not exist
+ */
+ private boolean isUnderInternalThreshold(File apkFile, long threshold)
+ throws FileNotFoundException {
final long size = apkFile.length();
+ if (size == 0 && !apkFile.exists()) {
+ throw new FileNotFoundException();
+ }
final StatFs internalStats = new StatFs(Environment.getDataDirectory().getPath());
final long availInternalSize = (long) internalStats.getAvailableBlocks()
@@ -484,12 +525,19 @@
}
- private boolean isUnderExternalThreshold(File apkFile) {
+ /**
+ * Measure a file to see if it fits in the external free space.
+ *
+ * @param apkFile file to check
+ * @return true if file fits
+ * @throws IOException when file does not exist
+ */
+ private boolean isUnderExternalThreshold(File apkFile) throws FileNotFoundException {
if (Environment.isExternalStorageEmulated()) {
return false;
}
- final int sizeMb = calculateContainerSize(apkFile, null);
+ final int sizeMb = calculateContainerSize(apkFile);
final int availSdMb;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
@@ -508,10 +556,14 @@
*
* @param apkFile file from which to calculate size
* @return size in megabytes (2^20 bytes)
+ * @throws FileNotFoundException when file does not exist
*/
- private int calculateContainerSize(File apkFile, List<Pair<ZipEntry, String>> outFiles) {
+ private int calculateContainerSize(File apkFile) throws FileNotFoundException {
// Calculate size of container needed to hold base APK.
long sizeBytes = apkFile.length();
+ if (sizeBytes == 0 && !apkFile.exists()) {
+ throw new FileNotFoundException();
+ }
// Check all the native files that need to be copied and add that to the
// container size.
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index c61da4e..12dbdf9 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -67,7 +67,7 @@
<string name="def_desk_undock_sound" translatable="false">/system/media/audio/ui/Undock.ogg</string>
<string name="def_car_dock_sound" translatable="false">/system/media/audio/ui/Dock.ogg</string>
<string name="def_car_undock_sound" translatable="false">/system/media/audio/ui/Undock.ogg</string>
- <integer name="def_lockscreen_sounds_enabled">0</integer>
+ <integer name="def_lockscreen_sounds_enabled">1</integer>
<string name="def_lock_sound" translatable="false">/system/media/audio/ui/Lock.ogg</string>
<string name="def_unlock_sound" translatable="false">/system/media/audio/ui/Unlock.ogg</string>
@@ -129,4 +129,8 @@
<!-- Default for Settings.System.POINTER_SPEED -->
<integer name="def_pointer_speed">0</integer>
+ <!-- Default for DTMF tones enabled -->
+ <bool name="def_dtmf_tones_enabled">true</bool>
+ <!-- Default for UI touch sounds enabled -->
+ <bool name="def_sound_effects_enabled">true</bool>
</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 7fecc9c..f4890e0 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -63,7 +63,7 @@
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
// is properly propagated through your change. Not doing so will result in a loss of user
// settings.
- private static final int DATABASE_VERSION = 68;
+ private static final int DATABASE_VERSION = 69;
private Context mContext;
@@ -862,34 +862,29 @@
}
if (upgradeVersion == 66) {
- // This upgrade makes sure that MODE_RINGER_STREAMS_AFFECTED and
- // NOTIFICATIONS_USE_RING_VOLUME settings are set according to device voice capability
- db.beginTransaction();
- try {
- int ringerModeAffectedStreams = (1 << AudioManager.STREAM_RING) |
- (1 << AudioManager.STREAM_NOTIFICATION) |
- (1 << AudioManager.STREAM_SYSTEM) |
- (1 << AudioManager.STREAM_SYSTEM_ENFORCED);
- if (!mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_voice_capable)) {
- ringerModeAffectedStreams |= (1 << AudioManager.STREAM_MUSIC);
-
- db.execSQL("DELETE FROM system WHERE name='"
- + Settings.System.NOTIFICATIONS_USE_RING_VOLUME + "'");
- db.execSQL("INSERT INTO system ('name', 'value') values ('"
- + Settings.System.NOTIFICATIONS_USE_RING_VOLUME + "', '1')");
- }
- db.execSQL("DELETE FROM system WHERE name='"
- + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
- db.execSQL("INSERT INTO system ('name', 'value') values ('"
- + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
- + String.valueOf(ringerModeAffectedStreams) + "')");
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
- upgradeVersion = 67;
- }
+ // This upgrade makes sure that MODE_RINGER_STREAMS_AFFECTED is set
+ // according to device voice capability
+ db.beginTransaction();
+ try {
+ int ringerModeAffectedStreams = (1 << AudioManager.STREAM_RING) |
+ (1 << AudioManager.STREAM_NOTIFICATION) |
+ (1 << AudioManager.STREAM_SYSTEM) |
+ (1 << AudioManager.STREAM_SYSTEM_ENFORCED);
+ if (!mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_voice_capable)) {
+ ringerModeAffectedStreams |= (1 << AudioManager.STREAM_MUSIC);
+ }
+ db.execSQL("DELETE FROM system WHERE name='"
+ + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
+ db.execSQL("INSERT INTO system ('name', 'value') values ('"
+ + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
+ + String.valueOf(ringerModeAffectedStreams) + "')");
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+ upgradeVersion = 67;
+ }
if (upgradeVersion == 67) {
// New setting to enable touch exploration.
@@ -909,6 +904,18 @@
upgradeVersion = 68;
}
+ if (upgradeVersion == 68) {
+ // Enable all system sounds by default
+ db.beginTransaction();
+ try {
+ db.execSQL("DELETE FROM system WHERE name='"
+ + Settings.System.NOTIFICATIONS_USE_RING_VOLUME + "'");
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+ upgradeVersion = 69;
+ }
// *** Remember to update DATABASE_VERSION above!
@@ -1284,21 +1291,12 @@
loadSetting(stmt, Settings.Secure.SET_INSTALL_LOCATION, 0);
loadSetting(stmt, Settings.Secure.DEFAULT_INSTALL_LOCATION,
PackageHelper.APP_INSTALL_AUTO);
-
+
loadUISoundEffectsSettings(stmt);
-
+
loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
R.bool.def_vibrate_in_silent);
- // Set notification volume to follow ringer volume by default
- if (mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_voice_capable)) {
- loadBooleanSetting(stmt, Settings.System.NOTIFICATIONS_USE_RING_VOLUME,
- R.bool.def_notifications_use_ring_volume);
- } else {
- loadSetting(stmt, Settings.System.NOTIFICATIONS_USE_RING_VOLUME, "1");
- }
-
loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,
R.integer.def_pointer_speed);
@@ -1312,6 +1310,12 @@
R.integer.def_power_sounds_enabled);
loadStringSetting(stmt, Settings.System.LOW_BATTERY_SOUND,
R.string.def_low_battery_sound);
+ loadBooleanSetting(stmt, Settings.System.DTMF_TONE_WHEN_DIALING,
+ R.bool.def_dtmf_tones_enabled);
+ loadBooleanSetting(stmt, Settings.System.SOUND_EFFECTS_ENABLED,
+ R.bool.def_sound_effects_enabled);
+ loadBooleanSetting(stmt, Settings.System.HAPTIC_FEEDBACK_ENABLED,
+ R.bool.def_haptic_feedback);
loadIntegerSetting(stmt, Settings.System.DOCK_SOUNDS_ENABLED,
R.integer.def_dock_sounds_enabled);
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
index 2c13069..c23a8a1 100644
--- a/packages/SystemUI/Android.mk
+++ b/packages/SystemUI/Android.mk
@@ -3,7 +3,7 @@
LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := $(call all-subdir-java-files) \
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
../../../ex/carousel/java/com/android/ex/carousel/carousel.rs
LOCAL_JAVA_LIBRARIES := services
@@ -16,3 +16,5 @@
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index cf0bdd3..2080fad 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -34,6 +34,10 @@
<service android:name=".LoadAverageService"
android:exported="true" />
+ <service android:name=".ImageWallpaper"
+ android:permission="android.permission.BIND_WALLPAPER"
+ android:exported="true" />
+
<receiver android:name=".BootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
diff --git a/core/res/res/anim/priority_alert_enter.xml b/packages/SystemUI/res/anim/priority_alert_enter.xml
similarity index 100%
rename from core/res/res/anim/priority_alert_enter.xml
rename to packages/SystemUI/res/anim/priority_alert_enter.xml
diff --git a/core/res/res/anim/priority_alert_exit.xml b/packages/SystemUI/res/anim/priority_alert_exit.xml
similarity index 100%
rename from core/res/res/anim/priority_alert_exit.xml
rename to packages/SystemUI/res/anim/priority_alert_exit.xml
diff --git a/core/res/res/anim/status_bar_enter.xml b/packages/SystemUI/res/anim/status_bar_enter.xml
similarity index 87%
rename from core/res/res/anim/status_bar_enter.xml
rename to packages/SystemUI/res/anim/status_bar_enter.xml
index 1a1dc9b..f1c1301 100644
--- a/core/res/res/anim/status_bar_enter.xml
+++ b/packages/SystemUI/res/anim/status_bar_enter.xml
@@ -18,7 +18,8 @@
*/
-->
-<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@interpolator/decelerate_quad">
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/decelerate_quad">
<translate android:fromYDelta="-75%" android:toYDelta="0"
android:duration="@android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
diff --git a/core/res/res/anim/status_bar_exit.xml b/packages/SystemUI/res/anim/status_bar_exit.xml
similarity index 88%
rename from core/res/res/anim/status_bar_exit.xml
rename to packages/SystemUI/res/anim/status_bar_exit.xml
index 1f71090..46462e2 100644
--- a/core/res/res/anim/status_bar_exit.xml
+++ b/packages/SystemUI/res/anim/status_bar_exit.xml
@@ -18,7 +18,8 @@
*/
-->
-<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@interpolator/accelerate_quad">
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/accelerate_quad">
<translate android:fromYDelta="0" android:toYDelta="-75%"
android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png
new file mode 100644
index 0000000..d17aae6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png
new file mode 100644
index 0000000..5a89d76
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/notify_panel_clock_bg_normal.9.png b/packages/SystemUI/res/drawable-hdpi/notify_panel_clock_bg_normal.9.png
deleted file mode 100644
index b7ad39c..0000000
--- a/packages/SystemUI/res/drawable-hdpi/notify_panel_clock_bg_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/notify_panel_clock_bg_pressed.9.png b/packages/SystemUI/res/drawable-hdpi/notify_panel_clock_bg_pressed.9.png
deleted file mode 100644
index c93bd8c..0000000
--- a/packages/SystemUI/res/drawable-hdpi/notify_panel_clock_bg_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/notify_panel_notify_bg.9.png b/packages/SystemUI/res/drawable-hdpi/notify_panel_notify_bg.9.png
deleted file mode 100644
index 1680887..0000000
--- a/packages/SystemUI/res/drawable-hdpi/notify_panel_notify_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_ticker_tile.png b/packages/SystemUI/res/drawable-hdpi/status_bar_ticker_tile.png
index 772f77d..3b826a9 100644
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_ticker_tile.png
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_ticker_tile.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_veto_normal.png b/packages/SystemUI/res/drawable-hdpi/status_bar_veto_normal.png
deleted file mode 100644
index 90b4baf..0000000
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_veto_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_veto_pressed.png b/packages/SystemUI/res/drawable-hdpi/status_bar_veto_pressed.png
deleted file mode 100644
index bc7034a..0000000
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_veto_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-hdpi/notify_panel_clock_bg_normal.9.png b/packages/SystemUI/res/drawable-large-hdpi/notify_panel_clock_bg_normal.9.png
new file mode 100644
index 0000000..002a663
--- /dev/null
+++ b/packages/SystemUI/res/drawable-large-hdpi/notify_panel_clock_bg_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-hdpi/notify_panel_clock_bg_pressed.9.png b/packages/SystemUI/res/drawable-large-hdpi/notify_panel_clock_bg_pressed.9.png
new file mode 100644
index 0000000..399d62e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-large-hdpi/notify_panel_clock_bg_pressed.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-hdpi/notify_panel_notify_bg.9.png b/packages/SystemUI/res/drawable-large-hdpi/notify_panel_notify_bg.9.png
new file mode 100644
index 0000000..7385ecc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-large-hdpi/notify_panel_notify_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-mdpi/notify_panel_clock_bg_normal.9.png b/packages/SystemUI/res/drawable-large-mdpi/notify_panel_clock_bg_normal.9.png
new file mode 100644
index 0000000..5a880e75
--- /dev/null
+++ b/packages/SystemUI/res/drawable-large-mdpi/notify_panel_clock_bg_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-mdpi/notify_panel_clock_bg_pressed.9.png b/packages/SystemUI/res/drawable-large-mdpi/notify_panel_clock_bg_pressed.9.png
new file mode 100644
index 0000000..489163d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-large-mdpi/notify_panel_clock_bg_pressed.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-mdpi/notify_panel_notify_bg.9.png b/packages/SystemUI/res/drawable-large-mdpi/notify_panel_notify_bg.9.png
new file mode 100644
index 0000000..78900a1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-large-mdpi/notify_panel_notify_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-xhdpi/notify_panel_clock_bg_normal.9.png b/packages/SystemUI/res/drawable-large-xhdpi/notify_panel_clock_bg_normal.9.png
new file mode 100644
index 0000000..37e7791
--- /dev/null
+++ b/packages/SystemUI/res/drawable-large-xhdpi/notify_panel_clock_bg_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-xhdpi/notify_panel_clock_bg_pressed.9.png b/packages/SystemUI/res/drawable-large-xhdpi/notify_panel_clock_bg_pressed.9.png
new file mode 100644
index 0000000..66fa4a8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-large-xhdpi/notify_panel_clock_bg_pressed.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-large-xhdpi/notify_panel_notify_bg.9.png b/packages/SystemUI/res/drawable-large-xhdpi/notify_panel_notify_bg.9.png
new file mode 100644
index 0000000..11e36ab
--- /dev/null
+++ b/packages/SystemUI/res/drawable-large-xhdpi/notify_panel_notify_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png
new file mode 100644
index 0000000..9490833
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png
new file mode 100644
index 0000000..0ff3efd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg_normal.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg_normal.9.png
deleted file mode 100644
index 2dcb659..0000000
--- a/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg_pressed.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg_pressed.9.png
deleted file mode 100644
index e7ed68b..0000000
--- a/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png
deleted file mode 100644
index e346167..0000000
--- a/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_ticker_tile.png b/packages/SystemUI/res/drawable-mdpi/status_bar_ticker_tile.png
index 0eb71d0..9999598 100644
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_ticker_tile.png
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_ticker_tile.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_veto_normal.png b/packages/SystemUI/res/drawable-mdpi/status_bar_veto_normal.png
deleted file mode 100644
index 90b4baf..0000000
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_veto_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_veto_pressed.png b/packages/SystemUI/res/drawable-mdpi/status_bar_veto_pressed.png
deleted file mode 100644
index bc7034a..0000000
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_veto_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png
new file mode 100644
index 0000000..6455423
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png
new file mode 100644
index 0000000..bfa8bb4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/status_bar_ticker_tile.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_ticker_tile.png
new file mode 100644
index 0000000..6585ad6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/status_bar_ticker_tile.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/status_bar_veto.xml b/packages/SystemUI/res/drawable/ic_notify_clear.xml
similarity index 75%
rename from packages/SystemUI/res/drawable/status_bar_veto.xml
rename to packages/SystemUI/res/drawable/ic_notify_clear.xml
index 6e1b681..9c432b2 100644
--- a/packages/SystemUI/res/drawable/status_bar_veto.xml
+++ b/packages/SystemUI/res/drawable/ic_notify_clear.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2011 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/status_bar_veto_pressed" />
- <item android:drawable="@drawable/status_bar_veto_normal" />
+ <item android:state_pressed="true"
+ android:drawable="@drawable/ic_notify_clear_pressed" />
+ <item android:drawable="@drawable/ic_notify_clear_normal" />
</selector>
-
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel.xml
index 72519fb..1641c70 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel.xml
@@ -22,21 +22,32 @@
android:layout_height="match_parent"
android:layout_width="match_parent"
android:gravity="right"
- android:background="@drawable/notify_panel_bg_protect_tiled"
>
+ <ImageView android:id="@+id/clear_all_button"
+ android:layout_width="wrap_content"
+ android:layout_height="@*android:dimen/status_bar_height"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentBottom="true"
+ android:layout_marginRight="20dp"
+ android:paddingLeft="15dp"
+ android:paddingRight="15dp"
+ android:src="@drawable/ic_notify_clear"
+ android:visibility="invisible"
+ />
+
<RelativeLayout
android:id="@+id/content_parent"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
- android:layout_marginBottom="-27dip"
+ android:layout_marginBottom="8dp"
>
<include layout="@layout/status_bar_notification_panel_title"
- android:layout_width="471dp"
- android:layout_height="465dp"
+ android:layout_width="478dp"
+ android:layout_height="224dp"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
/>
@@ -45,11 +56,11 @@
android:id="@+id/content_frame"
android:background="@drawable/notify_panel_notify_bg"
android:layout_height="wrap_content"
- android:layout_width="447dp"
+ android:layout_width="478dp"
android:orientation="vertical"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
- android:layout_marginTop="352dp"
+ android:layout_marginTop="178dp"
>
<ScrollView
android:id="@+id/notification_scroller"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 6670eff..0cfcae1 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -47,19 +47,13 @@
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="?android:attr/textColorSecondary"
/>
- <TextView android:id="@+id/clear_all_button"
+ <ImageView android:id="@+id/clear_all_button"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
android:layout_gravity="center_vertical"
- android:layout_marginTop="4dp"
- android:layout_marginBottom="1dp"
- android:textSize="14sp"
- android:textColor="#ff000000"
- android:text="@string/status_bar_clear_all_button"
- style="?android:attr/buttonStyle"
android:paddingLeft="15dp"
android:paddingRight="15dp"
- android:background="@drawable/btn_default_small"
+ android:src="@drawable/ic_notify_clear"
/>
</LinearLayout>
@@ -91,29 +85,6 @@
android:text="@string/status_bar_no_notifications_title"
/>
- <TextView android:id="@+id/ongoingTitle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/title_bar_portrait"
- android:paddingLeft="5dp"
- android:textAppearance="@style/TextAppearance.StatusBar.Title"
- android:text="@string/status_bar_ongoing_events_title"
- />
- <com.android.systemui.statusbar.policy.NotificationRowLayout
- android:id="@+id/ongoingItems"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- systemui:rowHeight="@dimen/notification_height"
- />
-
- <TextView android:id="@+id/latestTitle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/title_bar_portrait"
- android:paddingLeft="5dp"
- android:textAppearance="@style/TextAppearance.StatusBar.Title"
- android:text="@string/status_bar_latest_events_title"
- />
<com.android.systemui.statusbar.policy.NotificationRowLayout
android:id="@+id/latestItems"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index aff6a6e..ca584ab 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -3,15 +3,13 @@
android:layout_height="@dimen/notification_height"
>
- <ImageButton
+ <Button
android:id="@+id/veto"
android:layout_width="48dp"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_marginRight="-80dp"
- android:src="@drawable/status_bar_veto"
- android:scaleType="center"
android:background="@null"
android:paddingRight="8dp"
android:paddingLeft="8dp"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 116d6a0..9fbce5f 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -83,7 +83,7 @@
<skip />
<!-- no translation found for screenshot_saving_toast (8592630119048713208) -->
<skip />
- <!-- no translation found for screenshot_failed_toast (655180965533683356) -->
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
<skip />
<!-- no translation found for usb_preference_title (6551050377388882787) -->
<skip />
@@ -99,6 +99,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -187,4 +189,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 740fb2a..46e57e2 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -83,7 +83,7 @@
<skip />
<!-- no translation found for screenshot_saving_toast (8592630119048713208) -->
<skip />
- <!-- no translation found for screenshot_failed_toast (655180965533683356) -->
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
<skip />
<!-- no translation found for usb_preference_title (6551050377388882787) -->
<skip />
@@ -99,6 +99,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -187,4 +189,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ar-large/strings.xml b/packages/SystemUI/res/values-ar-large/strings.xml
index 3f3ac96..e706028 100644
--- a/packages/SystemUI/res/values-ar-large/strings.xml
+++ b/packages/SystemUI/res/values-ar-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"محو الكل"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"لا يوجد اتصال بالإنترنت"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi متصل"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"جارٍ البحث عن GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"تم تعيين الموقع بواسطة GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"إيقاف التنبيهات"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"انقر هنا لإعادة تشغيل التنبيهات."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 5b1d492..9451ca6 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"محو"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"عدم الإزعاج"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"إظهار التنبيهات"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"إزالة"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"فحص"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"ليس هناك أي تنبيهات"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"مستمر"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"التنبيهات"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"تكبير/تصغير التوافق"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"عند تصميم تطبيق لشاشة أصغر، سيظهر عنصر تحكم في التكبير/التصغير بجوار الساعة."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"تم حفظ لقطة الشاشة إلى المعرض."</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"تعذر حفظ لقطة الشاشة."</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"خيارات نقل الملفات عبر USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"تحميل كمشغل وسائط (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"تحميل ككاميرا (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"تثبيت تطبيق Android File Transfer لـ Mac"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"رجوع"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"الصفحة الرئيسية"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"القائمة"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"زر تبديل طريقة الإدخال."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"زر تكبير/تصغير للتوافق."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"استخدام التكبير/التصغير لتحويل شاشة صغيرة إلى شاشة أكبر"</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"تم توصيل البلوتوث."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"تم فصل البلوتوث."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"ليست هناك بطارية مركبة."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"إشارة البطارية تتكون من شريط واحد."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"إشارة البطارية تتكون من شريطين."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"إشارة البطارية تتكون من ثلاثة أشرطة."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"إشارة البطارية كاملة."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"ليست هناك إشارة بالهاتف."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"إشارة الهاتف تتكون من شريط واحد."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"إشارة الهاتف تتكون من شريطين."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"إشارة الهاتف تتكون من ثلاثة أشرطة."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"إشارة الهاتف كاملة."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"لا تتوفر بيانات."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"إشارة البيانات تتكون من شريط واحد."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"إشارة البيانات تتكون من شريطين."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"إشارة البيانات تتكون من ثلاثة أشرطة."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"إشارة البيانات كاملة."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"ليست هناك إشارة WiFi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"إشارة WiFi تتكون من شريط واحد."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"إشارة WiFi تتكون من شريطين."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"إشارة WiFi تتكون من ثلاثة أشرطة."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"إشارة WiFi كاملة."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"ليست هناك بطاقة SIM."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ربط البلوتوث."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"وضع الطائرة."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"مستوى البطارية <xliff:g id="NUMBER">%d</xliff:g> في المائة."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"زر الإعدادات."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"زر التنبيهات."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"إزالة التنبيه."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"تم تمكين GPS."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"الحصول على GPS."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"تم تمكين المبرقة الكاتبة."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"رنين مع الاهتزاز."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"رنين صامت."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-bg-large/strings.xml b/packages/SystemUI/res/values-bg-large/strings.xml
index 5563be4..5af2f99 100644
--- a/packages/SystemUI/res/values-bg-large/strings.xml
+++ b/packages/SystemUI/res/values-bg-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Изчистване"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Няма връзка с интернет"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi: има връзка"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Търси се GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Местоположението е зададено от GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Известията са изключени"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Докоснете тук, за да включите отново известията."</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 4890c0d..6e23d5f 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Промяна на мащаба за съвместимост"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Когато дадено приложение е създадено за по-малък екран, до часовника ще се покаже управление за промяна на мащаба."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Екранната снимка е запазена в галерията"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Екранната снимка не можа да бъде запазена"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Опции за пренос на файлове чрез USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Свързване като медиен плейър (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Свързване като камера (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ca-large/strings.xml b/packages/SystemUI/res/values-ca-large/strings.xml
index 876dae2..d78e758 100644
--- a/packages/SystemUI/res/values-ca-large/strings.xml
+++ b/packages/SystemUI/res/values-ca-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Esborra-ho"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"No hi ha connexió a Internet"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi: connectada"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"S\'està cercant un GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"S\'ha establert la ubicació per GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Notificacions desactivades"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Pica aquí per tornar a activar les notificacions."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 417987c..3be5349 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom de compatibilitat"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Quan una aplicació s\'hagi dissenyat per a una pantalla més petita, apareixerà un control de zoom al costat del rellotge."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Captura de pantalla desada a la galeria"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"No es pot desar la captura de pantalla"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opcions transf. fitxers USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Munta com a reproductor multimèdia (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Munta com a càmera (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-cs-large/strings.xml b/packages/SystemUI/res/values-cs-large/strings.xml
index 0ec142e..ef575da 100644
--- a/packages/SystemUI/res/values-cs-large/strings.xml
+++ b/packages/SystemUI/res/values-cs-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Smazat vše"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Bez internetu"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi: připojeno"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Vyhledávání satelitů GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Poloha nastavena pomocí GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Oznámení jsou vypnuta"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Chcete-li oznámení znovu zapnout, klepněte sem."</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 7544876..115abd5 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Kompatibilní přiblížení"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Pokud je aplikace navržena pro menší obrazovku, zobrazí se vedle hodin ovládací prvek přiblížení."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Snímek obrazovky byl uložen do Galerie"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Snímek obrazovky se nepodařilo uložit"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Možnosti přenosu souborů pomocí rozhraní USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Připojit jako přehrávač médií (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Připojit jako fotoaparát (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-da-large/strings.xml b/packages/SystemUI/res/values-da-large/strings.xml
index 116751e..eb2bc94 100644
--- a/packages/SystemUI/res/values-da-large/strings.xml
+++ b/packages/SystemUI/res/values-da-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Ryd alt"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Ingen internetforb."</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi er forbundet"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Søger efter GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Placeringen er angivet ved hjælp af GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Meddelelser: fra"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Tryk her for at slå meddelelser til igen."</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 89c6b64..ea67460 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Ryd"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Forstyr ikke"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Vis meddelelser"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Fjern"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Inspicer"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ingen meddelelser"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"I gang"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Meddelelser"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Kompatibilitetszoom"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Når en app er udviklet til en mindre skærm, vises der en zoomfunktion ved uret."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Skærmbilledet gemmes i Galleri"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Skærmbilledet kunne ikke gemmes"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Muligheder for USB-filoverførsel"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Isæt som en medieafspiller (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Isæt som et kamera (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Installer appen Android File Transfer Manager til Mac"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Tilbage"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Startside"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Skift indtastningsmetode-knappen."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Knap for kompatibilitetszoom."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom mindre til større skærm."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth tilsluttet."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth afbrudt."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Intet batteri."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Batteri en bjælke."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Batteri to bjælker."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Batteri tre bjælker."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Batteri fuldt."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Ingen telefon."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Telefon en bjælke."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Telefon to bjælker."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Telefon tre bjælker."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Telefonsignal fuldt."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Ingen data."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Data en bjælke."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data to bjælker."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data tre bjælker."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Datasignal fuldt."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Ingen Wi-Fi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi en bjælke."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi to bjælker."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi tre bjælker."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi-signal fuldt."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Intet SIM-kort."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-netdeling."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Flytilstand."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteri <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Knappen Indstillinger."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Knappen Meddelelser."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Fjern meddelelse."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS aktiveret."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS samler data."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter aktiveret."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Ringervibration."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Ringeren er lydløs."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-de-large/strings.xml b/packages/SystemUI/res/values-de-large/strings.xml
index 5f8c1d8..68d80a6 100644
--- a/packages/SystemUI/res/values-de-large/strings.xml
+++ b/packages/SystemUI/res/values-de-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Löschen"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Keine Internetverbindung"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"WLAN verbunden"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"GPS wird gesucht..."</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Standort durch GPS festgelegt"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Benachrichtigungen aus"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Tippen Sie hier, um die Benachrichtigungen wieder zu aktivieren."</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index dc68c22..cc06c26 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Kompatibilitätszoom"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Wenn eine App für einen kleineren Bildschirm ausgelegt ist, wird ein Zoom-Steuerelement neben der Uhr angezeigt."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Screenshot in Galerie gespeichert"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Screenshot konnte nicht gespeichert werden."</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB-Dateiübertragungsoptionen"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Als Medienplayer (MTP) bereitstellen"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Als Kamera (PTP) bereitstellen"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-el-large/strings.xml b/packages/SystemUI/res/values-el-large/strings.xml
index a4f4ac2..57d4b1e 100644
--- a/packages/SystemUI/res/values-el-large/strings.xml
+++ b/packages/SystemUI/res/values-el-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Εκκαθ. όλων"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Χωρ. σύνδ. στο Διαδ."</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi συνδεδεμένο"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Αναζήτηση για GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Ρύθμιση τοποθεσίας με GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Ειδοποιήσεις ανενεργές"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Πατήστε εδώ για να ενεργοποιήσετε ξανά τις ειδοποιήσεις."</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 29d84cb..8609c24 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Εκκαθάριση"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Μην ενοχλείτε"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Εμφάνιση ειδοποιήσεων"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Κατάργηση"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Επιθεώρηση"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Δεν υπάρχουν ειδοποιήσεις"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Εν εξελίξει"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Ειδοποιήσεις"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Ζουμ για συμβατότητα"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Όταν μια εφαρμογή έχει σχεδιαστεί για προβολή σε μικρότερη οθόνη, δίπλα από το ρολόι θα εμφανιστεί ένα στοιχείο ελέγχου ζουμ."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Το στιγμιότυπο οθόνης αποθηκεύτηκε στη συλλογή"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Δεν ήταν δυνατή η αποθήκευση του στιγμιοτύπου οθόνης"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Επιλογές μεταφοράς αρχείων μέσω USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Προσάρτηση ως μονάδας αναπαραγωγής μέσων (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Προσάρτηση ως κάμερας (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Εγκατάσταση της εφαρμογής μεταφοράς αρχείων Android για Mac"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Πίσω"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Αρχική σελίδα"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Μενού"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Κουμπί εναλλαγής μεθόδου εισόδου"</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Κουμπί ζουμ συμβατότητας."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Ζουμ από μικρότερη σε μεγαλύτερη οθόνη."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Το Bluetooth είναι συνδεδεμένο."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Το Bluetooth αποσυνδέθηκε."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Δεν υπάρχει μπαταρία."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Μία γραμμή μπαταρίας."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Δύο γραμμές μπαταρίας."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Τρεις γραμμές μπαταρίας."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Πλήρης μπαταρία."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Δεν υπάρχει τηλέφωνο."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Μία γραμμή τηλεφώνου."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Δύο γραμμές τηλεφώνου."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Τρεις γραμμές μπαταρίας."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Σήμα τηλεφώνου πλήρες."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Δεν υπάρχουν δεδομένα."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Μία γραμμή δεδομένων."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Δύο γραμμές δεδομένων."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Τρεις γραμμές δεδομένων."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Πλήρες σήμα δεδομένων."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Δεν υπάρχει WiFi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Μία γραμμή WiFi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Δύο γραμμές WiFi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Τρεις γραμμές WiFi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Πλήρες σήμα WiFi."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Δεν υπάρχει SIM."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Σύνδεση Bluetooth"</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Λειτουργία πτήσης."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Μπαταρία <xliff:g id="NUMBER">%d</xliff:g> %."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Κουμπί ρυθμίσεων."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Κουμπί ειδοοποιήσεων"</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Κατάργηση ειδοποίησης."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"Το GPS ενεργοποιήθηκε."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Ανάκτηση GPS."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"Το TeleTypewriter ενεργοποιήθηκε."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Δόνηση ειδοποίησης ήχου"</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Ήχος ειδοποίησης: Αθόρυβο."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB-large/strings.xml b/packages/SystemUI/res/values-en-rGB-large/strings.xml
index aec6899..5f7df68 100644
--- a/packages/SystemUI/res/values-en-rGB-large/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Clear all"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"No Internet connection"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi connected"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Searching for GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Location set by GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Notifications off"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Tap here to turn notifications back on."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 2d8c737..8e8734a 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Clear"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Do not disturb"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Show notifications"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Remove"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Inspect"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No notifications"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Ongoing"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notifications"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Compatibility Zoom"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"When an app was designed for a smaller screen, a zoom control will appear by the clock."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Screenshot saved to Gallery"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Could not save screenshot"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Mount as a media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Mount as a camera (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Install Android File Transfer application for Mac"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Back"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Home"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Switch input method button."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Compatibility zoom button."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom smaller to larger screen."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth connected."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth disconnected."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"No battery."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Battery one bar."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Battery two bars."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Battery three bars."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Battery full."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"No phone."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Phone one bar."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Phone two bars."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Phone three bars."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Phone signal full."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"No data."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Data one bar."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data two bars."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data three bars."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Data signal full."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"No Wi-Fi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi one bar."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi two bars."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi three bars."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi signal full."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"No SIM."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth tethering"</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Airplane mode"</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Settings button."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Notifications button."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Remove notification."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS enabled."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS acquiring."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter enabled."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Ringer vibrate."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Ringer silent."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-es-large/strings.xml b/packages/SystemUI/res/values-es-large/strings.xml
index ba5d28a..31a82e5 100644
--- a/packages/SystemUI/res/values-es-large/strings.xml
+++ b/packages/SystemUI/res/values-es-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Borrar todo"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Sin conexión a Internet"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Con conexión Wi-Fi"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Buscando GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Ubicación definida por GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Notificaciones desactivadas"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Toca aquí para volver a activar las notificaciones."</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS-large/strings.xml b/packages/SystemUI/res/values-es-rUS-large/strings.xml
index 0969d1d..3f96e87 100644
--- a/packages/SystemUI/res/values-es-rUS-large/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Borrar todas"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Sin conexión a Internet"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi conectado"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Buscando GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"La ubicación se estableció por GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Notificaciones desactivadas"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Toca aquí para volver a activar las notificaciones."</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 7ce69b6..224eec8 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Borrar"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"No molestar"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Mostrar notificaciones"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Eliminar"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Inspeccionar"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No hay notificaciones"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Continuo"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificaciones"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom de compatibilidad"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Cuando una aplicación fue diseñada para una pantalla más pequeña, aparece un control de zoom junto al reloj."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Captura de pantalla guardada en la Galería"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"No se pudo guardar la captura de pantalla."</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opciones de transferencia de archivos por USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Activar como reproductor de medios (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Activar como cámara (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Instalar la aplicación para transferir archivos de Android para Mac"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Atrás"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Página principal"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Menú"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Botón Cambiar método de entrada"</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botón de zoom de compatibilidad"</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de pantalla más pequeña a más grande"</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth conectado"</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth desconectado"</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"No hay batería."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Una barra de batería"</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Dos barras de batería"</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Tres barras de batería"</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Batería completa"</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"No hay teléfono."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Una barra de teléfono"</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Dos barras de teléfono"</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Tres barras de teléfono"</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Señal de teléfono completa"</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"No hay datos."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Una barra de datos"</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Dos barras de datos"</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Tres barras de datos"</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Señal de datos completa"</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"No hay WiFi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Una barra de WiFi"</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Dos barras de WiFi"</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Tres barras de WiFi"</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Señal de WiFi completa"</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"No hay tarjeta SIM."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Anclaje a red Bluetooth."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo avión"</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Batería <xliff:g id="NUMBER">%d</xliff:g> por ciento"</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Botón de configuración"</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Botón de notificaciones"</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Eliminar notificación"</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS habilitado"</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Adquisición de GPS"</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter habilitado"</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Timbre vibrar"</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Timbre silencio"</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 1ee4fed..8149989 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom de compatibilidad"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Si la aplicación se ha diseñado para una pantalla más pequeña, aparecerá un control de zoom junto al reloj."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Captura de pantalla guardada en la galería"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"No se ha podido guardar la captura de pantalla."</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opciones de transferencia de archivos por USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Activar como reproductor de medios (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Activar como cámara (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fa-large/strings.xml b/packages/SystemUI/res/values-fa-large/strings.xml
index 25a54dc..3d01dde 100644
--- a/packages/SystemUI/res/values-fa-large/strings.xml
+++ b/packages/SystemUI/res/values-fa-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"پاک کردن همه موارد"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"اتصال اینترنتی وجود ندارد"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi متصل شد"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"جستجو برای GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"مکان تنظیم شده توسط GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"اعلان ها خاموش"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"برای روشن کردن مجدد اعلان ها، اینجا را ضربه بزنید."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index dbdcbb6..e9a3a82 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"بزرگنمایی سازگاری"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"اگر یک برنامه برای صفحه کوچک تری طراحی شده باشد، یک کنترل بزرگنمایی توسط ساعت نشان داده می شود."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"تصویر از صفحه در گالری ذخیره شد"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"ذخیره تصویر صفحه ممکن نیست"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"گزینه های انتقال فایل USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"نصب به عنوان دستگاه پخش رسانه (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"تصب به عنوان دوربین (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fi-large/strings.xml b/packages/SystemUI/res/values-fi-large/strings.xml
index 1f87ef5..20efe2c 100644
--- a/packages/SystemUI/res/values-fi-large/strings.xml
+++ b/packages/SystemUI/res/values-fi-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Tyhjennä kaikki"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Ei internetyhteyttä"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wifi yhdistetty"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Haetaan GPS-yhteyttä"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Sijainti määritetty GPS:n avulla"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Ilmoitukset pois käytöstä"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Ota ilmoitukset uudelleen käyttöön napauttamalla tätä."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index bef79a5..02c7986 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Tyhjennä"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Varattu"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Näytä ilmoitukset"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Poista"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Tarkasta"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ei ilmoituksia"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Käynnissä olevat"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Ilmoitukset"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Yhteensopivuustilan zoomaus"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Jos sovellus on suunniteltu pienemmälle näytölle, kellon viereen tulee näkyviin zoomaussäädin."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Kuvakaappaus on tallennettu galleriaan"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Kuvakaappausta ei voitu tallentaa"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB-tiedostonsiirtoasetukset"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Käytä mediasoittimena (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Käytä kamerana (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Asenna Android File Transfer -sovellus Macille"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Takaisin"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Aloitusruutu"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Valikko"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Vaihda syöttötapapainiketta."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Yhteensopivuus-zoomauspainike."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoomaa pienemmältä suuremmalle ruudulle."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth yhdistetty."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth-yhteys katkaistu."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Ei akkua."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Akun virta - yksi palkki."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Akun virta - kaksi palkkia."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Akun virta - kolme palkkia."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Akku täynnä."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Katvealueella."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Puhelinverkkosignaali - yksi palkki."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Puhelinverkkosignaali - kaksi palkkia."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Puhelinverkkosignaali - kolme palkkia."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Vahva puhelinverkkosignaali."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Ei tietoja."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Datasignaali - yksi palkki"</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Datasignaali - kaksi palkkia"</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Datasignaali - kolme palkkia"</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Vahva datasignaali."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Ei wifi-yhteyttä."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wifi-signaali - yksi palkki."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wifi-signaali - kaksi palkkia."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wifi-signaali - kolme palkkia."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Vahva wifi-signaali."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wifi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Ei SIM-korttia."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Internetyhteyden jakaminen Bluetoothin kautta"</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Lentokonetila"</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Akun virta <xliff:g id="NUMBER">%d</xliff:g> prosenttia."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Asetukset-painike."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Ilmoitukset-painike."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Poista ilmoitus."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS käytössä."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Haetaan GPS-signaalia."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter käytössä."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Soittoääni: värinä."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Soittoääni: äänetön."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr-large/strings.xml b/packages/SystemUI/res/values-fr-large/strings.xml
index f8dd55e..ee130df 100644
--- a/packages/SystemUI/res/values-fr-large/strings.xml
+++ b/packages/SystemUI/res/values-fr-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Tout effacer"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Aucune connexion"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Connecté au Wi-Fi"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Recherche de GPS en cours"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Position définie par GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Notifications désactivées"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Appuyez ici pour réactiver les notifications."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 9815664..3669340 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom de compatibilité"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Si une application a été conçue pour un écran plus petit, une commande de zoom s\'affiche à côté de l\'horloge."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Capture d\'écran enregistrée dans la galerie."</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Impossible d\'enregistrer la capture d\'écran."</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Options transfert fichiers USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Installer en tant que lecteur multimédia (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Installer en tant qu\'appareil photo (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hr-large/strings.xml b/packages/SystemUI/res/values-hr-large/strings.xml
index f3a59b2..5033dab 100644
--- a/packages/SystemUI/res/values-hr-large/strings.xml
+++ b/packages/SystemUI/res/values-hr-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Obriši sve"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Nema internetske veze"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi povezan"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Traženje GPS-a"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Lokaciju utvrdio GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Obavijesti isključene"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Dotaknite ovdje da biste ponovo uključili obavijesti."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 45d2edc..b5b033c 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Kompatibilni zum"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Kada je aplikacija dizajnirana za manji zaslon, kontrole zumiranja prikazuju se pored sata."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Snimak zaslona spremljen u Galeriju"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Ne mogu spremiti snimak zaslona"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prijenosa datoteka"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Učitaj kao media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Učitaj kao fotoaparat (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hu-large/strings.xml b/packages/SystemUI/res/values-hu-large/strings.xml
index 1d2fd66..d9493cf 100644
--- a/packages/SystemUI/res/values-hu-large/strings.xml
+++ b/packages/SystemUI/res/values-hu-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Össz.törl."</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Nincs internetkapcs."</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi csatlakozva"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"GPS keresése"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"A GPS beállította a helyet"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Értesítések kikapcsolva"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Itt érintse meg az értesítések bekapcsolásához."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 468b875..cae8707 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Törlés"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Ne zavarjanak"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Értesítések megjelenítése"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Eltávolítás"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Vizsgálat"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nincs értesítés"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Folyamatban van"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Értesítések"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Kompatibilitás -- nagyítás/kicsinyítés"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Ha egy alkalmazást kisebb képernyőre terveztek, akkor a nagyítás/kicsinyítés vezérlője az óra mellett jelenik meg."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Képernyőkép mentve a galériába"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Nem sikerült menteni a képernyőképet"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB-fájlátvitel beállításai"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Csatlakoztatás médialejátszóként (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Csatlakoztatás kameraként (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Android fájlátviteli alkalmazás telepítése Machez"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Vissza"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Főoldal"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Menü"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Beviteli mód váltása gomb."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Kompatibilitási zoom gomb."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Kicsinyítsen a nagyobb képernyőhöz."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth csatlakoztatva."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth leválasztva."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Nincs akkumulátor."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Akkumulátor egy sáv."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Akkumulátor két sáv."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Akkumulátor három sáv."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Akkumulátor feltöltve."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Nincs telefon."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Telefon egy sáv."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Telefon két sáv."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Telefon három sáv."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Telefonjel megtelt."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Nincsenek adatok."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Adat egy sáv."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Adatok két sáv."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Adatok három sáv."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Adatjel megtelt."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Nincs Wi-Fi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi egy sáv."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi két sáv."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi három sáv."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi jel megtelt."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Nincs SIM."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth megosztása."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Repülőgép üzemmód."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Akkumulátor <xliff:g id="NUMBER">%d</xliff:g> százalék."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Beállítások gomb."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Értesítések gomb."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Értesítés eltávolítása."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS engedélyezve."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS lekérése."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"Távgépíró engedélyezve."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Csengő rezeg."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Csengő néma."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-in-large/strings.xml b/packages/SystemUI/res/values-in-large/strings.xml
index ac58c58..e09a646 100644
--- a/packages/SystemUI/res/values-in-large/strings.xml
+++ b/packages/SystemUI/res/values-in-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Hapus semua"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Tidak ada sambungan internet"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi tersambung"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Menelusuri GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Lokasi yang disetel oleh GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Pemberitahuan mati"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Ketuk di sini untuk menghidupkan pemberitahuan lagi."</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 9da6e73..957c7e9 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Bersihkan"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Jangan ganggu"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Tampilkan pemberitahuan"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Hapus"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Memeriksa"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Tidak ada pemberitahuan"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Berkelanjutan"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Pemberitahuan"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom Kompatibilitas"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Saat apl dirancang untuk layar yang lebih kecil, kontrol zoom akan tampil di dekat jam."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Tangkapan layar disimpan ke Galeri"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Tidak dapat menyimpan tangkapan layar"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opsi transfer berkas USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Pasang sebagai pemutar media (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Pasang sebagai kamera (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Pasang aplikasi Transfer Berkas Android untuk Mac"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Kembali"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Beranda"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Tombol beralih metode masukan."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Tombol perbesar/perkecil kompatibilitas."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Perkecil untuk layar yang lebih besar."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth tersambung."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth terputus."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Tidak ada baterai."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Baterai satu batang."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Baterai dua batang."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Baterai tiga batang."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Baterai penuh."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Tidak dapat melakukan panggilan."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Ponsel satu batang."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Ponsel dua batang."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Ponsel tiga batang."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Sinyal ponsel penuh."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Tidak ada data yang diterima."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Data satu batang."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data dua batang."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data tiga batang."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Sinyal data penuh."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Tidak ada WiFi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wifi satu batang."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"WiFi dua batang."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi tiga batang."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Sinyal WiFi penuh."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Tidak ada SIM."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Penambatan bluetooth."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode pesawat."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterai <xliff:g id="NUMBER">%d</xliff:g> persen."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Tombol setelan."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Tombol pemberitahuan."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Hapus pemberitahuan."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS diaktifkan."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Memperoleh GPS."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter diaktifkan."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Pendering bergetar."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Pendering senyap."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-it-large/strings.xml b/packages/SystemUI/res/values-it-large/strings.xml
index 18ccd07..7a2a9bc 100644
--- a/packages/SystemUI/res/values-it-large/strings.xml
+++ b/packages/SystemUI/res/values-it-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Cancella"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Nessuna connessione"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi connesso"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Ricerca del GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Posizione stabilita dal GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Notifiche disattivate"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Tocca qui per riattivare le notifiche."</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 476f190..1a5404e 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Cancella"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Non disturbare"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Mostra notifiche"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Rimuovi"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Esamina"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nessuna notifica"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"In corso"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notifiche"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom compatibilità"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Se un\'applicazione è stata progettata per uno schermo più piccolo, accanto all\'orologio viene visualizzato un controllo dello zoom."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Screenshot salvato nella galleria"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Impossibile salvare lo screenshot"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opzioni trasferimento file USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Monta come lettore multimediale (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Monta come videocamera (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Installa l\'applicazione Android File Transfer per Mac"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Indietro"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Home"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Pulsante per cambiare metodo di immissione."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Pulsante zoom compatibilità."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom inferiore per schermo più grande."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth collegato."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth scollegato."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Nessuna batteria."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Batteria: una barra."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Batteria: due barre."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Batteria: tre barre."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Batteria carica."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Nessun telefono."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Telefono: una barra."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Telefono: due barre."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Telefono: tre barre."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Massimo segnale telefonico."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Nessun dato presente."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Dati: una barra."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Dati: due barre."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Dati: tre barre."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Massimo segnale dati."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Nessun segnale Wi-Fi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi: una barra."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi: due barre."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi: tre barre."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Massimo segnale Wi-Fi."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Nessuna SIM presente."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Tethering Bluetooth."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Modalità aereo."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteria: <xliff:g id="NUMBER">%d</xliff:g>%."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Pulsante Impostazioni."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Pulsante per le notifiche."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Rimuovi la notifica."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS abilitato."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Acquisizione GPS."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"Telescrivente abilitata."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Suoneria vibrazione."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Suoneria silenziosa."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-iw-large/strings.xml b/packages/SystemUI/res/values-iw-large/strings.xml
index 4aba093..0c288c3 100644
--- a/packages/SystemUI/res/values-iw-large/strings.xml
+++ b/packages/SystemUI/res/values-iw-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"נקה הכל"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"אין חיבור לאינטרנט"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi מחובר"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"מחפש GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"מיקום מוגדר על ידי GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"מצב התראות כבוי"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"הקש כאן כדי להפעיל מחדש את ההתראות."</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 4552f23..92293abb 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"שינוי מרחק מתצוגה לתאימות"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"כאשר יישום מיועד למסך קטן יותר, פקד של מרחק מתצוגה יופיע ליד השעון."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"צילום המסך נשמר בגלריה"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"לא ניתן לשמור את צילום המסך"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"אפשרויות העברת קבצים ב-USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"טען כנגן מדיה (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"טען כמצלמה (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ja-large/strings.xml b/packages/SystemUI/res/values-ja-large/strings.xml
index 087320e..f38b84c 100644
--- a/packages/SystemUI/res/values-ja-large/strings.xml
+++ b/packages/SystemUI/res/values-ja-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"すべて消去"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"インターネット未接続"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi接続済み"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"GPSで検索中"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"GPSにより現在地が設定されました"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"通知OFF"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"通知を再度ONにするにはここをタップします。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index abee692..1446099 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"通知を消去"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"通知を非表示"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"通知を表示"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"削除"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"検査"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"通知なし"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"実行中"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"通知"</string>
@@ -62,103 +60,83 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"互換ズーム"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"より小型の画面向けのアプリの場合は、ズームコントロールが時計のそばに表示されます。"</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"スクリーンショットがギャラリーに保存されました"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"スクリーンショットを保存できませんでした"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USBファイル転送オプション"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"メディアプレーヤー(MTP)としてマウント"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"カメラ(PTP)としてマウント"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Mac版Android File Transferアプリのインストール"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"戻る"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"ホーム"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"メニュー"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"入力方法の切り替えボタン。"</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"互換ズームボタン。"</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"小さい画面から大きい画面にズームします。"</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetoothに接続済みです。"</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetoothが切断されました。"</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"電池: なし"</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"電池: レベル1"</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"電池: レベル2"</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"電池: レベル3"</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"電池: フル"</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"電波状態: なし"</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"電波状態: レベル1"</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"電波状態: レベル2"</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"電波状態: レベル3"</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"電波状態: フル"</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"データ信号: なし"</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"データ信号: レベル1"</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"データ信号: レベル2"</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"データ信号: レベル3"</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"データ信号: フル"</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Wi-Fi信号: なし"</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi信号: レベル1"</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi信号: レベル2"</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi信号: レベル3"</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi信号: フル"</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"EDGE"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"SIMがありません。"</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetoothテザリング。"</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"機内モード。"</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"電池: <xliff:g id="NUMBER">%d</xliff:g>パーセント"</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"設定ボタン。"</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"通知ボタン。"</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"通知を削除します。"</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPSが有効です。"</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS取得中です。"</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"テレタイプライターが有効です。"</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"バイブレーション着信。"</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"マナーモード着信。"</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
- <skip />
+
+ <!-- in Japanese the day of week should follow the date -->
+ <string name="status_bar_date_formatter">%2$s\n%1$s</string>
+
</resources>
diff --git a/packages/SystemUI/res/values-ko-large/strings.xml b/packages/SystemUI/res/values-ko-large/strings.xml
index 97c4467..fb5efd7 100644
--- a/packages/SystemUI/res/values-ko-large/strings.xml
+++ b/packages/SystemUI/res/values-ko-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"모두 지우기"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"인터넷에 연결되지 않음"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi 연결됨"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"GPS 검색 중"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"GPS에서 위치 설정"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"알림 사용 안함"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"알림을 다시 사용하려면 여기를 터치하세요."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index c34f0e4..8abc288 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"지우기"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"응답 거부"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"알림 표시"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"삭제"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"조사"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"알림 없음"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"진행 중"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"알림"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"호환성 확대/축소"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"앱이 작은 화면에 맞도록 설계된 경우 시계 옆에 확대/축소 컨트롤이 표시됩니다."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"캡쳐화면이 갤러리에 저장되었습니다."</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"캡쳐화면을 저장하지 못했습니다."</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB 파일 전송 옵션"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"미디어 플레이어로 마운트(MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"카메라로 마운트(PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Mac용 Android 파일 전송 애플리케이션 설치"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"뒤로"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"홈"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"메뉴"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"입력 방법 버튼을 전환합니다."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"호환성 확대/축소 버튼"</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"작은 화면을 큰 화면으로 확대합니다."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"블루투스가 연결되었습니다."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"블루투스 연결이 끊어졌습니다."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"배터리 없음"</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"배터리 막대가 하나입니다."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"배터리 막대가 두 개입니다."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"배터리 막대가 세 개입니다."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"배터리 충전이 완료되었습니다."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"휴대전화 없음"</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"휴대전화 신호 막대가 하나입니다."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"휴대전화 신호 막대가 두 개입니다."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"휴대전화 신호 막대가 세 개입니다."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"휴대전화의 신호가 강합니다."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"데이터가 없습니다."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"데이터 신호 막대가 하나입니다."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"데이터 신호 막대가 두 개입니다."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"데이터 신호 막대가 세 개입니다."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"데이터 신호가 강합니다."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"WiFi 없음"</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"WiFi 신호 막대가 하나입니다."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"WiFi 신호 막대가 두 개입니다."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi 신호 막대가 세 개입니다."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"WiFi 신호가 강합니다."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"SIM 없음"</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"블루투스 테더링"</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"비행기 모드"</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"배터리 <xliff:g id="NUMBER">%d</xliff:g>퍼센트"</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"설정 버튼"</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"알림 버튼"</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"알림을 삭제합니다."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS를 사용합니다."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS 가져오는 중"</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"전신 타자기 사용"</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"벨소리 장치 진동"</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"벨소리 장치 무음"</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-lt-large/strings.xml b/packages/SystemUI/res/values-lt-large/strings.xml
index 73906ea..fad3f18 100644
--- a/packages/SystemUI/res/values-lt-large/strings.xml
+++ b/packages/SystemUI/res/values-lt-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Išv. viską"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Nėra interneto r."</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Pris. prie „Wi-Fi“"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Ieškoma GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"GPS nustatyta vieta"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Pranešimai išjungti"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Jei norite įjungti pranešimus, palieskite čia."</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 040c74d..aae9a98 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Suderinamumo mastelio keitimas"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Kai programa bus pritaikyta mažesniam ekranui, mastelio keitimo valdiklis bus parodytas šalia laikrodžio."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Ekrano kopija išsaugota galerijoje"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Nepavyko išsaugoti ekrano kopijos"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB failo perdavimo parinktys"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Įmontuoti kaip medijos grotuvą (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Įmontuoti kaip fotoaparatą (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lv-large/strings.xml b/packages/SystemUI/res/values-lv-large/strings.xml
index 24c8a45..750168c 100644
--- a/packages/SystemUI/res/values-lv-large/strings.xml
+++ b/packages/SystemUI/res/values-lv-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Notīr.visu"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Nav interneta sav."</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Izv. sav. ar Wi-Fi"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Notiek GPS meklēšana..."</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"GPS iestatītā atrašanās vieta"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Paziņojumi ir izslēgti."</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Pieskarieties šeit, lai atkal ieslēgtu paziņojumus."</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 4c9b4b4..6a42ba1 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Notīrīt"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Netraucēt"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Rādīt paziņojumus"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Noņemšana"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Apskatīt"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nav paziņojumu"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Notiekošs"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Paziņojumi"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Saderības tālummaiņa"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Ja lietotne ir paredzēta mazākam ekrānam, blakus pulkstenim tiks parādīta tālummaiņas vadīkla."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Ekrānuzņēmums ir saglabāts galerijā."</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Nevarēja saglabāt ekrānuzņēmumu."</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB failu pārsūtīšanas opcijas"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Pievienot kā multivides atskaņotāju (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Pievienot kā kameru (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Instalēt Android failu pārsūt. liet. Mac datoram"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Atpakaļ"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Sākums"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Izvēlne"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Ievades metodes maiņas poga"</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Saderības tālummaiņas poga"</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Veikt tālummaiņu no mazāka ekrāna uz lielāku"</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth savienojums ir izveidots."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth savienojums ir pārtraukts."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Nav akumulatora."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Akumulators: viena josla"</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Akumulators: divas joslas"</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Akumulators: trīs joslas"</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Pilna piekļuve akumulatoram"</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Nav tālruņa."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Tālrunis: viena josla"</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Tālrunis: divas joslas"</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Tālrunis: trīs joslas"</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Pilna piekļuve tālruņa signālam"</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Nav datu."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Dati: viena josla"</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Dati: divas joslas"</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Dati: trīs joslas"</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Pilna piekļuve datu signālam"</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Nav Wi-Fi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi: viena josla"</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi: divas joslas"</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi: trīs joslas"</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Pilna piekļuve Wi-Fi signālam"</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"EDGE"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Nav SIM kartes."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth piesaiste"</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Lidmašīnas režīms"</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Akumulators: <xliff:g id="NUMBER">%d</xliff:g> procenti"</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Iestatījumu poga"</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Paziņojumu poga"</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Noņemt paziņojumu"</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ir iespējots."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS iegūšana"</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"Teletaips ir iespējots."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Zvana signāls — vibrācija"</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Zvana signāls — kluss"</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ms-large/strings.xml b/packages/SystemUI/res/values-ms-large/strings.xml
index 4897656..bdb5e7e 100644
--- a/packages/SystemUI/res/values-ms-large/strings.xml
+++ b/packages/SystemUI/res/values-ms-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Ksgkn smua"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Tiada smbg Internet"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi disambungkan"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Mencari GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Lokasi ditetapkan oleh GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Pemberitahuan dimatikan"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Ketik di sini untuk menghidupkan kembali pemberitahuan."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index eef7926..eafa653 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Pdm bersih"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Jangan ganggu"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Tunjukkan pemberitahuan"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Alih keluar"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Periksa"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Tiada pemberitahuan"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Sedang berlangsung"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Pemberitahuan"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Keserasian Zum"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Apabila apl direka untuk skrin yang lebih kecil, kawalan zum akan muncul di tepi jam."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Tangkapan skrin disimpan ke Galeri"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Tidak boleh menyimpan tangkapan skrin"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Pilihan pemindahan fail USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Lekapkan sebagai pemain media (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Lekapkan sebagai kamera (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Pasang aplikasi Pemindahan Fail Android untuk Mac"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Kembali"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Laman Utama"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Butang tukar kaedah masukan."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Butang zum keserasian."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Skrin zum lebih kecil kepada lebih besar."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth disambungkan."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth diputuskan sambungan."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Tiada bateri."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Bateri satu bar."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Bateri dua bar."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Bateri tiga bar."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Bateri penuh."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Tiada telefon."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Telefon satu bar."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Telefon dua bar."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Telefon tiga bar."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Isyarat telefon penuh."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Tiada data."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Data satu bar."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data dua bar."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data tiga bar."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Isyarat data penuh."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Tiada WiFi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"WiFi satu bar."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"WiFi dua bar."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi tiga bar."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Isyarat WiFi penuh."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Tiada SIM."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Penambatan Bluetooth."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Mod pesawat"</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateri <xliff:g id="NUMBER">%d</xliff:g> peratus."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Butang tetapan."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Butang pemberitahuan."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Alih keluar pemberitahuan."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS didayakan."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS sedang mendapatkan."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"Mesin Teletaip didayakan."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Pendering bergetar."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Pendering senyap."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-nb-large/strings.xml b/packages/SystemUI/res/values-nb-large/strings.xml
index 053abd4..09e6443 100644
--- a/packages/SystemUI/res/values-nb-large/strings.xml
+++ b/packages/SystemUI/res/values-nb-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Tøm alle"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Ingen Internett-tilkobling"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi tilkoblet"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Søker etter GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Posisjon angitt av GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Varslinger er deaktivert"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Trykk her for å aktivere varslinger på nytt."</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 589a6ab..10743e5 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Fjern"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Ikke forstyrr"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Vis varslinger"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Fjern"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Inspiser"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ingen varslinger"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Aktiviteter"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Varslinger"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Kompatibilitets-zooming"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Når en app er utformet for en mindre skjerm, vises det en zoomkontroll ved klokken."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Skjermdump ble lagret i galleriet"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Lagring av skjermdump mislyktes"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Altern. for USB-filoverføring"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Sett inn som mediespiller (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Sett inn som kamera (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Installer Android File Transfer for Mac"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Tilbake"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Startside"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Meny"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Bytt knapp for inndatametode."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Zoomknapp for kompatibilitet."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom mindre til større skjerm."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth er tilkoblet."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth frakoblet."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Uten batteri."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Batteri – én stolpe."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Batteri – to stolper."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Batteri – tre stolper."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Batteri er fullt."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Ingen telefon."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Telefon – én stolpe."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Telefon – to stolper."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Telefon – tre stolper."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Telefonsignal er fullt."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Ingen data."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Data – én stolpe"</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data – to stolper."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data – tre stolper."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Datasignal er fullt."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Ingen Wi-Fi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi – én stolpe."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi – to stolper."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi – tre stolper."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"WiFi-signal er fullt."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Uten SIM"</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-tilknytning"</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Flymodus."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteri – <xliff:g id="NUMBER">%d</xliff:g> prosent."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Innstillinger-knapp."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Varslingsknapp."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Fjern varsling."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS aktivert."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Henting av GPS-signal."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter aktivert."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibreringsmodus."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Stille modus."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-nl-large/strings.xml b/packages/SystemUI/res/values-nl-large/strings.xml
index cc2147c..4e55664 100644
--- a/packages/SystemUI/res/values-nl-large/strings.xml
+++ b/packages/SystemUI/res/values-nl-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Alles wissen"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Geen internetverbinding"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Verbonden via Wi-Fi"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Zoeken naar GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Locatie bepaald met GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Meldingen uit"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Tik hier om meldingen weer in te schakelen."</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index ab44aaf..c3afe27 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Wissen"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Niet storen"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Meldingen weergeven"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Verwijderen"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Inspecteren"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Geen meldingen"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Actief"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Meldingen"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Compatibiliteitszoom"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Wanneer een app is ontworpen voor een kleiner scherm, wordt naast de klok een zoomknop weergegeven."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Schermafbeelding is opgeslagen in de galerij"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Schermafbeelding is niet opgeslagen"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opties voor USB-bestandsoverdracht"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Koppelen als mediaspeler (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Koppelen als camera (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Applicatie Android File Transfer voor Mac installeren"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Terug"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Startpagina"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Knop voor wijzigen invoermethode."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Knop voor compatibiliteitszoom."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Kleiner scherm uitzoomen naar groter scherm."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth-verbinding ingesteld."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth-verbinding verbroken."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Geen accu."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Accu: één streepje."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Accu: twee streepjes."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Accu: drie streepjes."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Accu is vol."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Geen telefoonsignaal."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Telefoon: één streepje."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Telefoon: twee streepjes."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Telefoon: drie streepjes."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Telefoonsignaal is op volledige sterkte."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Geen gegevens."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Gegevens: één streepje."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Gegevens: twee streepjes."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Gegevens: drie streepjes."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Gegevenssignaal is op volledige sterkte."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Geen Wi-Fi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Wi-Fi: één streepje."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi: twee streepjes."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Wi-Fi: drie streepjes."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi-signaal is op volledige sterkte."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Geen simkaart."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-tethering."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Vliegmodus."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Accu: <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"De knop \'Instellingen\'."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Knop voor meldingen."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Melding verwijderen."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ingeschakeld."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Verbinding maken met GPS."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter ingeschakeld."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Belsoftware trilt."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Belsoftware stil."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-pl-large/strings.xml b/packages/SystemUI/res/values-pl-large/strings.xml
index d81e030..9070c83 100644
--- a/packages/SystemUI/res/values-pl-large/strings.xml
+++ b/packages/SystemUI/res/values-pl-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Wyczyść"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Brak połączenia internetowego"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi: połączono"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Wyszukiwanie sygnału GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Lokalizacja ustawiona wg GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Powiadomienia wyłączone"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Dotknij tutaj, aby z powrotem włączyć powiadomienia."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 977ba60..184ae8d 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Wyczyść"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Nie przeszkadzać"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Pokaż powiadomienia"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Usuń"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Sprawdź"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Brak powiadomień"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Bieżące"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Powiadomienia"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Powiększenie w trybie zgodności"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Jeśli aplikacja została przystosowana do mniejszego ekranu, obok zegara zostanie wyświetlony element sterujący powiększeniem."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Zrzut ekranu został zapisany w galerii."</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Nie można zapisać zrzutu ekranu."</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB – opcje przesyłania plików"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Podłącz jako odtwarzacz multimedialny (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Podłącz jako aparat (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Zainstaluj aplikację Android File Transfer dla Mac OS"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Wróć"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Ekran główny"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Przycisk przełączania metody wprowadzania."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Przycisk powiększenia na potrzeby zgodności."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Powiększa mniejszy ekran na większy."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth podłączony."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth rozłączony."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Brak baterii."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Bateria: jeden pasek."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Bateria: dwa paski."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Bateria: trzy paski."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Bateria naładowana."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Brak sygnału telefonu."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Telefon: jeden pasek."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Telefon: dwa paski."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Telefon: trzy paski."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Sygnał telefonu: pełny."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Brak danych."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Jeden pasek sygnału danych."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Dane: dwa paski."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Dane: trzy paski."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Pełna moc sygnału danych."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Brak Wi-Fi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Sieć Wi-Fi: jeden pasek."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Sieć Wi-Fi: dwa paski."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Sieć Wi-Fi: trzy paski."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Pełna moc sygnału Wi-Fi."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Brak karty SIM."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Powiązanie Bluetooth."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Tryb samolotowy."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Przycisk Ustawienia."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Przycisk powiadomień."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Usuń powiadomienie."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS włączony."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Pobieranie danych GPS."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"Dalekopis (TTY) włączony."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Dzwonek z wibracjami."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Dzwonek wyciszony."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt-large/strings.xml b/packages/SystemUI/res/values-pt-large/strings.xml
index 92615fd..654b3c6 100644
--- a/packages/SystemUI/res/values-pt-large/strings.xml
+++ b/packages/SystemUI/res/values-pt-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Limpar tudo"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Sem conexão à Internet"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Conectado à Wi-Fi"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Buscando GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Localização definida por GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Notificações desativadas"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Toque aqui para ativar as notificações novamente."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT-large/strings.xml b/packages/SystemUI/res/values-pt-rPT-large/strings.xml
index 5ceeae2..6fa5af3 100644
--- a/packages/SystemUI/res/values-pt-rPT-large/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Limpar td"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Sem ligação internet"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi ligado"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"A procurar GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Localização definida por GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Notificações desativadas"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Toque aqui para voltar a ativar as notificações."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 2c6d283..ae3ce7e 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Compatibilidade de zoom"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Sempre que uma aplicação tiver sido concebida para ecrãs mais pequenos, aparecerá um controlo de zoom junto ao relógio."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Captura de ecrã guardada na Galeria"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Não foi possível guardar a captura de ecrã"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opções de transm. de fich. USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Montar como leitor de multimédia (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montar como câmara (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 29aa510..681455a 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Limpar"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Não perturbe"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Mostrar notificações"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Remover"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Inspecionar"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Sem notificações"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Em andamento"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificações"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom em modo de compatibilidade"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Quando um aplicativo é desenvolvido para uma tela menor, um controle de zoom é exibido perto do relógio."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"A captura de tela foi salva na Galeria"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Não foi possível salvar a captura de tela"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opções transf. arq. por USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Conectar como media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montar como uma câmera (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Instalar aplic. Android File Transfer para Mac"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Voltar"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Página inicial"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Alterar botão do método de entrada."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Compatibilidade do botão de zoom."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Aumentar a tela com zoom."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth conectado."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth desconectado."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Sem bateria."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Uma barra de bateria."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Duas barras de bateria."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Três barras de bateria."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Bateria cheia."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Sem telefone."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Uma barra de sinal do telefone."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Duas barras de sinal do telefone."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Três barras de sinal do telefone."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Sinal do telefone cheio."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Nenhum dado."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Uma barra de sinal de dados."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Duas barras de sinal de dados."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Três barras de sinal de dados."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Sinal de dados cheio."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Sem WiFi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Uma barra de sinal WiFi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Duas barras de sinal WiFi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Três barras de sinal WiFi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Sinal do WiFi cheio."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Sem SIM."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Vínculo Bluetooth."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo para avião."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria em <xliff:g id="NUMBER">%d</xliff:g>%."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Botão Configurações."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Botão de notificação."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Remover notificação."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ativado."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Aquisição de GPS."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTYpewriter ativado."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibrar campainha."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Campainha silenciosa."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index b2c8b50..cd6b41a 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -93,7 +93,7 @@
<skip />
<!-- no translation found for screenshot_saving_toast (8592630119048713208) -->
<skip />
- <!-- no translation found for screenshot_failed_toast (655180965533683356) -->
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
<skip />
<!-- no translation found for usb_preference_title (6551050377388882787) -->
<skip />
@@ -109,6 +109,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -197,4 +199,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ro-large/strings.xml b/packages/SystemUI/res/values-ro-large/strings.xml
index 55b2b3e..d4983bc 100644
--- a/packages/SystemUI/res/values-ro-large/strings.xml
+++ b/packages/SystemUI/res/values-ro-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Şterg. tot"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Fără conex. internet"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi conectat"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Se caută GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Locaţie setată prin GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Notificările sunt dezactivate"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Apăsaţi aici pentru a reactiva notificările."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 5128088..add141c 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom de compatibilitate"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Atunci când o aplicaţie a fost concepută pentru un ecran mai mic, o comandă pentru mărire/micşorare va apărea alături de ceas."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Captura de ecran a fost salvată în Galerie"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Captura de ecran nu a putut fi salvată"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opţiuni pentru transferul de fişiere prin USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Montaţi ca player media (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montaţi drept cameră foto (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ru-large/strings.xml b/packages/SystemUI/res/values-ru-large/strings.xml
index bafb97f..79e80a6 100644
--- a/packages/SystemUI/res/values-ru-large/strings.xml
+++ b/packages/SystemUI/res/values-ru-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Очистить все"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Нет подключения к Интернету"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi подключено"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Поиск GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Местоположение установлено с помощью GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Уведомления отключены"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Нажмите здесь, чтобы снова включить уведомления."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 2f22ab4..eee42e2 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Масштаб и совместимость"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Если приложение рассчитано на экран меньших размеров, рядом с часами появятся средства масштабирования."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Скриншот сохранен в галерее"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Не удалось сохранить скриншот"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Параметры передачи через USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Подключить как мультимедийный проигрыватель (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Установить как камеру (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sk-large/strings.xml b/packages/SystemUI/res/values-sk-large/strings.xml
index 8de74a1..ccf7543 100644
--- a/packages/SystemUI/res/values-sk-large/strings.xml
+++ b/packages/SystemUI/res/values-sk-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Vymazať všetko"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Bez prip. na Internet"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi: pripojené"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Vyhľadávanie satelitov GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Poloha nastavená pomocou GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Upozornenia sú vypnuté"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Klepnutím sem upozornenia znova povolíte."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 9701572..946f426 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Kompatibilné priblíženie"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Ak je aplikácia navrhnutá pre menšiu obrazovku, zobrazí sa vedľa hodín ovládací prvok priblíženia."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Snímka obrazovky bola uložená do Galérie"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Snímku obrazovky sa nepodarilo uložiť"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Možnosti prenosu súborov USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Pripojiť ako prehrávač médií (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Pripojiť ako fotoaparát (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sl-large/strings.xml b/packages/SystemUI/res/values-sl-large/strings.xml
index d4c7e61..3790716 100644
--- a/packages/SystemUI/res/values-sl-large/strings.xml
+++ b/packages/SystemUI/res/values-sl-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Izbriši vse"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Ni internetne pov."</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi povezan"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Iskanje GPS-a"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Lokacija nastavljena z GPS-om"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Obvestila so izklopljena"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Tapnite tukaj, da spet vklopite obvestila."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 2b89f88..bb2781d 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Počisti"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Ne moti"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Pokaži obvestila"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Odstrani"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Preverite"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ni obvestil"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Trenutno"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Obvestila"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Povečava združljivosti"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Če je program izdelan za manjše zaslone, se ob uri pokaže kontrolnik za povečavo."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Posnetek zaslona je shranjen v galerijo"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Posnetka zaslona ni bilo mogoče shraniti"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Možnosti prenosa datotek prek USB-ja"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Vpni kot predvajalnik (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Vpni kot fotoaparat (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Namestite program Android File Transfer za Mac"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Nazaj"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Domača stran"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Meni"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Gumb za preklo načina vnosa."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Gumb povečave za združljivost."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Povečava manjšega na večji zaslon."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Povezava Bluetooth vzpostavljena."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Povezava Bluetooth prekinjena."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Ni baterije."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Baterija z eno črtico."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Baterija z dvema črticama."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Baterija s tremi črticami."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Baterija je polna."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Ni telefona."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Telefon z eno črtico."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Telefon z dvema črticama."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Telefon s tremi črticami."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Signal telefona je poln."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Ni podatkov."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Podatkovni signal z eno črtico."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Podatki z dvema črticama."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Podatki s tremi črticami."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Podatkovni signal poln."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Ni povezave Wi-Fi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"WiFi z eno črtico."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Wi-Fi z dvema črticama."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi s tremi črticami."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Signal Wi-Fi poln."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Ni kartice SIM."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Internet prek Bluetootha."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Način za letalo."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterija <xliff:g id="NUMBER">%d</xliff:g> odstotkov."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Gumb za nastavitve."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Gumb za obvestila."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Odstranite obvestilo."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS omogočen."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Pridobivanje GPS."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter omogočen."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Zvonjenje z vibriranjem."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Zvonjenje izklopljeno."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-sr-large/strings.xml b/packages/SystemUI/res/values-sr-large/strings.xml
index 3080a90..37b03d1 100644
--- a/packages/SystemUI/res/values-sr-large/strings.xml
+++ b/packages/SystemUI/res/values-sr-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Обриши све"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Нема интернет везе"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi је повезан"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Тражи се GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Локацију је подесио GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Обавештења су искључена"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Додирните овде да бисте поново укључили обавештења."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index fcd612f..8d1721c 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Компатибилно зумирање"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Када је апликација намењена мањем екрану, контрола зумирања приказује се поред сата."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Снимак екрана је сачуван у Галерији"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Није могуће сачувати снимак екрана"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Опције USB преноса датотека"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Прикључи као медија плејер (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Прикључи као камеру (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sv-large/strings.xml b/packages/SystemUI/res/values-sv-large/strings.xml
index b978cb9..ddea0d4 100644
--- a/packages/SystemUI/res/values-sv-large/strings.xml
+++ b/packages/SystemUI/res/values-sv-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Rensa alla"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Ingen anslutning"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi-ansluten"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Sökning efter GPS pågår"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Platsen har identifierats av GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Meddelanden inaktiverade"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Knacka lätt här om du vill aktivera meddelanden igen."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 6f3b2bb..5f81255 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom i kompatibilitetsläge"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"När en app är anpassad för en mindre skärm visas ett zoomreglage vid klockan."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Skärmdumpen sparades i galleriet"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Det gick inte att spara skärmdumpen"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Överföringsalternativ"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Montera som mediaspelare (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montera som kamera (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 450157c..e944ced 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -83,7 +83,7 @@
<skip />
<!-- no translation found for screenshot_saving_toast (8592630119048713208) -->
<skip />
- <!-- no translation found for screenshot_failed_toast (655180965533683356) -->
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
<skip />
<!-- no translation found for usb_preference_title (6551050377388882787) -->
<skip />
@@ -99,6 +99,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -187,4 +189,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-th-large/strings.xml b/packages/SystemUI/res/values-th-large/strings.xml
index 1158f81..76bd846 100644
--- a/packages/SystemUI/res/values-th-large/strings.xml
+++ b/packages/SystemUI/res/values-th-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"ล้างทั้งหมด"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"ไม่มีการเชื่อมต่ออินเทอร์เน็ต"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"เชื่อมต่อ Wi-Fi แล้ว"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"กำลังค้นหา GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"ตำแหน่งที่กำหนดโดย GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"การแจ้งเตือนปิดอยู่"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"แตะที่นี่เพื่อเปิดการแจ้งเตือนอีกครั้ง"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index a5315c6..2be5544 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"ล้างข้อมูล"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"ห้ามรบกวน"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"แสดงการแจ้งเตือน"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"นำออก"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"ตรวจสอบ"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"ไม่มีการแจ้งเตือน"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"ดำเนินอยู่"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"การแจ้งเตือน"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"ความเข้ากันได้ของการย่อ/ขยาย"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"สำหรับแอปพลิเคชันที่ออกแบบมาสำหรับหน้าจอขนาดเล็ก ตัวควบคุมการย่อ/ขยายจะปรากฏขึ้นข้างนาฬิกา"</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"บันทึกภาพหน้าจอในแกลเลอรีแล้ว"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"ไม่สามารถบันทึกภาพหน้าจอ"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"ตัวเลือกการถ่ายโอนไฟล์ USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"ต่อเชื่อมเป็นโปรแกรมเล่นสื่อ (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"ต่อเชื่อมเป็นกล้องถ่ายรูป (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"ติดตั้งแอปพลิเคชัน Android File Transfer ของ Mac"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"ย้อนกลับ"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"หน้าแรก"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"เมนู"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"ปุ่มสลับวิธีการป้อนข้อมูล"</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"ปุ่มซูมที่ใช้งานร่วมกันได้"</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ซูมหน้าจอให้มีขนาดใหญ่ขึ้น"</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"เชื่อมต่อบลูทูธอยู่"</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"ไม่ได้เชื่อมต่อบลูทูธ"</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"ไม่มีแบตเตอรี่"</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"แบตเตอรี่หนึ่งขีด"</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"แบตเตอรี่สองขีด"</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"แบตเตอรี่สามขีด"</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"แบตเตอรี่เต็ม"</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"ไม่มีสัญญาณ"</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"สัญญาณโทรศัพท์หนึ่งขีด"</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"สัญญาณโทรศัพท์สองขีด"</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"สัญญาณโทรศัพท์สามขีด"</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"สัญญาณโทรศัพท์เต็ม"</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"ไม่มีข้อมูล"</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"สัญญาณข้อมูลหนึ่งขีด"</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"สัญญาณข้อมูลสองขีด"</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"สัญญาณข้อมูลสามขีด"</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"สัญญาณข้อมูลเต็ม"</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"ไม่มี Wi-Fi"</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"สัญญาณ Wi-Fi หนึ่งขีด"</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"สัญญาณ Wi-Fi สองขีด"</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"สัญญาณ Wi-Fi สามขีด"</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"สัญญาณ Wi-Fi เต็ม"</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"EDGE"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Wi-Fi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"ไม่มีซิมการ์ด"</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"การปล่อยสัญญาณบลูทูธ"</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"โหมดใช้งานบนเครื่องบิน"</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"แบตเตอรี่ <xliff:g id="NUMBER">%d</xliff:g> เปอร์เซ็นต์"</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"ปุ่มการตั้งค่า"</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"ปุ่มแจ้งเตือน"</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"นำการแจ้งเตือนออก"</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"เปิดใช้งาน GPS อยู่"</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"การดึงข้อมูล GPS"</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"เปิดใช้งาน TeleTypewriter อยู่"</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"เสียงเรียกเข้าแบบสั่น"</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"เสียงเรียกเข้าแบบปิดเสียง"</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-tl-large/strings.xml b/packages/SystemUI/res/values-tl-large/strings.xml
index 5049fb2..821121f 100644
--- a/packages/SystemUI/res/values-tl-large/strings.xml
+++ b/packages/SystemUI/res/values-tl-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"I-clear"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Wala koneksyon net"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Konektado ang Wi-Fi"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Naghahanap ng GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Lokasyong itinatakda ng GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Naka-off ang mga notification"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Mag-tap dito upang i-on muli ang mga notification."</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index d44f82e..736231d 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"I-clear"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Huwag gambalain"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Magpakita ng notification"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Alisin"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Siyasatin"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Walang mga notification"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Nagpapatuloy"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Mga Notification"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom sa Pagiging Tugma"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Kapag nakadisenyo ang isang app para sa mas maliit na screen, isang kontrol ng zoom ang lalabas sa may orasan."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Na-save ang screenshot sa Gallery"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Hindi ma-save ang screenshot"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Opsyon paglipat ng USB file"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"I-mount bilang isang media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"I-mount bilang camera (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"I-install Android File Transfer para sa Mac"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Bumalik"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Home"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Ilipat ang button ng pamamaraan ng pag-input."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Button ng zoom ng compatibility."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Mag-zoom nang mas maliit sa mas malaking screen."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Nakakonekta ang Bluetooth."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Nadiskonekta ang Bluetooth."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Walang baterya."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Baterya isang bar."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Baterya dalawang bar."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Baterya tatlong bar."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Puno na ang baterya."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Walang telepono."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Telepono isang bar."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Telepono dalawang bar."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Telepono tatlong bar."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Puno ang signal ng telepono."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Walang data."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Data isang bar."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data dalawang bar."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data tatlong bar."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Puno ang signal ng data."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Walang WiFi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"WiFi isang bar."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"WiFi dalawang bar."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"WiFi tatlong bar."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Puno ang signal ng WiFi."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Walang SIM."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Pag-tether ng Bluetooth."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Airplane mode"</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterya <xliff:g id="NUMBER">%d</xliff:g> (na) porsyento."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Button ng mga setting."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Button ng mga notification."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Alisin ang notification."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"Pinagana ang GPS."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Nag-a-acquire ang GPS."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"Pinagana ang TeleTypewriter."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Naka-vibrate ang ringer."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Naka-silent ang ringer."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-tr-large/strings.xml b/packages/SystemUI/res/values-tr-large/strings.xml
index f38e962..8149970 100644
--- a/packages/SystemUI/res/values-tr-large/strings.xml
+++ b/packages/SystemUI/res/values-tr-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Tümü temzl"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"İnternet bağlantısı yok"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Kablosuz bağlandı"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"GPS aranıyor"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Konum GPS ile belirlendi"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Bildirimler kapalı"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Bildirimleri tekrar açmak için buraya hafifçe vurun."</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 308c434..6028181 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Temizle"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Rahatsız etmeyin"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Bildirimleri göster"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Kaldır"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Araştır"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Bildirim yok"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Sürüyor"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Bildirimler"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Uyumluluk Zum\'u"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Uygulama küçük bir ekran için tasarlanmışsa saatin yanında bir yakınlaştırma denetimi görünür."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Ekran görüntüsü Galeri\'ye kaydedildi"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Ekran görüntüsü kaydedilemedi"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB dosya aktarım seçenekleri"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Medya oynatıcı olarak ekle (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Kamera olarak ekle (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Mac için Android Dosya Aktarımı uygulamasını yükle"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Geri"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Ana Sayfa"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Menü"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Giriş yöntemini değiştirme düğmesi."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Uyumluluk yakınlaştırma düğmesi."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Daha büyük ekrana daha küçük yakınlaştır."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth bağlandı."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth bağlantısı kesildi."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Pil yok."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Pil gücü bir çubuk."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Pil gücü iki çubuk."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Pil gücü üç çubuk."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Pil tam dolu."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Telefon sinyali yok."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Telefon sinyali bir çubuk."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Telefon sinyali iki çubuk."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Telefon sinyali üç çubuk."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Telefon sinyali tam."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Veri yok."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Veri sinyali bir çubuk."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Veri sinyali iki çubuk."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Veri sinyali üç çubuk."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Veri sinyali tam."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Kablosuz sinyali yok"</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Kablosuz sinyali bir çubuk."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Kablosuz sinyali iki çubuk."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Kablosuz sinyali üç çubuk."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Kablosuz sinyali tam."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"Kablosuz"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"SIM kart yok."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth tethering."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Uçak modu."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Pil yüzdesi: <xliff:g id="NUMBER">%d</xliff:g>"</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Ayarlar düğmesi"</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Bildirim düğmesi."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Bildirimi kaldır."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS etkin."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS alınıyor."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter etkin."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Zil programı titreşim."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Zil programı sessiz."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-uk-large/strings.xml b/packages/SystemUI/res/values-uk-large/strings.xml
index 367dd5c..5cf696e 100644
--- a/packages/SystemUI/res/values-uk-large/strings.xml
+++ b/packages/SystemUI/res/values-uk-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Очист. все"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Немає з’єднання"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi під’єднано"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Виконується пошук за допомогою GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Місцезнаходження встановлено за допомогою GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Сповіщення вимкнено"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Торкніться тут, щоб знову ввімкнути сповіщення."</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 6687d0c..d1ec471 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Очист."</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Не турбувати"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Показувати сповіщення"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Видалити"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Перевірити"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Немає сповіщень"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Поточні"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Сповіщення"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Елемент керування масштабом для сумісності"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Якщо програму призначено для менших екранів, елемент керування масштабом буде відображатися біля годинника."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Знімок екрана збережено в Галереї"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Неможливо зберегти знімок екрана"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Парам.передав.файлів через USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Підключити як медіапрогравач (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Підключити як камеру (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Установити програму Android File Transfer для Mac"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Назад"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Домашня сторінка"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Меню"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Кнопка перемикання методу введення."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Кнопка масштабування сумісності."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Збільшення екрана."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth під’єднано."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth від’єднано."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Немає заряду батареї."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Одна смужка заряду батареї."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Дві смужки заряду батареї."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Три смужки заряду баратеї."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Повний заряд батареї."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Немає сигналу телефону."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Одна смужка сигналу телефону."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Дві смужки сигналу телефону."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Три смужки сигналу телефону."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Максимальний сигнал телефону."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Немає сигналу даних."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Одна смужка сигналу даних."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Дві смужки сигналу даних."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Три смужки сигналу даних."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Максимальний сигнал даних."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Немає сигналу Wi-Fi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Одна смужка сигналу WiFi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Дві смужки сигналу WiFi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Три смужки сигналу WiFi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Максимальний сигнал Wi-Fi."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Немає SIM-карти."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Прив’язка Bluetooth."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим польоту."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Відсотків батареї: <xliff:g id="NUMBER">%d</xliff:g>."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Кнопка налаштувань."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Кнопка сповіщень."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Видалити сповіщення."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS увімкнено."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Отримання GPS."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"Телетайп увімкнено."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Дзвінок на вібросигналі."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Дзвінок беззвучний."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-vi-large/strings.xml b/packages/SystemUI/res/values-vi-large/strings.xml
index 569d70f..bb2393d 100644
--- a/packages/SystemUI/res/values-vi-large/strings.xml
+++ b/packages/SystemUI/res/values-vi-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"Xóa tất cả"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"Không có k.nối Internet"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Đã kết nối Wi-Fi"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"Đang tìm kiếm GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"Vị trí đặt bởi GPS"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Tắt thông báo"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Chạm vào đây để bật lại thông báo."</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 5bca34b..1ec6fd6 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -23,10 +23,8 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Xoá"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Không làm phiền"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Hiển thị thông báo"</string>
- <!-- no translation found for status_bar_recent_remove_item_title (6561944127804037619) -->
- <skip />
- <!-- no translation found for status_bar_recent_inspect_item_title (4906947311448880529) -->
- <skip />
+ <string name="status_bar_recent_remove_item_title" msgid="6561944127804037619">"Xóa"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="4906947311448880529">"Kiểm tra"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Không có thông báo nào"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Đang diễn ra"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Thông báo"</string>
@@ -62,103 +60,79 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Thu phóng tương thích"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Khi ứng dụng được thiết kế cho một màn hình nhỏ hơn, điều khiển thu phóng sẽ xuất hiện bên cạnh đồng hồ."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Đã lưu ảnh chụp màn hình vào Thư viện"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"Không thể lưu ảnh chụp màn hình"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"Tùy chọn truyền tệp USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Gắn như một trình phát đa phương tiện (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Gắn như một máy ảnh (PTP)"</string>
<string name="installer_cd_button_title" msgid="8485631662288445893">"Cài đặt ứng dụng Truyền tệp của Android dành cho Mac"</string>
- <!-- no translation found for accessibility_back (567011538994429120) -->
+ <string name="accessibility_back" msgid="567011538994429120">"Quay lại"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Trang chủ"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Trình đơn"</string>
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
<skip />
- <!-- no translation found for accessibility_home (8217216074895377641) -->
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Nút chuyển phương thức nhập."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Nút thu phóng khả năng tương thích."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Thu phóng màn hình lớn hơn hoặc nhỏ hơn."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Đã kết nối bluetooth."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth bị ngắt kết nối."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Không có pin."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Mức pin một vạch."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Mức pin hai vạch."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Mức pin ba vạch."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Mức pin đầy."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"Không có điện thoại nào."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Tín hiệu điện thoại một vạch."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Tín hiệu điện thoại hai vạch."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Tín hiệu điện thoại ba vạch."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Tín hiệu điện thoại đầy đủ."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"Không có dữ liệu."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Tín hiệu dữ liệu một vạch."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Tín hiệu dữ liệu hai vạch."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Tín hiệu dữ liệu ba vạch."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Tín hiệu dữ liệu đầy đủ."</string>
+ <string name="accessibility_no_wifi" msgid="4017628918351949575">"Không có WiFi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="1914343229091303434">"Tín hiệu WiFi một vạch."</string>
+ <string name="accessibility_wifi_two_bars" msgid="7869150535859760698">"Tín hiệu WiFi hai vạch."</string>
+ <string name="accessibility_wifi_three_bars" msgid="2665319332961356254">"Tín hiệu WiFi ba vạch."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Tín hiệu WiFi đầy đủ."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="1127208787254436420">"WiFi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"Không có SIM nào."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Chia sẻ kết nối Bluetooth."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Chế độ trên máy bay."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> phần trăm pin."</string>
+ <string name="accessibility_settings_button" msgid="7913780116850379698">"Nút cài đặt."</string>
+ <string name="accessibility_notifications_button" msgid="2933903195211483438">"Nút thông báo."</string>
+ <string name="accessibility_remove_notification" msgid="4883990503785778699">"Xóa thông báo."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"Đã bật GPS."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Giành được GPS."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"Đã bật TeleTypewriter."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Chuông rung."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Chuông im lặng."</string>
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
<skip />
- <!-- no translation found for accessibility_menu (316839303324695949) -->
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
<skip />
- <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
<skip />
- <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
<skip />
- <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
<skip />
- <!-- no translation found for accessibility_no_battery (358343022352820946) -->
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
<skip />
- <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
<skip />
- <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
- <skip />
- <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
- <skip />
- <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
- <skip />
- <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
- <skip />
- <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
- <skip />
- <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
- <skip />
- <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
- <skip />
- <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
- <skip />
- <!-- no translation found for accessibility_no_data (4791966295096867555) -->
- <skip />
- <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
- <skip />
- <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
- <skip />
- <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
- <skip />
- <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (4017628918351949575) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (1914343229091303434) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (7869150535859760698) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (2665319332961356254) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (1275764416228473932) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
- <skip />
- <!-- no translation found for accessibility_data_connection_wifi (1127208787254436420) -->
- <skip />
- <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
- <skip />
- <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
- <skip />
- <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
- <skip />
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <!-- no translation found for accessibility_settings_button (7913780116850379698) -->
- <skip />
- <!-- no translation found for accessibility_notifications_button (2933903195211483438) -->
- <skip />
- <!-- no translation found for accessibility_remove_notification (4883990503785778699) -->
- <skip />
- <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
- <skip />
- <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
- <skip />
- <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
- <skip />
- <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
- <skip />
- <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN-large/strings.xml b/packages/SystemUI/res/values-zh-rCN-large/strings.xml
index fcd4dbc..2eccba9 100644
--- a/packages/SystemUI/res/values-zh-rCN-large/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"全部清除"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"未连接互联网"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi 已连接"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"正在搜索 GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"已通过 GPS 确定位置"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"通知功能已停用"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"点按此处可重新启用通知功能。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index dfab6d7..5ffaaab 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"兼容性缩放"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"如果应用程序是针对较小屏幕设计的,则时钟旁会显示缩放控件。"</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"屏幕截图已保存到“图库”"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"无法保存屏幕截图"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB 文件传输选项"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"作为媒体播放器 (MTP) 装载"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"作为摄像头 (PTP) 装载"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW-large/strings.xml b/packages/SystemUI/res/values-zh-rTW-large/strings.xml
index aba7453..bf1c0a0 100644
--- a/packages/SystemUI/res/values-zh-rTW-large/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW-large/strings.xml
@@ -20,10 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="status_bar_clear_all_button" msgid="4661583896803349732">"全部清除"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="383145178755329067">"沒有網際網路連線"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="2535465294437586528">"Wi-Fi 已連線"</string>
- <string name="gps_notification_searching_text" msgid="4467935186864208249">"正在搜尋 GPS"</string>
- <string name="gps_notification_found_text" msgid="6270628388918822956">"GPS 已定位"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"關閉通知"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"輕按這裡即可重新開啟通知。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 854d89d..032df88 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -62,7 +62,8 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"相容性縮放"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"執行專為較小螢幕設計的應用程式時,系統會在時鐘旁顯示縮放控制項。"</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"螢幕擷取畫面已儲存至圖片庫"</string>
- <string name="screenshot_failed_toast" msgid="655180965533683356">"無法儲存螢幕擷取畫面"</string>
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
+ <skip />
<string name="usb_preference_title" msgid="6551050377388882787">"USB 檔案傳輸選項"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"掛接為媒體播放器 (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"掛接為相機 (PTP)"</string>
@@ -73,6 +74,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -161,4 +164,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 05268bf..a114b69 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -83,7 +83,7 @@
<skip />
<!-- no translation found for screenshot_saving_toast (8592630119048713208) -->
<skip />
- <!-- no translation found for screenshot_failed_toast (655180965533683356) -->
+ <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
<skip />
<!-- no translation found for usb_preference_title (6551050377388882787) -->
<skip />
@@ -99,6 +99,8 @@
<skip />
<!-- no translation found for accessibility_menu (316839303324695949) -->
<skip />
+ <!-- no translation found for accessibility_recent (3027675523629738534) -->
+ <skip />
<!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
<skip />
<!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -187,4 +189,24 @@
<skip />
<!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
<skip />
+ <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_4g_title (4789143363492682629) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_mobile_title (1046047248844821202) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_title (2086815304858964954) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog (6524467913290900042) -->
+ <skip />
+ <!-- no translation found for data_usage_disabled_dialog_enable (7729772039208664606) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
+ <skip />
+ <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
+ <skip />
+ <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index b02015d..ba1aea3 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -57,4 +57,7 @@
<!-- opacity at which Notification icons will be drawn in the status bar -->
<item type="dimen" name="status_bar_icon_drawing_alpha">40%</item>
+
+ <!-- gap on either side of status bar notification icons -->
+ <dimen name="status_bar_icon_padding">0dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 2b3118d..03b82fd 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -41,8 +41,9 @@
<!-- Title shown in recents popup for inspecting an application's properties -->
<string name="status_bar_recent_inspect_item_title">Inspect</string>
-
-
+ <!-- For formatting day of week and date in DateView. Day of week precedes date by default,
+ but this may be overridden on a per-locale basis if necessary. -->
+ <string name="status_bar_date_formatter">%1$s\n%2$s</string>
<!-- The label in the bar at the top of the status bar when there are no notifications
showing. [CHAR LIMIT=40]-->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 91a8855..ad236b7 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -52,4 +52,15 @@
<item name="android:windowExitAnimation">@*android:anim/shrink_fade_out_from_bottom</item>
</style>
+ <!-- Standard animations for hiding and showing the status bar. -->
+ <style name="Animation.StatusBar">
+ <item name="android:windowEnterAnimation">@anim/status_bar_enter</item>
+ <item name="android:windowExitAnimation">@anim/status_bar_exit</item>
+ </style>
+
+ <style name="Animation.StatusBar.IntruderAlert">
+ <item name="android:windowEnterAnimation">@anim/priority_alert_enter</item>
+ <item name="android:windowExitAnimation">@anim/priority_alert_exit</item>
+ </style>
+
</resources>
diff --git a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
similarity index 78%
rename from core/java/com/android/internal/service/wallpaper/ImageWallpaper.java
rename to packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 45f3bc1..7cc5ff7 100644
--- a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -14,23 +14,19 @@
* limitations under the License.
*/
-package com.android.internal.service.wallpaper;
+package com.android.systemui;
import java.io.IOException;
-import com.android.internal.view.WindowManagerPolicyThread;
-
import android.app.WallpaperManager;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Region.Op;
import android.graphics.drawable.Drawable;
import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Process;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
+import android.util.Slog;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.content.Context;
@@ -45,40 +41,27 @@
private static final String TAG = "ImageWallpaper";
private static final boolean DEBUG = false;
+ static final boolean FIXED_SIZED_SURFACE = true;
+
WallpaperManager mWallpaperManager;
- private HandlerThread mThread;
private Handler mHandler;
@Override
public void onCreate() {
super.onCreate();
mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE);
- Looper looper = WindowManagerPolicyThread.getLooper();
- if (looper == null) {
- mThread = new HandlerThread("Wallpaper", Process.THREAD_PRIORITY_FOREGROUND);
- mThread.start();
- looper = mThread.getLooper();
- }
- setCallbackLooper(looper);
- mHandler = new Handler(looper);
+ mHandler = new Handler();
}
public Engine onCreateEngine() {
return new DrawableEngine();
}
- @Override
- public void onDestroy() {
- super.onDestroy();
- if (mThread != null) {
- mThread.quit();
- }
- }
-
class DrawableEngine extends Engine {
private final Object mLock = new Object();
private WallpaperObserver mReceiver;
Drawable mBackground;
+ int mBackgroundWidth = -1, mBackgroundHeight = -1;
float mXOffset;
float mYOffset;
@@ -95,7 +78,9 @@
}
synchronized (mLock) {
- updateWallpaperLocked();
+ mBackgroundWidth = mBackgroundHeight = -1;
+ mBackground = null;
+ mRedrawNeeded = true;
drawFrameLocked();
}
}
@@ -113,10 +98,6 @@
registerReceiver(mReceiver, filter, null, mHandler);
updateSurfaceSize(surfaceHolder);
-
- synchronized (mLock) {
- updateWallpaperLocked();
- }
}
@Override
@@ -135,11 +116,14 @@
}
void updateSurfaceSize(SurfaceHolder surfaceHolder) {
- surfaceHolder.setFixedSize(getDesiredMinimumWidth(), getDesiredMinimumHeight());
- // Used a fixed size surface, because we are special. We can do
- // this because we know the current design of window animations doesn't
- // cause this to break.
- //surfaceHolder.setSizeFromLayout();
+ if (FIXED_SIZED_SURFACE) {
+ // Used a fixed size surface, because we are special. We can do
+ // this because we know the current design of window animations doesn't
+ // cause this to break.
+ surfaceHolder.setFixedSize(getDesiredMinimumWidth(), getDesiredMinimumHeight());
+ } else {
+ surfaceHolder.setSizeFromLayout();
+ }
}
@Override
@@ -216,15 +200,18 @@
return;
}
+ if (mBackgroundWidth < 0 || mBackgroundHeight < 0) {
+ // If we don't yet know the size of the wallpaper bitmap,
+ // we need to get it now.
+ updateWallpaperLocked();
+ }
+
SurfaceHolder sh = getSurfaceHolder();
final Rect frame = sh.getSurfaceFrame();
- final Drawable background = mBackground;
final int dw = frame.width();
final int dh = frame.height();
- final int bw = background != null ? background.getIntrinsicWidth() : 0;
- final int bh = background != null ? background.getIntrinsicHeight() : 0;
- final int availw = dw - bw;
- final int availh = dh - bh;
+ final int availw = dw - mBackgroundWidth;
+ final int availh = dh - mBackgroundHeight;
int xPixels = availw < 0 ? (int)(availw * mXOffset + .5f) : (availw / 2);
int yPixels = availh < 0 ? (int)(availh * mYOffset + .5f) : (availh / 2);
@@ -241,6 +228,14 @@
mLastXTranslation = xPixels;
mLastYTranslation = yPixels;
+ if (mBackground == null) {
+ // If we somehow got to this point after we have last flushed
+ // the wallpaper, well we really need it to draw again. So
+ // seems like we need to reload it. Ouch.
+ updateWallpaperLocked();
+ }
+
+ //Slog.i(TAG, "************** DRAWING WALLAPER ******************");
Canvas c = sh.lockCanvas();
if (c != null) {
try {
@@ -251,20 +246,30 @@
c.translate(xPixels, yPixels);
if (availw < 0 || availh < 0) {
c.save(Canvas.CLIP_SAVE_FLAG);
- c.clipRect(0, 0, bw, bh, Op.DIFFERENCE);
+ c.clipRect(0, 0, mBackgroundWidth, mBackgroundHeight, Op.DIFFERENCE);
c.drawColor(0xff000000);
c.restore();
}
- if (background != null) {
- background.draw(c);
+ if (mBackground != null) {
+ mBackground.draw(c);
}
} finally {
sh.unlockCanvasAndPost(c);
}
}
+
+ if (FIXED_SIZED_SURFACE) {
+ // If the surface is fixed-size, we should only need to
+ // draw it once and then we'll let the window manager
+ // position it appropriately. As such, we no longer needed
+ // the loaded bitmap. Yay!
+ mBackground = null;
+ mWallpaperManager.forgetLoadedWallpaper();
+ }
}
void updateWallpaperLocked() {
+ //Slog.i(TAG, "************** LOADING WALLAPER ******************");
Throwable exception = null;
try {
mBackground = mWallpaperManager.getFastDrawable();
@@ -286,7 +291,8 @@
Log.w(TAG, "Unable reset to default wallpaper!", ex);
}
}
- mRedrawNeeded = true;
+ mBackgroundWidth = mBackground != null ? mBackground.getIntrinsicWidth() : 0;
+ mBackgroundHeight = mBackground != null ? mBackground.getIntrinsicHeight() : 0;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index c896046..d74b548 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -501,6 +501,7 @@
new RectF(mGlowBitmapPaddingLeftPx, mGlowBitmapPaddingTopPx,
outBitmap.getWidth() - mGlowBitmapPaddingRightPx,
outBitmap.getHeight() - mGlowBitmapPaddingBottomPx), paint);
+ canvas.setBitmap(null);
}
return outBitmap;
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 3a47e6e..fc21929 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -294,6 +294,7 @@
c.rotate(360f - degrees);
c.translate(-dims[0] / 2, -dims[1] / 2);
c.drawBitmap(mScreenBitmap, 0, 0, null);
+ c.setBitmap(null);
mScreenBitmap = ss;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
index 918d5a3..61da1f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
@@ -119,7 +119,8 @@
PixelFormat.RGBX_8888);
lp.gravity = getStatusBarGravity();
lp.setTitle("StatusBar");
- // TODO lp.windowAnimations = R.style.Animation_StatusBar;
+ lp.packageName = mContext.getPackageName();
+ lp.windowAnimations = R.style.Animation_StatusBar;
WindowManagerImpl.getDefault().addView(sb, lp);
if (SPEW) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandedView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandedView.java
index 51fc7c2..3276e1f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandedView.java
@@ -16,16 +16,9 @@
package com.android.systemui.statusbar.phone;
-import android.animation.LayoutTransition;
import android.content.Context;
import android.util.AttributeSet;
-import android.view.Display;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.WindowManager;
import android.widget.LinearLayout;
-import android.util.Slog;
-
public class ExpandedView extends LinearLayout {
PhoneStatusBar mService;
@@ -38,8 +31,6 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
-
- setLayerType(LAYER_TYPE_HARDWARE, null);
}
/** We want to shrink down to 0, and ignore the background. */
@@ -49,7 +40,7 @@
}
@Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
int height = bottom - top;
if (height != mPrevHeight) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
index f6aa159..20215bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
@@ -44,14 +44,15 @@
mMoreView = new StatusBarIconView(context, "more", null);
mMoreView.set(mMoreIcon);
- addView(mMoreView, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
+ super.addView(mMoreView, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
+ }
+
+ public void addView(StatusBarIconView v, int index, LinearLayout.LayoutParams p) {
+ super.addView(v, index+1, p);
}
public void addView(StatusBarIconView v, int index) {
- if (index == 0) {
- throw new RuntimeException("Attempt to put view before the more view: " + v);
- }
- addView(v, index, new LinearLayout.LayoutParams(mIconSize, mIconSize));
+ super.addView(v, index+1, new LinearLayout.LayoutParams(mIconSize, mIconSize));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index f8ceb8f..7d1aedc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -16,12 +16,10 @@
package com.android.systemui.statusbar.phone;
-import android.app.Service;
import android.app.ActivityManagerNative;
import android.app.Dialog;
import android.app.Notification;
import android.app.PendingIntent;
-import android.app.Service;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -30,8 +28,10 @@
import android.content.res.Resources;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
+import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
@@ -64,16 +64,12 @@
import android.widget.RemoteViews;
import android.widget.ScrollView;
import android.widget.TextView;
-import android.widget.FrameLayout;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Set;
import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.statusbar.StatusBarIconList;
import com.android.internal.statusbar.StatusBarNotification;
import com.android.systemui.R;
@@ -91,6 +87,9 @@
static final boolean SPEW = false;
public static final boolean DEBUG = false;
+ // additional instrumentation for testing purposes; intended to be left on during development
+ public static final boolean CHATTY = DEBUG || true;
+
public static final String ACTION_STATUSBAR_START
= "com.android.internal.policy.statusbar.START";
@@ -114,7 +113,9 @@
LocationController mLocationController;
NetworkController mNetworkController;
- int mIconSize;
+ int mNaturalBarHeight = -1;
+ int mIconSize = -1;
+ int mIconHPadding = -1;
Display mDisplay;
IWindowManager mWindowManager;
@@ -138,17 +139,14 @@
View mExpandedContents;
// top bar
TextView mNoNotificationsTitle;
- TextView mClearButton;
+ View mClearButton;
// drag bar
CloseDragHandle mCloseView;
- // ongoing
- NotificationData mOngoing = new NotificationData();
- TextView mOngoingTitle;
- ViewGroup mOngoingItems;
- // latest
- NotificationData mLatest = new NotificationData();
- TextView mLatestTitle;
- ViewGroup mLatestItems;
+
+ // all notifications
+ NotificationData mNotificationData = new NotificationData();
+ ViewGroup mPile;
+
// position
int[] mPositionTmp = new int[2];
boolean mExpanded;
@@ -186,7 +184,6 @@
boolean mAnimating;
long mCurAnimationTime;
- float mDisplayHeight;
float mAnimY;
float mAnimVel;
float mAnimAccel;
@@ -201,6 +198,8 @@
// tracking calls to View.setSystemUiVisibility()
int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
+ final Point mDisplaySize = new Point();
+
private class ExpandedDialog extends Dialog {
ExpandedDialog(Context context) {
super(context, com.android.internal.R.style.Theme_Light_NoTitleBar);
@@ -246,6 +245,9 @@
Resources res = context.getResources();
+ mDisplay.getSize(mDisplaySize);
+ loadDimens();
+
mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
ExpandedView expanded = (ExpandedView)View.inflate(context,
@@ -299,19 +301,13 @@
mExpandedDialog = new ExpandedDialog(context);
mExpandedView = expanded;
mExpandedContents = expanded.findViewById(R.id.notificationLinearLayout);
- mOngoingTitle = (TextView)expanded.findViewById(R.id.ongoingTitle);
- mOngoingItems = (ViewGroup)expanded.findViewById(R.id.ongoingItems);
- mLatestTitle = (TextView)expanded.findViewById(R.id.latestTitle);
- mLatestItems = (ViewGroup)expanded.findViewById(R.id.latestItems);
+ mPile = (ViewGroup)expanded.findViewById(R.id.latestItems);
mNoNotificationsTitle = (TextView)expanded.findViewById(R.id.noNotificationsTitle);
- mClearButton = (TextView)expanded.findViewById(R.id.clear_all_button);
+ mClearButton = expanded.findViewById(R.id.clear_all_button);
mClearButton.setOnClickListener(mClearButtonListener);
mScrollView = (ScrollView)expanded.findViewById(R.id.scroll);
mNotificationLinearLayout = expanded.findViewById(R.id.notificationLinearLayout);
- mOngoingTitle.setVisibility(View.GONE);
- mLatestTitle.setVisibility(View.GONE);
-
mTicker = new MyTicker(context, sb);
TickerView tickerView = (TickerView)sb.findViewById(R.id.tickerText);
@@ -512,7 +508,8 @@
lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
lp.y += height * 1.5; // FIXME
lp.setTitle("IntruderAlert");
- lp.windowAnimations = com.android.internal.R.style.Animation_StatusBar_IntruderAlert;
+ lp.packageName = mContext.getPackageName();
+ lp.windowAnimations = R.style.Animation_StatusBar_IntruderAlert;
WindowManagerImpl.getDefault().addView(mIntruderAlertView, lp);
}
@@ -563,7 +560,7 @@
View button = mIntruderAlertView.findViewById(R.id.intruder_alert_content);
button.setOnClickListener(
- new Launcher(notification.notification.contentIntent,
+ new NotificationClicker(notification.notification.contentIntent,
notification.pkg, notification.tag, notification.id));
// 2. Animate mIntruderAlertView in
@@ -594,25 +591,20 @@
}
public void updateNotification(IBinder key, StatusBarNotification notification) {
- Slog.d(TAG, "updateNotification key=" + key + " notification=" + notification);
+ if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ")");
- NotificationData oldList;
- NotificationData.Entry oldEntry = mOngoing.findByKey(key);
- if (oldEntry != null) {
- oldList = mOngoing;
- } else {
- oldEntry = mLatest.findByKey(key);
- if (oldEntry == null) {
- Slog.w(TAG, "updateNotification for unknown key: " + key);
- return;
- }
- oldList = mLatest;
+ final NotificationData.Entry oldEntry = mNotificationData.findByKey(key);
+ if (oldEntry == null) {
+ Slog.w(TAG, "updateNotification for unknown key: " + key);
+ return;
}
+
final StatusBarNotification oldNotification = oldEntry.notification;
final RemoteViews oldContentView = oldNotification.notification.contentView;
final RemoteViews contentView = notification.notification.contentView;
+
if (DEBUG) {
Slog.d(TAG, "old notification: when=" + oldNotification.notification.when
+ " ongoing=" + oldNotification.isOngoing()
@@ -637,8 +629,8 @@
boolean orderUnchanged = notification.notification.when==oldNotification.notification.when
&& notification.priority == oldNotification.priority;
// priority now encompasses isOngoing()
- boolean isLastAnyway = rowParent.indexOfChild(oldEntry.row) == rowParent.getChildCount()-1;
- if (contentsUnchanged && (orderUnchanged || isLastAnyway)) {
+ boolean isFirstAnyway = rowParent.indexOfChild(oldEntry.row) == 0;
+ if (contentsUnchanged && (orderUnchanged || isFirstAnyway)) {
if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
oldEntry.notification = notification;
try {
@@ -647,7 +639,7 @@
// update the contentIntent
final PendingIntent contentIntent = notification.notification.contentIntent;
if (contentIntent != null) {
- oldEntry.content.setOnClickListener(new Launcher(contentIntent,
+ oldEntry.content.setOnClickListener(new NotificationClicker(contentIntent,
notification.pkg, notification.tag, notification.id));
} else {
oldEntry.content.setOnClickListener(null);
@@ -655,7 +647,8 @@
// Update the icon.
final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
notification.notification.icon, notification.notification.iconLevel,
- notification.notification.number, notification.notification.tickerText);
+ notification.notification.number,
+ notification.notification.tickerText);
if (!oldEntry.icon.set(ic)) {
handleNotificationError(key, notification, "Couldn't update icon: " + ic);
return;
@@ -664,12 +657,9 @@
if (notification.notification.largeIcon != null) {
oldEntry.largeIcon.setImageBitmap(notification.notification.largeIcon);
} else {
- if (oldEntry.largeIcon != null) {
- oldEntry.largeIcon.getLayoutParams().width = 0;
- oldEntry.largeIcon.setVisibility(View.INVISIBLE);
- }
+ oldEntry.largeIcon.getLayoutParams().width = 0;
+ oldEntry.largeIcon.setVisibility(View.INVISIBLE);
}
-
}
catch (RuntimeException e) {
// It failed to add cleanly. Log, and remove the view from the panel.
@@ -709,15 +699,6 @@
}
}
- private int chooseIconIndex(boolean isOngoing, int viewIndex) {
- final int latestSize = mLatest.size();
- if (isOngoing) {
- return latestSize + (mOngoing.size() - viewIndex);
- } else {
- return latestSize - viewIndex;
- }
- }
-
@Override
protected void onConfigurationChanged(Configuration newConfig) {
updateRecentsPanel();
@@ -774,7 +755,7 @@
content.setOnFocusChangeListener(mFocusChangeListener);
PendingIntent contentIntent = n.contentIntent;
if (contentIntent != null) {
- content.setOnClickListener(new Launcher(contentIntent, notification.pkg,
+ content.setOnClickListener(new NotificationClicker(contentIntent, notification.pkg,
notification.tag, notification.id));
} else {
content.setOnClickListener(null);
@@ -801,82 +782,232 @@
}
StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) {
- NotificationData list;
- ViewGroup parent;
- final boolean isOngoing = notification.isOngoing();
- if (isOngoing) {
- list = mOngoing;
- parent = mOngoingItems;
- } else {
- list = mLatest;
- parent = mLatestItems;
+ if (DEBUG) {
+ Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification);
}
- // Construct the expanded view.
- final View[] views = makeNotificationView(notification, parent);
- if (views == null) {
- handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
- + notification);
- return null;
- }
- final View row = views[0];
- final View content = views[1];
- final View expanded = views[2];
// Construct the icon.
final StatusBarIconView iconView = new StatusBarIconView(mContext,
notification.pkg + "/0x" + Integer.toHexString(notification.id),
notification.notification);
- final StatusBarIcon ic = new StatusBarIcon(notification.pkg, notification.notification.icon,
- notification.notification.iconLevel, notification.notification.number,
+ iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+
+ final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
+ notification.notification.icon,
+ notification.notification.iconLevel,
+ notification.notification.number,
notification.notification.tickerText);
if (!iconView.set(ic)) {
- handleNotificationError(key, notification, "Coulding create icon: " + ic);
+ handleNotificationError(key, notification, "Couldn't create icon: " + ic);
return null;
}
- // Add the expanded view.
- final int viewIndex = list.add(key, notification, row, content, expanded, iconView);
- parent.addView(row, viewIndex);
- // Add the icon.
- final int iconIndex = chooseIconIndex(isOngoing, viewIndex);
- mNotificationIcons.addView(iconView, iconIndex);
+ // Construct the expanded view.
+ NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView);
+ if (!inflateViews(entry, mPile)) {
+ handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
+ + notification);
+ return null;
+ }
+
+ // Add the expanded view and icon.
+ int pos = mNotificationData.add(entry);
+ if (DEBUG) {
+ Slog.d(TAG, "addNotificationViews: added at " + pos);
+ }
+ updateNotificationIcons();
+
return iconView;
}
- StatusBarNotification removeNotificationViews(IBinder key) {
- NotificationData.Entry entry = mOngoing.remove(key);
- if (entry == null) {
- entry = mLatest.remove(key);
- if (entry == null) {
- Slog.w(TAG, "removeNotification for unknown key: " + key);
- return null;
+ private void loadNotificationShade() {
+ int N = mNotificationData.size();
+
+ ArrayList<View> toShow = new ArrayList<View>();
+
+ for (int i=0; i<N; i++) {
+ View row = mNotificationData.get(N-i-1).row;
+ toShow.add(row);
+ }
+
+ ArrayList<View> toRemove = new ArrayList<View>();
+ for (int i=0; i<mPile.getChildCount(); i++) {
+ View child = mPile.getChildAt(i);
+ if (!toShow.contains(child)) {
+ toRemove.add(child);
}
}
+
+ for (View remove : toRemove) {
+ mPile.removeView(remove);
+ }
+
+ for (int i=0; i<toShow.size(); i++) {
+ View v = toShow.get(i);
+ if (v.getParent() == null) {
+ mPile.addView(v, 0); // the notification shade has newest at the top
+ }
+ }
+ }
+
+ private void reloadAllNotificationIcons() {
+ if (mNotificationIcons == null) return;
+ mNotificationIcons.removeAllViews();
+ updateNotificationIcons();
+ }
+
+ private void updateNotificationIcons() {
+ loadNotificationShade();
+
+ final LinearLayout.LayoutParams params
+ = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
+
+ int N = mNotificationData.size();
+
+ if (DEBUG) {
+ Slog.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons);
+ }
+
+ ArrayList<View> toShow = new ArrayList<View>();
+
+ for (int i=0; i<N; i++) {
+ toShow.add(mNotificationData.get(N-i-1).icon);
+ }
+
+ ArrayList<View> toRemove = new ArrayList<View>();
+ for (int i=0; i<mNotificationIcons.getChildCount(); i++) {
+ View child = mNotificationIcons.getChildAt(i);
+ if (!toShow.contains(child)) {
+ toRemove.add(child);
+ }
+ }
+
+ for (View remove : toRemove) {
+ mNotificationIcons.removeView(remove);
+ }
+
+ for (int i=0; i<toShow.size(); i++) {
+ View v = toShow.get(i);
+ if (v.getParent() == null) {
+ mNotificationIcons.addView(v, i, params);
+ }
+ }
+ }
+
+ void workAroundBadLayerDrawableOpacity(View v) {
+ LayerDrawable d = (LayerDrawable)v.getBackground();
+ if (d == null) return;
+ v.setBackgroundDrawable(null);
+ d.setOpacity(PixelFormat.TRANSLUCENT);
+ v.setBackgroundDrawable(d);
+ }
+
+ private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
+ StatusBarNotification sbn = entry.notification;
+ RemoteViews remoteViews = sbn.notification.contentView;
+ if (remoteViews == null) {
+ return false;
+ }
+
+ // create the row view
+ LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
+ workAroundBadLayerDrawableOpacity(row);
+ View vetoButton = row.findViewById(R.id.veto);
+ if (entry.notification.isClearable()) {
+ final String _pkg = sbn.pkg;
+ final String _tag = sbn.tag;
+ final int _id = sbn.id;
+ vetoButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ try {
+ mBarService.onNotificationClear(_pkg, _tag, _id);
+ } catch (RemoteException ex) {
+ // system process is dead if we're here.
+ }
+ }
+ });
+ } else {
+ if ((sbn.notification.flags & Notification.FLAG_ONGOING_EVENT) == 0) {
+ vetoButton.setVisibility(View.INVISIBLE);
+ vetoButton.setContentDescription("VETO");
+ } else {
+ vetoButton.setVisibility(View.GONE);
+ }
+ }
+ vetoButton.setContentDescription(mContext.getString(
+ R.string.accessibility_remove_notification));
+
+ // the large icon
+ ImageView largeIcon = (ImageView)row.findViewById(R.id.large_icon);
+ if (sbn.notification.largeIcon != null) {
+ largeIcon.setImageBitmap(sbn.notification.largeIcon);
+ largeIcon.setContentDescription(sbn.notification.tickerText);
+ } else {
+ largeIcon.getLayoutParams().width = 0;
+ largeIcon.setVisibility(View.INVISIBLE);
+ }
+ largeIcon.setContentDescription(sbn.notification.tickerText);
+
+ // bind the click event to the content area
+ ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
+ // XXX: update to allow controls within notification views
+ content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+// content.setOnFocusChangeListener(mFocusChangeListener);
+ PendingIntent contentIntent = sbn.notification.contentIntent;
+ if (contentIntent != null) {
+ content.setOnClickListener(new NotificationClicker(contentIntent,
+ sbn.pkg, sbn.tag, sbn.id));
+ } else {
+ content.setOnClickListener(null);
+ }
+
+ View expanded = null;
+ Exception exception = null;
+ try {
+ expanded = remoteViews.apply(mContext, content);
+ }
+ catch (RuntimeException e) {
+ exception = e;
+ }
+ if (expanded == null) {
+ final String ident = sbn.pkg + "/0x" + Integer.toHexString(sbn.id);
+ Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
+ return false;
+ } else {
+ content.addView(expanded);
+ row.setDrawingCacheEnabled(true);
+ }
+
+ entry.row = row;
+ entry.content = content;
+ entry.expanded = expanded;
+ entry.largeIcon = largeIcon;
+
+ return true;
+ }
+
+ StatusBarNotification removeNotificationViews(IBinder key) {
+ NotificationData.Entry entry = mNotificationData.remove(key);
+ if (entry == null) {
+ Slog.w(TAG, "removeNotification for unknown key: " + key);
+ return null;
+ }
// Remove the expanded view.
- ((ViewGroup)entry.row.getParent()).removeView(entry.row);
- // Remove the icon.
- ((ViewGroup)entry.icon.getParent()).removeView(entry.icon);
+ ViewGroup rowParent = (ViewGroup)entry.row.getParent();
+ if (rowParent != null) rowParent.removeView(entry.row);
+ updateNotificationIcons();
return entry.notification;
}
private void setAreThereNotifications() {
- boolean ongoing = mOngoing.hasVisibleItems();
- boolean latest = mLatest.hasVisibleItems();
+ mClearButton.setVisibility(mNotificationData.hasClearableItems()
+ ? View.VISIBLE
+ : View.INVISIBLE);
- // (no ongoing notifications are clearable)
- if (mLatest.hasClearableItems()) {
- mClearButton.setVisibility(View.VISIBLE);
- } else {
- mClearButton.setVisibility(View.INVISIBLE);
- }
-
- mOngoingTitle.setVisibility(ongoing ? View.VISIBLE : View.GONE);
- mLatestTitle.setVisibility(latest ? View.VISIBLE : View.GONE);
-
- if (ongoing || latest) {
- mNoNotificationsTitle.setVisibility(View.GONE);
- } else {
- mNoNotificationsTitle.setVisibility(View.VISIBLE);
- }
+ mNoNotificationsTitle.setVisibility(mNotificationData.size() > 0
+ ? View.GONE
+ : View.VISIBLE);
}
@@ -1021,7 +1152,7 @@
if (mAnimating) {
y = (int)mAnimY;
} else {
- y = mDisplay.getHeight()-1;
+ y = mDisplaySize.y-1;
}
// Let the fling think that we're open so it goes in the right direction
// and doesn't try to re-open the windowshade.
@@ -1077,7 +1208,7 @@
if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY);
incrementAnim();
if (SPEW) Slog.d(TAG, "doAnimation after mAnimY=" + mAnimY);
- if (mAnimY >= mDisplay.getHeight()-1) {
+ if (mAnimY >= mDisplaySize.y-1) {
if (SPEW) Slog.d(TAG, "Animation completed to expanded state.");
mAnimating = false;
updateExpandedViewPos(EXPANDED_FULL_OPEN);
@@ -1133,6 +1264,10 @@
}
void prepareTracking(int y, boolean opening) {
+ if (CHATTY) {
+ Slog.d(TAG, "panel: beginning to track the user's touch, y=" + y + " opening=" + opening);
+ }
+
mTracking = true;
mVelocityTracker = VelocityTracker.obtain();
if (opening) {
@@ -1162,8 +1297,11 @@
}
void performFling(int y, float vel, boolean always) {
+ if (CHATTY) {
+ Slog.d(TAG, "panel: will fling, y=" + y + " vel=" + vel);
+ }
+
mAnimatingReveal = false;
- mDisplayHeight = mDisplay.getHeight();
mAnimY = y;
mAnimVel = vel;
@@ -1173,7 +1311,7 @@
if (mExpanded) {
if (!always && (
vel > 200.0f
- || (y > (mDisplayHeight-25) && vel > -200.0f))) {
+ || (y > (mDisplaySize.y-25) && vel > -200.0f))) {
// We are expanded, but they didn't move sufficiently to cause
// us to retract. Animate back to the expanded position.
mAnimAccel = 2000.0f;
@@ -1191,7 +1329,7 @@
} else {
if (always || (
vel > 200.0f
- || (y > (mDisplayHeight/2) && vel > -200.0f))) {
+ || (y > (mDisplaySize.y/2) && vel > -200.0f))) {
// We are collapsed, and they moved enough to allow us to
// expand. Animate in the notifications.
mAnimAccel = 2000.0f;
@@ -1225,6 +1363,12 @@
if (SPEW) {
Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
+ mDisabled);
+ } else if (CHATTY) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ Slog.d(TAG, String.format(
+ "panel: ACTION_DOWN at (%f, %f) mDisabled=0x%08x",
+ event.getRawX(), event.getRawY(), mDisabled));
+ }
}
if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
@@ -1243,14 +1387,14 @@
mViewDelta = mAbsPos[1] + mTrackingView.getHeight() - y;
}
if ((!mExpanded && y < hitSize) ||
- (mExpanded && y > (mDisplay.getHeight()-hitSize))) {
+ (mExpanded && y > (mDisplaySize.y-hitSize))) {
// We drop events at the edge of the screen to make the windowshade come
// down by accident less, especially when pushing open a device with a keyboard
// that rotates (like g1 and droid)
int x = (int)event.getRawX();
final int edgeBorder = mEdgeBorder;
- if (x >= edgeBorder && x < mDisplay.getWidth() - edgeBorder) {
+ if (x >= edgeBorder && x < mDisplaySize.x - edgeBorder) {
prepareTracking(y, !mExpanded);// opening if we're not already fully visible
mVelocityTracker.addMovement(event);
}
@@ -1339,13 +1483,17 @@
@Override
public void setHardKeyboardStatus(boolean available, boolean enabled) { }
- private class Launcher implements View.OnClickListener {
+ public NotificationClicker makeClicker(PendingIntent intent, String pkg, String tag, int id) {
+ return new NotificationClicker(intent, pkg, tag, id);
+ }
+
+ private class NotificationClicker implements View.OnClickListener {
private PendingIntent mIntent;
private String mPkg;
private String mTag;
private int mId;
- Launcher(PendingIntent intent, String pkg, String tag, int id) {
+ NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
mIntent = intent;
mPkg = pkg;
mTag = tag;
@@ -1494,19 +1642,15 @@
+ ", mAnimAccel=" + mAnimAccel);
pw.println(" mCurAnimationTime=" + mCurAnimationTime
+ " mAnimLastTime=" + mAnimLastTime);
- pw.println(" mDisplayHeight=" + mDisplayHeight
- + " mAnimatingReveal=" + mAnimatingReveal
+ pw.println(" mAnimatingReveal=" + mAnimatingReveal
+ " mViewDelta=" + mViewDelta);
- pw.println(" mDisplayHeight=" + mDisplayHeight);
+ pw.println(" mDisplaySize=" + mDisplaySize);
pw.println(" mExpandedParams: " + mExpandedParams);
pw.println(" mExpandedView: " + viewInfo(mExpandedView));
pw.println(" mExpandedDialog: " + mExpandedDialog);
pw.println(" mTrackingParams: " + mTrackingParams);
pw.println(" mTrackingView: " + viewInfo(mTrackingView));
- pw.println(" mOngoingTitle: " + viewInfo(mOngoingTitle));
- pw.println(" mOngoingItems: " + viewInfo(mOngoingItems));
- pw.println(" mLatestTitle: " + viewInfo(mLatestTitle));
- pw.println(" mLatestItems: " + viewInfo(mLatestItems));
+ pw.println(" mPile: " + viewInfo(mPile));
pw.println(" mNoNotificationsTitle: " + viewInfo(mNoNotificationsTitle));
pw.println(" mCloseView: " + viewInfo(mCloseView));
pw.println(" mTickerView: " + viewInfo(mTickerView));
@@ -1592,17 +1736,13 @@
void onTrackingViewAttached() {
WindowManager.LayoutParams lp;
int pixelFormat;
- Drawable bg;
/// ---------- Expanded View --------------
pixelFormat = PixelFormat.TRANSLUCENT;
- final int disph = mDisplay.getHeight();
lp = mExpandedDialog.getWindow().getAttributes();
- lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
- lp.height = getExpandedHeight();
lp.x = 0;
- mTrackingPosition = lp.y = -disph; // sufficiently large negative
+ mTrackingPosition = lp.y = mDisplaySize.y; // sufficiently large negative
lp.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
@@ -1612,9 +1752,9 @@
lp.format = pixelFormat;
lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
lp.setTitle("StatusBarExpanded");
- mExpandedDialog.getWindow().setAttributes(lp);
- mExpandedDialog.getWindow().setFormat(pixelFormat);
mExpandedParams = lp;
+ updateExpandedSize();
+ mExpandedDialog.getWindow().setFormat(pixelFormat);
mExpandedDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
mExpandedDialog.setContentView(mExpandedView,
@@ -1622,7 +1762,6 @@
ViewGroup.LayoutParams.MATCH_PARENT));
mExpandedDialog.getWindow().setBackgroundDrawable(null);
mExpandedDialog.show();
- FrameLayout hack = (FrameLayout)mExpandedView.getParent();
}
void setDateViewVisibility(boolean visible, int anim) {
@@ -1639,6 +1778,20 @@
}
}
+ void updateExpandedInvisiblePosition() {
+ if (mTrackingView != null) {
+ mTrackingPosition = -mDisplaySize.y;
+ if (mTrackingParams != null) {
+ mTrackingParams.y = mTrackingPosition;
+ WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams);
+ }
+ }
+ if (mExpandedParams != null) {
+ mExpandedParams.y = -mDisplaySize.y;
+ mExpandedDialog.getWindow().setAttributes(mExpandedParams);
+ }
+ }
+
void updateExpandedViewPos(int expandedPosition) {
if (SPEW) {
Slog.d(TAG, "updateExpandedViewPos before expandedPosition=" + expandedPosition
@@ -1647,22 +1800,12 @@
}
int h = mStatusBarView.getHeight();
- int disph = mDisplay.getHeight();
+ int disph = mDisplaySize.y;
// If the expanded view is not visible, make sure they're still off screen.
// Maybe the view was resized.
if (!mExpandedVisible) {
- if (mTrackingView != null) {
- mTrackingPosition = -disph;
- if (mTrackingParams != null) {
- mTrackingParams.y = mTrackingPosition;
- WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams);
- }
- }
- if (mExpandedParams != null) {
- mExpandedParams.y = -disph;
- mExpandedDialog.getWindow().setAttributes(mExpandedParams);
- }
+ updateExpandedInvisiblePosition();
return;
}
@@ -1687,14 +1830,21 @@
WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams);
if (mExpandedParams != null) {
- mCloseView.getLocationInWindow(mPositionTmp);
- final int closePos = mPositionTmp[1];
+ if (mCloseView.getWindowVisibility() == View.VISIBLE) {
+ mCloseView.getLocationInWindow(mPositionTmp);
+ final int closePos = mPositionTmp[1];
- mExpandedContents.getLocationInWindow(mPositionTmp);
- final int contentsBottom = mPositionTmp[1] + mExpandedContents.getHeight();
+ mExpandedContents.getLocationInWindow(mPositionTmp);
+ final int contentsBottom = mPositionTmp[1] + mExpandedContents.getHeight();
- mExpandedParams.y = pos + mTrackingView.getHeight()
- - (mTrackingParams.height-closePos) - contentsBottom;
+ mExpandedParams.y = pos + mTrackingView.getHeight()
+ - (mTrackingParams.height-closePos) - contentsBottom;
+ } else {
+ // If the tracking view is not yet visible, then we can't have
+ // a good value of the close view location. We need to wait for
+ // it to be visible to do a layout.
+ mExpandedParams.y = -mDisplaySize.y;
+ }
int max = h;
if (mExpandedParams.y > max) {
mExpandedParams.y = max;
@@ -1730,14 +1880,24 @@
}
}
- int getExpandedHeight() {
- return mDisplay.getHeight() - mStatusBarView.getHeight() - mCloseView.getHeight();
+ int getExpandedHeight(int disph) {
+ return disph - mStatusBarView.getHeight() - mCloseView.getHeight();
}
- void updateExpandedHeight() {
- if (mExpandedView != null) {
- mExpandedParams.height = getExpandedHeight();
- mExpandedDialog.getWindow().setAttributes(mExpandedParams);
+ void updateDisplaySize() {
+ mDisplay.getSize(mDisplaySize);
+ updateExpandedSize();
+ }
+
+ void updateExpandedSize() {
+ if (mExpandedDialog != null && mExpandedParams != null && mDisplaySize != null) {
+ mExpandedParams.width = mDisplaySize.x;
+ mExpandedParams.height = getExpandedHeight(mDisplaySize.y);
+ if (!mExpandedVisible) {
+ updateExpandedInvisiblePosition();
+ } else {
+ mExpandedDialog.getWindow().setAttributes(mExpandedParams);
+ }
}
}
@@ -1855,11 +2015,32 @@
final Context context = mContext;
final Resources res = context.getResources();
- mClearButton.setText(context.getText(R.string.status_bar_clear_all_button));
- mOngoingTitle.setText(context.getText(R.string.status_bar_ongoing_events_title));
- mLatestTitle.setText(context.getText(R.string.status_bar_latest_events_title));
+ if (mClearButton instanceof TextView) {
+ ((TextView)mClearButton).setText(context.getText(R.string.status_bar_clear_all_button));
+ }
mNoNotificationsTitle.setText(context.getText(R.string.status_bar_no_notifications_title));
+ loadDimens();
+ }
+
+ protected void loadDimens() {
+ final Resources res = mContext.getResources();
+
+ mNaturalBarHeight = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height);
+
+ int newIconSize = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_icon_size);
+ int newIconHPadding = res.getDimensionPixelSize(
+ R.dimen.status_bar_icon_padding);
+
+ if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
+// Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
+ mIconHPadding = newIconHPadding;
+ mIconSize = newIconSize;
+ //reloadAllNotificationIcons(); // reload the tray
+ }
+
mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
if (false) Slog.v(TAG, "updateResources");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index c2390e8..db6907c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -77,6 +77,7 @@
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
+ mService.updateDisplaySize();
boolean nightMode = (newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK)
== Configuration.UI_MODE_NIGHT_YES;
if (mNightMode != nightMode) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingView.java
index fd32a3d..fc0f332 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingView.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;
import android.content.Context;
+import android.os.Handler;
import android.util.AttributeSet;
import android.view.Display;
import android.view.KeyEvent;
@@ -29,6 +30,7 @@
PhoneStatusBar mService;
boolean mTracking;
int mStartX, mStartY;
+ Handler mHandler = new Handler();
public TrackingView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -39,7 +41,6 @@
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
- mService.updateExpandedHeight();
}
@Override
@@ -60,4 +61,16 @@
super.onAttachedToWindow();
mService.onTrackingViewAttached();
}
+
+ @Override
+ protected void onWindowVisibilityChanged(int visibility) {
+ super.onWindowVisibilityChanged(visibility);
+ if (visibility == VISIBLE) {
+ mHandler.post(new Runnable() {
+ @Override public void run() {
+ mService.updateExpandedViewPos(PhoneStatusBar.EXPANDED_LEAVE_ALONE);
+ }
+ });
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
index 6ab03e1..a171514 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
@@ -28,6 +28,8 @@
import android.view.View;
import android.view.ViewParent;
+import com.android.systemui.R;
+
import java.util.Date;
public final class DateView extends TextView {
@@ -90,7 +92,7 @@
Date now = new Date();
CharSequence dow = DateFormat.format("EEEE", now);
CharSequence date = DateFormat.getMediumDateFormat(getContext()).format(now);
- setText(dow + "\n" + date);
+ setText(context.getString(R.string.status_bar_date_formatter, dow, date));
}
private boolean isVisible() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index f32c602..97b6298 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -61,6 +61,7 @@
// debug
static final String TAG = "StatusBar.NetworkController";
static final boolean DEBUG = false;
+ static final boolean CHATTY = true; // additional diagnostics, but not logspew
// telephony
boolean mHspaDataDistinguishable;
@@ -286,7 +287,7 @@
@Override
public void onDataConnectionStateChanged(int state, int networkType) {
- if (DEBUG) {
+ if (DEBUG || CHATTY) {
Slog.d(TAG, "onDataConnectionStateChanged: state=" + state
+ " type=" + networkType);
}
@@ -682,10 +683,19 @@
// ===== Full or limited Internet connectivity ==================================
private void updateConnectivity(Intent intent) {
+ if (CHATTY) {
+ Slog.d(TAG, "updateConnectivity: intent=" + intent);
+ }
+
NetworkInfo info = (NetworkInfo)(intent.getParcelableExtra(
ConnectivityManager.EXTRA_NETWORK_INFO));
int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0);
+ if (CHATTY) {
+ Slog.d(TAG, "updateConnectivity: networkInfo=" + info);
+ Slog.d(TAG, "updateConnectivity: connectionStatus=" + connectionStatus);
+ }
+
int inetCondition = (connectionStatus > INET_CONDITION_THRESHOLD ? 1 : 0);
switch (info.getType()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
index 90234c7..2a0dfb5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
@@ -324,7 +324,14 @@
if (child.getVisibility() == GONE) {
continue;
}
- final int thisRowHeight = (int)(child.getAlpha() * mRowHeight);
+ float alpha = child.getAlpha();
+ if (alpha > 1.0f) {
+ if (DEBUG) {
+ Slog.w(TAG, "alpha=" + alpha + " > 1!!! " + child);
+ }
+ alpha = 1f;
+ }
+ final int thisRowHeight = (int)(alpha * mRowHeight);
if (DEBUG) {
Slog.d(TAG, String.format(
"laying out child #%d: (0, %d, %d, %d) h=%d",
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
index 100ed55..fd58174 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
@@ -22,6 +22,7 @@
import android.util.AttributeSet;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethodSubtype;
import android.view.View;
import android.widget.ImageView;
@@ -48,6 +49,9 @@
private boolean mScreenLocked = false;
private boolean mHardKeyboardAvailable;
+ // Please refer to InputMethodManagerService.TAG_TRY_SUPPRESSING_IME_SWITCHER
+ private static final String TAG_TRY_SUPPRESSING_IME_SWITCHER = "TrySuppressingImeSwitcher";
+
public InputMethodButton(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -64,10 +68,49 @@
refreshStatusIcon();
}
- // Display IME switcher icon only when all of the followings are true:
- // * There is only one enabled IME on the device. (Note that the IME should be the system IME)
- // * There are no explicitly enabled (by the user) subtypes of the IME, or the IME doesn't have
- // its subtypes at all
+ // Refer to InputMethodManagerService.needsToShowImeSwitchOngoingNotification()
+ private boolean needsToShowIMEButtonWhenVisibilityAuto() {
+ List<InputMethodInfo> imis = mImm.getEnabledInputMethodList();
+ final int N = imis.size();
+ if (N > 2) return true;
+ if (N < 1) return false;
+ int nonAuxCount = 0;
+ int auxCount = 0;
+ InputMethodSubtype nonAuxSubtype = null;
+ InputMethodSubtype auxSubtype = null;
+ for(int i = 0; i < N; ++i) {
+ final InputMethodInfo imi = imis.get(i);
+ final List<InputMethodSubtype> subtypes = mImm.getEnabledInputMethodSubtypeList(
+ imi, true);
+ final int subtypeCount = subtypes.size();
+ if (subtypeCount == 0) {
+ ++nonAuxCount;
+ } else {
+ for (int j = 0; j < subtypeCount; ++j) {
+ final InputMethodSubtype subtype = subtypes.get(j);
+ if (!subtype.isAuxiliary()) {
+ ++nonAuxCount;
+ nonAuxSubtype = subtype;
+ } else {
+ ++auxCount;
+ auxSubtype = subtype;
+ }
+ }
+ }
+ }
+ if (nonAuxCount > 1 || auxCount > 1) {
+ return true;
+ } else if (nonAuxCount == 1 && auxCount == 1) {
+ if (nonAuxSubtype != null && auxSubtype != null
+ && nonAuxSubtype.getLocale().equals(auxSubtype.getLocale())
+ && nonAuxSubtype.containsExtraValueKey(TAG_TRY_SUPPRESSING_IME_SWITCHER)) {
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
private boolean needsToShowIMEButton() {
if (!mShowButton || mScreenLocked) return false;
@@ -75,13 +118,10 @@
return true;
}
- List<InputMethodInfo> imis = mImm.getEnabledInputMethodList();
- final int size = imis.size();
final int visibility = loadInputMethodSelectorVisibility();
switch (visibility) {
case ID_IME_BUTTON_VISIBILITY_AUTO:
- return size > 1 || (size == 1
- && mImm.getEnabledInputMethodSubtypeList(imis.get(0), false).size() > 1);
+ return needsToShowIMEButtonWhenVisibilityAuto();
case ID_IME_BUTTON_VISIBILITY_ALWAYS_SHOW:
return true;
case ID_IME_BUTTON_VISIBILITY_ALWAYS_HIDE:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index a316e4b..d9cb4e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -40,6 +40,7 @@
final static int PANEL_FADE_DURATION = 150;
boolean mShowing;
+ boolean mHasClearableNotifications = false;
int mNotificationCount = 0;
NotificationPanelTitle mTitleArea;
View mSettingsButton;
@@ -49,6 +50,8 @@
Rect mContentArea = new Rect();
View mSettingsView;
ViewGroup mContentParent;
+ TabletStatusBar mBar;
+ View mClearButton;
// amount to slide mContentParent down by when mContentFrame is missing
float mContentFrameMissingTranslation;
@@ -63,6 +66,10 @@
super(context, attrs, defStyle);
}
+ public void setBar(TabletStatusBar b) {
+ mBar = b;
+ }
+
@Override
public void onFinishInflate() {
super.onFinishInflate();
@@ -79,14 +86,27 @@
mNotificationScroller = findViewById(R.id.notification_scroller);
mContentFrame = (ViewGroup)findViewById(R.id.content_frame);
- mContentFrameMissingTranslation =
- mContentFrame.getBackground().getMinimumHeight() + 10;
+ mContentFrameMissingTranslation = 0; // not needed with current assets
+
+ // the "X" that appears in place of the clock when the panel is showing notifications
+ mClearButton = findViewById(R.id.clear_all_button);
+ mClearButton.setOnClickListener(mClearButtonListener);
mShowing = false;
setContentFrameVisible(mNotificationCount > 0, false);
}
+ private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
+ public void onClick(View v) {
+ mBar.clearAll();
+ }
+ };
+
+ public View getClearButton() {
+ return mClearButton;
+ }
+
public void show(boolean show, boolean animate) {
if (show && !mShowing) {
setContentFrameVisible(mSettingsView != null || mNotificationCount > 0, false);
@@ -202,15 +222,16 @@
;
set.setDuration(200);
- if (!showing) {
- set.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator _a) {
+ set.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator _a) {
+ if (!showing) {
mContentFrame.setVisibility(View.GONE);
mContentFrame.setAlpha(1f);
}
- });
- }
+ updateClearButton();
+ }
+ });
set.start();
}
@@ -247,12 +268,27 @@
removeSettingsView();
}
}
+ updateClearButton();
updatePanelModeButtons();
}
});
a.start();
}
+ public void updateClearButton() {
+ if (mBar != null) {
+ final boolean showX
+ = (isShowing()
+ && mHasClearableNotifications
+ && mNotificationScroller.getVisibility() == View.VISIBLE);
+ getClearButton().setVisibility(showX ? View.VISIBLE : View.INVISIBLE);
+ }
+ }
+
+ public void setClearable(boolean clearable) {
+ mHasClearableNotifications = clearable;
+ }
+
public void updatePanelModeButtons() {
final boolean settingsVisible = (mSettingsView != null);
mSettingsButton.setVisibility(!settingsVisible ? View.VISIBLE : View.INVISIBLE);
@@ -294,11 +330,11 @@
AnimatorSet mContentAnim;
// should group this into a multi-property animation
- final static int OPEN_DURATION = 136;
- final static int CLOSE_DURATION = 250;
+ final static int OPEN_DURATION = 300;
+ final static int CLOSE_DURATION = 300;
// the panel will start to appear this many px from the end
- final int HYPERSPACE_OFFRAMP = 100;
+ final int HYPERSPACE_OFFRAMP = 200;
Choreographer() {
}
@@ -306,10 +342,6 @@
void createAnimation(boolean appearing) {
// mVisible: previous state; appearing: new state
- View root = findViewById(R.id.panel_root);
- Animator bgAnim = ObjectAnimator.ofInt(root.getBackground(), "alpha",
- mVisible ? 255 : 0, appearing ? 255 : 0);
-
float start, end;
// 0: on-screen
@@ -347,7 +379,6 @@
mContentAnim = new AnimatorSet();
mContentAnim
.play(fadeAnim)
- .with(bgAnim)
.with(posAnim)
;
mContentAnim.setDuration((DEBUG?10:1)*(appearing ? OPEN_DURATION : CLOSE_DURATION));
@@ -363,6 +394,9 @@
mContentAnim.start();
mVisible = appearing;
+
+ // we want to start disappearing promptly
+ if (!mVisible) updateClearButton();
}
public void onAnimationCancel(Animator animation) {
@@ -376,6 +410,9 @@
}
mContentParent.setLayerType(View.LAYER_TYPE_NONE, null);
mContentAnim = null;
+
+ // we want to show the X lazily
+ if (mVisible) updateClearButton();
}
public void onAnimationRepeat(Animator animation) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index c6e546e..7f56d45 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -187,6 +187,7 @@
// Notification Panel
mNotificationPanel = (NotificationPanel)View.inflate(context,
R.layout.status_bar_notification_panel, null);
+ mNotificationPanel.setBar(this);
mNotificationPanel.show(false, false);
mNotificationPanel.setOnTouchListener(
new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PANEL, mNotificationPanel));
@@ -1076,7 +1077,10 @@
mCompatModeButton.refresh();
if (mCompatModeButton.getVisibility() == View.VISIBLE) {
+ if (DEBUG_COMPAT_HELP
+ || ! Prefs.read(mContext).getBoolean(Prefs.SHOWN_COMPAT_MODE_HELP, false)) {
showCompatibilityHelp();
+ }
} else {
hideCompatibilityHelp();
mCompatModePanel.closePanel();
@@ -1183,7 +1187,9 @@
}
private void setAreThereNotifications() {
- final boolean hasClearable = mNotificationData.hasClearableItems();
+ if (mNotificationPanel != null) {
+ mNotificationPanel.setClearable(mNotificationData.hasClearableItems());
+ }
}
/**
@@ -1586,6 +1592,10 @@
}
return;
+ } else if (0 != (mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS)) {
+ // if icons are disabled but we're not in DND mode, this is probably Setup and we should
+ // just leave the area totally empty
+ return;
}
int N = mNotificationData.size();
@@ -1755,6 +1765,15 @@
return true;
}
+ public void clearAll() {
+ try {
+ mBarService.onClearAllNotifications();
+ } catch (RemoteException ex) {
+ // system process is dead if we're here.
+ }
+ animateCollapse();
+ }
+
public void userActivity() {
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
index dff1f6a..7d11251 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
@@ -94,6 +94,11 @@
mHandler = h;
}
+ /**
+ * Let the status bar know that if you tap on ignore while panel is showing, don't do anything.
+ *
+ * Debounces taps on, say, a popup's trigger when the popup is already showing.
+ */
public void setIgnoreChildren(int index, View ignore, View panel) {
mIgnoreChildren[index] = ignore;
mPanels[index] = panel;
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
new file mode 100644
index 0000000..28e4b86
--- /dev/null
+++ b/packages/SystemUI/tests/Android.mk
@@ -0,0 +1,30 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := SystemUITests
+
+# sign this with platform cert, so this test is allowed to inject key events into
+# UI it doesn't own. This is necessary to allow screenshots to be taken
+LOCAL_CERTIFICATE := platform
+
+include $(BUILD_PACKAGE)
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
new file mode 100644
index 0000000..e52806d
--- /dev/null
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.systemui.tests">
+
+ <uses-permission android:name="android.permission.INJECT_EVENTS" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <activity android:name="com.android.systemui.screenshot.ScreenshotStubActivity" />
+ </application>
+
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.systemui.tests"
+ android:label="Tests for SystemUI">
+ </instrumentation>
+</manifest>
diff --git a/packages/SystemUI/tests/res/layout/main.xml b/packages/SystemUI/tests/res/layout/main.xml
new file mode 100644
index 0000000..56dffe6
--- /dev/null
+++ b/packages/SystemUI/tests/res/layout/main.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="this is a test activity"
+ />
+ <EditText
+ android:layout_height="wrap_content"
+ android:id="@+id/editText1"
+ android:layout_width="match_parent">
+ <requestFocus></requestFocus>
+ </EditText>
+</LinearLayout>
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotStubActivity.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotStubActivity.java
new file mode 100644
index 0000000..2935373
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotStubActivity.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.screenshot;
+
+import com.android.systemui.tests.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * A stub activity used in {@link ScreenshotTest}.
+ */
+public class ScreenshotStubActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotTest.java
new file mode 100644
index 0000000..a0bc4d7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.screenshot;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Environment;
+import android.os.FileObserver;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import java.io.File;
+
+/**
+ * Functional tests for the global screenshot feature.
+ */
+@LargeTest
+public class ScreenshotTest extends ActivityInstrumentationTestCase2<ScreenshotStubActivity> {
+
+ private static final String LOG_TAG = "ScreenshotTest";
+ private static final int SCREEN_WAIT_TIME_SEC = 5;
+
+ public ScreenshotTest() {
+ super(ScreenshotStubActivity.class);
+ }
+
+ /**
+ * A simple test for screenshots that launches an Activity, injects the key event combo
+ * to trigger the screenshot, and verifies the screenshot was taken successfully.
+ */
+ public void testScreenshot() throws Exception {
+ Log.d(LOG_TAG, "starting testScreenshot");
+ // launch the activity.
+ ScreenshotStubActivity activity = getActivity();
+ assertNotNull(activity);
+
+ File screenshotDir = getScreenshotDir();
+ NewScreenshotObserver observer = new NewScreenshotObserver(
+ screenshotDir.getAbsolutePath());
+ observer.startWatching();
+ takeScreenshot();
+ // unlikely, but check if a new screenshot file was already created
+ if (observer.getCreatedPath() == null) {
+ // wait for screenshot to be created
+ synchronized(observer) {
+ observer.wait(SCREEN_WAIT_TIME_SEC*1000);
+ }
+ }
+ assertNotNull(String.format("Could not find screenshot after %d seconds",
+ SCREEN_WAIT_TIME_SEC), observer.getCreatedPath());
+
+ File screenshotFile = new File(screenshotDir, observer.getCreatedPath());
+ try {
+ assertTrue(String.format("Detected new screenshot %s but its not a file",
+ screenshotFile.getName()), screenshotFile.isFile());
+ assertTrue(String.format("Detected new screenshot %s but its not an image",
+ screenshotFile.getName()), isValidImage(screenshotFile));
+ } finally {
+ // delete the file to prevent external storage from filing up
+ screenshotFile.delete();
+ }
+ }
+
+ private static class NewScreenshotObserver extends FileObserver {
+ private String mAddedPath = null;
+
+ NewScreenshotObserver(String path) {
+ super(path, FileObserver.CREATE);
+ }
+
+ synchronized String getCreatedPath() {
+ return mAddedPath;
+ }
+
+ @Override
+ public void onEvent(int event, String path) {
+ Log.d(LOG_TAG, String.format("Detected new file added %s", path));
+ synchronized (this) {
+ mAddedPath = path;
+ notify();
+ }
+ }
+ }
+
+ /**
+ * Inject the key sequence to take a screenshot.
+ */
+ private void takeScreenshot() {
+ getInstrumentation().sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN,
+ KeyEvent.KEYCODE_POWER));
+ getInstrumentation().sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN,
+ KeyEvent.KEYCODE_VOLUME_DOWN));
+ // the volume down key event will cause the 'volume adjustment' UI to appear in the
+ // foreground, and steal UI focus
+ // unfortunately this means the next key event will get directed to the
+ // 'volume adjustment' UI, instead of this test's activity
+ // for this reason this test must be signed with platform certificate, to grant this test
+ // permission to inject key events to another process
+ getInstrumentation().sendKeySync(new KeyEvent(KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_VOLUME_DOWN));
+ getInstrumentation().sendKeySync(new KeyEvent(KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_POWER));
+ }
+
+ /**
+ * Get the directory where screenshot images are stored.
+ */
+ private File getScreenshotDir() {
+ // TODO: get this dir location from a constant
+ return new File(Environment.getExternalStorageDirectory(), "Pictures" + File.separator +
+ "Screenshots");
+ }
+
+ /**
+ * Return true if file is valid image file
+ */
+ private boolean isValidImage(File screenshotFile) {
+ Bitmap b = BitmapFactory.decodeFile(screenshotFile.getAbsolutePath());
+ // TODO: do more checks on image
+ return b != null;
+ }
+}
diff --git a/packages/VpnDialogs/AndroidManifest.xml b/packages/VpnDialogs/AndroidManifest.xml
index bd5f739..8e062b7 100644
--- a/packages/VpnDialogs/AndroidManifest.xml
+++ b/packages/VpnDialogs/AndroidManifest.xml
@@ -5,7 +5,6 @@
<application android:label="VpnDialogs"
android:allowBackup="false" >
<activity android:name=".ConfirmDialog"
- android:permission="android.permission.VPN"
android:theme="@style/transparent">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
index 40c0a02..d668e98 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
@@ -79,7 +79,7 @@
mDataTransmitted = (TextView) view.findViewById(R.id.data_transmitted);
mDataReceived = (TextView) view.findViewById(R.id.data_received);
- if (mConfig.packagz.equals(VpnConfig.LEGACY_VPN)) {
+ if (mConfig.user.equals(VpnConfig.LEGACY_VPN)) {
mDialog = new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_info)
.setTitle(R.string.legacy_title)
@@ -89,7 +89,7 @@
.create();
} else {
PackageManager pm = getPackageManager();
- ApplicationInfo app = pm.getApplicationInfo(mConfig.packagz, 0);
+ ApplicationInfo app = pm.getApplicationInfo(mConfig.user, 0);
mDialog = new AlertDialog.Builder(this)
.setIcon(app.loadIcon(pm))
.setTitle(app.loadLabel(pm))
@@ -131,7 +131,7 @@
if (which == AlertDialog.BUTTON_POSITIVE) {
mConfig.configureIntent.send();
} else if (which == AlertDialog.BUTTON_NEUTRAL) {
- mService.prepareVpn(mConfig.packagz, VpnConfig.LEGACY_VPN);
+ mService.prepareVpn(mConfig.user, VpnConfig.LEGACY_VPN);
}
} catch (Exception e) {
Log.e(TAG, "onClick", e);
diff --git a/policy/src/com/android/internal/policy/impl/IconUtilities.java b/policy/src/com/android/internal/policy/impl/IconUtilities.java
index 99055cf..4564f90 100644
--- a/policy/src/com/android/internal/policy/impl/IconUtilities.java
+++ b/policy/src/com/android/internal/policy/impl/IconUtilities.java
@@ -186,6 +186,7 @@
mask.recycle();
dest.drawBitmap(src, 0, 0, mPaint);
+ dest.setBitmap(null);
return result;
}
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index 7a14480..21a8c14 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -232,10 +232,14 @@
* @param resId resource id of the message
*/
public void setCarrierHelpText(int resId) {
- mCarrierHelpText = getContext().getText(resId);
+ mCarrierHelpText = getText(resId);
update(CARRIER_HELP_TEXT, mCarrierHelpText);
}
+ private CharSequence getText(int resId) {
+ return resId == 0 ? null : getContext().getText(resId);
+ }
+
/**
* Unlock help message. This is typically for help with unlock widgets, e.g. "wrong password"
* or "try again."
@@ -244,7 +248,7 @@
* @param lockIcon
*/
public void setHelpMessage(int textResId, int lockIcon) {
- mHelpMessageText = getContext().getString(textResId);
+ mHelpMessageText = getText(textResId).toString();
update(HELP_MESSAGE_TEXT, mHelpMessageText);
}
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 4a14dd9..9d360ac 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -23,7 +23,9 @@
import com.android.internal.widget.multiwaveview.MultiWaveView;
import android.app.ActivityManager;
+import android.content.ActivityNotFoundException;
import android.content.Context;
+import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.view.KeyEvent;
@@ -181,14 +183,33 @@
UnlockWidgetCommonMethods {
private final MultiWaveView mMultiWaveView;
+ private boolean mCameraDisabled;
MultiWaveViewMethods(MultiWaveView multiWaveView) {
mMultiWaveView = multiWaveView;
+ final boolean cameraDisabled = mLockPatternUtils.getDevicePolicyManager()
+ .getCameraDisabled(null);
+ if (cameraDisabled) {
+ Log.v(TAG, "Camera disabled by Device Policy");
+ mCameraDisabled = true;
+ } else {
+ // Camera is enabled if resource is initially defined for MultiWaveView
+ // in the lockscreen layout file
+ mCameraDisabled = mMultiWaveView.getTargetResourceId()
+ != R.array.lockscreen_targets_with_camera;
+ }
}
public void updateResources() {
- mMultiWaveView.setTargetResources(mSilentMode ? R.array.lockscreen_targets_when_silent
- : R.array.lockscreen_targets_when_soundon);
+ int resId;
+ if (mCameraDisabled) {
+ // Fall back to showing ring/silence if camera is disabled by DPM...
+ resId = mSilentMode ? R.array.lockscreen_targets_when_silent
+ : R.array.lockscreen_targets_when_soundon;
+ } else {
+ resId = R.array.lockscreen_targets_with_camera;
+ }
+ mMultiWaveView.setTargetResources(resId);
}
public void onGrabbed(View v, int handle) {
@@ -200,12 +221,19 @@
}
public void onTrigger(View v, int target) {
- if (target == 0) { // TODO: Use resources to determine which handle was used
+ if (target == 0 || target == 1) { // 0 = unlock/portrait, 1 = unlock/landscape
mCallback.goToUnlockScreen();
- } else if (target == 2) {
- toggleRingMode();
- mUnlockWidgetMethods.updateResources();
- mCallback.pokeWakelock();
+ } else if (target == 2 || target == 3) { // 2 = alt/portrait, 3 = alt/landscape
+ if (!mCameraDisabled) {
+ // Broadcast an intent to start the Camera
+ Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null);
+ mContext.sendOrderedBroadcast(intent, null);
+ mCallback.goToUnlockScreen();
+ } else {
+ toggleRingMode();
+ mUnlockWidgetMethods.updateResources();
+ mCallback.pokeWakelock();
+ }
}
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 174f733..14f7c11 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -35,13 +35,13 @@
import com.android.internal.view.menu.MenuDialogHelper;
import com.android.internal.view.menu.MenuPresenter;
import com.android.internal.view.menu.MenuView;
-import com.android.internal.view.menu.SubMenuBuilder;
import com.android.internal.widget.ActionBarContainer;
import com.android.internal.widget.ActionBarContextView;
import com.android.internal.widget.ActionBarView;
import android.app.KeyguardManager;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Canvas;
@@ -175,6 +175,8 @@
private AudioManager mAudioManager;
private KeyguardManager mKeyguardManager;
+ private int mUiOptions = 0;
+
public PhoneWindow(Context context) {
super(context);
mLayoutInflater = LayoutInflater.from(context);
@@ -213,6 +215,11 @@
}
@Override
+ public void setUiOptions(int uiOptions) {
+ mUiOptions = uiOptions;
+ }
+
+ @Override
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor();
@@ -545,6 +552,8 @@
if (!st.shownPanelView.hasFocus()) {
st.shownPanelView.requestFocus();
}
+ } else if (!st.isInExpandedMode) {
+ width = MATCH_PARENT;
}
st.isOpen = true;
@@ -2634,8 +2643,14 @@
mActionBar.initIndeterminateProgress();
}
- final boolean splitActionBar = getWindowStyle().getBoolean(
- com.android.internal.R.styleable.Window_windowSplitActionBar, false);
+ boolean splitActionBar = false;
+ if ((mUiOptions & ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW) != 0) {
+ splitActionBar = getContext().getResources().getBoolean(
+ com.android.internal.R.bool.split_action_bar_is_narrow);
+ } else {
+ splitActionBar = getWindowStyle().getBoolean(
+ com.android.internal.R.styleable.Window_windowSplitActionBar, false);
+ }
if (splitActionBar) {
final ActionBarContainer splitView = (ActionBarContainer) findViewById(
com.android.internal.R.id.split_action_bar);
@@ -2648,7 +2663,7 @@
com.android.internal.R.id.action_context_bar);
cab.setSplitView(splitView);
} else {
- Log.e(TAG, "Window style requested split action bar with " +
+ Log.e(TAG, "Requested split action bar with " +
"incompatible window decor! Ignoring request.");
}
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index b7f6adf..a2dbb78 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -113,6 +113,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
+import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
@@ -162,36 +163,39 @@
static final int APPLICATION_LAYER = 2;
static final int PHONE_LAYER = 3;
static final int SEARCH_BAR_LAYER = 4;
- static final int STATUS_BAR_SUB_PANEL_LAYER = 5;
- static final int SYSTEM_DIALOG_LAYER = 6;
+ static final int SYSTEM_DIALOG_LAYER = 5;
// toasts and the plugged-in battery thing
- static final int TOAST_LAYER = 7;
+ static final int TOAST_LAYER = 6;
// SIM errors and unlock. Not sure if this really should be in a high layer.
- static final int PRIORITY_PHONE_LAYER = 8;
+ static final int PRIORITY_PHONE_LAYER = 7;
// like the ANR / app crashed dialogs
- static final int SYSTEM_ALERT_LAYER = 9;
+ static final int SYSTEM_ALERT_LAYER = 8;
// system-level error dialogs
- static final int SYSTEM_ERROR_LAYER = 10;
+ static final int SYSTEM_ERROR_LAYER = 9;
// on-screen keyboards and other such input method user interfaces go here.
- static final int INPUT_METHOD_LAYER = 11;
+ static final int INPUT_METHOD_LAYER = 10;
// on-screen keyboards and other such input method user interfaces go here.
- static final int INPUT_METHOD_DIALOG_LAYER = 12;
+ static final int INPUT_METHOD_DIALOG_LAYER = 11;
// the keyguard; nothing on top of these can take focus, since they are
// responsible for power management when displayed.
- static final int KEYGUARD_LAYER = 13;
- static final int KEYGUARD_DIALOG_LAYER = 14;
+ static final int KEYGUARD_LAYER = 12;
+ static final int KEYGUARD_DIALOG_LAYER = 13;
+ static final int STATUS_BAR_SUB_PANEL_LAYER = 14;
static final int STATUS_BAR_LAYER = 15;
static final int STATUS_BAR_PANEL_LAYER = 16;
// the navigation bar, if available, shows atop most things
static final int NAVIGATION_BAR_LAYER = 17;
+ // the on-screen volume indicator and controller shown when the user
+ // changes the device volume
+ static final int VOLUME_OVERLAY_LAYER = 18;
// the drag layer: input for drag-and-drop is associated with this window,
// which sits above all other focusable windows
- static final int DRAG_LAYER = 18;
+ static final int DRAG_LAYER = 19;
// things in here CAN NOT take focus, but are shown on top of everything else.
- static final int SYSTEM_OVERLAY_LAYER = 19;
- static final int SECURE_SYSTEM_OVERLAY_LAYER = 20;
+ static final int SYSTEM_OVERLAY_LAYER = 20;
+ static final int SECURE_SYSTEM_OVERLAY_LAYER = 21;
// the (mouse) pointer layer
- static final int POINTER_LAYER = 21;
+ static final int POINTER_LAYER = 22;
static final int APPLICATION_MEDIA_SUBLAYER = -2;
static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
@@ -1057,6 +1061,8 @@
return INPUT_METHOD_LAYER;
case TYPE_INPUT_METHOD_DIALOG:
return INPUT_METHOD_DIALOG_LAYER;
+ case TYPE_VOLUME_OVERLAY:
+ return VOLUME_OVERLAY_LAYER;
case TYPE_SYSTEM_OVERLAY:
return SYSTEM_OVERLAY_LAYER;
case TYPE_SECURE_SYSTEM_OVERLAY:
@@ -3012,7 +3018,8 @@
}
}
- Runnable mScreenSaverActivator = new Runnable() {
+ Runnable mScreenSaverActivator = null;
+ /*new Runnable() {
public void run() {
synchronized (this) {
if (!(mScreenSaverEnabled && mScreenOn)) {
@@ -3043,9 +3050,12 @@
}
}
};
+ */
// Must call while holding mLock
private void updateScreenSaverTimeoutLocked() {
+ if (mScreenSaverActivator == null) return;
+
synchronized (mScreenSaverActivator) {
mHandler.removeCallbacks(mScreenSaverActivator);
if (mScreenSaverEnabled && mScreenOn && mScreenSaverTimeout > 0) {
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index ec45530..2355d5c 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -51,6 +51,8 @@
#include <media/EffectsFactoryApi.h>
#include <audio_effects/effect_visualizer.h>
+#include <audio_effects/effect_ns.h>
+#include <audio_effects/effect_aec.h>
#include <cpustats/ThreadCpuUsage.h>
#include <powermanager/PowerManager.h>
@@ -148,7 +150,8 @@
AudioFlinger::AudioFlinger()
: BnAudioFlinger(),
- mPrimaryHardwareDev(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1)
+ mPrimaryHardwareDev(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1),
+ mBtNrec(false)
{
}
@@ -717,6 +720,31 @@
final_result = result ?: final_result;
}
mHardwareStatus = AUDIO_HW_IDLE;
+ // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
+ AudioParameter param = AudioParameter(keyValuePairs);
+ String8 value;
+ if (param.get(String8(AUDIO_PARAMETER_KEY_BT_NREC), value) == NO_ERROR) {
+ Mutex::Autolock _l(mLock);
+ bool btNrec = (value == AUDIO_PARAMETER_VALUE_ON);
+ if (mBtNrec != btNrec) {
+ for (size_t i = 0; i < mRecordThreads.size(); i++) {
+ sp<RecordThread> thread = mRecordThreads.valueAt(i);
+ RecordThread::RecordTrack *track = thread->track();
+ if (track != NULL) {
+ audio_devices_t device = (audio_devices_t)(
+ thread->device() & AUDIO_DEVICE_IN_ALL);
+ bool suspend = audio_is_bluetooth_sco_device(device) && btNrec;
+ thread->setEffectSuspended(FX_IID_AEC,
+ suspend,
+ track->sessionId());
+ thread->setEffectSuspended(FX_IID_NS,
+ suspend,
+ track->sessionId());
+ }
+ }
+ mBtNrec = btNrec;
+ }
+ }
return final_result;
}
@@ -1130,6 +1158,140 @@
LOGW("power manager service died !!!");
}
+void AudioFlinger::ThreadBase::setEffectSuspended(
+ const effect_uuid_t *type, bool suspend, int sessionId)
+{
+ Mutex::Autolock _l(mLock);
+ setEffectSuspended_l(type, suspend, sessionId);
+}
+
+void AudioFlinger::ThreadBase::setEffectSuspended_l(
+ const effect_uuid_t *type, bool suspend, int sessionId)
+{
+ sp<EffectChain> chain;
+ chain = getEffectChain_l(sessionId);
+ if (chain != 0) {
+ if (type != NULL) {
+ chain->setEffectSuspended_l(type, suspend);
+ } else {
+ chain->setEffectSuspendedAll_l(suspend);
+ }
+ }
+
+ updateSuspendedSessions_l(type, suspend, sessionId);
+}
+
+void AudioFlinger::ThreadBase::checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain)
+{
+ int index = mSuspendedSessions.indexOfKey(chain->sessionId());
+ if (index < 0) {
+ return;
+ }
+
+ KeyedVector <int, sp<SuspendedSessionDesc> > sessionEffects =
+ mSuspendedSessions.editValueAt(index);
+
+ for (size_t i = 0; i < sessionEffects.size(); i++) {
+ sp <SuspendedSessionDesc> desc = sessionEffects.valueAt(i);
+ for (int j = 0; j < desc->mRefCount; j++) {
+ if (sessionEffects.keyAt(i) == EffectChain::kKeyForSuspendAll) {
+ chain->setEffectSuspendedAll_l(true);
+ } else {
+ LOGV("checkSuspendOnAddEffectChain_l() suspending effects %08x",
+ desc->mType.timeLow);
+ chain->setEffectSuspended_l(&desc->mType, true);
+ }
+ }
+ }
+}
+
+void AudioFlinger::ThreadBase::updateSuspendedSessionsOnRemoveEffectChain_l(
+ const sp<EffectChain>& chain)
+{
+ int index = mSuspendedSessions.indexOfKey(chain->sessionId());
+ if (index < 0) {
+ return;
+ }
+ LOGV("updateSuspendedSessionsOnRemoveEffectChain_l() removed suspended session %d",
+ chain->sessionId());
+ mSuspendedSessions.removeItemsAt(index);
+}
+
+void AudioFlinger::ThreadBase::updateSuspendedSessions_l(const effect_uuid_t *type,
+ bool suspend,
+ int sessionId)
+{
+ int index = mSuspendedSessions.indexOfKey(sessionId);
+
+ KeyedVector <int, sp<SuspendedSessionDesc> > sessionEffects;
+
+ if (suspend) {
+ if (index >= 0) {
+ sessionEffects = mSuspendedSessions.editValueAt(index);
+ } else {
+ mSuspendedSessions.add(sessionId, sessionEffects);
+ }
+ } else {
+ if (index < 0) {
+ return;
+ }
+ sessionEffects = mSuspendedSessions.editValueAt(index);
+ }
+
+
+ int key = EffectChain::kKeyForSuspendAll;
+ if (type != NULL) {
+ key = type->timeLow;
+ }
+ index = sessionEffects.indexOfKey(key);
+
+ sp <SuspendedSessionDesc> desc;
+ if (suspend) {
+ if (index >= 0) {
+ desc = sessionEffects.valueAt(index);
+ } else {
+ desc = new SuspendedSessionDesc();
+ if (type != NULL) {
+ memcpy(&desc->mType, type, sizeof(effect_uuid_t));
+ }
+ sessionEffects.add(key, desc);
+ LOGV("updateSuspendedSessions_l() suspend adding effect %08x", key);
+ }
+ desc->mRefCount++;
+ } else {
+ if (index < 0) {
+ return;
+ }
+ desc = sessionEffects.valueAt(index);
+ if (--desc->mRefCount == 0) {
+ LOGV("updateSuspendedSessions_l() restore removing effect %08x", key);
+ sessionEffects.removeItemsAt(index);
+ if (sessionEffects.isEmpty()) {
+ LOGV("updateSuspendedSessions_l() restore removing session %d",
+ sessionId);
+ mSuspendedSessions.removeItem(sessionId);
+ }
+ }
+ }
+ if (!sessionEffects.isEmpty()) {
+ mSuspendedSessions.replaceValueFor(sessionId, sessionEffects);
+ }
+}
+
+void AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
+ bool enabled,
+ int sessionId)
+{
+ Mutex::Autolock _l(mLock);
+
+ // TODO: implement PlaybackThread or RecordThread specific behavior here
+
+ sp<EffectChain> chain = getEffectChain_l(sessionId);
+ if (chain != 0) {
+ chain->checkSuspendOnEffectEnabled(effect, enabled);
+ }
+}
+
// ----------------------------------------------------------------------------
AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger,
@@ -4143,7 +4305,11 @@
}
mTrack = track.get();
-
+ // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
+ bool suspend = audio_is_bluetooth_sco_device(
+ (audio_devices_t)(mDevice & AUDIO_DEVICE_IN_ALL)) && mAudioFlinger->btNrec();
+ setEffectSuspended_l(FX_IID_AEC, suspend, sessionId);
+ setEffectSuspended_l(FX_IID_NS, suspend, sessionId);
}
lStatus = NO_ERROR;
@@ -4363,6 +4529,13 @@
status = BAD_VALUE;
} else {
mDevice &= (uint32_t)~(value & AUDIO_DEVICE_IN_ALL);
+ // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
+ if (mTrack != NULL) {
+ bool suspend = audio_is_bluetooth_sco_device(
+ (audio_devices_t)value) && mAudioFlinger->btNrec();
+ setEffectSuspended_l(FX_IID_AEC, suspend, mTrack->sessionId());
+ setEffectSuspended_l(FX_IID_NS, suspend, mTrack->sessionId());
+ }
}
mDevice |= (uint32_t)value;
}
@@ -4490,6 +4663,12 @@
return result;
}
+AudioFlinger::RecordThread::RecordTrack* AudioFlinger::RecordThread::track()
+{
+ Mutex::Autolock _l(mLock);
+ return mTrack;
+}
+
// ----------------------------------------------------------------------------
int AudioFlinger::openOutput(uint32_t *pDevices,
@@ -4874,10 +5053,6 @@
}
-// this UUID must match the one defined in media/libeffects/EffectVisualizer.cpp
-static const effect_uuid_t VISUALIZATION_UUID_ =
- {0xd069d9e0, 0x8329, 0x11df, 0x9168, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-
sp<IEffect> AudioFlinger::createEffect(pid_t pid,
effect_descriptor_t *pDesc,
const sp<IEffectClient>& effectClient,
@@ -4915,14 +5090,6 @@
goto Exit;
}
- // check recording permission for visualizer
- if ((memcmp(&pDesc->type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0 ||
- memcmp(&pDesc->uuid, &VISUALIZATION_UUID_, sizeof(effect_uuid_t)) == 0) &&
- !recordingAllowed()) {
- lStatus = PERMISSION_DENIED;
- goto Exit;
- }
-
if (io == 0) {
if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) {
// output must be specified by AudioPolicyManager when using session
@@ -5003,6 +5170,13 @@
goto Exit;
}
+ // check recording permission for visualizer
+ if ((memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) &&
+ !recordingAllowed()) {
+ lStatus = PERMISSION_DENIED;
+ goto Exit;
+ }
+
// return effect descriptor
memcpy(pDesc, &desc, sizeof(effect_descriptor_t));
@@ -5069,10 +5243,10 @@
return handle;
}
-status_t AudioFlinger::moveEffects(int session, int srcOutput, int dstOutput)
+status_t AudioFlinger::moveEffects(int sessionId, int srcOutput, int dstOutput)
{
LOGV("moveEffects() session %d, srcOutput %d, dstOutput %d",
- session, srcOutput, dstOutput);
+ sessionId, srcOutput, dstOutput);
Mutex::Autolock _l(mLock);
if (srcOutput == dstOutput) {
LOGW("moveEffects() same dst and src outputs %d", dstOutput);
@@ -5091,24 +5265,24 @@
Mutex::Autolock _dl(dstThread->mLock);
Mutex::Autolock _sl(srcThread->mLock);
- moveEffectChain_l(session, srcThread, dstThread, false);
+ moveEffectChain_l(sessionId, srcThread, dstThread, false);
return NO_ERROR;
}
// moveEffectChain_l mustbe called with both srcThread and dstThread mLocks held
-status_t AudioFlinger::moveEffectChain_l(int session,
+status_t AudioFlinger::moveEffectChain_l(int sessionId,
AudioFlinger::PlaybackThread *srcThread,
AudioFlinger::PlaybackThread *dstThread,
bool reRegister)
{
LOGV("moveEffectChain_l() session %d from thread %p to thread %p",
- session, srcThread, dstThread);
+ sessionId, srcThread, dstThread);
- sp<EffectChain> chain = srcThread->getEffectChain_l(session);
+ sp<EffectChain> chain = srcThread->getEffectChain_l(sessionId);
if (chain == 0) {
LOGW("moveEffectChain_l() effect chain for session %d not on source thread %p",
- session, srcThread);
+ sessionId, srcThread);
return INVALID_OPERATION;
}
@@ -5143,7 +5317,7 @@
AudioSystem::registerEffect(&effect->desc(),
dstOutput,
strategy,
- session,
+ sessionId,
effect->id());
}
effect = chain->getEffectFromId_l(0);
@@ -5385,6 +5559,7 @@
void AudioFlinger::ThreadBase::disconnectEffect(const sp<EffectModule>& effect,
const wp<EffectHandle>& handle) {
+
Mutex::Autolock _l(mLock);
LOGV("disconnectEffect() %p effect %p", this, effect.get());
// delete the effect module if removing last handle on it
@@ -5451,6 +5626,7 @@
if (mEffectChains[i]->sessionId() < session) break;
}
mEffectChains.insertAt(chain, i);
+ checkSuspendOnAddEffectChain_l(chain);
return NO_ERROR;
}
@@ -5463,6 +5639,7 @@
for (size_t i = 0; i < mEffectChains.size(); i++) {
if (chain == mEffectChains[i]) {
+ updateSuspendedSessionsOnRemoveEffectChain_l(chain);
mEffectChains.removeAt(i);
// detach all active tracks from the chain
for (size_t i = 0 ; i < mActiveTracks.size() ; ++i) {
@@ -5540,6 +5717,8 @@
chain->setInBuffer(NULL);
chain->setOutBuffer(NULL);
+ checkSuspendOnAddEffectChain_l(chain);
+
mEffectChains.add(chain);
return NO_ERROR;
@@ -5552,6 +5731,7 @@
"removeEffectChain_l() %p invalid chain size %d on thread %p",
chain.get(), mEffectChains.size(), this);
if (mEffectChains.size() == 1) {
+ updateSuspendedSessionsOnRemoveEffectChain_l(chain);
mEffectChains.removeAt(0);
}
return 0;
@@ -5570,7 +5750,7 @@
int id,
int sessionId)
: mThread(wThread), mChain(chain), mId(id), mSessionId(sessionId), mEffectInterface(NULL),
- mStatus(NO_INIT), mState(IDLE)
+ mStatus(NO_INIT), mState(IDLE), mSuspended(false)
{
LOGV("Constructor %p", this);
int lStatus;
@@ -5634,14 +5814,17 @@
}
// if inserted in first place, move effect control from previous owner to this handle
if (i == 0) {
+ bool enabled = false;
if (h != 0) {
- h->setControl(false, true);
+ enabled = h->enabled();
+ h->setControl(false/*hasControl*/, true /*signal*/, enabled /*enabled*/);
}
- handle->setControl(true, false);
+ handle->setControl(true /*hasControl*/, false /*signal*/, enabled /*enabled*/);
status = NO_ERROR;
} else {
status = ALREADY_EXISTS;
}
+ LOGV("addHandle() %p added handle %p in position %d", this, handle.get(), i);
mHandles.insertAt(handle, i);
return status;
}
@@ -5657,13 +5840,21 @@
if (i == size) {
return size;
}
+ LOGV("removeHandle() %p removed handle %p in position %d", this, handle.unsafe_get(), i);
+
+ bool enabled = false;
+ EffectHandle *hdl = handle.unsafe_get();
+ if (hdl) {
+ LOGV("removeHandle() unsafe_get OK");
+ enabled = hdl->enabled();
+ }
mHandles.removeAt(i);
size = mHandles.size();
// if removed from first place, move effect control from this handle to next in line
if (i == 0 && size != 0) {
sp<EffectHandle> h = mHandles[0].promote();
if (h != 0) {
- h->setControl(true, true);
+ h->setControl(true /*hasControl*/, true /*signal*/ , enabled /*enabled*/);
}
}
@@ -5677,8 +5868,21 @@
return size;
}
+sp<AudioFlinger::EffectHandle> AudioFlinger::EffectModule::controlHandle()
+{
+ Mutex::Autolock _l(mLock);
+ sp<EffectHandle> handle;
+ if (mHandles.size() != 0) {
+ handle = mHandles[0].promote();
+ }
+ return handle;
+}
+
+
+
void AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle)
{
+ LOGV("disconnect() %p handle %p ", this, handle.unsafe_get());
// keep a strong reference on this EffectModule to avoid calling the
// destructor before we exit
sp<EffectModule> keep(this);
@@ -6139,6 +6343,17 @@
return status;
}
+void AudioFlinger::EffectModule::setSuspended(bool suspended)
+{
+ Mutex::Autolock _l(mLock);
+ mSuspended = suspended;
+}
+bool AudioFlinger::EffectModule::suspended()
+{
+ Mutex::Autolock _l(mLock);
+ return mSuspended;
+}
+
status_t AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args)
{
const size_t SIZE = 256;
@@ -6235,7 +6450,8 @@
const sp<IEffectClient>& effectClient,
int32_t priority)
: BnEffect(),
- mEffect(effect), mEffectClient(effectClient), mClient(client), mPriority(priority), mHasControl(false)
+ mEffect(effect), mEffectClient(effectClient), mClient(client),
+ mPriority(priority), mHasControl(false), mEnabled(false)
{
LOGV("constructor %p", this);
@@ -6258,30 +6474,66 @@
{
LOGV("Destructor %p", this);
disconnect();
+ LOGV("Destructor DONE %p", this);
}
status_t AudioFlinger::EffectHandle::enable()
{
+ LOGV("enable %p", this);
if (!mHasControl) return INVALID_OPERATION;
if (mEffect == 0) return DEAD_OBJECT;
+ mEnabled = true;
+
+ sp<ThreadBase> thread = mEffect->thread().promote();
+ if (thread != 0) {
+ thread->checkSuspendOnEffectEnabled(mEffect, true, mEffect->sessionId());
+ }
+
+ // checkSuspendOnEffectEnabled() can suspend this same effect when enabled
+ if (mEffect->suspended()) {
+ return NO_ERROR;
+ }
+
return mEffect->setEnabled(true);
}
status_t AudioFlinger::EffectHandle::disable()
{
+ LOGV("disable %p", this);
if (!mHasControl) return INVALID_OPERATION;
- if (mEffect == NULL) return DEAD_OBJECT;
+ if (mEffect == 0) return DEAD_OBJECT;
- return mEffect->setEnabled(false);
+ mEnabled = false;
+
+ if (mEffect->suspended()) {
+ return NO_ERROR;
+ }
+
+ status_t status = mEffect->setEnabled(false);
+
+ sp<ThreadBase> thread = mEffect->thread().promote();
+ if (thread != 0) {
+ thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
+ }
+
+ return status;
}
void AudioFlinger::EffectHandle::disconnect()
{
+ LOGV("disconnect %p", this);
if (mEffect == 0) {
return;
}
+
mEffect->disconnect(this);
+
+ sp<ThreadBase> thread = mEffect->thread().promote();
+ if (thread != 0) {
+ thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
+ }
+
// release sp on module => module destructor can be called now
mEffect.clear();
if (mCblk) {
@@ -6373,11 +6625,13 @@
return mCblkMemory;
}
-void AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal)
+void AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal, bool enabled)
{
LOGV("setControl %p control %d", this, hasControl);
mHasControl = hasControl;
+ mEnabled = enabled;
+
if (signal && mEffectClient != 0) {
mEffectClient->controlStatusChanged(hasControl);
}
@@ -6448,7 +6702,7 @@
}
-// getEffectFromDesc_l() must be called with PlaybackThread::mLock held
+// getEffectFromDesc_l() must be called with ThreadBase::mLock held
sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromDesc_l(effect_descriptor_t *descriptor)
{
sp<EffectModule> effect;
@@ -6463,7 +6717,7 @@
return effect;
}
-// getEffectFromId_l() must be called with PlaybackThread::mLock held
+// getEffectFromId_l() must be called with ThreadBase::mLock held
sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int id)
{
sp<EffectModule> effect;
@@ -6479,6 +6733,22 @@
return effect;
}
+// getEffectFromType_l() must be called with ThreadBase::mLock held
+sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromType_l(
+ const effect_uuid_t *type)
+{
+ sp<EffectModule> effect;
+ size_t size = mEffects.size();
+
+ for (size_t i = 0; i < size; i++) {
+ if (memcmp(&mEffects[i]->desc().type, type, sizeof(effect_uuid_t)) == 0) {
+ effect = mEffects[i];
+ break;
+ }
+ }
+ return effect;
+}
+
// Must be called with EffectChain::mLock locked
void AudioFlinger::EffectChain::process_l()
{
@@ -6773,6 +7043,166 @@
return NO_ERROR;
}
+// must be called with ThreadBase::mLock held
+void AudioFlinger::EffectChain::setEffectSuspended_l(
+ const effect_uuid_t *type, bool suspend)
+{
+ sp<SuspendedEffectDesc> desc;
+ // use effect type UUID timelow as key as there is no real risk of identical
+ // timeLow fields among effect type UUIDs.
+ int index = mSuspendedEffects.indexOfKey(type->timeLow);
+ if (suspend) {
+ if (index >= 0) {
+ desc = mSuspendedEffects.valueAt(index);
+ } else {
+ desc = new SuspendedEffectDesc();
+ memcpy(&desc->mType, type, sizeof(effect_uuid_t));
+ mSuspendedEffects.add(type->timeLow, desc);
+ LOGV("setEffectSuspended_l() add entry for %08x", type->timeLow);
+ }
+ if (desc->mRefCount++ == 0) {
+ sp<EffectModule> effect = getEffectIfEnabled(type);
+ if (effect != 0) {
+ desc->mEffect = effect;
+ effect->setSuspended(true);
+ effect->setEnabled(false);
+ }
+ }
+ } else {
+ if (index < 0) {
+ return;
+ }
+ desc = mSuspendedEffects.valueAt(index);
+ if (desc->mRefCount <= 0) {
+ LOGW("setEffectSuspended_l() restore refcount should not be 0 %d", desc->mRefCount);
+ desc->mRefCount = 1;
+ }
+ if (--desc->mRefCount == 0) {
+ LOGV("setEffectSuspended_l() remove entry for %08x", mSuspendedEffects.keyAt(index));
+ if (desc->mEffect != 0) {
+ sp<EffectModule> effect = desc->mEffect.promote();
+ if (effect != 0) {
+ effect->setSuspended(false);
+ sp<EffectHandle> handle = effect->controlHandle();
+ if (handle != 0) {
+ effect->setEnabled(handle->enabled());
+ }
+ }
+ desc->mEffect.clear();
+ }
+ mSuspendedEffects.removeItemsAt(index);
+ }
+ }
+}
+
+// must be called with ThreadBase::mLock held
+void AudioFlinger::EffectChain::setEffectSuspendedAll_l(bool suspend)
+{
+ sp<SuspendedEffectDesc> desc;
+
+ int index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
+ if (suspend) {
+ if (index >= 0) {
+ desc = mSuspendedEffects.valueAt(index);
+ } else {
+ desc = new SuspendedEffectDesc();
+ mSuspendedEffects.add((int)kKeyForSuspendAll, desc);
+ LOGV("setEffectSuspendedAll_l() add entry for 0");
+ }
+ if (desc->mRefCount++ == 0) {
+ Vector< sp<EffectModule> > effects = getSuspendEligibleEffects();
+ for (size_t i = 0; i < effects.size(); i++) {
+ setEffectSuspended_l(&effects[i]->desc().type, true);
+ }
+ }
+ } else {
+ if (index < 0) {
+ return;
+ }
+ desc = mSuspendedEffects.valueAt(index);
+ if (desc->mRefCount <= 0) {
+ LOGW("setEffectSuspendedAll_l() restore refcount should not be 0 %d", desc->mRefCount);
+ desc->mRefCount = 1;
+ }
+ if (--desc->mRefCount == 0) {
+ Vector<const effect_uuid_t *> types;
+ for (size_t i = 0; i < mSuspendedEffects.size(); i++) {
+ if (mSuspendedEffects.keyAt(i) == (int)kKeyForSuspendAll) {
+ continue;
+ }
+ types.add(&mSuspendedEffects.valueAt(i)->mType);
+ }
+ for (size_t i = 0; i < types.size(); i++) {
+ setEffectSuspended_l(types[i], false);
+ }
+ LOGV("setEffectSuspendedAll_l() remove entry for %08x", mSuspendedEffects.keyAt(index));
+ mSuspendedEffects.removeItem((int)kKeyForSuspendAll);
+ }
+ }
+}
+
+Vector< sp<AudioFlinger::EffectModule> > AudioFlinger::EffectChain::getSuspendEligibleEffects()
+{
+ Vector< sp<EffectModule> > effects;
+ for (size_t i = 0; i < mEffects.size(); i++) {
+ effect_descriptor_t desc = mEffects[i]->desc();
+ // auxiliary effects and vizualizer are never suspended on output mix
+ if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) && (
+ ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) ||
+ (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0))) {
+ continue;
+ }
+ effects.add(mEffects[i]);
+ }
+ return effects;
+}
+
+sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectIfEnabled(
+ const effect_uuid_t *type)
+{
+ sp<EffectModule> effect;
+ effect = getEffectFromType_l(type);
+ if (effect != 0 && !effect->isEnabled()) {
+ effect.clear();
+ }
+ return effect;
+}
+
+void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
+ bool enabled)
+{
+ int index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
+ if (enabled) {
+ if (index < 0) {
+ // if the effect is not suspend check if all effects are suspended
+ index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
+ if (index < 0) {
+ return;
+ }
+ setEffectSuspended_l(&effect->desc().type, enabled);
+ index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
+ }
+ LOGV("checkSuspendOnEffectEnabled() enable suspending fx %08x",
+ effect->desc().type.timeLow);
+ sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
+ // if effect is requested to suspended but was not yet enabled, supend it now.
+ if (desc->mEffect == 0) {
+ desc->mEffect = effect;
+ effect->setEnabled(false);
+ effect->setSuspended(true);
+ }
+ } else {
+ if (index < 0) {
+ return;
+ }
+ LOGV("checkSuspendOnEffectEnabled() disable restoring fx %08x",
+ effect->desc().type.timeLow);
+ sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
+ desc->mEffect.clear();
+ effect->setSuspended(false);
+ }
+}
+
#undef LOG_TAG
#define LOG_TAG "AudioFlinger"
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 7b6215f..791341a 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -165,7 +165,7 @@
int *id,
int *enabled);
- virtual status_t moveEffects(int session, int srcOutput, int dstOutput);
+ virtual status_t moveEffects(int sessionId, int srcOutput, int dstOutput);
enum hardware_call_state {
AUDIO_HW_IDLE = 0,
@@ -206,6 +206,8 @@
uint32_t getMode() { return mMode; }
+ bool btNrec() { return mBtNrec; }
+
private:
AudioFlinger();
virtual ~AudioFlinger();
@@ -477,14 +479,45 @@
// strategy is only meaningful for PlaybackThread which implements this method
virtual uint32_t getStrategyForSession_l(int sessionId) { return 0; }
+ // suspend or restore effect according to the type of effect passed. a NULL
+ // type pointer means suspend all effects in the session
+ void setEffectSuspended(const effect_uuid_t *type,
+ bool suspend,
+ int sessionId = AUDIO_SESSION_OUTPUT_MIX);
+ // check if some effects must be suspended/restored when an effect is enabled
+ // or disabled
+ virtual void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
+ bool enabled,
+ int sessionId = AUDIO_SESSION_OUTPUT_MIX);
+
mutable Mutex mLock;
protected:
+ // entry describing an effect being suspended in mSuspendedSessions keyed vector
+ class SuspendedSessionDesc : public RefBase {
+ public:
+ SuspendedSessionDesc() : mRefCount(0) {}
+
+ int mRefCount; // number of active suspend requests
+ effect_uuid_t mType; // effect type UUID
+ };
+
void acquireWakeLock();
void acquireWakeLock_l();
void releaseWakeLock();
void releaseWakeLock_l();
+ void setEffectSuspended_l(const effect_uuid_t *type,
+ bool suspend,
+ int sessionId = AUDIO_SESSION_OUTPUT_MIX);
+ // updated mSuspendedSessions when an effect suspended or restored
+ void updateSuspendedSessions_l(const effect_uuid_t *type,
+ bool suspend,
+ int sessionId);
+ // check if some effects must be suspended when an effect chain is added
+ void checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain);
+ // updated mSuspendedSessions when an effect chain is removed
+ void updateSuspendedSessionsOnRemoveEffectChain_l(const sp<EffectChain>& chain);
friend class Track;
friend class TrackBase;
@@ -519,6 +552,9 @@
sp<IPowerManager> mPowerManager;
sp<IBinder> mWakeLockToken;
sp<PMDeathRecipient> mDeathRecipient;
+ // list of suspended effects per session and per type. The first vector is
+ // keyed by session ID, the second by type UUID timeLow field
+ KeyedVector< int, KeyedVector< int, sp<SuspendedSessionDesc> > > mSuspendedSessions;
};
// --- PlaybackThread ---
@@ -848,7 +884,7 @@
void audioConfigChanged_l(int event, int ioHandle, void *param2);
uint32_t nextUniqueId();
- status_t moveEffectChain_l(int session,
+ status_t moveEffectChain_l(int sessionId,
AudioFlinger::PlaybackThread *srcThread,
AudioFlinger::PlaybackThread *dstThread,
bool reRegister);
@@ -908,6 +944,7 @@
bool setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
void dump(char* buffer, size_t size);
+
private:
friend class AudioFlinger;
friend class RecordThread;
@@ -950,8 +987,6 @@
AudioStreamIn* getInput() { return mInput; }
virtual audio_stream_t* stream() { return &mInput->stream->common; }
-
- void setTrack(RecordTrack *recordTrack) { mTrack = recordTrack; }
virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
virtual bool checkForNewParameters_l();
@@ -963,6 +998,7 @@
virtual status_t addEffectChain_l(const sp<EffectChain>& chain);
virtual size_t removeEffectChain_l(const sp<EffectChain>& chain);
virtual uint32_t hasAudioSession(int sessionId);
+ RecordTrack* track();
private:
RecordThread();
@@ -1059,6 +1095,7 @@
int16_t *outBuffer() { return mConfig.outputCfg.buffer.s16; }
void setChain(const wp<EffectChain>& chain) { mChain = chain; }
void setThread(const wp<ThreadBase>& thread) { mThread = thread; }
+ wp<ThreadBase>& thread() { return mThread; }
status_t addHandle(sp<EffectHandle>& handle);
void disconnect(const wp<EffectHandle>& handle);
@@ -1071,6 +1108,10 @@
status_t setVolume(uint32_t *left, uint32_t *right, bool controller);
status_t setMode(uint32_t mode);
status_t stop();
+ void setSuspended(bool suspended);
+ bool suspended();
+
+ sp<EffectHandle> controlHandle();
status_t dump(int fd, const Vector<String16>& args);
@@ -1099,6 +1140,7 @@
uint32_t mMaxDisableWaitCnt; // maximum grace period before forcing an effect off after
// sending disable command.
uint32_t mDisableWaitCnt; // current process() calls count during disable period.
+ bool mSuspended; // effect is suspended: temporarily disabled by framework
};
// The EffectHandle class implements the IEffect interface. It provides resources
@@ -1131,13 +1173,17 @@
// Give or take control of effect module
- void setControl(bool hasControl, bool signal);
+ // - hasControl: true if control is given, false if removed
+ // - signal: true client app should be signaled of change, false otherwise
+ // - enabled: state of the effect when control is passed
+ void setControl(bool hasControl, bool signal, bool enabled);
void commandExecuted(uint32_t cmdCode,
uint32_t cmdSize,
void *pCmdData,
uint32_t replySize,
void *pReplyData);
void setEnabled(bool enabled);
+ bool enabled() { return mEnabled; }
// Getters
int id() { return mEffect->id(); }
@@ -1160,6 +1206,8 @@
uint8_t* mBuffer; // pointer to parameter area in shared memory
int mPriority; // client application priority to control the effect
bool mHasControl; // true if this handle is controlling the effect
+ bool mEnabled; // cached enable state: needed when the effect is
+ // restored after being suspended
};
// the EffectChain class represents a group of effects associated to one audio session.
@@ -1174,6 +1222,10 @@
EffectChain(const wp<ThreadBase>& wThread, int sessionId);
~EffectChain();
+ // special key used for an entry in mSuspendedEffects keyed vector
+ // corresponding to a suspend all request.
+ static const int kKeyForSuspendAll = 0;
+
void process_l();
void lock() {
@@ -1191,6 +1243,7 @@
sp<EffectModule> getEffectFromDesc_l(effect_descriptor_t *descriptor);
sp<EffectModule> getEffectFromId_l(int id);
+ sp<EffectModule> getEffectFromType_l(const effect_uuid_t *type);
bool setVolume_l(uint32_t *left, uint32_t *right);
void setDevice_l(uint32_t device);
void setMode_l(uint32_t mode);
@@ -1221,6 +1274,15 @@
void setStrategy(uint32_t strategy)
{ mStrategy = strategy; }
+ // suspend effect of the given type
+ void setEffectSuspended_l(const effect_uuid_t *type,
+ bool suspend);
+ // suspend all eligible effects
+ void setEffectSuspendedAll_l(bool suspend);
+ // check if effects should be suspend or restored when a given effect is enable or disabled
+ virtual void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
+ bool enabled);
+
status_t dump(int fd, const Vector<String16>& args);
protected:
@@ -1228,6 +1290,21 @@
EffectChain(const EffectChain&);
EffectChain& operator =(const EffectChain&);
+ class SuspendedEffectDesc : public RefBase {
+ public:
+ SuspendedEffectDesc() : mRefCount(0) {}
+
+ int mRefCount;
+ effect_uuid_t mType;
+ wp<EffectModule> mEffect;
+ };
+
+ // get a list of effect modules to suspend when an effect of the type
+ // passed is enabled.
+ Vector< sp<EffectModule> > getSuspendEligibleEffects();
+ // get an effect module if it is currently enable
+ sp<EffectModule> getEffectIfEnabled(const effect_uuid_t *type);
+
wp<ThreadBase> mThread; // parent mixer thread
Mutex mLock; // mutex protecting effect list
Vector<sp<EffectModule> > mEffects; // list of effect modules
@@ -1243,6 +1320,10 @@
uint32_t mNewLeftVolume; // new volume on left channel
uint32_t mNewRightVolume; // new volume on right channel
uint32_t mStrategy; // strategy for this effect chain
+ // mSuspendedEffects lists all effect currently suspended in the chain
+ // use effect type UUID timelow field as key. There is no real risk of identical
+ // timeLow fields among effect type UUIDs.
+ KeyedVector< int, sp<SuspendedEffectDesc> > mSuspendedEffects;
};
struct AudioStreamOut {
@@ -1283,7 +1364,8 @@
DefaultKeyedVector< pid_t, sp<NotificationClient> > mNotificationClients;
volatile int32_t mNextUniqueId;
- uint32_t mMode;
+ uint32_t mMode;
+ bool mBtNrec;
};
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index b03649e..e193be0 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -350,10 +350,9 @@
dataCallbackTimestamp,
(void *)cameraId);
- // Enable zoom, error, and focus messages by default
- enableMsgType(CAMERA_MSG_ERROR |
- CAMERA_MSG_ZOOM |
- CAMERA_MSG_FOCUS);
+ // Enable zoom, error, focus, and metadata messages by default
+ enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
+ CAMERA_MSG_PREVIEW_METADATA);
// Callback is disabled by default
mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
@@ -460,10 +459,10 @@
static void disconnectWindow(const sp<ANativeWindow>& window) {
if (window != 0) {
- status_t result = native_window_disconnect(window.get(),
+ status_t result = native_window_api_disconnect(window.get(),
NATIVE_WINDOW_API_CAMERA);
if (result != NO_ERROR) {
- LOGW("native_window_disconnect failed: %s (%d)", strerror(-result),
+ LOGW("native_window_api_disconnect failed: %s (%d)", strerror(-result),
result);
}
}
@@ -526,9 +525,9 @@
}
if (window != 0) {
- result = native_window_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
+ result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
if (result != NO_ERROR) {
- LOGE("native_window_connect failed: %s (%d)", strerror(-result),
+ LOGE("native_window_api_connect failed: %s (%d)", strerror(-result),
result);
return result;
}
@@ -995,15 +994,15 @@
if (client == 0) return;
if (!client->lockIfMessageWanted(msgType)) return;
- if (dataPtr == 0) {
+ if (dataPtr == 0 && metadata == NULL) {
LOGE("Null data returned in data callback");
client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
return;
}
- switch (msgType) {
+ switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
case CAMERA_MSG_PREVIEW_FRAME:
- client->handlePreviewData(dataPtr);
+ client->handlePreviewData(msgType, dataPtr, metadata);
break;
case CAMERA_MSG_POSTVIEW_FRAME:
client->handlePostview(dataPtr);
@@ -1015,7 +1014,7 @@
client->handleCompressedPicture(dataPtr);
break;
default:
- client->handleGenericData(msgType, dataPtr);
+ client->handleGenericData(msgType, dataPtr, metadata);
break;
}
}
@@ -1055,7 +1054,9 @@
}
// preview callback - frame buffer update
-void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) {
+void CameraService::Client::handlePreviewData(int32_t msgType,
+ const sp<IMemory>& mem,
+ camera_frame_metadata_t *metadata) {
ssize_t offset;
size_t size;
sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
@@ -1087,11 +1088,11 @@
// Is the received frame copied out or not?
if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
LOG2("frame is copied");
- copyFrameAndPostCopiedFrame(c, heap, offset, size);
+ copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
} else {
LOG2("frame is forwarded");
mLock.unlock();
- c->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem);
+ c->dataCallback(msgType, mem, metadata);
}
} else {
mLock.unlock();
@@ -1105,7 +1106,7 @@
sp<ICameraClient> c = mCameraClient;
mLock.unlock();
if (c != 0) {
- c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem);
+ c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
}
}
@@ -1120,7 +1121,7 @@
sp<ICameraClient> c = mCameraClient;
mLock.unlock();
if (c != 0) {
- c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem);
+ c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
}
}
@@ -1131,7 +1132,7 @@
sp<ICameraClient> c = mCameraClient;
mLock.unlock();
if (c != 0) {
- c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem);
+ c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
}
}
@@ -1146,11 +1147,11 @@
}
void CameraService::Client::handleGenericData(int32_t msgType,
- const sp<IMemory>& dataPtr) {
+ const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
sp<ICameraClient> c = mCameraClient;
mLock.unlock();
if (c != 0) {
- c->dataCallback(msgType, dataPtr);
+ c->dataCallback(msgType, dataPtr, metadata);
}
}
@@ -1164,8 +1165,9 @@
}
void CameraService::Client::copyFrameAndPostCopiedFrame(
- const sp<ICameraClient>& client, const sp<IMemoryHeap>& heap,
- size_t offset, size_t size) {
+ int32_t msgType, const sp<ICameraClient>& client,
+ const sp<IMemoryHeap>& heap, size_t offset, size_t size,
+ camera_frame_metadata_t *metadata) {
LOG2("copyFrameAndPostCopiedFrame");
// It is necessary to copy out of pmem before sending this to
// the callback. For efficiency, reuse the same MemoryHeapBase
@@ -1197,7 +1199,7 @@
}
mLock.unlock();
- client->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame);
+ client->dataCallback(msgType, frame, metadata);
}
int CameraService::Client::getOrientation(int degrees, bool mirror) {
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index af7f06e..57abf83 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -147,18 +147,22 @@
static sp<Client> getClientFromCookie(void* user);
// handlers for messages
void handleShutter(void);
- void handlePreviewData(const sp<IMemory>& mem);
+ void handlePreviewData(int32_t msgType, const sp<IMemory>& mem,
+ camera_frame_metadata_t *metadata);
void handlePostview(const sp<IMemory>& mem);
void handleRawPicture(const sp<IMemory>& mem);
void handleCompressedPicture(const sp<IMemory>& mem);
void handleGenericNotify(int32_t msgType, int32_t ext1, int32_t ext2);
- void handleGenericData(int32_t msgType, const sp<IMemory>& dataPtr);
+ void handleGenericData(int32_t msgType, const sp<IMemory>& dataPtr,
+ camera_frame_metadata_t *metadata);
void handleGenericDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
void copyFrameAndPostCopiedFrame(
+ int32_t msgType,
const sp<ICameraClient>& client,
const sp<IMemoryHeap>& heap,
- size_t offset, size_t size);
+ size_t offset, size_t size,
+ camera_frame_metadata_t *metadata);
int getOrientation(int orientation, bool mirror);
diff --git a/services/input/Android.mk b/services/input/Android.mk
index e36507a..afbe546 100644
--- a/services/input/Android.mk
+++ b/services/input/Android.mk
@@ -19,6 +19,7 @@
LOCAL_SRC_FILES:= \
EventHub.cpp \
InputDispatcher.cpp \
+ InputListener.cpp \
InputManager.cpp \
InputReader.cpp \
InputWindow.cpp \
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index af13945..ce9e14f 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -2550,16 +2550,16 @@
return splitMotionEntry;
}
-void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
+void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
#if DEBUG_INBOUND_EVENT_DETAILS
- LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
+ LOGD("notifyConfigurationChanged - eventTime=%lld", args->eventTime);
#endif
bool needWake;
{ // acquire lock
AutoMutex _l(mLock);
- ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(eventTime);
+ ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(args->eventTime);
needWake = enqueueInboundEventLocked(newEntry);
} // release lock
@@ -2568,19 +2568,21 @@
}
}
-void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t action, int32_t flags,
- int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
+void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
#if DEBUG_INBOUND_EVENT_DETAILS
LOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
"flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
- eventTime, deviceId, source, policyFlags, action, flags,
- keyCode, scanCode, metaState, downTime);
+ args->eventTime, args->deviceId, args->source, args->policyFlags,
+ args->action, args->flags, args->keyCode, args->scanCode,
+ args->metaState, args->downTime);
#endif
- if (! validateKeyEvent(action)) {
+ if (!validateKeyEvent(args->action)) {
return;
}
+ uint32_t policyFlags = args->policyFlags;
+ int32_t flags = args->flags;
+ int32_t metaState = args->metaState;
if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
policyFlags |= POLICY_FLAG_VIRTUAL;
flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
@@ -2604,8 +2606,9 @@
policyFlags |= POLICY_FLAG_TRUSTED;
KeyEvent event;
- event.initialize(deviceId, source, action, flags, keyCode, scanCode,
- metaState, 0, downTime, eventTime);
+ event.initialize(args->deviceId, args->source, args->action,
+ flags, args->keyCode, args->scanCode, metaState, 0,
+ args->downTime, args->eventTime);
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
@@ -2629,9 +2632,10 @@
}
int32_t repeatCount = 0;
- KeyEntry* newEntry = new KeyEntry(eventTime,
- deviceId, source, policyFlags, action, flags, keyCode, scanCode,
- metaState, repeatCount, downTime);
+ KeyEntry* newEntry = new KeyEntry(args->eventTime,
+ args->deviceId, args->source, policyFlags,
+ args->action, flags, args->keyCode, args->scanCode,
+ metaState, repeatCount, args->downTime);
needWake = enqueueInboundEventLocked(newEntry);
mLock.unlock();
@@ -2642,43 +2646,39 @@
}
}
-void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t action, int32_t flags,
- int32_t metaState, int32_t buttonState, int32_t edgeFlags,
- uint32_t pointerCount, const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords,
- float xPrecision, float yPrecision, nsecs_t downTime) {
+void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
#if DEBUG_INBOUND_EVENT_DETAILS
LOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
"action=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, edgeFlags=0x%x, "
"xPrecision=%f, yPrecision=%f, downTime=%lld",
- eventTime, deviceId, source, policyFlags, action, flags,
- metaState, buttonState, edgeFlags,
- xPrecision, yPrecision, downTime);
- for (uint32_t i = 0; i < pointerCount; i++) {
+ args->eventTime, args->deviceId, args->source, args->policyFlags,
+ args->action, args->flags, args->metaState, args->buttonState,
+ args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);
+ for (uint32_t i = 0; i < args->pointerCount; i++) {
LOGD(" Pointer %d: id=%d, toolType=%d, "
"x=%f, y=%f, pressure=%f, size=%f, "
"touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
"orientation=%f",
- i, pointerProperties[i].id,
- pointerProperties[i].toolType,
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
+ i, args->pointerProperties[i].id,
+ args->pointerProperties[i].toolType,
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
}
#endif
- if (! validateMotionEvent(action, pointerCount, pointerProperties)) {
+ if (!validateMotionEvent(args->action, args->pointerCount, args->pointerProperties)) {
return;
}
+ uint32_t policyFlags = args->policyFlags;
policyFlags |= POLICY_FLAG_TRUSTED;
- mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
+ mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
bool needWake;
{ // acquire lock
@@ -2688,10 +2688,11 @@
mLock.unlock();
MotionEvent event;
- event.initialize(deviceId, source, action, flags, edgeFlags, metaState,
- buttonState, 0, 0,
- xPrecision, yPrecision, downTime, eventTime,
- pointerCount, pointerProperties, pointerCoords);
+ event.initialize(args->deviceId, args->source, args->action, args->flags,
+ args->edgeFlags, args->metaState, args->buttonState, 0, 0,
+ args->xPrecision, args->yPrecision,
+ args->downTime, args->eventTime,
+ args->pointerCount, args->pointerProperties, args->pointerCoords);
policyFlags |= POLICY_FLAG_FILTERED;
if (!mPolicy->filterInputEvent(&event, policyFlags)) {
@@ -2702,8 +2703,8 @@
}
// Attempt batching and streaming of move events.
- if (action == AMOTION_EVENT_ACTION_MOVE
- || action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
+ if (args->action == AMOTION_EVENT_ACTION_MOVE
+ || args->action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
// BATCHING CASE
//
// Try to append a move sample to the tail of the inbound queue for this device.
@@ -2716,20 +2717,22 @@
}
MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
- if (motionEntry->deviceId != deviceId
- || motionEntry->source != source) {
+ if (motionEntry->deviceId != args->deviceId
+ || motionEntry->source != args->source) {
// Keep looking for this device and source.
continue;
}
- if (!motionEntry->canAppendSamples(action, pointerCount, pointerProperties)) {
+ if (!motionEntry->canAppendSamples(args->action,
+ args->pointerCount, args->pointerProperties)) {
// Last motion event in the queue for this device and source is
// not compatible for appending new samples. Stop here.
goto NoBatchingOrStreaming;
}
// Do the batching magic.
- batchMotionLocked(motionEntry, eventTime, metaState, pointerCoords,
+ batchMotionLocked(motionEntry, args->eventTime,
+ args->metaState, args->pointerCoords,
"most recent motion event for this device and source in the inbound queue");
mLock.unlock();
return; // done!
@@ -2744,15 +2747,18 @@
&& (!mPendingEvent->dispatchInProgress || !mCurrentInputTargetsValid)
&& mPendingEvent->type == EventEntry::TYPE_MOTION) {
MotionEntry* motionEntry = static_cast<MotionEntry*>(mPendingEvent);
- if (motionEntry->deviceId == deviceId && motionEntry->source == source) {
- if (!motionEntry->canAppendSamples(action, pointerCount, pointerProperties)) {
+ if (motionEntry->deviceId == args->deviceId
+ && motionEntry->source == args->source) {
+ if (!motionEntry->canAppendSamples(args->action,
+ args->pointerCount, args->pointerProperties)) {
// Pending motion event is for this device and source but it is
// not compatible for appending new samples. Stop here.
goto NoBatchingOrStreaming;
}
// Do the batching magic.
- batchMotionLocked(motionEntry, eventTime, metaState, pointerCoords,
+ batchMotionLocked(motionEntry, args->eventTime,
+ args->metaState, args->pointerCoords,
"pending motion event");
mLock.unlock();
return; // done!
@@ -2799,16 +2805,16 @@
MotionEntry* motionEntry = static_cast<MotionEntry*>(
dispatchEntry->eventEntry);
- if (motionEntry->action != action
- || motionEntry->deviceId != deviceId
- || motionEntry->source != source
- || motionEntry->pointerCount != pointerCount
+ if (motionEntry->action != args->action
+ || motionEntry->deviceId != args->deviceId
+ || motionEntry->source != args->source
+ || motionEntry->pointerCount != args->pointerCount
|| motionEntry->isInjected()) {
// The motion event is not compatible with this move.
continue;
}
- if (action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
+ if (args->action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
if (mLastHoverWindowHandle == NULL) {
#if DEBUG_BATCHING
LOGD("Not streaming hover move because there is no "
@@ -2818,8 +2824,8 @@
}
sp<InputWindowHandle> hoverWindowHandle = findTouchedWindowAtLocked(
- pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X),
- pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
+ args->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X),
+ args->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
if (mLastHoverWindowHandle != hoverWindowHandle) {
#if DEBUG_BATCHING
LOGD("Not streaming hover move because the last hovered window "
@@ -2834,7 +2840,7 @@
// Hurray! This foreground target is currently dispatching a move event
// that we can stream onto. Append the motion sample and resume dispatch.
- motionEntry->appendSample(eventTime, pointerCoords);
+ motionEntry->appendSample(args->eventTime, args->pointerCoords);
#if DEBUG_BATCHING
LOGD("Appended motion sample onto batch for most recently dispatched "
"motion event for this device and source in the outbound queues. "
@@ -2854,10 +2860,11 @@
}
// Just enqueue a new motion event.
- MotionEntry* newEntry = new MotionEntry(eventTime,
- deviceId, source, policyFlags, action, flags, metaState, buttonState, edgeFlags,
- xPrecision, yPrecision, downTime,
- pointerCount, pointerProperties, pointerCoords);
+ MotionEntry* newEntry = new MotionEntry(args->eventTime,
+ args->deviceId, args->source, policyFlags,
+ args->action, args->flags, args->metaState, args->buttonState,
+ args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
+ args->pointerCount, args->pointerProperties, args->pointerCoords);
needWake = enqueueInboundEventLocked(newEntry);
mLock.unlock();
@@ -2898,15 +2905,17 @@
#endif
}
-void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
- uint32_t policyFlags) {
+void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
#if DEBUG_INBOUND_EVENT_DETAILS
- LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
- switchCode, switchValue, policyFlags);
+ LOGD("notifySwitch - eventTime=%lld, policyFlags=0x%x, switchCode=%d, switchValue=%d",
+ args->eventTime, args->policyFlags,
+ args->switchCode, args->switchValue);
#endif
+ uint32_t policyFlags = args->policyFlags;
policyFlags |= POLICY_FLAG_TRUSTED;
- mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
+ mPolicy->notifySwitch(args->eventTime,
+ args->switchCode, args->switchValue, policyFlags);
}
int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 1d39b2e..01c7b35 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -34,6 +34,7 @@
#include "InputWindow.h"
#include "InputApplication.h"
+#include "InputListener.h"
namespace android {
@@ -270,7 +271,7 @@
/* Notifies the system about input events generated by the input reader.
* The dispatcher is expected to be mostly asynchronous. */
-class InputDispatcherInterface : public virtual RefBase {
+class InputDispatcherInterface : public virtual RefBase, public InputListenerInterface {
protected:
InputDispatcherInterface() { }
virtual ~InputDispatcherInterface() { }
@@ -288,23 +289,6 @@
*/
virtual void dispatchOnce() = 0;
- /* Notifies the dispatcher about new events.
- *
- * These methods should only be called on the input reader thread.
- */
- virtual void notifyConfigurationChanged(nsecs_t eventTime) = 0;
- virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
- int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
- virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t action, int32_t flags,
- int32_t metaState, int32_t buttonState, int32_t edgeFlags,
- uint32_t pointerCount, const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords,
- float xPrecision, float yPrecision, nsecs_t downTime) = 0;
- virtual void notifySwitch(nsecs_t when,
- int32_t switchCode, int32_t switchValue, uint32_t policyFlags) = 0;
-
/* Injects an input event and optionally waits for sync.
* The synchronization mode determines whether the method blocks while waiting for
* input injection to proceed.
@@ -389,18 +373,10 @@
virtual void dispatchOnce();
- virtual void notifyConfigurationChanged(nsecs_t eventTime);
- virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
- int32_t scanCode, int32_t metaState, nsecs_t downTime);
- virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t action, int32_t flags,
- int32_t metaState, int32_t buttonState, int32_t edgeFlags,
- uint32_t pointerCount, const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords,
- float xPrecision, float yPrecision, nsecs_t downTime);
- virtual void notifySwitch(nsecs_t when,
- int32_t switchCode, int32_t switchValue, uint32_t policyFlags) ;
+ virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
+ virtual void notifyKey(const NotifyKeyArgs* args);
+ virtual void notifyMotion(const NotifyMotionArgs* args);
+ virtual void notifySwitch(const NotifySwitchArgs* args);
virtual int32_t injectInputEvent(const InputEvent* event,
int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
diff --git a/services/input/InputListener.cpp b/services/input/InputListener.cpp
new file mode 100644
index 0000000..4f9fe90
--- /dev/null
+++ b/services/input/InputListener.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "InputListener"
+
+//#define LOG_NDEBUG 0
+
+#include "InputListener.h"
+
+#include <cutils/log.h>
+
+namespace android {
+
+// --- NotifyConfigurationChangedArgs ---
+
+NotifyConfigurationChangedArgs::NotifyConfigurationChangedArgs(nsecs_t eventTime) :
+ eventTime(eventTime) {
+}
+
+NotifyConfigurationChangedArgs::NotifyConfigurationChangedArgs(
+ const NotifyConfigurationChangedArgs& other) :
+ eventTime(other.eventTime) {
+}
+
+void NotifyConfigurationChangedArgs::notify(const sp<InputListenerInterface>& listener) const {
+ listener->notifyConfigurationChanged(this);
+}
+
+
+// --- NotifyKeyArgs ---
+
+NotifyKeyArgs::NotifyKeyArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
+ uint32_t policyFlags,
+ int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
+ int32_t metaState, nsecs_t downTime) :
+ eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
+ action(action), flags(flags), keyCode(keyCode), scanCode(scanCode),
+ metaState(metaState), downTime(downTime) {
+}
+
+NotifyKeyArgs::NotifyKeyArgs(const NotifyKeyArgs& other) :
+ eventTime(other.eventTime), deviceId(other.deviceId), source(other.source),
+ policyFlags(other.policyFlags),
+ action(other.action), flags(other.flags),
+ keyCode(other.keyCode), scanCode(other.scanCode),
+ metaState(other.metaState), downTime(other.downTime) {
+}
+
+void NotifyKeyArgs::notify(const sp<InputListenerInterface>& listener) const {
+ listener->notifyKey(this);
+}
+
+
+// --- NotifyMotionArgs ---
+
+NotifyMotionArgs::NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
+ uint32_t policyFlags,
+ int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
+ int32_t edgeFlags, uint32_t pointerCount,
+ const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
+ float xPrecision, float yPrecision, nsecs_t downTime) :
+ eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
+ action(action), flags(flags), metaState(metaState), buttonState(buttonState),
+ edgeFlags(edgeFlags), pointerCount(pointerCount),
+ xPrecision(xPrecision), yPrecision(yPrecision), downTime(downTime) {
+ for (uint32_t i = 0; i < pointerCount; i++) {
+ this->pointerProperties[i].copyFrom(pointerProperties[i]);
+ this->pointerCoords[i].copyFrom(pointerCoords[i]);
+ }
+}
+
+NotifyMotionArgs::NotifyMotionArgs(const NotifyMotionArgs& other) :
+ eventTime(other.eventTime), deviceId(other.deviceId), source(other.source),
+ policyFlags(other.policyFlags),
+ action(other.action), flags(other.flags),
+ metaState(other.metaState), buttonState(other.buttonState),
+ edgeFlags(other.edgeFlags), pointerCount(other.pointerCount),
+ xPrecision(other.xPrecision), yPrecision(other.yPrecision), downTime(other.downTime) {
+ for (uint32_t i = 0; i < pointerCount; i++) {
+ pointerProperties[i].copyFrom(other.pointerProperties[i]);
+ pointerCoords[i].copyFrom(other.pointerCoords[i]);
+ }
+}
+
+void NotifyMotionArgs::notify(const sp<InputListenerInterface>& listener) const {
+ listener->notifyMotion(this);
+}
+
+
+// --- NotifySwitchArgs ---
+
+NotifySwitchArgs::NotifySwitchArgs(nsecs_t eventTime, uint32_t policyFlags,
+ int32_t switchCode, int32_t switchValue) :
+ eventTime(eventTime), policyFlags(policyFlags),
+ switchCode(switchCode), switchValue(switchValue) {
+}
+
+NotifySwitchArgs::NotifySwitchArgs(const NotifySwitchArgs& other) :
+ eventTime(other.eventTime), policyFlags(other.policyFlags),
+ switchCode(other.switchCode), switchValue(other.switchValue) {
+}
+
+void NotifySwitchArgs::notify(const sp<InputListenerInterface>& listener) const {
+ listener->notifySwitch(this);
+}
+
+
+// --- QueuedInputListener ---
+
+QueuedInputListener::QueuedInputListener(const sp<InputListenerInterface>& innerListener) :
+ mInnerListener(innerListener) {
+}
+
+QueuedInputListener::~QueuedInputListener() {
+ size_t count = mArgsQueue.size();
+ for (size_t i = 0; i < count; i++) {
+ delete mArgsQueue[i];
+ }
+}
+
+void QueuedInputListener::notifyConfigurationChanged(
+ const NotifyConfigurationChangedArgs* args) {
+ mArgsQueue.push(new NotifyConfigurationChangedArgs(*args));
+}
+
+void QueuedInputListener::notifyKey(const NotifyKeyArgs* args) {
+ mArgsQueue.push(new NotifyKeyArgs(*args));
+}
+
+void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
+ mArgsQueue.push(new NotifyMotionArgs(*args));
+}
+
+void QueuedInputListener::notifySwitch(const NotifySwitchArgs* args) {
+ mArgsQueue.push(new NotifySwitchArgs(*args));
+}
+
+void QueuedInputListener::flush() {
+ size_t count = mArgsQueue.size();
+ for (size_t i = 0; i < count; i++) {
+ NotifyArgs* args = mArgsQueue[i];
+ args->notify(mInnerListener);
+ delete args;
+ }
+ mArgsQueue.clear();
+}
+
+
+} // namespace android
diff --git a/services/input/InputListener.h b/services/input/InputListener.h
new file mode 100644
index 0000000..3fef132
--- /dev/null
+++ b/services/input/InputListener.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UI_INPUT_LISTENER_H
+#define _UI_INPUT_LISTENER_H
+
+#include <ui/Input.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class InputListenerInterface;
+
+
+/* Superclass of all input event argument objects */
+struct NotifyArgs {
+ virtual ~NotifyArgs() { }
+
+ virtual void notify(const sp<InputListenerInterface>& listener) const = 0;
+};
+
+
+/* Describes a configuration change event. */
+struct NotifyConfigurationChangedArgs : public NotifyArgs {
+ nsecs_t eventTime;
+
+ inline NotifyConfigurationChangedArgs() { }
+
+ NotifyConfigurationChangedArgs(nsecs_t eventTime);
+
+ NotifyConfigurationChangedArgs(const NotifyConfigurationChangedArgs& other);
+
+ virtual ~NotifyConfigurationChangedArgs() { }
+
+ virtual void notify(const sp<InputListenerInterface>& listener) const;
+};
+
+
+/* Describes a key event. */
+struct NotifyKeyArgs : public NotifyArgs {
+ nsecs_t eventTime;
+ int32_t deviceId;
+ uint32_t source;
+ uint32_t policyFlags;
+ int32_t action;
+ int32_t flags;
+ int32_t keyCode;
+ int32_t scanCode;
+ int32_t metaState;
+ nsecs_t downTime;
+
+ inline NotifyKeyArgs() { }
+
+ NotifyKeyArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
+ int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
+ int32_t metaState, nsecs_t downTime);
+
+ NotifyKeyArgs(const NotifyKeyArgs& other);
+
+ virtual ~NotifyKeyArgs() { }
+
+ virtual void notify(const sp<InputListenerInterface>& listener) const;
+};
+
+
+/* Describes a motion event. */
+struct NotifyMotionArgs : public NotifyArgs {
+ nsecs_t eventTime;
+ int32_t deviceId;
+ uint32_t source;
+ uint32_t policyFlags;
+ int32_t action;
+ int32_t flags;
+ int32_t metaState;
+ int32_t buttonState;
+ int32_t edgeFlags;
+ uint32_t pointerCount;
+ PointerProperties pointerProperties[MAX_POINTERS];
+ PointerCoords pointerCoords[MAX_POINTERS];
+ float xPrecision;
+ float yPrecision;
+ nsecs_t downTime;
+
+ inline NotifyMotionArgs() { }
+
+ NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
+ int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
+ int32_t edgeFlags, uint32_t pointerCount,
+ const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
+ float xPrecision, float yPrecision, nsecs_t downTime);
+
+ NotifyMotionArgs(const NotifyMotionArgs& other);
+
+ virtual ~NotifyMotionArgs() { }
+
+ virtual void notify(const sp<InputListenerInterface>& listener) const;
+};
+
+
+/* Describes a switch event. */
+struct NotifySwitchArgs : public NotifyArgs {
+ nsecs_t eventTime;
+ uint32_t policyFlags;
+ int32_t switchCode;
+ int32_t switchValue;
+
+ inline NotifySwitchArgs() { }
+
+ NotifySwitchArgs(nsecs_t eventTime, uint32_t policyFlags,
+ int32_t switchCode, int32_t switchValue);
+
+ NotifySwitchArgs(const NotifySwitchArgs& other);
+
+ virtual ~NotifySwitchArgs() { }
+
+ virtual void notify(const sp<InputListenerInterface>& listener) const;
+};
+
+
+/*
+ * The interface used by the InputReader to notify the InputListener about input events.
+ */
+class InputListenerInterface : public virtual RefBase {
+protected:
+ InputListenerInterface() { }
+ virtual ~InputListenerInterface() { }
+
+public:
+ virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) = 0;
+ virtual void notifyKey(const NotifyKeyArgs* args) = 0;
+ virtual void notifyMotion(const NotifyMotionArgs* args) = 0;
+ virtual void notifySwitch(const NotifySwitchArgs* args) = 0;
+};
+
+
+/*
+ * An implementation of the listener interface that queues up and defers dispatch
+ * of decoded events until flushed.
+ */
+class QueuedInputListener : public InputListenerInterface {
+protected:
+ virtual ~QueuedInputListener();
+
+public:
+ QueuedInputListener(const sp<InputListenerInterface>& innerListener);
+
+ virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
+ virtual void notifyKey(const NotifyKeyArgs* args);
+ virtual void notifyMotion(const NotifyMotionArgs* args);
+ virtual void notifySwitch(const NotifySwitchArgs* args);
+
+ void flush();
+
+private:
+ sp<InputListenerInterface> mInnerListener;
+ Vector<NotifyArgs*> mArgsQueue;
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_LISTENER_H
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index db312ad..8786c24 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -180,8 +180,9 @@
|| (action == AKEY_EVENT_ACTION_UP
&& (lastButtonState & buttonState)
&& !(currentButtonState & buttonState))) {
- context->getDispatcher()->notifyKey(when, deviceId, source, policyFlags,
+ NotifyKeyArgs args(when, deviceId, source, policyFlags,
action, 0, keyCode, 0, context->getGlobalMetaState(), when);
+ context->getListener()->notifyKey(&args);
}
}
@@ -201,13 +202,19 @@
InputReader::InputReader(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
- const sp<InputDispatcherInterface>& dispatcher) :
- mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
+ const sp<InputListenerInterface>& listener) :
+ mContext(this), mEventHub(eventHub), mPolicy(policy),
mGlobalMetaState(0), mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
mConfigurationChangesToRefresh(0) {
- refreshConfiguration(0);
- updateGlobalMetaState();
- updateInputConfiguration();
+ mQueuedListener = new QueuedInputListener(listener);
+
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ refreshConfigurationLocked(0);
+ updateGlobalMetaStateLocked();
+ updateInputConfigurationLocked();
+ } // release lock
}
InputReader::~InputReader() {
@@ -217,39 +224,52 @@
}
void InputReader::loopOnce() {
- uint32_t changes;
+ int32_t timeoutMillis;
{ // acquire lock
- AutoMutex _l(mStateLock);
+ AutoMutex _l(mLock);
- changes = mConfigurationChangesToRefresh;
- mConfigurationChangesToRefresh = 0;
+ uint32_t changes = mConfigurationChangesToRefresh;
+ if (changes) {
+ mConfigurationChangesToRefresh = 0;
+ refreshConfigurationLocked(changes);
+ }
+
+ timeoutMillis = -1;
+ if (mNextTimeout != LLONG_MAX) {
+ nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+ timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
+ }
} // release lock
- if (changes) {
- refreshConfiguration(changes);
- }
-
- int32_t timeoutMillis = -1;
- if (mNextTimeout != LLONG_MAX) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
- }
-
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
- if (count) {
- processEvents(mEventBuffer, count);
- }
- if (!count || timeoutMillis == 0) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ if (count) {
+ processEventsLocked(mEventBuffer, count);
+ }
+ if (!count || timeoutMillis == 0) {
+ nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
#if DEBUG_RAW_EVENTS
- LOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
+ LOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
#endif
- mNextTimeout = LLONG_MAX;
- timeoutExpired(now);
- }
+ mNextTimeout = LLONG_MAX;
+ timeoutExpiredLocked(now);
+ }
+ } // release lock
+
+ // Flush queued events out to the listener.
+ // This must happen outside of the lock because the listener could potentially call
+ // back into the InputReader's methods, such as getScanCodeState, or become blocked
+ // on another thread similarly waiting to acquire the InputReader lock thereby
+ // resulting in a deadlock. This situation is actually quite plausible because the
+ // listener is actually the input dispatcher, which calls into the window manager,
+ // which occasionally calls into the input reader.
+ mQueuedListener->flush();
}
-void InputReader::processEvents(const RawEvent* rawEvents, size_t count) {
+void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
for (const RawEvent* rawEvent = rawEvents; count;) {
int32_t type = rawEvent->type;
size_t batchSize = 1;
@@ -265,17 +285,17 @@
#if DEBUG_RAW_EVENTS
LOGD("BatchSize: %d Count: %d", batchSize, count);
#endif
- processEventsForDevice(deviceId, rawEvent, batchSize);
+ processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
} else {
switch (rawEvent->type) {
case EventHubInterface::DEVICE_ADDED:
- addDevice(rawEvent->deviceId);
+ addDeviceLocked(rawEvent->deviceId);
break;
case EventHubInterface::DEVICE_REMOVED:
- removeDevice(rawEvent->deviceId);
+ removeDeviceLocked(rawEvent->deviceId);
break;
case EventHubInterface::FINISHED_DEVICE_SCAN:
- handleConfigurationChanged(rawEvent->when);
+ handleConfigurationChangedLocked(rawEvent->when);
break;
default:
LOG_ASSERT(false); // can't happen
@@ -287,11 +307,11 @@
}
}
-void InputReader::addDevice(int32_t deviceId) {
+void InputReader::addDeviceLocked(int32_t deviceId) {
String8 name = mEventHub->getDeviceName(deviceId);
uint32_t classes = mEventHub->getDeviceClasses(deviceId);
- InputDevice* device = createDevice(deviceId, name, classes);
+ InputDevice* device = createDeviceLocked(deviceId, name, classes);
device->configure(&mConfig, 0);
if (device->isIgnored()) {
@@ -301,39 +321,23 @@
device->getSources());
}
- bool added = false;
- { // acquire device registry writer lock
- RWLock::AutoWLock _wl(mDeviceRegistryLock);
-
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex < 0) {
- mDevices.add(deviceId, device);
- added = true;
- }
- } // release device registry writer lock
-
- if (! added) {
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex < 0) {
+ mDevices.add(deviceId, device);
+ } else {
LOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
delete device;
return;
}
}
-void InputReader::removeDevice(int32_t deviceId) {
- bool removed = false;
+void InputReader::removeDeviceLocked(int32_t deviceId) {
InputDevice* device = NULL;
- { // acquire device registry writer lock
- RWLock::AutoWLock _wl(mDeviceRegistryLock);
-
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex >= 0) {
- device = mDevices.valueAt(deviceIndex);
- mDevices.removeItemsAt(deviceIndex, 1);
- removed = true;
- }
- } // release device registry writer lock
-
- if (! removed) {
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex >= 0) {
+ device = mDevices.valueAt(deviceIndex);
+ mDevices.removeItemsAt(deviceIndex, 1);
+ } else {
LOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
return;
}
@@ -351,8 +355,9 @@
delete device;
}
-InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, uint32_t classes) {
- InputDevice* device = new InputDevice(this, deviceId, name);
+InputDevice* InputReader::createDeviceLocked(int32_t deviceId,
+ const String8& name, uint32_t classes) {
+ InputDevice* device = new InputDevice(&mContext, deviceId, name);
// External devices.
if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
@@ -404,52 +409,45 @@
return device;
}
-void InputReader::processEventsForDevice(int32_t deviceId,
+void InputReader::processEventsForDeviceLocked(int32_t deviceId,
const RawEvent* rawEvents, size_t count) {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex < 0) {
+ LOGW("Discarding event for unknown deviceId %d.", deviceId);
+ return;
+ }
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex < 0) {
- LOGW("Discarding event for unknown deviceId %d.", deviceId);
- return;
- }
+ InputDevice* device = mDevices.valueAt(deviceIndex);
+ if (device->isIgnored()) {
+ //LOGD("Discarding event for ignored deviceId %d.", deviceId);
+ return;
+ }
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (device->isIgnored()) {
- //LOGD("Discarding event for ignored deviceId %d.", deviceId);
- return;
- }
-
- device->process(rawEvents, count);
- } // release device registry reader lock
+ device->process(rawEvents, count);
}
-void InputReader::timeoutExpired(nsecs_t when) {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (!device->isIgnored()) {
- device->timeoutExpired(when);
- }
+void InputReader::timeoutExpiredLocked(nsecs_t when) {
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ if (!device->isIgnored()) {
+ device->timeoutExpired(when);
}
- } // release device registry reader lock
+ }
}
-void InputReader::handleConfigurationChanged(nsecs_t when) {
+void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
// Reset global meta state because it depends on the list of all configured devices.
- updateGlobalMetaState();
+ updateGlobalMetaStateLocked();
// Update input configuration.
- updateInputConfiguration();
+ updateInputConfigurationLocked();
// Enqueue configuration changed.
- mDispatcher->notifyConfigurationChanged(when);
+ NotifyConfigurationChangedArgs args(when);
+ mQueuedListener->notifyConfigurationChanged(&args);
}
-void InputReader::refreshConfiguration(uint32_t changes) {
+void InputReader::refreshConfigurationLocked(uint32_t changes) {
mPolicy->getReaderConfiguration(&mConfig);
mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
@@ -459,84 +457,60 @@
if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
mEventHub->requestReopenDevices();
} else {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- device->configure(&mConfig, changes);
- }
- } // release device registry reader lock
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ device->configure(&mConfig, changes);
+ }
}
}
}
-void InputReader::updateGlobalMetaState() {
- { // acquire state lock
- AutoMutex _l(mStateLock);
+void InputReader::updateGlobalMetaStateLocked() {
+ mGlobalMetaState = 0;
- mGlobalMetaState = 0;
-
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- mGlobalMetaState |= device->getMetaState();
- }
- } // release device registry reader lock
- } // release state lock
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ mGlobalMetaState |= device->getMetaState();
+ }
}
-int32_t InputReader::getGlobalMetaState() {
- { // acquire state lock
- AutoMutex _l(mStateLock);
-
- return mGlobalMetaState;
- } // release state lock
+int32_t InputReader::getGlobalMetaStateLocked() {
+ return mGlobalMetaState;
}
-void InputReader::updateInputConfiguration() {
- { // acquire state lock
- AutoMutex _l(mStateLock);
+void InputReader::updateInputConfigurationLocked() {
+ int32_t touchScreenConfig = InputConfiguration::TOUCHSCREEN_NOTOUCH;
+ int32_t keyboardConfig = InputConfiguration::KEYBOARD_NOKEYS;
+ int32_t navigationConfig = InputConfiguration::NAVIGATION_NONAV;
+ InputDeviceInfo deviceInfo;
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ device->getDeviceInfo(& deviceInfo);
+ uint32_t sources = deviceInfo.getSources();
- int32_t touchScreenConfig = InputConfiguration::TOUCHSCREEN_NOTOUCH;
- int32_t keyboardConfig = InputConfiguration::KEYBOARD_NOKEYS;
- int32_t navigationConfig = InputConfiguration::NAVIGATION_NONAV;
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
+ if ((sources & AINPUT_SOURCE_TOUCHSCREEN) == AINPUT_SOURCE_TOUCHSCREEN) {
+ touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER;
+ }
+ if ((sources & AINPUT_SOURCE_TRACKBALL) == AINPUT_SOURCE_TRACKBALL) {
+ navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL;
+ } else if ((sources & AINPUT_SOURCE_DPAD) == AINPUT_SOURCE_DPAD) {
+ navigationConfig = InputConfiguration::NAVIGATION_DPAD;
+ }
+ if (deviceInfo.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) {
+ keyboardConfig = InputConfiguration::KEYBOARD_QWERTY;
+ }
+ }
- InputDeviceInfo deviceInfo;
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- device->getDeviceInfo(& deviceInfo);
- uint32_t sources = deviceInfo.getSources();
-
- if ((sources & AINPUT_SOURCE_TOUCHSCREEN) == AINPUT_SOURCE_TOUCHSCREEN) {
- touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER;
- }
- if ((sources & AINPUT_SOURCE_TRACKBALL) == AINPUT_SOURCE_TRACKBALL) {
- navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL;
- } else if ((sources & AINPUT_SOURCE_DPAD) == AINPUT_SOURCE_DPAD) {
- navigationConfig = InputConfiguration::NAVIGATION_DPAD;
- }
- if (deviceInfo.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) {
- keyboardConfig = InputConfiguration::KEYBOARD_QWERTY;
- }
- }
- } // release device registry reader lock
-
- mInputConfiguration.touchScreen = touchScreenConfig;
- mInputConfiguration.keyboard = keyboardConfig;
- mInputConfiguration.navigation = navigationConfig;
- } // release state lock
+ mInputConfiguration.touchScreen = touchScreenConfig;
+ mInputConfiguration.keyboard = keyboardConfig;
+ mInputConfiguration.navigation = navigationConfig;
}
-void InputReader::disableVirtualKeysUntil(nsecs_t time) {
+void InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
mDisableVirtualKeysTimeout = time;
}
-bool InputReader::shouldDropVirtualKey(nsecs_t now,
+bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now,
InputDevice* device, int32_t keyCode, int32_t scanCode) {
if (now < mDisableVirtualKeysTimeout) {
LOGI("Dropping virtual key from device %s because virtual keys are "
@@ -550,153 +524,141 @@
}
}
-void InputReader::fadePointer() {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- device->fadePointer();
- }
- } // release device registry reader lock
+void InputReader::fadePointerLocked() {
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ device->fadePointer();
+ }
}
-void InputReader::requestTimeoutAtTime(nsecs_t when) {
+void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
if (when < mNextTimeout) {
mNextTimeout = when;
}
}
void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) {
- { // acquire state lock
- AutoMutex _l(mStateLock);
+ AutoMutex _l(mLock);
- *outConfiguration = mInputConfiguration;
- } // release state lock
+ *outConfiguration = mInputConfiguration;
}
status_t InputReader::getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
+ AutoMutex _l(mLock);
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex < 0) {
- return NAME_NOT_FOUND;
- }
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex < 0) {
+ return NAME_NOT_FOUND;
+ }
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (device->isIgnored()) {
- return NAME_NOT_FOUND;
- }
+ InputDevice* device = mDevices.valueAt(deviceIndex);
+ if (device->isIgnored()) {
+ return NAME_NOT_FOUND;
+ }
- device->getDeviceInfo(outDeviceInfo);
- return OK;
- } // release device registy reader lock
+ device->getDeviceInfo(outDeviceInfo);
+ return OK;
}
void InputReader::getInputDeviceIds(Vector<int32_t>& outDeviceIds) {
+ AutoMutex _l(mLock);
+
outDeviceIds.clear();
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- size_t numDevices = mDevices.size();
- for (size_t i = 0; i < numDevices; i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (! device->isIgnored()) {
- outDeviceIds.add(device->getId());
- }
+ size_t numDevices = mDevices.size();
+ for (size_t i = 0; i < numDevices; i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ if (!device->isIgnored()) {
+ outDeviceIds.add(device->getId());
}
- } // release device registy reader lock
+ }
}
int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
int32_t keyCode) {
- return getState(deviceId, sourceMask, keyCode, & InputDevice::getKeyCodeState);
+ AutoMutex _l(mLock);
+
+ return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
}
int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
int32_t scanCode) {
- return getState(deviceId, sourceMask, scanCode, & InputDevice::getScanCodeState);
+ AutoMutex _l(mLock);
+
+ return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
}
int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
- return getState(deviceId, sourceMask, switchCode, & InputDevice::getSwitchState);
+ AutoMutex _l(mLock);
+
+ return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
}
-int32_t InputReader::getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
+int32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
GetStateFunc getStateFunc) {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- int32_t result = AKEY_STATE_UNKNOWN;
- if (deviceId >= 0) {
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex >= 0) {
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result = (device->*getStateFunc)(sourceMask, code);
- }
+ int32_t result = AKEY_STATE_UNKNOWN;
+ if (deviceId >= 0) {
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex >= 0) {
+ InputDevice* device = mDevices.valueAt(deviceIndex);
+ if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+ result = (device->*getStateFunc)(sourceMask, code);
}
- } else {
- size_t numDevices = mDevices.size();
- for (size_t i = 0; i < numDevices; i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result = (device->*getStateFunc)(sourceMask, code);
- if (result >= AKEY_STATE_DOWN) {
- return result;
- }
+ }
+ } else {
+ size_t numDevices = mDevices.size();
+ for (size_t i = 0; i < numDevices; i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+ result = (device->*getStateFunc)(sourceMask, code);
+ if (result >= AKEY_STATE_DOWN) {
+ return result;
}
}
}
- return result;
- } // release device registy reader lock
+ }
+ return result;
}
bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
+ AutoMutex _l(mLock);
+
memset(outFlags, 0, numCodes);
- return markSupportedKeyCodes(deviceId, sourceMask, numCodes, keyCodes, outFlags);
+ return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
}
-bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
- const int32_t* keyCodes, uint8_t* outFlags) {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
- bool result = false;
- if (deviceId >= 0) {
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex >= 0) {
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result = device->markSupportedKeyCodes(sourceMask,
- numCodes, keyCodes, outFlags);
- }
- }
- } else {
- size_t numDevices = mDevices.size();
- for (size_t i = 0; i < numDevices; i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result |= device->markSupportedKeyCodes(sourceMask,
- numCodes, keyCodes, outFlags);
- }
+bool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
+ size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
+ bool result = false;
+ if (deviceId >= 0) {
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex >= 0) {
+ InputDevice* device = mDevices.valueAt(deviceIndex);
+ if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+ result = device->markSupportedKeyCodes(sourceMask,
+ numCodes, keyCodes, outFlags);
}
}
- return result;
- } // release device registy reader lock
+ } else {
+ size_t numDevices = mDevices.size();
+ for (size_t i = 0; i < numDevices; i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+ result |= device->markSupportedKeyCodes(sourceMask,
+ numCodes, keyCodes, outFlags);
+ }
+ }
+ }
+ return result;
}
void InputReader::requestRefreshConfiguration(uint32_t changes) {
- if (changes) {
- bool needWake;
- { // acquire lock
- AutoMutex _l(mStateLock);
+ AutoMutex _l(mLock);
- needWake = !mConfigurationChangesToRefresh;
- mConfigurationChangesToRefresh |= changes;
- } // release lock
+ if (changes) {
+ bool needWake = !mConfigurationChangesToRefresh;
+ mConfigurationChangesToRefresh |= changes;
if (needWake) {
mEventHub->wake();
@@ -705,18 +667,16 @@
}
void InputReader::dump(String8& dump) {
+ AutoMutex _l(mLock);
+
mEventHub->dump(dump);
dump.append("\n");
dump.append("Input Reader State:\n");
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- for (size_t i = 0; i < mDevices.size(); i++) {
- mDevices.valueAt(i)->dump(dump);
- }
- } // release device registy reader lock
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ mDevices.valueAt(i)->dump(dump);
+ }
dump.append(INDENT "Configuration:\n");
dump.append(INDENT2 "ExcludedDeviceNames: [");
@@ -772,6 +732,56 @@
}
+// --- InputReader::ContextImpl ---
+
+InputReader::ContextImpl::ContextImpl(InputReader* reader) :
+ mReader(reader) {
+}
+
+void InputReader::ContextImpl::updateGlobalMetaState() {
+ // lock is already held by the input loop
+ mReader->updateGlobalMetaStateLocked();
+}
+
+int32_t InputReader::ContextImpl::getGlobalMetaState() {
+ // lock is already held by the input loop
+ return mReader->getGlobalMetaStateLocked();
+}
+
+void InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
+ // lock is already held by the input loop
+ mReader->disableVirtualKeysUntilLocked(time);
+}
+
+bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now,
+ InputDevice* device, int32_t keyCode, int32_t scanCode) {
+ // lock is already held by the input loop
+ return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
+}
+
+void InputReader::ContextImpl::fadePointer() {
+ // lock is already held by the input loop
+ mReader->fadePointerLocked();
+}
+
+void InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
+ // lock is already held by the input loop
+ mReader->requestTimeoutAtTimeLocked(when);
+}
+
+InputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
+ return mReader->mPolicy.get();
+}
+
+InputListenerInterface* InputReader::ContextImpl::getListener() {
+ return mReader->mQueuedListener.get();
+}
+
+EventHubInterface* InputReader::ContextImpl::getEventHub() {
+ return mReader->mEventHub.get();
+}
+
+
// --- InputReaderThread ---
InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
@@ -1170,6 +1180,96 @@
}
+// --- RawPointerAxes ---
+
+RawPointerAxes::RawPointerAxes() {
+ clear();
+}
+
+void RawPointerAxes::clear() {
+ x.clear();
+ y.clear();
+ pressure.clear();
+ touchMajor.clear();
+ touchMinor.clear();
+ toolMajor.clear();
+ toolMinor.clear();
+ orientation.clear();
+ distance.clear();
+ trackingId.clear();
+ slot.clear();
+}
+
+
+// --- RawPointerData ---
+
+RawPointerData::RawPointerData() {
+ clear();
+}
+
+void RawPointerData::clear() {
+ pointerCount = 0;
+ clearIdBits();
+}
+
+void RawPointerData::copyFrom(const RawPointerData& other) {
+ pointerCount = other.pointerCount;
+ hoveringIdBits = other.hoveringIdBits;
+ touchingIdBits = other.touchingIdBits;
+
+ for (uint32_t i = 0; i < pointerCount; i++) {
+ pointers[i] = other.pointers[i];
+
+ int id = pointers[i].id;
+ idToIndex[id] = other.idToIndex[id];
+ }
+}
+
+void RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) const {
+ float x = 0, y = 0;
+ uint32_t count = touchingIdBits.count();
+ if (count) {
+ for (BitSet32 idBits(touchingIdBits); !idBits.isEmpty(); ) {
+ uint32_t id = idBits.clearFirstMarkedBit();
+ const Pointer& pointer = pointerForId(id);
+ x += pointer.x;
+ y += pointer.y;
+ }
+ x /= count;
+ y /= count;
+ }
+ *outX = x;
+ *outY = y;
+}
+
+
+// --- CookedPointerData ---
+
+CookedPointerData::CookedPointerData() {
+ clear();
+}
+
+void CookedPointerData::clear() {
+ pointerCount = 0;
+ hoveringIdBits.clear();
+ touchingIdBits.clear();
+}
+
+void CookedPointerData::copyFrom(const CookedPointerData& other) {
+ pointerCount = other.pointerCount;
+ hoveringIdBits = other.hoveringIdBits;
+ touchingIdBits = other.touchingIdBits;
+
+ for (uint32_t i = 0; i < pointerCount; i++) {
+ pointerProperties[i].copyFrom(other.pointerProperties[i]);
+ pointerCoords[i].copyFrom(other.pointerCoords[i]);
+
+ int id = pointerProperties[i].id;
+ idToIndex[id] = other.idToIndex[id];
+ }
+}
+
+
// --- SingleTouchMotionAccumulator ---
SingleTouchMotionAccumulator::SingleTouchMotionAccumulator() {
@@ -1298,6 +1398,10 @@
slot->mInUse = true;
slot->mAbsMTPressure = rawEvent->value;
break;
+ case ABS_MT_DISTANCE:
+ slot->mInUse = true;
+ slot->mAbsMTDistance = rawEvent->value;
+ break;
case ABS_MT_TOOL_TYPE:
slot->mInUse = true;
slot->mAbsMTToolType = rawEvent->value;
@@ -1338,8 +1442,8 @@
mAbsMTOrientation = 0;
mAbsMTTrackingId = -1;
mAbsMTPressure = 0;
- mAbsMTToolType = 0;
mAbsMTDistance = 0;
+ mAbsMTToolType = 0;
}
int32_t MultiTouchMotionAccumulator::Slot::getToolType() const {
@@ -1404,6 +1508,10 @@
void InputMapper::fadePointer() {
}
+status_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo) {
+ return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo);
+}
+
void InputMapper::dumpRawAbsoluteAxisInfo(String8& dump,
const RawAbsoluteAxisInfo& axis, const char* name) {
if (axis.valid) {
@@ -1437,7 +1545,8 @@
}
void SwitchInputMapper::processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) {
- getDispatcher()->notifySwitch(when, switchCode, switchValue, 0);
+ NotifySwitchArgs args(when, 0, switchCode, switchValue);
+ getListener()->notifySwitch(&args);
}
int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
@@ -1451,15 +1560,15 @@
uint32_t source, int32_t keyboardType) :
InputMapper(device), mSource(source),
mKeyboardType(keyboardType) {
- initializeLocked();
+ initialize();
}
KeyboardInputMapper::~KeyboardInputMapper() {
}
-void KeyboardInputMapper::initializeLocked() {
- mLocked.metaState = AMETA_NONE;
- mLocked.downTime = 0;
+void KeyboardInputMapper::initialize() {
+ mMetaState = AMETA_NONE;
+ mDownTime = 0;
}
uint32_t KeyboardInputMapper::getSources() {
@@ -1473,15 +1582,12 @@
}
void KeyboardInputMapper::dump(String8& dump) {
- { // acquire lock
- AutoMutex _l(mLock);
- dump.append(INDENT2 "Keyboard Input Mapper:\n");
- dumpParameters(dump);
- dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
- dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mLocked.keyDowns.size());
- dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mLocked.metaState);
- dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
- } // release lock
+ dump.append(INDENT2 "Keyboard Input Mapper:\n");
+ dumpParameters(dump);
+ dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
+ dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mKeyDowns.size());
+ dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mMetaState);
+ dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
}
@@ -1493,10 +1599,7 @@
configureParameters();
// Reset LEDs.
- {
- AutoMutex _l(mLock);
- resetLedStateLocked();
- }
+ resetLedState();
}
}
@@ -1520,27 +1623,16 @@
}
void KeyboardInputMapper::reset() {
- for (;;) {
- int32_t keyCode, scanCode;
- { // acquire lock
- AutoMutex _l(mLock);
-
- // Synthesize key up event on reset if keys are currently down.
- if (mLocked.keyDowns.isEmpty()) {
- initializeLocked();
- resetLedStateLocked();
- break; // done
- }
-
- const KeyDown& keyDown = mLocked.keyDowns.top();
- keyCode = keyDown.keyCode;
- scanCode = keyDown.scanCode;
- } // release lock
-
+ // Synthesize key up event on reset if keys are currently down.
+ while (!mKeyDowns.isEmpty()) {
+ const KeyDown& keyDown = mKeyDowns.top();
nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- processKey(when, false, keyCode, scanCode, 0);
+ processKey(when, false, keyDown.keyCode, keyDown.scanCode, 0);
}
+ initialize();
+ resetLedState();
+
InputMapper::reset();
getContext()->updateGlobalMetaState();
}
@@ -1567,72 +1659,66 @@
void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
int32_t scanCode, uint32_t policyFlags) {
- int32_t newMetaState;
- nsecs_t downTime;
- bool metaStateChanged = false;
- { // acquire lock
- AutoMutex _l(mLock);
-
- if (down) {
- // Rotate key codes according to orientation if needed.
- // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
- if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0) {
- int32_t orientation;
- if (!getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
- false /*external*/, NULL, NULL, & orientation)) {
- orientation = DISPLAY_ORIENTATION_0;
- }
-
- keyCode = rotateKeyCode(keyCode, orientation);
+ if (down) {
+ // Rotate key codes according to orientation if needed.
+ // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+ if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0) {
+ int32_t orientation;
+ if (!getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
+ false /*external*/, NULL, NULL, & orientation)) {
+ orientation = DISPLAY_ORIENTATION_0;
}
- // Add key down.
- ssize_t keyDownIndex = findKeyDownLocked(scanCode);
- if (keyDownIndex >= 0) {
- // key repeat, be sure to use same keycode as before in case of rotation
- keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
- } else {
- // key down
- if ((policyFlags & POLICY_FLAG_VIRTUAL)
- && mContext->shouldDropVirtualKey(when,
- getDevice(), keyCode, scanCode)) {
- return;
- }
+ keyCode = rotateKeyCode(keyCode, orientation);
+ }
- mLocked.keyDowns.push();
- KeyDown& keyDown = mLocked.keyDowns.editTop();
- keyDown.keyCode = keyCode;
- keyDown.scanCode = scanCode;
- }
-
- mLocked.downTime = when;
+ // Add key down.
+ ssize_t keyDownIndex = findKeyDown(scanCode);
+ if (keyDownIndex >= 0) {
+ // key repeat, be sure to use same keycode as before in case of rotation
+ keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
} else {
- // Remove key down.
- ssize_t keyDownIndex = findKeyDownLocked(scanCode);
- if (keyDownIndex >= 0) {
- // key up, be sure to use same keycode as before in case of rotation
- keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
- mLocked.keyDowns.removeAt(size_t(keyDownIndex));
- } else {
- // key was not actually down
- LOGI("Dropping key up from device %s because the key was not down. "
- "keyCode=%d, scanCode=%d",
- getDeviceName().string(), keyCode, scanCode);
+ // key down
+ if ((policyFlags & POLICY_FLAG_VIRTUAL)
+ && mContext->shouldDropVirtualKey(when,
+ getDevice(), keyCode, scanCode)) {
return;
}
+
+ mKeyDowns.push();
+ KeyDown& keyDown = mKeyDowns.editTop();
+ keyDown.keyCode = keyCode;
+ keyDown.scanCode = scanCode;
}
- int32_t oldMetaState = mLocked.metaState;
- newMetaState = updateMetaState(keyCode, down, oldMetaState);
- if (oldMetaState != newMetaState) {
- mLocked.metaState = newMetaState;
- metaStateChanged = true;
- updateLedStateLocked(false);
+ mDownTime = when;
+ } else {
+ // Remove key down.
+ ssize_t keyDownIndex = findKeyDown(scanCode);
+ if (keyDownIndex >= 0) {
+ // key up, be sure to use same keycode as before in case of rotation
+ keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
+ mKeyDowns.removeAt(size_t(keyDownIndex));
+ } else {
+ // key was not actually down
+ LOGI("Dropping key up from device %s because the key was not down. "
+ "keyCode=%d, scanCode=%d",
+ getDeviceName().string(), keyCode, scanCode);
+ return;
}
+ }
- downTime = mLocked.downTime;
- } // release lock
+ bool metaStateChanged = false;
+ int32_t oldMetaState = mMetaState;
+ int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
+ if (oldMetaState != newMetaState) {
+ mMetaState = newMetaState;
+ metaStateChanged = true;
+ updateLedState(false);
+ }
+
+ nsecs_t downTime = mDownTime;
// Key down on external an keyboard should wake the device.
// We don't do this for internal keyboards to prevent them from waking up in your pocket.
@@ -1652,15 +1738,16 @@
getContext()->fadePointer();
}
- getDispatcher()->notifyKey(when, getDeviceId(), mSource, policyFlags,
+ NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
+ getListener()->notifyKey(&args);
}
-ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) {
- size_t n = mLocked.keyDowns.size();
+ssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
+ size_t n = mKeyDowns.size();
for (size_t i = 0; i < n; i++) {
- if (mLocked.keyDowns[i].scanCode == scanCode) {
+ if (mKeyDowns[i].scanCode == scanCode) {
return i;
}
}
@@ -1681,38 +1768,35 @@
}
int32_t KeyboardInputMapper::getMetaState() {
- { // acquire lock
- AutoMutex _l(mLock);
- return mLocked.metaState;
- } // release lock
+ return mMetaState;
}
-void KeyboardInputMapper::resetLedStateLocked() {
- initializeLedStateLocked(mLocked.capsLockLedState, LED_CAPSL);
- initializeLedStateLocked(mLocked.numLockLedState, LED_NUML);
- initializeLedStateLocked(mLocked.scrollLockLedState, LED_SCROLLL);
+void KeyboardInputMapper::resetLedState() {
+ initializeLedState(mCapsLockLedState, LED_CAPSL);
+ initializeLedState(mNumLockLedState, LED_NUML);
+ initializeLedState(mScrollLockLedState, LED_SCROLLL);
- updateLedStateLocked(true);
+ updateLedState(true);
}
-void KeyboardInputMapper::initializeLedStateLocked(LockedState::LedState& ledState, int32_t led) {
+void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
ledState.on = false;
}
-void KeyboardInputMapper::updateLedStateLocked(bool reset) {
- updateLedStateForModifierLocked(mLocked.capsLockLedState, LED_CAPSL,
+void KeyboardInputMapper::updateLedState(bool reset) {
+ updateLedStateForModifier(mCapsLockLedState, LED_CAPSL,
AMETA_CAPS_LOCK_ON, reset);
- updateLedStateForModifierLocked(mLocked.numLockLedState, LED_NUML,
+ updateLedStateForModifier(mNumLockLedState, LED_NUML,
AMETA_NUM_LOCK_ON, reset);
- updateLedStateForModifierLocked(mLocked.scrollLockLedState, LED_SCROLLL,
+ updateLedStateForModifier(mScrollLockLedState, LED_SCROLLL,
AMETA_SCROLL_LOCK_ON, reset);
}
-void KeyboardInputMapper::updateLedStateForModifierLocked(LockedState::LedState& ledState,
+void KeyboardInputMapper::updateLedStateForModifier(LedState& ledState,
int32_t led, int32_t modifier, bool reset) {
if (ledState.avail) {
- bool desiredState = (mLocked.metaState & modifier) != 0;
+ bool desiredState = (mMetaState & modifier) != 0;
if (reset || ledState.on != desiredState) {
getEventHub()->setLedState(getDeviceId(), led, desiredState);
ledState.on = desiredState;
@@ -1725,7 +1809,7 @@
CursorInputMapper::CursorInputMapper(InputDevice* device) :
InputMapper(device) {
- initializeLocked();
+ initialize();
}
CursorInputMapper::~CursorInputMapper() {
@@ -1759,24 +1843,21 @@
}
void CursorInputMapper::dump(String8& dump) {
- { // acquire lock
- AutoMutex _l(mLock);
- dump.append(INDENT2 "Cursor Input Mapper:\n");
- dumpParameters(dump);
- dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
- dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
- dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
- dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
- dump.appendFormat(INDENT3 "HaveVWheel: %s\n",
- toString(mCursorMotionAccumulator.haveRelativeVWheel()));
- dump.appendFormat(INDENT3 "HaveHWheel: %s\n",
- toString(mCursorMotionAccumulator.haveRelativeHWheel()));
- dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
- dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
- dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mLocked.buttonState);
- dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mLocked.buttonState)));
- dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
- } // release lock
+ dump.append(INDENT2 "Cursor Input Mapper:\n");
+ dumpParameters(dump);
+ dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
+ dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
+ dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
+ dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
+ dump.appendFormat(INDENT3 "HaveVWheel: %s\n",
+ toString(mCursorMotionAccumulator.haveRelativeVWheel()));
+ dump.appendFormat(INDENT3 "HaveHWheel: %s\n",
+ toString(mCursorMotionAccumulator.haveRelativeHWheel()));
+ dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
+ dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
+ dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
+ dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
+ dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
}
void CursorInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) {
@@ -1859,38 +1940,27 @@
toString(mParameters.orientationAware));
}
-void CursorInputMapper::initializeLocked() {
+void CursorInputMapper::initialize() {
mCursorButtonAccumulator.clearButtons();
mCursorMotionAccumulator.clearRelativeAxes();
- mLocked.buttonState = 0;
- mLocked.downTime = 0;
+ mButtonState = 0;
+ mDownTime = 0;
}
void CursorInputMapper::reset() {
- for (;;) {
- int32_t buttonState;
- { // acquire lock
- AutoMutex _l(mLock);
+ // Reset velocity.
+ mPointerVelocityControl.reset();
+ mWheelXVelocityControl.reset();
+ mWheelYVelocityControl.reset();
- buttonState = mLocked.buttonState;
- if (!buttonState) {
- initializeLocked();
- break; // done
- }
- } // release lock
+ // Synthesize button up event on reset.
+ nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+ mCursorButtonAccumulator.clearButtons();
+ mCursorMotionAccumulator.clearRelativeAxes();
+ sync(when);
- // Reset velocity.
- mPointerVelocityControl.reset();
- mWheelXVelocityControl.reset();
- mWheelYVelocityControl.reset();
-
- // Synthesize button up event on reset.
- nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- mCursorButtonAccumulator.clearButtons();
- mCursorMotionAccumulator.clearRelativeAxes();
- sync(when);
- }
+ initialize();
InputMapper::reset();
}
@@ -1905,98 +1975,84 @@
}
void CursorInputMapper::sync(nsecs_t when) {
- int32_t motionEventAction;
- int32_t lastButtonState, currentButtonState;
+ int32_t lastButtonState = mButtonState;
+ int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
+ mButtonState = currentButtonState;
+
+ bool wasDown = isPointerDown(lastButtonState);
+ bool down = isPointerDown(currentButtonState);
+ bool downChanged;
+ if (!wasDown && down) {
+ mDownTime = when;
+ downChanged = true;
+ } else if (wasDown && !down) {
+ downChanged = true;
+ } else {
+ downChanged = false;
+ }
+ nsecs_t downTime = mDownTime;
+ bool buttonsChanged = currentButtonState != lastButtonState;
+
+ float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
+ float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
+ bool moved = deltaX != 0 || deltaY != 0;
+
+ if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0
+ && (deltaX != 0.0f || deltaY != 0.0f)) {
+ // Rotate motion based on display orientation if needed.
+ // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+ int32_t orientation;
+ if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
+ false /*external*/, NULL, NULL, & orientation)) {
+ orientation = DISPLAY_ORIENTATION_0;
+ }
+
+ rotateDelta(orientation, &deltaX, &deltaY);
+ }
+
PointerProperties pointerProperties;
+ pointerProperties.clear();
+ pointerProperties.id = 0;
+ pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
+
PointerCoords pointerCoords;
- nsecs_t downTime;
- float vscroll, hscroll;
- { // acquire lock
- AutoMutex _l(mLock);
+ pointerCoords.clear();
- lastButtonState = mLocked.buttonState;
- currentButtonState = mCursorButtonAccumulator.getButtonState();
- mLocked.buttonState = currentButtonState;
+ float vscroll = mCursorMotionAccumulator.getRelativeVWheel();
+ float hscroll = mCursorMotionAccumulator.getRelativeHWheel();
+ bool scrolled = vscroll != 0 || hscroll != 0;
- bool wasDown = isPointerDown(lastButtonState);
- bool down = isPointerDown(currentButtonState);
- bool downChanged;
- if (!wasDown && down) {
- mLocked.downTime = when;
- downChanged = true;
- } else if (wasDown && !down) {
- downChanged = true;
- } else {
- downChanged = false;
- }
- downTime = mLocked.downTime;
+ mWheelYVelocityControl.move(when, NULL, &vscroll);
+ mWheelXVelocityControl.move(when, &hscroll, NULL);
- if (downChanged) {
- motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
- } else if (down || mPointerController == NULL) {
- motionEventAction = AMOTION_EVENT_ACTION_MOVE;
- } else {
- motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
- }
+ mPointerVelocityControl.move(when, &deltaX, &deltaY);
- float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
- float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
+ if (mPointerController != NULL) {
+ if (moved || scrolled || buttonsChanged) {
+ mPointerController->setPresentation(
+ PointerControllerInterface::PRESENTATION_POINTER);
- if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0
- && (deltaX != 0.0f || deltaY != 0.0f)) {
- // Rotate motion based on display orientation if needed.
- // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
- int32_t orientation;
- if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
- false /*external*/, NULL, NULL, & orientation)) {
- orientation = DISPLAY_ORIENTATION_0;
+ if (moved) {
+ mPointerController->move(deltaX, deltaY);
}
- rotateDelta(orientation, &deltaX, &deltaY);
- }
-
- pointerProperties.clear();
- pointerProperties.id = 0;
- pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
-
- pointerCoords.clear();
-
- vscroll = mCursorMotionAccumulator.getRelativeVWheel();
- hscroll = mCursorMotionAccumulator.getRelativeHWheel();
-
- mWheelYVelocityControl.move(when, NULL, &vscroll);
- mWheelXVelocityControl.move(when, &hscroll, NULL);
-
- mPointerVelocityControl.move(when, &deltaX, &deltaY);
-
- if (mPointerController != NULL) {
- if (deltaX != 0 || deltaY != 0 || vscroll != 0 || hscroll != 0
- || currentButtonState != lastButtonState) {
- mPointerController->setPresentation(
- PointerControllerInterface::PRESENTATION_POINTER);
-
- if (deltaX != 0 || deltaY != 0) {
- mPointerController->move(deltaX, deltaY);
- }
-
- if (currentButtonState != lastButtonState) {
- mPointerController->setButtonState(currentButtonState);
- }
-
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+ if (buttonsChanged) {
+ mPointerController->setButtonState(currentButtonState);
}
- float x, y;
- mPointerController->getPosition(&x, &y);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- } else {
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
+ mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
}
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
- } // release lock
+ float x, y;
+ mPointerController->getPosition(&x, &y);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+ } else {
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
+ }
+
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
// Moving an external trackball or mouse should wake the device.
// We don't do this for internal cursor devices to prevent them from waking up
@@ -2012,29 +2068,43 @@
policyFlags, lastButtonState, currentButtonState);
// Send motion event.
- int32_t metaState = mContext->getGlobalMetaState();
- getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags,
- motionEventAction, 0, metaState, currentButtonState, 0,
- 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+ if (downChanged || moved || scrolled || buttonsChanged) {
+ int32_t metaState = mContext->getGlobalMetaState();
+ int32_t motionEventAction;
+ if (downChanged) {
+ motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
+ } else if (down || mPointerController == NULL) {
+ motionEventAction = AMOTION_EVENT_ACTION_MOVE;
+ } else {
+ motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
+ }
- // Send hover move after UP to tell the application that the mouse is hovering now.
- if (motionEventAction == AMOTION_EVENT_ACTION_UP
- && mPointerController != NULL) {
- getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
- metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+ NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+ motionEventAction, 0, metaState, currentButtonState, 0,
1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
- }
+ getListener()->notifyMotion(&args);
- // Send scroll events.
- if (vscroll != 0 || hscroll != 0) {
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
+ // Send hover move after UP to tell the application that the mouse is hovering now.
+ if (motionEventAction == AMOTION_EVENT_ACTION_UP
+ && mPointerController != NULL) {
+ NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
+ AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
+ metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+ 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+ getListener()->notifyMotion(&hoverArgs);
+ }
- getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
- AMOTION_EVENT_EDGE_FLAG_NONE,
- 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+ // Send scroll events.
+ if (scrolled) {
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
+
+ NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
+ AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+ getListener()->notifyMotion(&scrollArgs);
+ }
}
// Synthesize key up from buttons if needed.
@@ -2053,24 +2123,18 @@
}
void CursorInputMapper::fadePointer() {
- { // acquire lock
- AutoMutex _l(mLock);
- if (mPointerController != NULL) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- }
- } // release lock
+ if (mPointerController != NULL) {
+ mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ }
}
// --- TouchInputMapper ---
TouchInputMapper::TouchInputMapper(InputDevice* device) :
- InputMapper(device) {
- mLocked.surfaceOrientation = -1;
- mLocked.surfaceWidth = -1;
- mLocked.surfaceHeight = -1;
-
- initializeLocked();
+ InputMapper(device),
+ mSurfaceOrientation(-1), mSurfaceWidth(-1), mSurfaceHeight(-1) {
+ initialize();
}
TouchInputMapper::~TouchInputMapper() {
@@ -2083,126 +2147,148 @@
void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
InputMapper::populateDeviceInfo(info);
- { // acquire lock
- AutoMutex _l(mLock);
+ // Ensure surface information is up to date so that orientation changes are
+ // noticed immediately.
+ if (!configureSurface()) {
+ return;
+ }
- // Ensure surface information is up to date so that orientation changes are
- // noticed immediately.
- if (!configureSurfaceLocked()) {
- return;
+ info->addMotionRange(mOrientedRanges.x);
+ info->addMotionRange(mOrientedRanges.y);
+
+ if (mOrientedRanges.havePressure) {
+ info->addMotionRange(mOrientedRanges.pressure);
+ }
+
+ if (mOrientedRanges.haveSize) {
+ info->addMotionRange(mOrientedRanges.size);
+ }
+
+ if (mOrientedRanges.haveTouchSize) {
+ info->addMotionRange(mOrientedRanges.touchMajor);
+ info->addMotionRange(mOrientedRanges.touchMinor);
+ }
+
+ if (mOrientedRanges.haveToolSize) {
+ info->addMotionRange(mOrientedRanges.toolMajor);
+ info->addMotionRange(mOrientedRanges.toolMinor);
+ }
+
+ if (mOrientedRanges.haveOrientation) {
+ info->addMotionRange(mOrientedRanges.orientation);
+ }
+
+ if (mOrientedRanges.haveDistance) {
+ info->addMotionRange(mOrientedRanges.distance);
+ }
+
+ if (mPointerController != NULL) {
+ float minX, minY, maxX, maxY;
+ if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
+ info->addMotionRange(AMOTION_EVENT_AXIS_X, mPointerSource,
+ minX, maxX, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_Y, mPointerSource,
+ minY, maxY, 0.0f, 0.0f);
}
-
- info->addMotionRange(mLocked.orientedRanges.x);
- info->addMotionRange(mLocked.orientedRanges.y);
-
- if (mLocked.orientedRanges.havePressure) {
- info->addMotionRange(mLocked.orientedRanges.pressure);
- }
-
- if (mLocked.orientedRanges.haveSize) {
- info->addMotionRange(mLocked.orientedRanges.size);
- }
-
- if (mLocked.orientedRanges.haveTouchSize) {
- info->addMotionRange(mLocked.orientedRanges.touchMajor);
- info->addMotionRange(mLocked.orientedRanges.touchMinor);
- }
-
- if (mLocked.orientedRanges.haveToolSize) {
- info->addMotionRange(mLocked.orientedRanges.toolMajor);
- info->addMotionRange(mLocked.orientedRanges.toolMinor);
- }
-
- if (mLocked.orientedRanges.haveOrientation) {
- info->addMotionRange(mLocked.orientedRanges.orientation);
- }
-
- if (mLocked.orientedRanges.haveDistance) {
- info->addMotionRange(mLocked.orientedRanges.distance);
- }
-
- if (mPointerController != NULL) {
- float minX, minY, maxX, maxY;
- if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
- info->addMotionRange(AMOTION_EVENT_AXIS_X, mPointerSource,
- minX, maxX, 0.0f, 0.0f);
- info->addMotionRange(AMOTION_EVENT_AXIS_Y, mPointerSource,
- minY, maxY, 0.0f, 0.0f);
- }
- info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mPointerSource,
- 0.0f, 1.0f, 0.0f, 0.0f);
- }
- } // release lock
+ info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mPointerSource,
+ 0.0f, 1.0f, 0.0f, 0.0f);
+ }
}
void TouchInputMapper::dump(String8& dump) {
- { // acquire lock
- AutoMutex _l(mLock);
- dump.append(INDENT2 "Touch Input Mapper:\n");
- dumpParameters(dump);
- dumpVirtualKeysLocked(dump);
- dumpRawAxes(dump);
- dumpCalibration(dump);
- dumpSurfaceLocked(dump);
+ dump.append(INDENT2 "Touch Input Mapper:\n");
+ dumpParameters(dump);
+ dumpVirtualKeys(dump);
+ dumpRawPointerAxes(dump);
+ dumpCalibration(dump);
+ dumpSurface(dump);
- dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
- dump.appendFormat(INDENT4 "XScale: %0.3f\n", mLocked.xScale);
- dump.appendFormat(INDENT4 "YScale: %0.3f\n", mLocked.yScale);
- dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mLocked.xPrecision);
- dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mLocked.yPrecision);
- dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mLocked.geometricScale);
- dump.appendFormat(INDENT4 "ToolSizeLinearScale: %0.3f\n", mLocked.toolSizeLinearScale);
- dump.appendFormat(INDENT4 "ToolSizeLinearBias: %0.3f\n", mLocked.toolSizeLinearBias);
- dump.appendFormat(INDENT4 "ToolSizeAreaScale: %0.3f\n", mLocked.toolSizeAreaScale);
- dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mLocked.toolSizeAreaBias);
- dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mLocked.pressureScale);
- dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mLocked.sizeScale);
- dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mLocked.orientationScale);
- dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mLocked.distanceScale);
+ dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
+ dump.appendFormat(INDENT4 "XScale: %0.3f\n", mXScale);
+ dump.appendFormat(INDENT4 "YScale: %0.3f\n", mYScale);
+ dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mXPrecision);
+ dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mYPrecision);
+ dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mGeometricScale);
+ dump.appendFormat(INDENT4 "ToolSizeLinearScale: %0.3f\n", mToolSizeLinearScale);
+ dump.appendFormat(INDENT4 "ToolSizeLinearBias: %0.3f\n", mToolSizeLinearBias);
+ dump.appendFormat(INDENT4 "ToolSizeAreaScale: %0.3f\n", mToolSizeAreaScale);
+ dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mToolSizeAreaBias);
+ dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mPressureScale);
+ dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mSizeScale);
+ dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mOrientationScale);
+ dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mDistanceScale);
- dump.appendFormat(INDENT3 "Last Touch:\n");
- dump.appendFormat(INDENT4 "Button State: 0x%08x\n", mLastTouch.buttonState);
- dump.appendFormat(INDENT4 "Pointer Count: %d\n", mLastTouch.pointerCount);
- for (uint32_t i = 0; i < mLastTouch.pointerCount; i++) {
- const PointerData& pointer = mLastTouch.pointers[i];
- dump.appendFormat(INDENT5 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
- "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
- "orientation=%d, distance=%d, toolType=%d, isHovering=%s\n", i,
- pointer.id, pointer.x, pointer.y, pointer.pressure,
- pointer.touchMajor, pointer.touchMinor, pointer.toolMajor, pointer.toolMinor,
- pointer.orientation, pointer.distance,
- pointer.toolType, toString(pointer.isHovering));
- }
+ dump.appendFormat(INDENT3 "Last Button State: 0x%08x\n", mLastButtonState);
- if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
- dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n");
- dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n",
- mLocked.pointerGestureXMovementScale);
- dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n",
- mLocked.pointerGestureYMovementScale);
- dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n",
- mLocked.pointerGestureXZoomScale);
- dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n",
- mLocked.pointerGestureYZoomScale);
- dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
- mLocked.pointerGestureMaxSwipeWidth);
- }
- } // release lock
+ dump.appendFormat(INDENT3 "Last Raw Touch: pointerCount=%d\n",
+ mLastRawPointerData.pointerCount);
+ for (uint32_t i = 0; i < mLastRawPointerData.pointerCount; i++) {
+ const RawPointerData::Pointer& pointer = mLastRawPointerData.pointers[i];
+ dump.appendFormat(INDENT4 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
+ "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
+ "orientation=%d, distance=%d, toolType=%d, isHovering=%s\n", i,
+ pointer.id, pointer.x, pointer.y, pointer.pressure,
+ pointer.touchMajor, pointer.touchMinor,
+ pointer.toolMajor, pointer.toolMinor,
+ pointer.orientation, pointer.distance,
+ pointer.toolType, toString(pointer.isHovering));
+ }
+
+ dump.appendFormat(INDENT3 "Last Cooked Touch: pointerCount=%d\n",
+ mLastCookedPointerData.pointerCount);
+ for (uint32_t i = 0; i < mLastCookedPointerData.pointerCount; i++) {
+ const PointerProperties& pointerProperties = mLastCookedPointerData.pointerProperties[i];
+ const PointerCoords& pointerCoords = mLastCookedPointerData.pointerCoords[i];
+ dump.appendFormat(INDENT4 "[%d]: id=%d, x=%0.3f, y=%0.3f, pressure=%0.3f, "
+ "touchMajor=%0.3f, touchMinor=%0.3f, toolMajor=%0.3f, toolMinor=%0.3f, "
+ "orientation=%0.3f, distance=%0.3f, toolType=%d, isHovering=%s\n", i,
+ pointerProperties.id,
+ pointerCoords.getX(),
+ pointerCoords.getY(),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE),
+ pointerProperties.toolType,
+ toString(mLastCookedPointerData.isHovering(i)));
+ }
+
+ if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
+ dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n");
+ dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n",
+ mPointerGestureXMovementScale);
+ dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n",
+ mPointerGestureYMovementScale);
+ dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n",
+ mPointerGestureXZoomScale);
+ dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n",
+ mPointerGestureYZoomScale);
+ dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
+ mPointerGestureMaxSwipeWidth);
+ }
}
-void TouchInputMapper::initializeLocked() {
- mCurrentTouch.clear();
- mLastTouch.clear();
+void TouchInputMapper::initialize() {
+ mCurrentRawPointerData.clear();
+ mLastRawPointerData.clear();
+ mCurrentCookedPointerData.clear();
+ mLastCookedPointerData.clear();
+ mCurrentButtonState = 0;
+ mLastButtonState = 0;
+ mSentHoverEnter = false;
mDownTime = 0;
- mLocked.currentVirtualKey.down = false;
+ mCurrentVirtualKey.down = false;
- mLocked.orientedRanges.havePressure = false;
- mLocked.orientedRanges.haveSize = false;
- mLocked.orientedRanges.haveTouchSize = false;
- mLocked.orientedRanges.haveToolSize = false;
- mLocked.orientedRanges.haveOrientation = false;
- mLocked.orientedRanges.haveDistance = false;
+ mOrientedRanges.havePressure = false;
+ mOrientedRanges.haveSize = false;
+ mOrientedRanges.haveTouchSize = false;
+ mOrientedRanges.haveToolSize = false;
+ mOrientedRanges.haveOrientation = false;
+ mOrientedRanges.haveDistance = false;
mPointerGesture.reset();
}
@@ -2235,18 +2321,14 @@
}
// Configure absolute axis information.
- configureRawAxes();
+ configureRawPointerAxes();
// Prepare input device calibration.
parseCalibration();
resolveCalibration();
- { // acquire lock
- AutoMutex _l(mLock);
-
- // Configure surface dimensions and orientation.
- configureSurfaceLocked();
- } // release lock
+ // Configure surface dimensions and orientation.
+ configureSurface();
}
if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
@@ -2359,38 +2441,28 @@
toString(mParameters.orientationAware));
}
-void TouchInputMapper::configureRawAxes() {
- mRawAxes.x.clear();
- mRawAxes.y.clear();
- mRawAxes.pressure.clear();
- mRawAxes.touchMajor.clear();
- mRawAxes.touchMinor.clear();
- mRawAxes.toolMajor.clear();
- mRawAxes.toolMinor.clear();
- mRawAxes.orientation.clear();
- mRawAxes.distance.clear();
- mRawAxes.trackingId.clear();
- mRawAxes.slot.clear();
+void TouchInputMapper::configureRawPointerAxes() {
+ mRawPointerAxes.clear();
}
-void TouchInputMapper::dumpRawAxes(String8& dump) {
- dump.append(INDENT3 "Raw Axes:\n");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.x, "X");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.y, "Y");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.pressure, "Pressure");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.touchMajor, "TouchMajor");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.touchMinor, "TouchMinor");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.toolMajor, "ToolMajor");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.toolMinor, "ToolMinor");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.orientation, "Orientation");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.distance, "Distance");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.trackingId, "TrackingId");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.slot, "Slot");
+void TouchInputMapper::dumpRawPointerAxes(String8& dump) {
+ dump.append(INDENT3 "Raw Touch Axes:\n");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.x, "X");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.y, "Y");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.pressure, "Pressure");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMajor, "TouchMajor");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMinor, "TouchMinor");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMajor, "ToolMajor");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMinor, "ToolMinor");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.orientation, "Orientation");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.distance, "Distance");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.trackingId, "TrackingId");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.slot, "Slot");
}
-bool TouchInputMapper::configureSurfaceLocked() {
+bool TouchInputMapper::configureSurface() {
// Ensure we have valid X and Y axes.
- if (!mRawAxes.x.valid || !mRawAxes.y.valid) {
+ if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) {
LOGW(INDENT "Touch device '%s' did not report support for X or Y axis! "
"The device will be inoperable.", getDeviceName().string());
return false;
@@ -2398,27 +2470,27 @@
// Update orientation and dimensions if needed.
int32_t orientation = DISPLAY_ORIENTATION_0;
- int32_t width = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1;
- int32_t height = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1;
+ int32_t width = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
+ int32_t height = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
if (mParameters.associatedDisplayId >= 0) {
// Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
mParameters.associatedDisplayIsExternal,
- &mLocked.associatedDisplayWidth, &mLocked.associatedDisplayHeight,
- &mLocked.associatedDisplayOrientation)) {
+ &mAssociatedDisplayWidth, &mAssociatedDisplayHeight,
+ &mAssociatedDisplayOrientation)) {
return false;
}
// A touch screen inherits the dimensions of the display.
if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) {
- width = mLocked.associatedDisplayWidth;
- height = mLocked.associatedDisplayHeight;
+ width = mAssociatedDisplayWidth;
+ height = mAssociatedDisplayHeight;
}
// The device inherits the orientation of the display if it is orientation aware.
if (mParameters.orientationAware) {
- orientation = mLocked.associatedDisplayOrientation;
+ orientation = mAssociatedDisplayOrientation;
}
}
@@ -2427,118 +2499,120 @@
mPointerController = getPolicy()->obtainPointerController(getDeviceId());
}
- bool orientationChanged = mLocked.surfaceOrientation != orientation;
+ bool orientationChanged = mSurfaceOrientation != orientation;
if (orientationChanged) {
- mLocked.surfaceOrientation = orientation;
+ mSurfaceOrientation = orientation;
}
- bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
+ bool sizeChanged = mSurfaceWidth != width || mSurfaceHeight != height;
if (sizeChanged) {
LOGI("Device reconfigured: id=%d, name='%s', surface size is now %dx%d",
getDeviceId(), getDeviceName().string(), width, height);
- mLocked.surfaceWidth = width;
- mLocked.surfaceHeight = height;
+ mSurfaceWidth = width;
+ mSurfaceHeight = height;
// Configure X and Y factors.
- mLocked.xScale = float(width) / (mRawAxes.x.maxValue - mRawAxes.x.minValue + 1);
- mLocked.yScale = float(height) / (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1);
- mLocked.xPrecision = 1.0f / mLocked.xScale;
- mLocked.yPrecision = 1.0f / mLocked.yScale;
+ mXScale = float(width) / (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1);
+ mYScale = float(height) / (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1);
+ mXPrecision = 1.0f / mXScale;
+ mYPrecision = 1.0f / mYScale;
- mLocked.orientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
- mLocked.orientedRanges.x.source = mTouchSource;
- mLocked.orientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
- mLocked.orientedRanges.y.source = mTouchSource;
+ mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
+ mOrientedRanges.x.source = mTouchSource;
+ mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
+ mOrientedRanges.y.source = mTouchSource;
- configureVirtualKeysLocked();
+ configureVirtualKeys();
// Scale factor for terms that are not oriented in a particular axis.
// If the pixels are square then xScale == yScale otherwise we fake it
// by choosing an average.
- mLocked.geometricScale = avg(mLocked.xScale, mLocked.yScale);
+ mGeometricScale = avg(mXScale, mYScale);
// Size of diagonal axis.
float diagonalSize = hypotf(width, height);
// TouchMajor and TouchMinor factors.
if (mCalibration.touchSizeCalibration != Calibration::TOUCH_SIZE_CALIBRATION_NONE) {
- mLocked.orientedRanges.haveTouchSize = true;
+ mOrientedRanges.haveTouchSize = true;
- mLocked.orientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
- mLocked.orientedRanges.touchMajor.source = mTouchSource;
- mLocked.orientedRanges.touchMajor.min = 0;
- mLocked.orientedRanges.touchMajor.max = diagonalSize;
- mLocked.orientedRanges.touchMajor.flat = 0;
- mLocked.orientedRanges.touchMajor.fuzz = 0;
+ mOrientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
+ mOrientedRanges.touchMajor.source = mTouchSource;
+ mOrientedRanges.touchMajor.min = 0;
+ mOrientedRanges.touchMajor.max = diagonalSize;
+ mOrientedRanges.touchMajor.flat = 0;
+ mOrientedRanges.touchMajor.fuzz = 0;
- mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor;
- mLocked.orientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
+ mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
+ mOrientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
}
// ToolMajor and ToolMinor factors.
- mLocked.toolSizeLinearScale = 0;
- mLocked.toolSizeLinearBias = 0;
- mLocked.toolSizeAreaScale = 0;
- mLocked.toolSizeAreaBias = 0;
+ mToolSizeLinearScale = 0;
+ mToolSizeLinearBias = 0;
+ mToolSizeAreaScale = 0;
+ mToolSizeAreaBias = 0;
if (mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) {
if (mCalibration.toolSizeCalibration == Calibration::TOOL_SIZE_CALIBRATION_LINEAR) {
if (mCalibration.haveToolSizeLinearScale) {
- mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale;
- } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
- mLocked.toolSizeLinearScale = float(min(width, height))
- / mRawAxes.toolMajor.maxValue;
+ mToolSizeLinearScale = mCalibration.toolSizeLinearScale;
+ } else if (mRawPointerAxes.toolMajor.valid
+ && mRawPointerAxes.toolMajor.maxValue != 0) {
+ mToolSizeLinearScale = float(min(width, height))
+ / mRawPointerAxes.toolMajor.maxValue;
}
if (mCalibration.haveToolSizeLinearBias) {
- mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias;
+ mToolSizeLinearBias = mCalibration.toolSizeLinearBias;
}
} else if (mCalibration.toolSizeCalibration ==
Calibration::TOOL_SIZE_CALIBRATION_AREA) {
if (mCalibration.haveToolSizeLinearScale) {
- mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale;
+ mToolSizeLinearScale = mCalibration.toolSizeLinearScale;
} else {
- mLocked.toolSizeLinearScale = min(width, height);
+ mToolSizeLinearScale = min(width, height);
}
if (mCalibration.haveToolSizeLinearBias) {
- mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias;
+ mToolSizeLinearBias = mCalibration.toolSizeLinearBias;
}
if (mCalibration.haveToolSizeAreaScale) {
- mLocked.toolSizeAreaScale = mCalibration.toolSizeAreaScale;
- } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
- mLocked.toolSizeAreaScale = 1.0f / mRawAxes.toolMajor.maxValue;
+ mToolSizeAreaScale = mCalibration.toolSizeAreaScale;
+ } else if (mRawPointerAxes.toolMajor.valid
+ && mRawPointerAxes.toolMajor.maxValue != 0) {
+ mToolSizeAreaScale = 1.0f / mRawPointerAxes.toolMajor.maxValue;
}
if (mCalibration.haveToolSizeAreaBias) {
- mLocked.toolSizeAreaBias = mCalibration.toolSizeAreaBias;
+ mToolSizeAreaBias = mCalibration.toolSizeAreaBias;
}
}
- mLocked.orientedRanges.haveToolSize = true;
+ mOrientedRanges.haveToolSize = true;
- mLocked.orientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
- mLocked.orientedRanges.toolMajor.source = mTouchSource;
- mLocked.orientedRanges.toolMajor.min = 0;
- mLocked.orientedRanges.toolMajor.max = diagonalSize;
- mLocked.orientedRanges.toolMajor.flat = 0;
- mLocked.orientedRanges.toolMajor.fuzz = 0;
+ mOrientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
+ mOrientedRanges.toolMajor.source = mTouchSource;
+ mOrientedRanges.toolMajor.min = 0;
+ mOrientedRanges.toolMajor.max = diagonalSize;
+ mOrientedRanges.toolMajor.flat = 0;
+ mOrientedRanges.toolMajor.fuzz = 0;
- mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor;
- mLocked.orientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
+ mOrientedRanges.toolMinor = mOrientedRanges.toolMajor;
+ mOrientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
}
// Pressure factors.
- mLocked.pressureScale = 0;
+ mPressureScale = 0;
if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE) {
RawAbsoluteAxisInfo rawPressureAxis;
switch (mCalibration.pressureSource) {
case Calibration::PRESSURE_SOURCE_PRESSURE:
- rawPressureAxis = mRawAxes.pressure;
+ rawPressureAxis = mRawPointerAxes.pressure;
break;
case Calibration::PRESSURE_SOURCE_TOUCH:
- rawPressureAxis = mRawAxes.touchMajor;
+ rawPressureAxis = mRawPointerAxes.touchMajor;
break;
default:
rawPressureAxis.clear();
@@ -2548,84 +2622,84 @@
|| mCalibration.pressureCalibration
== Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
if (mCalibration.havePressureScale) {
- mLocked.pressureScale = mCalibration.pressureScale;
+ mPressureScale = mCalibration.pressureScale;
} else if (rawPressureAxis.valid && rawPressureAxis.maxValue != 0) {
- mLocked.pressureScale = 1.0f / rawPressureAxis.maxValue;
+ mPressureScale = 1.0f / rawPressureAxis.maxValue;
}
}
- mLocked.orientedRanges.havePressure = true;
+ mOrientedRanges.havePressure = true;
- mLocked.orientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
- mLocked.orientedRanges.pressure.source = mTouchSource;
- mLocked.orientedRanges.pressure.min = 0;
- mLocked.orientedRanges.pressure.max = 1.0;
- mLocked.orientedRanges.pressure.flat = 0;
- mLocked.orientedRanges.pressure.fuzz = 0;
+ mOrientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
+ mOrientedRanges.pressure.source = mTouchSource;
+ mOrientedRanges.pressure.min = 0;
+ mOrientedRanges.pressure.max = 1.0;
+ mOrientedRanges.pressure.flat = 0;
+ mOrientedRanges.pressure.fuzz = 0;
}
// Size factors.
- mLocked.sizeScale = 0;
+ mSizeScale = 0;
if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_NORMALIZED) {
- if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
- mLocked.sizeScale = 1.0f / mRawAxes.toolMajor.maxValue;
+ if (mRawPointerAxes.toolMajor.valid && mRawPointerAxes.toolMajor.maxValue != 0) {
+ mSizeScale = 1.0f / mRawPointerAxes.toolMajor.maxValue;
}
}
- mLocked.orientedRanges.haveSize = true;
+ mOrientedRanges.haveSize = true;
- mLocked.orientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
- mLocked.orientedRanges.size.source = mTouchSource;
- mLocked.orientedRanges.size.min = 0;
- mLocked.orientedRanges.size.max = 1.0;
- mLocked.orientedRanges.size.flat = 0;
- mLocked.orientedRanges.size.fuzz = 0;
+ mOrientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
+ mOrientedRanges.size.source = mTouchSource;
+ mOrientedRanges.size.min = 0;
+ mOrientedRanges.size.max = 1.0;
+ mOrientedRanges.size.flat = 0;
+ mOrientedRanges.size.fuzz = 0;
}
// Orientation
- mLocked.orientationScale = 0;
+ mOrientationScale = 0;
if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) {
if (mCalibration.orientationCalibration
== Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
- if (mRawAxes.orientation.valid && mRawAxes.orientation.maxValue != 0) {
- mLocked.orientationScale = float(M_PI_2) / mRawAxes.orientation.maxValue;
+ if (mRawPointerAxes.orientation.valid && mRawPointerAxes.orientation.maxValue != 0) {
+ mOrientationScale = float(M_PI_2) / mRawPointerAxes.orientation.maxValue;
}
}
- mLocked.orientedRanges.haveOrientation = true;
+ mOrientedRanges.haveOrientation = true;
- mLocked.orientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
- mLocked.orientedRanges.orientation.source = mTouchSource;
- mLocked.orientedRanges.orientation.min = - M_PI_2;
- mLocked.orientedRanges.orientation.max = M_PI_2;
- mLocked.orientedRanges.orientation.flat = 0;
- mLocked.orientedRanges.orientation.fuzz = 0;
+ mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
+ mOrientedRanges.orientation.source = mTouchSource;
+ mOrientedRanges.orientation.min = - M_PI_2;
+ mOrientedRanges.orientation.max = M_PI_2;
+ mOrientedRanges.orientation.flat = 0;
+ mOrientedRanges.orientation.fuzz = 0;
}
// Distance
- mLocked.distanceScale = 0;
+ mDistanceScale = 0;
if (mCalibration.distanceCalibration != Calibration::DISTANCE_CALIBRATION_NONE) {
if (mCalibration.distanceCalibration
== Calibration::DISTANCE_CALIBRATION_SCALED) {
if (mCalibration.haveDistanceScale) {
- mLocked.distanceScale = mCalibration.distanceScale;
+ mDistanceScale = mCalibration.distanceScale;
} else {
- mLocked.distanceScale = 1.0f;
+ mDistanceScale = 1.0f;
}
}
- mLocked.orientedRanges.haveDistance = true;
+ mOrientedRanges.haveDistance = true;
- mLocked.orientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE;
- mLocked.orientedRanges.distance.source = mTouchSource;
- mLocked.orientedRanges.distance.min =
- mRawAxes.distance.minValue * mLocked.distanceScale;
- mLocked.orientedRanges.distance.max =
- mRawAxes.distance.minValue * mLocked.distanceScale;
- mLocked.orientedRanges.distance.flat = 0;
- mLocked.orientedRanges.distance.fuzz =
- mRawAxes.distance.fuzz * mLocked.distanceScale;
+ mOrientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE;
+ mOrientedRanges.distance.source = mTouchSource;
+ mOrientedRanges.distance.min =
+ mRawPointerAxes.distance.minValue * mDistanceScale;
+ mOrientedRanges.distance.max =
+ mRawPointerAxes.distance.minValue * mDistanceScale;
+ mOrientedRanges.distance.flat = 0;
+ mOrientedRanges.distance.fuzz =
+ mRawPointerAxes.distance.fuzz * mDistanceScale;
}
}
@@ -2633,78 +2707,77 @@
// Compute oriented surface dimensions, precision, scales and ranges.
// Note that the maximum value reported is an inclusive maximum value so it is one
// unit less than the total width or height of surface.
- switch (mLocked.surfaceOrientation) {
+ switch (mSurfaceOrientation) {
case DISPLAY_ORIENTATION_90:
case DISPLAY_ORIENTATION_270:
- mLocked.orientedSurfaceWidth = mLocked.surfaceHeight;
- mLocked.orientedSurfaceHeight = mLocked.surfaceWidth;
+ mOrientedSurfaceWidth = mSurfaceHeight;
+ mOrientedSurfaceHeight = mSurfaceWidth;
- mLocked.orientedXPrecision = mLocked.yPrecision;
- mLocked.orientedYPrecision = mLocked.xPrecision;
+ mOrientedXPrecision = mYPrecision;
+ mOrientedYPrecision = mXPrecision;
- mLocked.orientedRanges.x.min = 0;
- mLocked.orientedRanges.x.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue)
- * mLocked.yScale;
- mLocked.orientedRanges.x.flat = 0;
- mLocked.orientedRanges.x.fuzz = mLocked.yScale;
+ mOrientedRanges.x.min = 0;
+ mOrientedRanges.x.max = (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue)
+ * mYScale;
+ mOrientedRanges.x.flat = 0;
+ mOrientedRanges.x.fuzz = mYScale;
- mLocked.orientedRanges.y.min = 0;
- mLocked.orientedRanges.y.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue)
- * mLocked.xScale;
- mLocked.orientedRanges.y.flat = 0;
- mLocked.orientedRanges.y.fuzz = mLocked.xScale;
+ mOrientedRanges.y.min = 0;
+ mOrientedRanges.y.max = (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue)
+ * mXScale;
+ mOrientedRanges.y.flat = 0;
+ mOrientedRanges.y.fuzz = mXScale;
break;
default:
- mLocked.orientedSurfaceWidth = mLocked.surfaceWidth;
- mLocked.orientedSurfaceHeight = mLocked.surfaceHeight;
+ mOrientedSurfaceWidth = mSurfaceWidth;
+ mOrientedSurfaceHeight = mSurfaceHeight;
- mLocked.orientedXPrecision = mLocked.xPrecision;
- mLocked.orientedYPrecision = mLocked.yPrecision;
+ mOrientedXPrecision = mXPrecision;
+ mOrientedYPrecision = mYPrecision;
- mLocked.orientedRanges.x.min = 0;
- mLocked.orientedRanges.x.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue)
- * mLocked.xScale;
- mLocked.orientedRanges.x.flat = 0;
- mLocked.orientedRanges.x.fuzz = mLocked.xScale;
+ mOrientedRanges.x.min = 0;
+ mOrientedRanges.x.max = (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue)
+ * mXScale;
+ mOrientedRanges.x.flat = 0;
+ mOrientedRanges.x.fuzz = mXScale;
- mLocked.orientedRanges.y.min = 0;
- mLocked.orientedRanges.y.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue)
- * mLocked.yScale;
- mLocked.orientedRanges.y.flat = 0;
- mLocked.orientedRanges.y.fuzz = mLocked.yScale;
+ mOrientedRanges.y.min = 0;
+ mOrientedRanges.y.max = (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue)
+ * mYScale;
+ mOrientedRanges.y.flat = 0;
+ mOrientedRanges.y.fuzz = mYScale;
break;
}
// Compute pointer gesture detection parameters.
- // TODO: These factors should not be hardcoded.
if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
- int32_t rawWidth = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1;
- int32_t rawHeight = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1;
+ int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
+ int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
float rawDiagonal = hypotf(rawWidth, rawHeight);
- float displayDiagonal = hypotf(mLocked.associatedDisplayWidth,
- mLocked.associatedDisplayHeight);
+ float displayDiagonal = hypotf(mAssociatedDisplayWidth,
+ mAssociatedDisplayHeight);
// Scale movements such that one whole swipe of the touch pad covers a
// given area relative to the diagonal size of the display when no acceleration
// is applied.
// Assume that the touch pad has a square aspect ratio such that movements in
// X and Y of the same number of raw units cover the same physical distance.
- mLocked.pointerGestureXMovementScale = mConfig.pointerGestureMovementSpeedRatio
+ mPointerGestureXMovementScale = mConfig.pointerGestureMovementSpeedRatio
* displayDiagonal / rawDiagonal;
- mLocked.pointerGestureYMovementScale = mLocked.pointerGestureXMovementScale;
+ mPointerGestureYMovementScale = mPointerGestureXMovementScale;
// Scale zooms to cover a smaller range of the display than movements do.
// This value determines the area around the pointer that is affected by freeform
// pointer gestures.
- mLocked.pointerGestureXZoomScale = mConfig.pointerGestureZoomSpeedRatio
+ mPointerGestureXZoomScale = mConfig.pointerGestureZoomSpeedRatio
* displayDiagonal / rawDiagonal;
- mLocked.pointerGestureYZoomScale = mLocked.pointerGestureXZoomScale;
+ mPointerGestureYZoomScale = mPointerGestureXZoomScale;
// Max width between pointers to detect a swipe gesture is more than some fraction
// of the diagonal axis of the touch pad. Touches that are wider than this are
// translated into freeform gestures.
- mLocked.pointerGestureMaxSwipeWidth =
+ mPointerGestureMaxSwipeWidth =
mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
// Reset the current pointer gesture.
@@ -2720,35 +2793,35 @@
return true;
}
-void TouchInputMapper::dumpSurfaceLocked(String8& dump) {
- dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mLocked.surfaceWidth);
- dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mLocked.surfaceHeight);
- dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mLocked.surfaceOrientation);
+void TouchInputMapper::dumpSurface(String8& dump) {
+ dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
+ dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
+ dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
}
-void TouchInputMapper::configureVirtualKeysLocked() {
+void TouchInputMapper::configureVirtualKeys() {
Vector<VirtualKeyDefinition> virtualKeyDefinitions;
getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
- mLocked.virtualKeys.clear();
+ mVirtualKeys.clear();
if (virtualKeyDefinitions.size() == 0) {
return;
}
- mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size());
+ mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
- int32_t touchScreenLeft = mRawAxes.x.minValue;
- int32_t touchScreenTop = mRawAxes.y.minValue;
- int32_t touchScreenWidth = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1;
- int32_t touchScreenHeight = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1;
+ int32_t touchScreenLeft = mRawPointerAxes.x.minValue;
+ int32_t touchScreenTop = mRawPointerAxes.y.minValue;
+ int32_t touchScreenWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
+ int32_t touchScreenHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
const VirtualKeyDefinition& virtualKeyDefinition =
virtualKeyDefinitions[i];
- mLocked.virtualKeys.add();
- VirtualKey& virtualKey = mLocked.virtualKeys.editTop();
+ mVirtualKeys.add();
+ VirtualKey& virtualKey = mVirtualKeys.editTop();
virtualKey.scanCode = virtualKeyDefinition.scanCode;
int32_t keyCode;
@@ -2757,7 +2830,7 @@
& keyCode, & flags)) {
LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
virtualKey.scanCode);
- mLocked.virtualKeys.pop(); // drop the key
+ mVirtualKeys.pop(); // drop the key
continue;
}
@@ -2769,22 +2842,22 @@
int32_t halfHeight = virtualKeyDefinition.height / 2;
virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
- * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+ * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
- * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+ * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
- * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
+ * touchScreenHeight / mSurfaceHeight + touchScreenTop;
virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
- * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
+ * touchScreenHeight / mSurfaceHeight + touchScreenTop;
}
}
-void TouchInputMapper::dumpVirtualKeysLocked(String8& dump) {
- if (!mLocked.virtualKeys.isEmpty()) {
+void TouchInputMapper::dumpVirtualKeys(String8& dump) {
+ if (!mVirtualKeys.isEmpty()) {
dump.append(INDENT3 "Virtual Keys:\n");
- for (size_t i = 0; i < mLocked.virtualKeys.size(); i++) {
- const VirtualKey& virtualKey = mLocked.virtualKeys.itemAt(i);
+ for (size_t i = 0; i < mVirtualKeys.size(); i++) {
+ const VirtualKey& virtualKey = mVirtualKeys.itemAt(i);
dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, "
"hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
i, virtualKey.scanCode, virtualKey.keyCode,
@@ -2927,22 +3000,22 @@
// Pressure
switch (mCalibration.pressureSource) {
case Calibration::PRESSURE_SOURCE_DEFAULT:
- if (mRawAxes.pressure.valid) {
+ if (mRawPointerAxes.pressure.valid) {
mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
- } else if (mRawAxes.touchMajor.valid) {
+ } else if (mRawPointerAxes.touchMajor.valid) {
mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
}
break;
case Calibration::PRESSURE_SOURCE_PRESSURE:
- if (! mRawAxes.pressure.valid) {
+ if (! mRawPointerAxes.pressure.valid) {
LOGW("Calibration property touch.pressure.source is 'pressure' but "
"the pressure axis is not available.");
}
break;
case Calibration::PRESSURE_SOURCE_TOUCH:
- if (! mRawAxes.touchMajor.valid) {
+ if (! mRawPointerAxes.touchMajor.valid) {
LOGW("Calibration property touch.pressure.source is 'touch' but "
"the touchMajor axis is not available.");
}
@@ -2968,7 +3041,7 @@
// Tool Size
switch (mCalibration.toolSizeCalibration) {
case Calibration::TOOL_SIZE_CALIBRATION_DEFAULT:
- if (mRawAxes.toolMajor.valid) {
+ if (mRawPointerAxes.toolMajor.valid) {
mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR;
} else {
mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE;
@@ -2997,7 +3070,7 @@
// Size
switch (mCalibration.sizeCalibration) {
case Calibration::SIZE_CALIBRATION_DEFAULT:
- if (mRawAxes.toolMajor.valid) {
+ if (mRawPointerAxes.toolMajor.valid) {
mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
} else {
mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
@@ -3011,7 +3084,7 @@
// Orientation
switch (mCalibration.orientationCalibration) {
case Calibration::ORIENTATION_CALIBRATION_DEFAULT:
- if (mRawAxes.orientation.valid) {
+ if (mRawPointerAxes.orientation.valid) {
mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
} else {
mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
@@ -3025,7 +3098,7 @@
// Distance
switch (mCalibration.distanceCalibration) {
case Calibration::DISTANCE_CALIBRATION_DEFAULT:
- if (mRawAxes.distance.valid) {
+ if (mRawPointerAxes.distance.valid) {
mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
} else {
mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
@@ -3177,50 +3250,58 @@
}
void TouchInputMapper::reset() {
- // Synthesize touch up event if touch is currently down.
+ // Synthesize touch up event.
// This will also take care of finishing virtual key processing if needed.
- if (mLastTouch.pointerCount != 0) {
- nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- mCurrentTouch.clear();
- syncTouch(when, true);
+ nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+ mCurrentRawPointerData.clear();
+ mCurrentButtonState = 0;
+ syncTouch(when, true);
+
+ initialize();
+
+ if (mPointerController != NULL
+ && mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
+ mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ mPointerController->clearSpots();
}
- { // acquire lock
- AutoMutex _l(mLock);
- initializeLocked();
-
- if (mPointerController != NULL
- && mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- mPointerController->clearSpots();
- }
- } // release lock
-
InputMapper::reset();
}
void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
#if DEBUG_RAW_EVENTS
if (!havePointerIds) {
- LOGD("syncTouch: pointerCount=%d, no pointer ids", mCurrentTouch.pointerCount);
+ LOGD("syncTouch: pointerCount %d -> %d, no pointer ids",
+ mLastRawPointerData.pointerCount,
+ mCurrentRawPointerData.pointerCount);
} else {
- LOGD("syncTouch: pointerCount=%d, up=0x%08x, down=0x%08x, move=0x%08x, "
- "last=0x%08x, current=0x%08x", mCurrentTouch.pointerCount,
- mLastTouch.idBits.value & ~mCurrentTouch.idBits.value,
- mCurrentTouch.idBits.value & ~mLastTouch.idBits.value,
- mLastTouch.idBits.value & mCurrentTouch.idBits.value,
- mLastTouch.idBits.value, mCurrentTouch.idBits.value);
+ LOGD("syncTouch: pointerCount %d -> %d, touching ids 0x%08x -> 0x%08x, "
+ "hovering ids 0x%08x -> 0x%08x",
+ mLastRawPointerData.pointerCount,
+ mCurrentRawPointerData.pointerCount,
+ mLastRawPointerData.touchingIdBits.value,
+ mCurrentRawPointerData.touchingIdBits.value,
+ mLastRawPointerData.hoveringIdBits.value,
+ mCurrentRawPointerData.hoveringIdBits.value);
}
#endif
- // Preprocess pointer data.
- if (!havePointerIds) {
- calculatePointerIds();
+ // Configure the surface now, if possible.
+ if (!configureSurface()) {
+ mLastRawPointerData.clear();
+ mLastCookedPointerData.clear();
+ mLastButtonState = 0;
+ return;
}
- // Handle initial down events.
+ // Preprocess pointer data.
+ if (!havePointerIds) {
+ assignPointerIds();
+ }
+
+ // Handle policy on initial down or hover events.
uint32_t policyFlags = 0;
- if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) {
+ if (mLastRawPointerData.pointerCount == 0 && mCurrentRawPointerData.pointerCount != 0) {
if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) {
// If this is a touch screen, hide the pointer on an initial down.
getContext()->fadePointer();
@@ -3235,40 +3316,31 @@
}
}
- // Synthesize key down from buttons if needed.
+ // Synthesize key down from raw buttons if needed.
synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mTouchSource,
- policyFlags, mLastTouch.buttonState, mCurrentTouch.buttonState);
+ policyFlags, mLastButtonState, mCurrentButtonState);
- // Send motion events.
- TouchResult touchResult;
- if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount == 0
- && mLastTouch.buttonState == mCurrentTouch.buttonState) {
- // Drop spurious syncs.
- touchResult = DROP_STROKE;
- } else {
- // Process touches and virtual keys.
- touchResult = consumeOffScreenTouches(when, policyFlags);
- if (touchResult == DISPATCH_TOUCH) {
- suppressSwipeOntoVirtualKeys(when);
- if (mPointerController != NULL && mConfig.pointerGesturesEnabled) {
- dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
- }
- dispatchTouches(when, policyFlags);
- }
+ if (consumeRawTouches(when, policyFlags)) {
+ mCurrentRawPointerData.clear();
}
- // Synthesize key up from buttons if needed.
+ if (mPointerController != NULL && mConfig.pointerGesturesEnabled) {
+ dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
+ }
+
+ cookPointerData();
+ dispatchHoverExit(when, policyFlags);
+ dispatchTouches(when, policyFlags);
+ dispatchHoverEnterAndMove(when, policyFlags);
+
+ // Synthesize key up from raw buttons if needed.
synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mTouchSource,
- policyFlags, mLastTouch.buttonState, mCurrentTouch.buttonState);
+ policyFlags, mLastButtonState, mCurrentButtonState);
// Copy current touch to last touch in preparation for the next cycle.
- // Keep the button state so we can track edge-triggered button state changes.
- if (touchResult == DROP_STROKE) {
- mLastTouch.clear();
- mLastTouch.buttonState = mCurrentTouch.buttonState;
- } else {
- mLastTouch.copyFrom(mCurrentTouch);
- }
+ mLastRawPointerData.copyFrom(mCurrentRawPointerData);
+ mLastCookedPointerData.copyFrom(mCurrentCookedPointerData);
+ mLastButtonState = mCurrentButtonState;
}
void TouchInputMapper::timeoutExpired(nsecs_t when) {
@@ -3277,125 +3349,88 @@
}
}
-TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
- nsecs_t when, uint32_t policyFlags) {
- int32_t keyEventAction, keyEventFlags;
- int32_t keyCode, scanCode, downTime;
- TouchResult touchResult;
-
- { // acquire lock
- AutoMutex _l(mLock);
-
- // Update surface size and orientation, including virtual key positions.
- if (! configureSurfaceLocked()) {
- return DROP_STROKE;
- }
-
- // Check for virtual key press.
- if (mLocked.currentVirtualKey.down) {
- if (mCurrentTouch.pointerCount == 0) {
- // Pointer went up while virtual key was down.
- mLocked.currentVirtualKey.down = false;
+bool TouchInputMapper::consumeRawTouches(nsecs_t when, uint32_t policyFlags) {
+ // Check for release of a virtual key.
+ if (mCurrentVirtualKey.down) {
+ if (mCurrentRawPointerData.touchingIdBits.isEmpty()) {
+ // Pointer went up while virtual key was down.
+ mCurrentVirtualKey.down = false;
+ if (!mCurrentVirtualKey.ignored) {
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
- mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode);
+ mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
#endif
- keyEventAction = AKEY_EVENT_ACTION_UP;
- keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
- touchResult = SKIP_TOUCH;
- goto DispatchVirtualKey;
+ dispatchVirtualKey(when, policyFlags,
+ AKEY_EVENT_ACTION_UP,
+ AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
}
-
- if (mCurrentTouch.pointerCount == 1) {
- int32_t x = mCurrentTouch.pointers[0].x;
- int32_t y = mCurrentTouch.pointers[0].y;
- const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
- if (virtualKey && virtualKey->keyCode == mLocked.currentVirtualKey.keyCode) {
- // Pointer is still within the space of the virtual key.
- return SKIP_TOUCH;
- }
- }
-
- // Pointer left virtual key area or another pointer also went down.
- // Send key cancellation and drop the stroke so subsequent motions will be
- // considered fresh downs. This is useful when the user swipes away from the
- // virtual key area into the main display surface.
- mLocked.currentVirtualKey.down = false;
-#if DEBUG_VIRTUAL_KEYS
- LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
- mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode);
-#endif
- keyEventAction = AKEY_EVENT_ACTION_UP;
- keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
- | AKEY_EVENT_FLAG_CANCELED;
-
- // Check whether the pointer moved inside the display area where we should
- // start a new stroke.
- int32_t x = mCurrentTouch.pointers[0].x;
- int32_t y = mCurrentTouch.pointers[0].y;
- if (isPointInsideSurfaceLocked(x, y)) {
- mLastTouch.clear();
- touchResult = DISPATCH_TOUCH;
- } else {
- touchResult = DROP_STROKE;
- }
- } else {
- if (mCurrentTouch.pointerCount >= 1 && mLastTouch.pointerCount == 0) {
- // Pointer just went down. Handle off-screen touches, if needed.
- int32_t x = mCurrentTouch.pointers[0].x;
- int32_t y = mCurrentTouch.pointers[0].y;
- if (! isPointInsideSurfaceLocked(x, y)) {
- // If exactly one pointer went down, check for virtual key hit.
- // Otherwise we will drop the entire stroke.
- if (mCurrentTouch.pointerCount == 1) {
- const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
- if (virtualKey) {
- if (mContext->shouldDropVirtualKey(when, getDevice(),
- virtualKey->keyCode, virtualKey->scanCode)) {
- return DROP_STROKE;
- }
-
- mLocked.currentVirtualKey.down = true;
- mLocked.currentVirtualKey.downTime = when;
- mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
- mLocked.currentVirtualKey.scanCode = virtualKey->scanCode;
-#if DEBUG_VIRTUAL_KEYS
- LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
- mLocked.currentVirtualKey.keyCode,
- mLocked.currentVirtualKey.scanCode);
-#endif
- keyEventAction = AKEY_EVENT_ACTION_DOWN;
- keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM
- | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
- touchResult = SKIP_TOUCH;
- goto DispatchVirtualKey;
- }
- }
- return DROP_STROKE;
- }
- }
- return DISPATCH_TOUCH;
+ return true;
}
- DispatchVirtualKey:
- // Collect remaining state needed to dispatch virtual key.
- keyCode = mLocked.currentVirtualKey.keyCode;
- scanCode = mLocked.currentVirtualKey.scanCode;
- downTime = mLocked.currentVirtualKey.downTime;
- } // release lock
+ if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
+ uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
+ const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
+ const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
+ if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
+ // Pointer is still within the space of the virtual key.
+ return true;
+ }
+ }
- // Dispatch virtual key.
- int32_t metaState = mContext->getGlobalMetaState();
- policyFlags |= POLICY_FLAG_VIRTUAL;
- getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
- keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
- return touchResult;
-}
+ // Pointer left virtual key area or another pointer also went down.
+ // Send key cancellation but do not consume the touch yet.
+ // This is useful when the user swipes through from the virtual key area
+ // into the main display surface.
+ mCurrentVirtualKey.down = false;
+ if (!mCurrentVirtualKey.ignored) {
+#if DEBUG_VIRTUAL_KEYS
+ LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
+ mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
+#endif
+ dispatchVirtualKey(when, policyFlags,
+ AKEY_EVENT_ACTION_UP,
+ AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
+ | AKEY_EVENT_FLAG_CANCELED);
+ }
+ }
-void TouchInputMapper::suppressSwipeOntoVirtualKeys(nsecs_t when) {
+ if (mLastRawPointerData.touchingIdBits.isEmpty()
+ && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
+ // Pointer just went down. Check for virtual key press or off-screen touches.
+ uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
+ const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
+ if (!isPointInsideSurface(pointer.x, pointer.y)) {
+ // If exactly one pointer went down, check for virtual key hit.
+ // Otherwise we will drop the entire stroke.
+ if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
+ const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
+ if (virtualKey) {
+ mCurrentVirtualKey.down = true;
+ mCurrentVirtualKey.downTime = when;
+ mCurrentVirtualKey.keyCode = virtualKey->keyCode;
+ mCurrentVirtualKey.scanCode = virtualKey->scanCode;
+ mCurrentVirtualKey.ignored = mContext->shouldDropVirtualKey(
+ when, getDevice(), virtualKey->keyCode, virtualKey->scanCode);
+
+ if (!mCurrentVirtualKey.ignored) {
+#if DEBUG_VIRTUAL_KEYS
+ LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
+ mCurrentVirtualKey.keyCode,
+ mCurrentVirtualKey.scanCode);
+#endif
+ dispatchVirtualKey(when, policyFlags,
+ AKEY_EVENT_ACTION_DOWN,
+ AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
+ }
+ }
+ }
+ return true;
+ }
+ }
+
// Disable all virtual key touches that happen within a short time interval of the
- // most recent touch. The idea is to filter out stray virtual key presses when
- // interacting with the touch screen.
+ // most recent touch within the screen area. The idea is to filter out stray
+ // virtual key presses when interacting with the touch screen.
//
// Problems we're trying to solve:
//
@@ -3407,37 +3442,44 @@
// area and accidentally triggers a virtual key. This often happens when virtual keys
// are layed out below the screen near to where the on screen keyboard's space bar
// is displayed.
- if (mConfig.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) {
+ if (mConfig.virtualKeyQuietTime > 0 && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
}
+ return false;
+}
+
+void TouchInputMapper::dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
+ int32_t keyEventAction, int32_t keyEventFlags) {
+ int32_t keyCode = mCurrentVirtualKey.keyCode;
+ int32_t scanCode = mCurrentVirtualKey.scanCode;
+ nsecs_t downTime = mCurrentVirtualKey.downTime;
+ int32_t metaState = mContext->getGlobalMetaState();
+ policyFlags |= POLICY_FLAG_VIRTUAL;
+
+ NotifyKeyArgs args(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
+ keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
+ getListener()->notifyKey(&args);
}
void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
- uint32_t currentPointerCount = mCurrentTouch.pointerCount;
- uint32_t lastPointerCount = mLastTouch.pointerCount;
- if (currentPointerCount == 0 && lastPointerCount == 0) {
- return; // nothing to do!
- }
-
- // Update current touch coordinates.
- float xPrecision, yPrecision;
- prepareTouches(&xPrecision, &yPrecision);
-
- // Dispatch motions.
- BitSet32 currentIdBits = mCurrentTouch.idBits;
- BitSet32 lastIdBits = mLastTouch.idBits;
+ BitSet32 currentIdBits = mCurrentCookedPointerData.touchingIdBits;
+ BitSet32 lastIdBits = mLastCookedPointerData.touchingIdBits;
int32_t metaState = getContext()->getGlobalMetaState();
- int32_t buttonState = mCurrentTouch.buttonState;
+ int32_t buttonState = mCurrentButtonState;
if (currentIdBits == lastIdBits) {
- // No pointer id changes so this is a move event.
- // The dispatcher takes care of batching moves so we don't have to deal with that here.
- dispatchMotion(when, policyFlags, mTouchSource,
- AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState,
- AMOTION_EVENT_EDGE_FLAG_NONE,
- mCurrentTouchProperties, mCurrentTouchCoords,
- mCurrentTouch.idToIndex, currentIdBits, -1,
- xPrecision, yPrecision, mDownTime);
+ if (!currentIdBits.isEmpty()) {
+ // No pointer id changes so this is a move event.
+ // The listener takes care of batching moves so we don't have to deal with that here.
+ dispatchMotion(when, policyFlags, mTouchSource,
+ AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ currentIdBits, -1,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+ }
} else {
// There may be pointers going up and pointers going down and pointers moving
// all at the same time.
@@ -3449,23 +3491,28 @@
// Update last coordinates of pointers that have moved so that we observe the new
// pointer positions at the same time as other pointers that have just gone up.
bool moveNeeded = updateMovedPointers(
- mCurrentTouchProperties, mCurrentTouchCoords, mCurrentTouch.idToIndex,
- mLastTouchProperties, mLastTouchCoords, mLastTouch.idToIndex,
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ mLastCookedPointerData.pointerProperties,
+ mLastCookedPointerData.pointerCoords,
+ mLastCookedPointerData.idToIndex,
moveIdBits);
- if (buttonState != mLastTouch.buttonState) {
+ if (buttonState != mLastButtonState) {
moveNeeded = true;
}
// Dispatch pointer up events.
while (!upIdBits.isEmpty()) {
- uint32_t upId = upIdBits.firstMarkedBit();
- upIdBits.clearBit(upId);
+ uint32_t upId = upIdBits.clearFirstMarkedBit();
dispatchMotion(when, policyFlags, mTouchSource,
AMOTION_EVENT_ACTION_POINTER_UP, 0, metaState, buttonState, 0,
- mLastTouchProperties, mLastTouchCoords,
- mLastTouch.idToIndex, dispatchedIdBits, upId,
- xPrecision, yPrecision, mDownTime);
+ mLastCookedPointerData.pointerProperties,
+ mLastCookedPointerData.pointerCoords,
+ mLastCookedPointerData.idToIndex,
+ dispatchedIdBits, upId,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
dispatchedIdBits.clearBit(upId);
}
@@ -3476,15 +3523,16 @@
LOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
dispatchMotion(when, policyFlags, mTouchSource,
AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 0,
- mCurrentTouchProperties, mCurrentTouchCoords,
- mCurrentTouch.idToIndex, dispatchedIdBits, -1,
- xPrecision, yPrecision, mDownTime);
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ dispatchedIdBits, -1,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
}
// Dispatch pointer down events using the new pointer locations.
while (!downIdBits.isEmpty()) {
- uint32_t downId = downIdBits.firstMarkedBit();
- downIdBits.clearBit(downId);
+ uint32_t downId = downIdBits.clearFirstMarkedBit();
dispatchedIdBits.markBit(downId);
if (dispatchedIdBits.count() == 1) {
@@ -3494,49 +3542,88 @@
dispatchMotion(when, policyFlags, mTouchSource,
AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
- mCurrentTouchProperties, mCurrentTouchCoords,
- mCurrentTouch.idToIndex, dispatchedIdBits, downId,
- xPrecision, yPrecision, mDownTime);
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ dispatchedIdBits, downId,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
}
}
-
- // Update state for next time.
- for (uint32_t i = 0; i < currentPointerCount; i++) {
- mLastTouchProperties[i].copyFrom(mCurrentTouchProperties[i]);
- mLastTouchCoords[i].copyFrom(mCurrentTouchCoords[i]);
- }
}
-void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision) {
- uint32_t currentPointerCount = mCurrentTouch.pointerCount;
- uint32_t lastPointerCount = mLastTouch.pointerCount;
+void TouchInputMapper::dispatchHoverExit(nsecs_t when, uint32_t policyFlags) {
+ if (mSentHoverEnter &&
+ (mCurrentCookedPointerData.hoveringIdBits.isEmpty()
+ || !mCurrentCookedPointerData.touchingIdBits.isEmpty())) {
+ int32_t metaState = getContext()->getGlobalMetaState();
+ dispatchMotion(when, policyFlags, mTouchSource,
+ AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
+ mLastCookedPointerData.pointerProperties,
+ mLastCookedPointerData.pointerCoords,
+ mLastCookedPointerData.idToIndex,
+ mLastCookedPointerData.hoveringIdBits, -1,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+ mSentHoverEnter = false;
+ }
+}
- AutoMutex _l(mLock);
+void TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags) {
+ if (mCurrentCookedPointerData.touchingIdBits.isEmpty()
+ && !mCurrentCookedPointerData.hoveringIdBits.isEmpty()) {
+ int32_t metaState = getContext()->getGlobalMetaState();
+ if (!mSentHoverEnter) {
+ dispatchMotion(when, policyFlags, mTouchSource,
+ AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ mCurrentCookedPointerData.hoveringIdBits, -1,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+ mSentHoverEnter = true;
+ }
- // Walk through the the active pointers and map touch screen coordinates (TouchData) into
- // display or surface coordinates (PointerCoords) and adjust for display orientation.
+ dispatchMotion(when, policyFlags, mTouchSource,
+ AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ mCurrentCookedPointerData.hoveringIdBits, -1,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+ }
+}
+
+void TouchInputMapper::cookPointerData() {
+ uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
+
+ mCurrentCookedPointerData.clear();
+ mCurrentCookedPointerData.pointerCount = currentPointerCount;
+ mCurrentCookedPointerData.hoveringIdBits = mCurrentRawPointerData.hoveringIdBits;
+ mCurrentCookedPointerData.touchingIdBits = mCurrentRawPointerData.touchingIdBits;
+
+ // Walk through the the active pointers and map device coordinates onto
+ // surface coordinates and adjust for display orientation.
for (uint32_t i = 0; i < currentPointerCount; i++) {
- const PointerData& in = mCurrentTouch.pointers[i];
+ const RawPointerData::Pointer& in = mCurrentRawPointerData.pointers[i];
// ToolMajor and ToolMinor
float toolMajor, toolMinor;
switch (mCalibration.toolSizeCalibration) {
case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC:
- toolMajor = in.toolMajor * mLocked.geometricScale;
- if (mRawAxes.toolMinor.valid) {
- toolMinor = in.toolMinor * mLocked.geometricScale;
+ toolMajor = in.toolMajor * mGeometricScale;
+ if (mRawPointerAxes.toolMinor.valid) {
+ toolMinor = in.toolMinor * mGeometricScale;
} else {
toolMinor = toolMajor;
}
break;
case Calibration::TOOL_SIZE_CALIBRATION_LINEAR:
toolMajor = in.toolMajor != 0
- ? in.toolMajor * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias
+ ? in.toolMajor * mToolSizeLinearScale + mToolSizeLinearBias
: 0;
- if (mRawAxes.toolMinor.valid) {
+ if (mRawPointerAxes.toolMinor.valid) {
toolMinor = in.toolMinor != 0
- ? in.toolMinor * mLocked.toolSizeLinearScale
- + mLocked.toolSizeLinearBias
+ ? in.toolMinor * mToolSizeLinearScale
+ + mToolSizeLinearBias
: 0;
} else {
toolMinor = toolMajor;
@@ -3545,8 +3632,8 @@
case Calibration::TOOL_SIZE_CALIBRATION_AREA:
if (in.toolMajor != 0) {
float diameter = sqrtf(in.toolMajor
- * mLocked.toolSizeAreaScale + mLocked.toolSizeAreaBias);
- toolMajor = diameter * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias;
+ * mToolSizeAreaScale + mToolSizeAreaBias);
+ toolMajor = diameter * mToolSizeLinearScale + mToolSizeLinearBias;
} else {
toolMajor = 0;
}
@@ -3559,8 +3646,9 @@
}
if (mCalibration.haveToolSizeIsSummed && mCalibration.toolSizeIsSummed) {
- toolMajor /= currentPointerCount;
- toolMinor /= currentPointerCount;
+ uint32_t touchingCount = mCurrentRawPointerData.touchingIdBits.count();
+ toolMajor /= touchingCount;
+ toolMinor /= touchingCount;
}
// Pressure
@@ -3580,10 +3668,10 @@
switch (mCalibration.pressureCalibration) {
case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
- pressure = rawPressure * mLocked.pressureScale;
+ pressure = rawPressure * mPressureScale;
break;
default:
- pressure = 1;
+ pressure = in.isHovering ? 0 : 1;
break;
}
@@ -3591,9 +3679,9 @@
float touchMajor, touchMinor;
switch (mCalibration.touchSizeCalibration) {
case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC:
- touchMajor = in.touchMajor * mLocked.geometricScale;
- if (mRawAxes.touchMinor.valid) {
- touchMinor = in.touchMinor * mLocked.geometricScale;
+ touchMajor = in.touchMajor * mGeometricScale;
+ if (mRawPointerAxes.touchMinor.valid) {
+ touchMinor = in.touchMinor * mGeometricScale;
} else {
touchMinor = touchMajor;
}
@@ -3619,10 +3707,10 @@
float size;
switch (mCalibration.sizeCalibration) {
case Calibration::SIZE_CALIBRATION_NORMALIZED: {
- float rawSize = mRawAxes.toolMinor.valid
+ float rawSize = mRawPointerAxes.toolMinor.valid
? avg(in.toolMajor, in.toolMinor)
: in.toolMajor;
- size = rawSize * mLocked.sizeScale;
+ size = rawSize * mSizeScale;
break;
}
default:
@@ -3634,7 +3722,7 @@
float orientation;
switch (mCalibration.orientationCalibration) {
case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
- orientation = in.orientation * mLocked.orientationScale;
+ orientation = in.orientation * mOrientationScale;
break;
case Calibration::ORIENTATION_CALIBRATION_VECTOR: {
int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
@@ -3659,7 +3747,7 @@
float distance;
switch (mCalibration.distanceCalibration) {
case Calibration::DISTANCE_CALIBRATION_SCALED:
- distance = in.distance * mLocked.distanceScale;
+ distance = in.distance * mDistanceScale;
break;
default:
distance = 0;
@@ -3668,35 +3756,35 @@
// X and Y
// Adjust coords for surface orientation.
float x, y;
- switch (mLocked.surfaceOrientation) {
+ switch (mSurfaceOrientation) {
case DISPLAY_ORIENTATION_90:
- x = float(in.y - mRawAxes.y.minValue) * mLocked.yScale;
- y = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale;
+ x = float(in.y - mRawPointerAxes.y.minValue) * mYScale;
+ y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale;
orientation -= M_PI_2;
if (orientation < - M_PI_2) {
orientation += M_PI;
}
break;
case DISPLAY_ORIENTATION_180:
- x = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale;
- y = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale;
+ x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale;
+ y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale;
break;
case DISPLAY_ORIENTATION_270:
- x = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale;
- y = float(in.x - mRawAxes.x.minValue) * mLocked.xScale;
+ x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale;
+ y = float(in.x - mRawPointerAxes.x.minValue) * mXScale;
orientation += M_PI_2;
if (orientation > M_PI_2) {
orientation -= M_PI;
}
break;
default:
- x = float(in.x - mRawAxes.x.minValue) * mLocked.xScale;
- y = float(in.y - mRawAxes.y.minValue) * mLocked.yScale;
+ x = float(in.x - mRawPointerAxes.x.minValue) * mXScale;
+ y = float(in.y - mRawPointerAxes.y.minValue) * mYScale;
break;
}
// Write output coords.
- PointerCoords& out = mCurrentTouchCoords[i];
+ PointerCoords& out = mCurrentCookedPointerData.pointerCoords[i];
out.clear();
out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
@@ -3707,19 +3795,18 @@
out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
- if (distance != 0) {
- out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
- }
+ out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
// Write output properties.
- PointerProperties& properties = mCurrentTouchProperties[i];
+ PointerProperties& properties = mCurrentCookedPointerData.pointerProperties[i];
+ uint32_t id = in.id;
properties.clear();
- properties.id = mCurrentTouch.pointers[i].id;
- properties.toolType = mCurrentTouch.pointers[i].toolType;
- }
+ properties.id = id;
+ properties.toolType = in.toolType;
- *outXPrecision = mLocked.orientedXPrecision;
- *outYPrecision = mLocked.orientedYPrecision;
+ // Write id index.
+ mCurrentCookedPointerData.idToIndex[id] = i;
+ }
}
void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags,
@@ -3782,7 +3869,7 @@
// Send events!
int32_t metaState = getContext()->getGlobalMetaState();
- int32_t buttonState = mCurrentTouch.buttonState;
+ int32_t buttonState = mCurrentButtonState;
// Update last coordinates of pointers that have moved so that we observe the new
// pointer positions at the same time as other pointers that have just gone up.
@@ -3803,7 +3890,7 @@
mPointerGesture.lastGestureProperties,
mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
movedGestureIdBits);
- if (buttonState != mLastTouch.buttonState) {
+ if (buttonState != mLastButtonState) {
moveNeeded = true;
}
}
@@ -3830,8 +3917,7 @@
& ~mPointerGesture.currentGestureIdBits.value;
}
while (!upGestureIdBits.isEmpty()) {
- uint32_t id = upGestureIdBits.firstMarkedBit();
- upGestureIdBits.clearBit(id);
+ uint32_t id = upGestureIdBits.clearFirstMarkedBit();
dispatchMotion(when, policyFlags, mPointerSource,
AMOTION_EVENT_ACTION_POINTER_UP, 0,
@@ -3861,8 +3947,7 @@
BitSet32 downGestureIdBits(mPointerGesture.currentGestureIdBits.value
& ~dispatchedGestureIdBits.value);
while (!downGestureIdBits.isEmpty()) {
- uint32_t id = downGestureIdBits.firstMarkedBit();
- downGestureIdBits.clearBit(id);
+ uint32_t id = downGestureIdBits.clearFirstMarkedBit();
dispatchedGestureIdBits.markBit(id);
if (dispatchedGestureIdBits.count() == 1) {
@@ -3906,10 +3991,11 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- getDispatcher()->notifyMotion(when, getDeviceId(), mPointerSource, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), mPointerSource, policyFlags,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
1, &pointerProperties, &pointerCoords, 0, 0, mPointerGesture.downTime);
+ getListener()->notifyMotion(&args);
}
// Update state.
@@ -3919,8 +4005,7 @@
} else {
mPointerGesture.lastGestureIdBits = mPointerGesture.currentGestureIdBits;
for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
+ uint32_t id = idBits.clearFirstMarkedBit();
uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
mPointerGesture.lastGestureProperties[index].copyFrom(
mPointerGesture.currentGestureProperties[index]);
@@ -3936,8 +4021,6 @@
*outCancelPreviousGesture = false;
*outFinishPreviousGesture = false;
- AutoMutex _l(mLock);
-
// Handle TAP timeout.
if (isTimeout) {
#if DEBUG_GESTURES
@@ -3973,16 +4056,14 @@
{
VelocityTracker::Position positions[MAX_POINTERS];
uint32_t count = 0;
- for (BitSet32 idBits(mCurrentTouch.idBits); !idBits.isEmpty(); count++) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
- uint32_t index = mCurrentTouch.idToIndex[id];
- positions[count].x = mCurrentTouch.pointers[index].x
- * mLocked.pointerGestureXMovementScale;
- positions[count].y = mCurrentTouch.pointers[index].y
- * mLocked.pointerGestureYMovementScale;
+ for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits); !idBits.isEmpty(); count++) {
+ uint32_t id = idBits.clearFirstMarkedBit();
+ const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
+ positions[count].x = pointer.x * mPointerGestureXMovementScale;
+ positions[count].y = pointer.y * mPointerGestureYMovementScale;
}
- mPointerGesture.velocityTracker.addMovement(when, mCurrentTouch.idBits, positions);
+ mPointerGesture.velocityTracker.addMovement(when,
+ mCurrentRawPointerData.touchingIdBits, positions);
}
// Pick a new active touch id if needed.
@@ -3994,20 +4075,25 @@
int32_t lastActiveTouchId = mPointerGesture.activeTouchId;
int32_t activeTouchId = lastActiveTouchId;
if (activeTouchId < 0) {
- if (!mCurrentTouch.idBits.isEmpty()) {
+ if (!mCurrentRawPointerData.touchingIdBits.isEmpty()) {
activeTouchChanged = true;
- activeTouchId = mPointerGesture.activeTouchId = mCurrentTouch.idBits.firstMarkedBit();
+ activeTouchId = mPointerGesture.activeTouchId =
+ mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
mPointerGesture.firstTouchTime = when;
}
- } else if (!mCurrentTouch.idBits.hasBit(activeTouchId)) {
+ } else if (!mCurrentRawPointerData.touchingIdBits.hasBit(activeTouchId)) {
activeTouchChanged = true;
- if (!mCurrentTouch.idBits.isEmpty()) {
- activeTouchId = mPointerGesture.activeTouchId = mCurrentTouch.idBits.firstMarkedBit();
+ if (!mCurrentRawPointerData.touchingIdBits.isEmpty()) {
+ activeTouchId = mPointerGesture.activeTouchId =
+ mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
} else {
activeTouchId = mPointerGesture.activeTouchId = -1;
}
}
+ uint32_t currentTouchingPointerCount = mCurrentRawPointerData.touchingIdBits.count();
+ uint32_t lastTouchingPointerCount = mLastRawPointerData.touchingIdBits.count();
+
// Determine whether we are in quiet time.
bool isQuietTime = false;
if (activeTouchId < 0) {
@@ -4018,14 +4104,14 @@
if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS
|| mPointerGesture.lastGestureMode == PointerGesture::SWIPE
|| mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)
- && mCurrentTouch.pointerCount < 2) {
+ && currentTouchingPointerCount < 2) {
// Enter quiet time when exiting swipe or freeform state.
// This is to prevent accidentally entering the hover state and flinging the
// pointer when finishing a swipe and there is still one pointer left onscreen.
isQuietTime = true;
} else if (mPointerGesture.lastGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
- && mCurrentTouch.pointerCount >= 2
- && !isPointerDown(mCurrentTouch.buttonState)) {
+ && currentTouchingPointerCount >= 2
+ && !isPointerDown(mCurrentButtonState)) {
// Enter quiet time when releasing the button and there are still two or more
// fingers down. This may indicate that one finger was used to press the button
// but it has not gone up yet.
@@ -4053,7 +4139,7 @@
mPointerGesture.currentGestureIdBits.clear();
mPointerGesture.pointerVelocityControl.reset();
- } else if (isPointerDown(mCurrentTouch.buttonState)) {
+ } else if (isPointerDown(mCurrentButtonState)) {
// Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG)
// The pointer follows the active touch point.
// Emit DOWN, MOVE, UP events at the pointer location.
@@ -4069,7 +4155,7 @@
// being dragged.
#if DEBUG_GESTURES
LOGD("Gestures: BUTTON_CLICK_OR_DRAG activeTouchId=%d, "
- "currentTouchPointerCount=%d", activeTouchId, mCurrentTouch.pointerCount);
+ "currentTouchingPointerCount=%d", activeTouchId, currentTouchingPointerCount);
#endif
// Reset state when just starting.
if (mPointerGesture.lastGestureMode != PointerGesture::BUTTON_CLICK_OR_DRAG) {
@@ -4079,11 +4165,11 @@
// Switch pointers if needed.
// Find the fastest pointer and follow it.
- if (activeTouchId >= 0 && mCurrentTouch.pointerCount > 1) {
+ if (activeTouchId >= 0 && currentTouchingPointerCount > 1) {
int32_t bestId = -1;
float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed;
- for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) {
- uint32_t id = mCurrentTouch.pointers[i].id;
+ for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits); !idBits.isEmpty(); ) {
+ uint32_t id = idBits.clearFirstMarkedBit();
float vx, vy;
if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) {
float speed = hypotf(vx, vy);
@@ -4103,17 +4189,15 @@
}
}
- if (activeTouchId >= 0 && mLastTouch.idBits.hasBit(activeTouchId)) {
- const PointerData& currentPointer =
- mCurrentTouch.pointers[mCurrentTouch.idToIndex[activeTouchId]];
- const PointerData& lastPointer =
- mLastTouch.pointers[mLastTouch.idToIndex[activeTouchId]];
- float deltaX = (currentPointer.x - lastPointer.x)
- * mLocked.pointerGestureXMovementScale;
- float deltaY = (currentPointer.y - lastPointer.y)
- * mLocked.pointerGestureYMovementScale;
+ if (activeTouchId >= 0 && mLastRawPointerData.touchingIdBits.hasBit(activeTouchId)) {
+ const RawPointerData::Pointer& currentPointer =
+ mCurrentRawPointerData.pointerForId(activeTouchId);
+ const RawPointerData::Pointer& lastPointer =
+ mLastRawPointerData.pointerForId(activeTouchId);
+ float deltaX = (currentPointer.x - lastPointer.x) * mPointerGestureXMovementScale;
+ float deltaY = (currentPointer.y - lastPointer.y) * mPointerGestureYMovementScale;
- rotateDelta(mLocked.surfaceOrientation, &deltaX, &deltaY);
+ rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
mPointerGesture.pointerVelocityControl.move(when, &deltaX, &deltaY);
// Move the pointer using a relative motion.
@@ -4138,7 +4222,7 @@
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
- } else if (mCurrentTouch.pointerCount == 0) {
+ } else if (currentTouchingPointerCount == 0) {
// Case 3. No fingers down and button is not pressed. (NEUTRAL)
if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) {
*outFinishPreviousGesture = true;
@@ -4149,7 +4233,7 @@
bool tapped = false;
if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER
|| mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG)
- && mLastTouch.pointerCount == 1) {
+ && lastTouchingPointerCount == 1) {
if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) {
float x, y;
mPointerController->getPosition(&x, &y);
@@ -4209,7 +4293,7 @@
mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
mPointerGesture.currentGestureIdBits.clear();
}
- } else if (mCurrentTouch.pointerCount == 1) {
+ } else if (currentTouchingPointerCount == 1) {
// Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG)
// The pointer follows the active touch point.
// When in HOVER, emit HOVER_MOVE events at the pointer location.
@@ -4241,17 +4325,17 @@
mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
}
- if (mLastTouch.idBits.hasBit(activeTouchId)) {
- const PointerData& currentPointer =
- mCurrentTouch.pointers[mCurrentTouch.idToIndex[activeTouchId]];
- const PointerData& lastPointer =
- mLastTouch.pointers[mLastTouch.idToIndex[activeTouchId]];
+ if (mLastRawPointerData.touchingIdBits.hasBit(activeTouchId)) {
+ const RawPointerData::Pointer& currentPointer =
+ mCurrentRawPointerData.pointerForId(activeTouchId);
+ const RawPointerData::Pointer& lastPointer =
+ mLastRawPointerData.pointerForId(activeTouchId);
float deltaX = (currentPointer.x - lastPointer.x)
- * mLocked.pointerGestureXMovementScale;
+ * mPointerGestureXMovementScale;
float deltaY = (currentPointer.y - lastPointer.y)
- * mLocked.pointerGestureYMovementScale;
+ * mPointerGestureYMovementScale;
- rotateDelta(mLocked.surfaceOrientation, &deltaX, &deltaY);
+ rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
mPointerGesture.pointerVelocityControl.move(when, &deltaX, &deltaY);
// Move the pointer using a relative motion.
@@ -4294,7 +4378,7 @@
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
down ? 1.0f : 0.0f);
- if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) {
+ if (lastTouchingPointerCount == 0 && currentTouchingPointerCount != 0) {
mPointerGesture.resetTap();
mPointerGesture.tapDownTime = when;
mPointerGesture.tapX = x;
@@ -4322,7 +4406,7 @@
&& mPointerGesture.lastGestureMode != PointerGesture::SWIPE
&& mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
*outFinishPreviousGesture = true;
- } else if (!settled && mCurrentTouch.pointerCount > mLastTouch.pointerCount) {
+ } else if (!settled && currentTouchingPointerCount > lastTouchingPointerCount) {
// Additional pointers have gone down but not yet settled.
// Reset the gesture.
#if DEBUG_GESTURES
@@ -4350,33 +4434,31 @@
+ mConfig.pointerGestureMultitouchSettleInterval - when)
* 0.000001f);
#endif
- mCurrentTouch.getCentroid(&mPointerGesture.referenceTouchX,
+ mCurrentRawPointerData.getCentroidOfTouchingPointers(
+ &mPointerGesture.referenceTouchX,
&mPointerGesture.referenceTouchY);
mPointerController->getPosition(&mPointerGesture.referenceGestureX,
&mPointerGesture.referenceGestureY);
}
// Clear the reference deltas for fingers not yet included in the reference calculation.
- for (BitSet32 idBits(mCurrentTouch.idBits.value & ~mPointerGesture.referenceIdBits.value);
- !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
+ for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits.value
+ & ~mPointerGesture.referenceIdBits.value); !idBits.isEmpty(); ) {
+ uint32_t id = idBits.clearFirstMarkedBit();
mPointerGesture.referenceDeltas[id].dx = 0;
mPointerGesture.referenceDeltas[id].dy = 0;
}
- mPointerGesture.referenceIdBits = mCurrentTouch.idBits;
+ mPointerGesture.referenceIdBits = mCurrentRawPointerData.touchingIdBits;
// Add delta for all fingers and calculate a common movement delta.
float commonDeltaX = 0, commonDeltaY = 0;
- BitSet32 commonIdBits(mLastTouch.idBits.value & mCurrentTouch.idBits.value);
+ BitSet32 commonIdBits(mLastRawPointerData.touchingIdBits.value
+ & mCurrentRawPointerData.touchingIdBits.value);
for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
bool first = (idBits == commonIdBits);
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
- const PointerData& cpd = mCurrentTouch.pointers[mCurrentTouch.idToIndex[id]];
- const PointerData& lpd = mLastTouch.pointers[mLastTouch.idToIndex[id]];
+ uint32_t id = idBits.clearFirstMarkedBit();
+ const RawPointerData::Pointer& cpd = mCurrentRawPointerData.pointerForId(id);
+ const RawPointerData::Pointer& lpd = mLastRawPointerData.pointerForId(id);
PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
delta.dx += cpd.x - lpd.x;
delta.dy += cpd.y - lpd.y;
@@ -4395,12 +4477,10 @@
float dist[MAX_POINTER_ID + 1];
int32_t distOverThreshold = 0;
for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
+ uint32_t id = idBits.clearFirstMarkedBit();
PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
- dist[id] = hypotf(delta.dx * mLocked.pointerGestureXZoomScale,
- delta.dy * mLocked.pointerGestureYZoomScale);
+ dist[id] = hypotf(delta.dx * mPointerGestureXZoomScale,
+ delta.dy * mPointerGestureYZoomScale);
if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) {
distOverThreshold += 1;
}
@@ -4409,71 +4489,74 @@
// Only transition when at least two pointers have moved further than
// the minimum distance threshold.
if (distOverThreshold >= 2) {
- float d;
- if (mCurrentTouch.pointerCount > 2) {
+ if (currentTouchingPointerCount > 2) {
// There are more than two pointers, switch to FREEFORM.
#if DEBUG_GESTURES
LOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2",
- mCurrentTouch.pointerCount);
-#endif
- *outCancelPreviousGesture = true;
- mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
- } else if (((d = distance(
- mCurrentTouch.pointers[0].x, mCurrentTouch.pointers[0].y,
- mCurrentTouch.pointers[1].x, mCurrentTouch.pointers[1].y))
- > mLocked.pointerGestureMaxSwipeWidth)) {
- // There are two pointers but they are too far apart for a SWIPE,
- // switch to FREEFORM.
-#if DEBUG_GESTURES
- LOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
- d, mLocked.pointerGestureMaxSwipeWidth);
+ currentTouchingPointerCount);
#endif
*outCancelPreviousGesture = true;
mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
} else {
- // There are two pointers. Wait for both pointers to start moving
- // before deciding whether this is a SWIPE or FREEFORM gesture.
- uint32_t id1 = mCurrentTouch.pointers[0].id;
- uint32_t id2 = mCurrentTouch.pointers[1].id;
- float dist1 = dist[id1];
- float dist2 = dist[id2];
- if (dist1 >= mConfig.pointerGestureMultitouchMinDistance
- && dist2 >= mConfig.pointerGestureMultitouchMinDistance) {
- // Calculate the dot product of the displacement vectors.
- // When the vectors are oriented in approximately the same direction,
- // the angle betweeen them is near zero and the cosine of the angle
- // approches 1.0. Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
- PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
- PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
- float dx1 = delta1.dx * mLocked.pointerGestureXZoomScale;
- float dy1 = delta1.dy * mLocked.pointerGestureYZoomScale;
- float dx2 = delta2.dx * mLocked.pointerGestureXZoomScale;
- float dy2 = delta2.dy * mLocked.pointerGestureYZoomScale;
- float dot = dx1 * dx2 + dy1 * dy2;
- float cosine = dot / (dist1 * dist2); // denominator always > 0
- if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) {
- // Pointers are moving in the same direction. Switch to SWIPE.
+ // There are exactly two pointers.
+ BitSet32 idBits(mCurrentRawPointerData.touchingIdBits);
+ uint32_t id1 = idBits.clearFirstMarkedBit();
+ uint32_t id2 = idBits.firstMarkedBit();
+ const RawPointerData::Pointer& p1 = mCurrentRawPointerData.pointerForId(id1);
+ const RawPointerData::Pointer& p2 = mCurrentRawPointerData.pointerForId(id2);
+ float mutualDistance = distance(p1.x, p1.y, p2.x, p2.y);
+ if (mutualDistance > mPointerGestureMaxSwipeWidth) {
+ // There are two pointers but they are too far apart for a SWIPE,
+ // switch to FREEFORM.
#if DEBUG_GESTURES
- LOGD("Gestures: PRESS transitioned to SWIPE, "
- "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
- "cosine %0.3f >= %0.3f",
- dist1, mConfig.pointerGestureMultitouchMinDistance,
- dist2, mConfig.pointerGestureMultitouchMinDistance,
- cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
+ LOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
+ mutualDistance, mPointerGestureMaxSwipeWidth);
#endif
- mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
- } else {
- // Pointers are moving in different directions. Switch to FREEFORM.
+ *outCancelPreviousGesture = true;
+ mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+ } else {
+ // There are two pointers. Wait for both pointers to start moving
+ // before deciding whether this is a SWIPE or FREEFORM gesture.
+ float dist1 = dist[id1];
+ float dist2 = dist[id2];
+ if (dist1 >= mConfig.pointerGestureMultitouchMinDistance
+ && dist2 >= mConfig.pointerGestureMultitouchMinDistance) {
+ // Calculate the dot product of the displacement vectors.
+ // When the vectors are oriented in approximately the same direction,
+ // the angle betweeen them is near zero and the cosine of the angle
+ // approches 1.0. Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
+ PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
+ PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
+ float dx1 = delta1.dx * mPointerGestureXZoomScale;
+ float dy1 = delta1.dy * mPointerGestureYZoomScale;
+ float dx2 = delta2.dx * mPointerGestureXZoomScale;
+ float dy2 = delta2.dy * mPointerGestureYZoomScale;
+ float dot = dx1 * dx2 + dy1 * dy2;
+ float cosine = dot / (dist1 * dist2); // denominator always > 0
+ if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) {
+ // Pointers are moving in the same direction. Switch to SWIPE.
#if DEBUG_GESTURES
- LOGD("Gestures: PRESS transitioned to FREEFORM, "
- "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
- "cosine %0.3f < %0.3f",
- dist1, mConfig.pointerGestureMultitouchMinDistance,
- dist2, mConfig.pointerGestureMultitouchMinDistance,
- cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
+ LOGD("Gestures: PRESS transitioned to SWIPE, "
+ "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
+ "cosine %0.3f >= %0.3f",
+ dist1, mConfig.pointerGestureMultitouchMinDistance,
+ dist2, mConfig.pointerGestureMultitouchMinDistance,
+ cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
#endif
- *outCancelPreviousGesture = true;
- mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+ mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
+ } else {
+ // Pointers are moving in different directions. Switch to FREEFORM.
+#if DEBUG_GESTURES
+ LOGD("Gestures: PRESS transitioned to FREEFORM, "
+ "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
+ "cosine %0.3f < %0.3f",
+ dist1, mConfig.pointerGestureMultitouchMinDistance,
+ dist2, mConfig.pointerGestureMultitouchMinDistance,
+ cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
+#endif
+ *outCancelPreviousGesture = true;
+ mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+ }
}
}
}
@@ -4481,10 +4564,10 @@
} else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
// Switch from SWIPE to FREEFORM if additional pointers go down.
// Cancel previous gesture.
- if (mCurrentTouch.pointerCount > 2) {
+ if (currentTouchingPointerCount > 2) {
#if DEBUG_GESTURES
LOGD("Gestures: SWIPE transitioned to FREEFORM, number of pointers %d > 2",
- mCurrentTouch.pointerCount);
+ currentTouchingPointerCount);
#endif
*outCancelPreviousGesture = true;
mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
@@ -4496,9 +4579,7 @@
if (mPointerGesture.currentGestureMode != PointerGesture::PRESS
&& (commonDeltaX || commonDeltaY)) {
for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
+ uint32_t id = idBits.clearFirstMarkedBit();
PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
delta.dx = 0;
delta.dy = 0;
@@ -4507,10 +4588,10 @@
mPointerGesture.referenceTouchX += commonDeltaX;
mPointerGesture.referenceTouchY += commonDeltaY;
- commonDeltaX *= mLocked.pointerGestureXMovementScale;
- commonDeltaY *= mLocked.pointerGestureYMovementScale;
+ commonDeltaX *= mPointerGestureXMovementScale;
+ commonDeltaY *= mPointerGestureYMovementScale;
- rotateDelta(mLocked.surfaceOrientation, &commonDeltaX, &commonDeltaY);
+ rotateDelta(mSurfaceOrientation, &commonDeltaX, &commonDeltaY);
mPointerGesture.pointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY);
mPointerGesture.referenceGestureX += commonDeltaX;
@@ -4524,7 +4605,7 @@
#if DEBUG_GESTURES
LOGD("Gestures: PRESS or SWIPE activeTouchId=%d,"
"activeGestureId=%d, currentTouchPointerCount=%d",
- activeTouchId, mPointerGesture.activeGestureId, mCurrentTouch.pointerCount);
+ activeTouchId, mPointerGesture.activeGestureId, currentTouchingPointerCount);
#endif
LOG_ASSERT(mPointerGesture.activeGestureId >= 0);
@@ -4546,7 +4627,7 @@
#if DEBUG_GESTURES
LOGD("Gestures: FREEFORM activeTouchId=%d,"
"activeGestureId=%d, currentTouchPointerCount=%d",
- activeTouchId, mPointerGesture.activeGestureId, mCurrentTouch.pointerCount);
+ activeTouchId, mPointerGesture.activeGestureId, currentTouchingPointerCount);
#endif
LOG_ASSERT(mPointerGesture.activeGestureId >= 0);
@@ -4568,15 +4649,16 @@
} else {
// Otherwise, assume we mapped all touches from the previous frame.
// Reuse all mappings that are still applicable.
- mappedTouchIdBits.value = mLastTouch.idBits.value & mCurrentTouch.idBits.value;
+ mappedTouchIdBits.value = mLastRawPointerData.touchingIdBits.value
+ & mCurrentRawPointerData.touchingIdBits.value;
usedGestureIdBits = mPointerGesture.lastGestureIdBits;
// Check whether we need to choose a new active gesture id because the
// current went went up.
- for (BitSet32 upTouchIdBits(mLastTouch.idBits.value & ~mCurrentTouch.idBits.value);
+ for (BitSet32 upTouchIdBits(mLastRawPointerData.touchingIdBits.value
+ & ~mCurrentRawPointerData.touchingIdBits.value);
!upTouchIdBits.isEmpty(); ) {
- uint32_t upTouchId = upTouchIdBits.firstMarkedBit();
- upTouchIdBits.clearBit(upTouchId);
+ uint32_t upTouchId = upTouchIdBits.clearFirstMarkedBit();
uint32_t upGestureId = mPointerGesture.freeformTouchToGestureIdMap[upTouchId];
if (upGestureId == uint32_t(mPointerGesture.activeGestureId)) {
mPointerGesture.activeGestureId = -1;
@@ -4593,12 +4675,12 @@
mPointerGesture.activeGestureId);
#endif
- for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) {
- uint32_t touchId = mCurrentTouch.pointers[i].id;
+ BitSet32 idBits(mCurrentRawPointerData.touchingIdBits);
+ for (uint32_t i = 0; i < currentTouchingPointerCount; i++) {
+ uint32_t touchId = idBits.clearFirstMarkedBit();
uint32_t gestureId;
if (!mappedTouchIdBits.hasBit(touchId)) {
- gestureId = usedGestureIdBits.firstUnmarkedBit();
- usedGestureIdBits.markBit(gestureId);
+ gestureId = usedGestureIdBits.markFirstUnmarkedBit();
mPointerGesture.freeformTouchToGestureIdMap[touchId] = gestureId;
#if DEBUG_GESTURES
LOGD("Gestures: FREEFORM "
@@ -4616,11 +4698,13 @@
mPointerGesture.currentGestureIdBits.markBit(gestureId);
mPointerGesture.currentGestureIdToIndex[gestureId] = i;
- float deltaX = (mCurrentTouch.pointers[i].x - mPointerGesture.referenceTouchX)
- * mLocked.pointerGestureXZoomScale;
- float deltaY = (mCurrentTouch.pointers[i].y - mPointerGesture.referenceTouchY)
- * mLocked.pointerGestureYZoomScale;
- rotateDelta(mLocked.surfaceOrientation, &deltaX, &deltaY);
+ const RawPointerData::Pointer& pointer =
+ mCurrentRawPointerData.pointerForId(touchId);
+ float deltaX = (pointer.x - mPointerGesture.referenceTouchX)
+ * mPointerGestureXZoomScale;
+ float deltaY = (pointer.y - mPointerGesture.referenceTouchY)
+ * mPointerGestureYZoomScale;
+ rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
mPointerGesture.currentGestureProperties[i].clear();
mPointerGesture.currentGestureProperties[i].id = gestureId;
@@ -4646,7 +4730,7 @@
}
}
- mPointerController->setButtonState(mCurrentTouch.buttonState);
+ mPointerController->setButtonState(mCurrentButtonState);
#if DEBUG_GESTURES
LOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, "
@@ -4656,8 +4740,7 @@
mPointerGesture.currentGestureMode, mPointerGesture.currentGestureIdBits.value,
mPointerGesture.lastGestureMode, mPointerGesture.lastGestureIdBits.value);
for (BitSet32 idBits = mPointerGesture.currentGestureIdBits; !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
+ uint32_t id = idBits.clearFirstMarkedBit();
uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
const PointerProperties& properties = mPointerGesture.currentGestureProperties[index];
const PointerCoords& coords = mPointerGesture.currentGestureCoords[index];
@@ -4669,8 +4752,7 @@
coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
}
for (BitSet32 idBits = mPointerGesture.lastGestureIdBits; !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
+ uint32_t id = idBits.clearFirstMarkedBit();
uint32_t index = mPointerGesture.lastGestureIdToIndex[id];
const PointerProperties& properties = mPointerGesture.lastGestureProperties[index];
const PointerCoords& coords = mPointerGesture.lastGestureCoords[index];
@@ -4694,8 +4776,7 @@
PointerProperties pointerProperties[MAX_POINTERS];
uint32_t pointerCount = 0;
while (!idBits.isEmpty()) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
+ uint32_t id = idBits.clearFirstMarkedBit();
uint32_t index = idToIndex[id];
pointerProperties[pointerCount].copyFrom(properties[index]);
pointerCoords[pointerCount].copyFrom(coords[index]);
@@ -4723,9 +4804,10 @@
}
}
- getDispatcher()->notifyMotion(when, getDeviceId(), source, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
action, flags, metaState, buttonState, edgeFlags,
pointerCount, pointerProperties, pointerCoords, xPrecision, yPrecision, downTime);
+ getListener()->notifyMotion(&args);
}
bool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties,
@@ -4734,9 +4816,7 @@
BitSet32 idBits) const {
bool changed = false;
while (!idBits.isEmpty()) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
+ uint32_t id = idBits.clearFirstMarkedBit();
uint32_t inIndex = inIdToIndex[id];
uint32_t outIndex = outIdToIndex[id];
@@ -4759,24 +4839,21 @@
}
void TouchInputMapper::fadePointer() {
- { // acquire lock
- AutoMutex _l(mLock);
- if (mPointerController != NULL) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- }
- } // release lock
+ if (mPointerController != NULL) {
+ mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ }
}
-bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) {
- return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue
- && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue;
+bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
+ return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
+ && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
}
-const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked(
+const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
int32_t x, int32_t y) {
- size_t numVirtualKeys = mLocked.virtualKeys.size();
+ size_t numVirtualKeys = mVirtualKeys.size();
for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mLocked.virtualKeys[i];
+ const VirtualKey& virtualKey = mVirtualKeys[i];
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
@@ -4795,43 +4872,59 @@
return NULL;
}
-void TouchInputMapper::calculatePointerIds() {
- uint32_t currentPointerCount = mCurrentTouch.pointerCount;
- uint32_t lastPointerCount = mLastTouch.pointerCount;
+void TouchInputMapper::assignPointerIds() {
+ uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
+ uint32_t lastPointerCount = mLastRawPointerData.pointerCount;
+
+ mCurrentRawPointerData.clearIdBits();
if (currentPointerCount == 0) {
// No pointers to assign.
- mCurrentTouch.idBits.clear();
- } else if (lastPointerCount == 0) {
- // All pointers are new.
- mCurrentTouch.idBits.clear();
- for (uint32_t i = 0; i < currentPointerCount; i++) {
- mCurrentTouch.pointers[i].id = i;
- mCurrentTouch.idToIndex[i] = i;
- mCurrentTouch.idBits.markBit(i);
- }
- } else if (currentPointerCount == 1 && lastPointerCount == 1) {
- // Only one pointer and no change in count so it must have the same id as before.
- uint32_t id = mLastTouch.pointers[0].id;
- mCurrentTouch.pointers[0].id = id;
- mCurrentTouch.idToIndex[id] = 0;
- mCurrentTouch.idBits.value = BitSet32::valueForBit(id);
- } else {
- // General case.
- // We build a heap of squared euclidean distances between current and last pointers
- // associated with the current and last pointer indices. Then, we find the best
- // match (by distance) for each current pointer.
- PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
+ return;
+ }
- uint32_t heapSize = 0;
- for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
- currentPointerIndex++) {
- for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
- lastPointerIndex++) {
- int64_t deltaX = mCurrentTouch.pointers[currentPointerIndex].x
- - mLastTouch.pointers[lastPointerIndex].x;
- int64_t deltaY = mCurrentTouch.pointers[currentPointerIndex].y
- - mLastTouch.pointers[lastPointerIndex].y;
+ if (lastPointerCount == 0) {
+ // All pointers are new.
+ for (uint32_t i = 0; i < currentPointerCount; i++) {
+ uint32_t id = i;
+ mCurrentRawPointerData.pointers[i].id = id;
+ mCurrentRawPointerData.idToIndex[id] = i;
+ mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(i));
+ }
+ return;
+ }
+
+ if (currentPointerCount == 1 && lastPointerCount == 1
+ && mCurrentRawPointerData.pointers[0].toolType
+ == mLastRawPointerData.pointers[0].toolType) {
+ // Only one pointer and no change in count so it must have the same id as before.
+ uint32_t id = mLastRawPointerData.pointers[0].id;
+ mCurrentRawPointerData.pointers[0].id = id;
+ mCurrentRawPointerData.idToIndex[id] = 0;
+ mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(0));
+ return;
+ }
+
+ // General case.
+ // We build a heap of squared euclidean distances between current and last pointers
+ // associated with the current and last pointer indices. Then, we find the best
+ // match (by distance) for each current pointer.
+ // The pointers must have the same tool type but it is possible for them to
+ // transition from hovering to touching or vice-versa while retaining the same id.
+ PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
+
+ uint32_t heapSize = 0;
+ for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
+ currentPointerIndex++) {
+ for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
+ lastPointerIndex++) {
+ const RawPointerData::Pointer& currentPointer =
+ mCurrentRawPointerData.pointers[currentPointerIndex];
+ const RawPointerData::Pointer& lastPointer =
+ mLastRawPointerData.pointers[lastPointerIndex];
+ if (currentPointer.toolType == lastPointer.toolType) {
+ int64_t deltaX = currentPointer.x - lastPointer.x;
+ int64_t deltaY = currentPointer.y - lastPointer.y;
uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
@@ -4842,193 +4935,174 @@
heapSize += 1;
}
}
+ }
- // Heapify
- for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
- startIndex -= 1;
- for (uint32_t parentIndex = startIndex; ;) {
- uint32_t childIndex = parentIndex * 2 + 1;
- if (childIndex >= heapSize) {
- break;
- }
-
- if (childIndex + 1 < heapSize
- && heap[childIndex + 1].distance < heap[childIndex].distance) {
- childIndex += 1;
- }
-
- if (heap[parentIndex].distance <= heap[childIndex].distance) {
- break;
- }
-
- swap(heap[parentIndex], heap[childIndex]);
- parentIndex = childIndex;
- }
- }
-
-#if DEBUG_POINTER_ASSIGNMENT
- LOGD("calculatePointerIds - initial distance min-heap: size=%d", heapSize);
- for (size_t i = 0; i < heapSize; i++) {
- LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
- i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
- heap[i].distance);
- }
-#endif
-
- // Pull matches out by increasing order of distance.
- // To avoid reassigning pointers that have already been matched, the loop keeps track
- // of which last and current pointers have been matched using the matchedXXXBits variables.
- // It also tracks the used pointer id bits.
- BitSet32 matchedLastBits(0);
- BitSet32 matchedCurrentBits(0);
- BitSet32 usedIdBits(0);
- bool first = true;
- for (uint32_t i = min(currentPointerCount, lastPointerCount); i > 0; i--) {
- for (;;) {
- if (first) {
- // The first time through the loop, we just consume the root element of
- // the heap (the one with smallest distance).
- first = false;
- } else {
- // Previous iterations consumed the root element of the heap.
- // Pop root element off of the heap (sift down).
- heapSize -= 1;
- LOG_ASSERT(heapSize > 0);
-
- // Sift down.
- heap[0] = heap[heapSize];
- for (uint32_t parentIndex = 0; ;) {
- uint32_t childIndex = parentIndex * 2 + 1;
- if (childIndex >= heapSize) {
- break;
- }
-
- if (childIndex + 1 < heapSize
- && heap[childIndex + 1].distance < heap[childIndex].distance) {
- childIndex += 1;
- }
-
- if (heap[parentIndex].distance <= heap[childIndex].distance) {
- break;
- }
-
- swap(heap[parentIndex], heap[childIndex]);
- parentIndex = childIndex;
- }
-
-#if DEBUG_POINTER_ASSIGNMENT
- LOGD("calculatePointerIds - reduced distance min-heap: size=%d", heapSize);
- for (size_t i = 0; i < heapSize; i++) {
- LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
- i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
- heap[i].distance);
- }
-#endif
- }
-
- uint32_t currentPointerIndex = heap[0].currentPointerIndex;
- if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
-
- uint32_t lastPointerIndex = heap[0].lastPointerIndex;
- if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
-
- matchedCurrentBits.markBit(currentPointerIndex);
- matchedLastBits.markBit(lastPointerIndex);
-
- uint32_t id = mLastTouch.pointers[lastPointerIndex].id;
- mCurrentTouch.pointers[currentPointerIndex].id = id;
- mCurrentTouch.idToIndex[id] = currentPointerIndex;
- usedIdBits.markBit(id);
-
-#if DEBUG_POINTER_ASSIGNMENT
- LOGD("calculatePointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
- lastPointerIndex, currentPointerIndex, id, heap[0].distance);
-#endif
+ // Heapify
+ for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
+ startIndex -= 1;
+ for (uint32_t parentIndex = startIndex; ;) {
+ uint32_t childIndex = parentIndex * 2 + 1;
+ if (childIndex >= heapSize) {
break;
}
+
+ if (childIndex + 1 < heapSize
+ && heap[childIndex + 1].distance < heap[childIndex].distance) {
+ childIndex += 1;
+ }
+
+ if (heap[parentIndex].distance <= heap[childIndex].distance) {
+ break;
+ }
+
+ swap(heap[parentIndex], heap[childIndex]);
+ parentIndex = childIndex;
}
-
- // Assign fresh ids to new pointers.
- if (currentPointerCount > lastPointerCount) {
- for (uint32_t i = currentPointerCount - lastPointerCount; ;) {
- uint32_t currentPointerIndex = matchedCurrentBits.firstUnmarkedBit();
- uint32_t id = usedIdBits.firstUnmarkedBit();
-
- mCurrentTouch.pointers[currentPointerIndex].id = id;
- mCurrentTouch.idToIndex[id] = currentPointerIndex;
- usedIdBits.markBit(id);
+ }
#if DEBUG_POINTER_ASSIGNMENT
- LOGD("calculatePointerIds - assigned: cur=%d, id=%d",
- currentPointerIndex, id);
+ LOGD("assignPointerIds - initial distance min-heap: size=%d", heapSize);
+ for (size_t i = 0; i < heapSize; i++) {
+ LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
+ i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
+ heap[i].distance);
+ }
#endif
- if (--i == 0) break; // done
- matchedCurrentBits.markBit(currentPointerIndex);
- }
- }
+ // Pull matches out by increasing order of distance.
+ // To avoid reassigning pointers that have already been matched, the loop keeps track
+ // of which last and current pointers have been matched using the matchedXXXBits variables.
+ // It also tracks the used pointer id bits.
+ BitSet32 matchedLastBits(0);
+ BitSet32 matchedCurrentBits(0);
+ BitSet32 usedIdBits(0);
+ bool first = true;
+ for (uint32_t i = min(currentPointerCount, lastPointerCount); heapSize > 0 && i > 0; i--) {
+ while (heapSize > 0) {
+ if (first) {
+ // The first time through the loop, we just consume the root element of
+ // the heap (the one with smallest distance).
+ first = false;
+ } else {
+ // Previous iterations consumed the root element of the heap.
+ // Pop root element off of the heap (sift down).
+ heap[0] = heap[heapSize];
+ for (uint32_t parentIndex = 0; ;) {
+ uint32_t childIndex = parentIndex * 2 + 1;
+ if (childIndex >= heapSize) {
+ break;
+ }
- // Fix id bits.
- mCurrentTouch.idBits = usedIdBits;
+ if (childIndex + 1 < heapSize
+ && heap[childIndex + 1].distance < heap[childIndex].distance) {
+ childIndex += 1;
+ }
+
+ if (heap[parentIndex].distance <= heap[childIndex].distance) {
+ break;
+ }
+
+ swap(heap[parentIndex], heap[childIndex]);
+ parentIndex = childIndex;
+ }
+
+#if DEBUG_POINTER_ASSIGNMENT
+ LOGD("assignPointerIds - reduced distance min-heap: size=%d", heapSize);
+ for (size_t i = 0; i < heapSize; i++) {
+ LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
+ i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
+ heap[i].distance);
+ }
+#endif
+ }
+
+ heapSize -= 1;
+
+ uint32_t currentPointerIndex = heap[0].currentPointerIndex;
+ if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
+
+ uint32_t lastPointerIndex = heap[0].lastPointerIndex;
+ if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
+
+ matchedCurrentBits.markBit(currentPointerIndex);
+ matchedLastBits.markBit(lastPointerIndex);
+
+ uint32_t id = mLastRawPointerData.pointers[lastPointerIndex].id;
+ mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
+ mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
+ mCurrentRawPointerData.markIdBit(id,
+ mCurrentRawPointerData.isHovering(currentPointerIndex));
+ usedIdBits.markBit(id);
+
+#if DEBUG_POINTER_ASSIGNMENT
+ LOGD("assignPointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
+ lastPointerIndex, currentPointerIndex, id, heap[0].distance);
+#endif
+ break;
+ }
+ }
+
+ // Assign fresh ids to pointers that were not matched in the process.
+ for (uint32_t i = currentPointerCount - matchedCurrentBits.count(); i != 0; i--) {
+ uint32_t currentPointerIndex = matchedCurrentBits.markFirstUnmarkedBit();
+ uint32_t id = usedIdBits.markFirstUnmarkedBit();
+
+ mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
+ mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
+ mCurrentRawPointerData.markIdBit(id,
+ mCurrentRawPointerData.isHovering(currentPointerIndex));
+
+#if DEBUG_POINTER_ASSIGNMENT
+ LOGD("assignPointerIds - assigned: cur=%d, id=%d",
+ currentPointerIndex, id);
+#endif
}
}
int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
- { // acquire lock
- AutoMutex _l(mLock);
+ if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
+ return AKEY_STATE_VIRTUAL;
+ }
- if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.keyCode == keyCode) {
- return AKEY_STATE_VIRTUAL;
+ size_t numVirtualKeys = mVirtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mVirtualKeys[i];
+ if (virtualKey.keyCode == keyCode) {
+ return AKEY_STATE_UP;
}
-
- size_t numVirtualKeys = mLocked.virtualKeys.size();
- for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mLocked.virtualKeys[i];
- if (virtualKey.keyCode == keyCode) {
- return AKEY_STATE_UP;
- }
- }
- } // release lock
+ }
return AKEY_STATE_UNKNOWN;
}
int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
- { // acquire lock
- AutoMutex _l(mLock);
+ if (mCurrentVirtualKey.down && mCurrentVirtualKey.scanCode == scanCode) {
+ return AKEY_STATE_VIRTUAL;
+ }
- if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.scanCode == scanCode) {
- return AKEY_STATE_VIRTUAL;
+ size_t numVirtualKeys = mVirtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mVirtualKeys[i];
+ if (virtualKey.scanCode == scanCode) {
+ return AKEY_STATE_UP;
}
-
- size_t numVirtualKeys = mLocked.virtualKeys.size();
- for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mLocked.virtualKeys[i];
- if (virtualKey.scanCode == scanCode) {
- return AKEY_STATE_UP;
- }
- }
- } // release lock
+ }
return AKEY_STATE_UNKNOWN;
}
bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags) {
- { // acquire lock
- AutoMutex _l(mLock);
+ size_t numVirtualKeys = mVirtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mVirtualKeys[i];
- size_t numVirtualKeys = mLocked.virtualKeys.size();
- for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mLocked.virtualKeys[i];
-
- for (size_t i = 0; i < numCodes; i++) {
- if (virtualKey.keyCode == keyCodes[i]) {
- outFlags[i] = 1;
- }
+ for (size_t i = 0; i < numCodes; i++) {
+ if (virtualKey.keyCode == keyCodes[i]) {
+ outFlags[i] = 1;
}
}
- } // release lock
+ }
return true;
}
@@ -5067,21 +5141,18 @@
}
void SingleTouchInputMapper::sync(nsecs_t when) {
- mCurrentTouch.clear();
+ mCurrentRawPointerData.clear();
+ mCurrentButtonState = 0;
if (mTouchButtonAccumulator.isActive()) {
- uint32_t buttonState = mTouchButtonAccumulator.getButtonState();
- bool isHovering = mTouchButtonAccumulator.isHovering();
- if (mSingleTouchMotionAccumulator.getAbsoluteDistance() > 0) {
- isHovering = true;
- }
+ mCurrentRawPointerData.pointerCount = 1;
+ mCurrentRawPointerData.idToIndex[0] = 0;
- mCurrentTouch.pointerCount = 1;
- mCurrentTouch.idToIndex[0] = 0;
- mCurrentTouch.idBits.markBit(0);
- mCurrentTouch.buttonState = buttonState;
+ bool isHovering = mTouchButtonAccumulator.isHovering()
+ || mSingleTouchMotionAccumulator.getAbsoluteDistance() > 0;
+ mCurrentRawPointerData.markIdBit(0, isHovering);
- PointerData& outPointer = mCurrentTouch.pointers[0];
+ RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[0];
outPointer.id = 0;
outPointer.x = mSingleTouchMotionAccumulator.getAbsoluteX();
outPointer.y = mSingleTouchMotionAccumulator.getAbsoluteY();
@@ -5097,21 +5168,24 @@
outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
}
outPointer.isHovering = isHovering;
+
+ mCurrentButtonState = mTouchButtonAccumulator.getButtonState()
+ | mCursorButtonAccumulator.getButtonState();
}
syncTouch(when, true);
}
-void SingleTouchInputMapper::configureRawAxes() {
- TouchInputMapper::configureRawAxes();
+void SingleTouchInputMapper::configureRawPointerAxes() {
+ TouchInputMapper::configureRawPointerAxes();
mTouchButtonAccumulator.configure(getDevice());
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mRawAxes.pressure);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mRawAxes.toolMajor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_DISTANCE, & mRawAxes.distance);
+ getAbsoluteAxisInfo(ABS_X, &mRawPointerAxes.x);
+ getAbsoluteAxisInfo(ABS_Y, &mRawPointerAxes.y);
+ getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPointerAxes.pressure);
+ getAbsoluteAxisInfo(ABS_TOOL_WIDTH, &mRawPointerAxes.toolMajor);
+ getAbsoluteAxisInfo(ABS_DISTANCE, &mRawPointerAxes.distance);
}
@@ -5172,8 +5246,9 @@
size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
size_t outCount = 0;
bool havePointerIds = true;
+ BitSet32 newPointerIdBits;
- mCurrentTouch.clear();
+ mCurrentRawPointerData.clear();
for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
const MultiTouchMotionAccumulator::Slot* inSlot =
@@ -5191,7 +5266,7 @@
break; // too many fingers!
}
- PointerData& outPointer = mCurrentTouch.pointers[outCount];
+ RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[outCount];
outPointer.x = inSlot->getX();
outPointer.y = inSlot->getY();
outPointer.pressure = inSlot->getPressure();
@@ -5210,8 +5285,9 @@
}
}
- outPointer.isHovering = mTouchButtonAccumulator.isHovering()
+ bool isHovering = mTouchButtonAccumulator.isHovering()
|| inSlot->getDistance() > 0;
+ outPointer.isHovering = isHovering;
// Assign pointer id using tracking id if available.
if (havePointerIds) {
@@ -5219,37 +5295,37 @@
int32_t id = -1;
if (trackingId >= 0) {
for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) {
- uint32_t n = idBits.firstMarkedBit();
- idBits.clearBit(n);
-
+ uint32_t n = idBits.clearFirstMarkedBit();
if (mPointerTrackingIdMap[n] == trackingId) {
id = n;
}
}
if (id < 0 && !mPointerIdBits.isFull()) {
- id = mPointerIdBits.firstUnmarkedBit();
- mPointerIdBits.markBit(id);
+ id = mPointerIdBits.markFirstUnmarkedBit();
mPointerTrackingIdMap[id] = trackingId;
}
}
if (id < 0) {
havePointerIds = false;
- mCurrentTouch.idBits.clear();
+ mCurrentRawPointerData.clearIdBits();
+ newPointerIdBits.clear();
} else {
outPointer.id = id;
- mCurrentTouch.idToIndex[id] = outCount;
- mCurrentTouch.idBits.markBit(id);
+ mCurrentRawPointerData.idToIndex[id] = outCount;
+ mCurrentRawPointerData.markIdBit(id, isHovering);
+ newPointerIdBits.markBit(id);
}
}
outCount += 1;
}
- mCurrentTouch.pointerCount = outCount;
- mCurrentTouch.buttonState = mTouchButtonAccumulator.getButtonState();
+ mCurrentRawPointerData.pointerCount = outCount;
+ mCurrentButtonState = mTouchButtonAccumulator.getButtonState()
+ | mCursorButtonAccumulator.getButtonState();
- mPointerIdBits = mCurrentTouch.idBits;
+ mPointerIdBits = newPointerIdBits;
syncTouch(when, havePointerIds);
@@ -5258,26 +5334,27 @@
}
}
-void MultiTouchInputMapper::configureRawAxes() {
- TouchInputMapper::configureRawAxes();
+void MultiTouchInputMapper::configureRawPointerAxes() {
+ TouchInputMapper::configureRawPointerAxes();
mTouchButtonAccumulator.configure(getDevice());
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, &mRawAxes.x);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, &mRawAxes.y);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, &mRawAxes.touchMajor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, &mRawAxes.touchMinor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, &mRawAxes.toolMajor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, &mRawAxes.toolMinor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, &mRawAxes.orientation);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, &mRawAxes.pressure);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_DISTANCE, &mRawAxes.distance);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TRACKING_ID, &mRawAxes.trackingId);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_SLOT, &mRawAxes.slot);
+ getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.x);
+ getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.y);
+ getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &mRawPointerAxes.touchMajor);
+ getAbsoluteAxisInfo(ABS_MT_TOUCH_MINOR, &mRawPointerAxes.touchMinor);
+ getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR, &mRawPointerAxes.toolMajor);
+ getAbsoluteAxisInfo(ABS_MT_WIDTH_MINOR, &mRawPointerAxes.toolMinor);
+ getAbsoluteAxisInfo(ABS_MT_ORIENTATION, &mRawPointerAxes.orientation);
+ getAbsoluteAxisInfo(ABS_MT_PRESSURE, &mRawPointerAxes.pressure);
+ getAbsoluteAxisInfo(ABS_MT_DISTANCE, &mRawPointerAxes.distance);
+ getAbsoluteAxisInfo(ABS_MT_TRACKING_ID, &mRawPointerAxes.trackingId);
+ getAbsoluteAxisInfo(ABS_MT_SLOT, &mRawPointerAxes.slot);
- if (mRawAxes.trackingId.valid
- && mRawAxes.slot.valid && mRawAxes.slot.minValue == 0 && mRawAxes.slot.maxValue > 0) {
- size_t slotCount = mRawAxes.slot.maxValue + 1;
+ if (mRawPointerAxes.trackingId.valid
+ && mRawPointerAxes.slot.valid
+ && mRawPointerAxes.slot.minValue == 0 && mRawPointerAxes.slot.maxValue > 0) {
+ size_t slotCount = mRawPointerAxes.slot.maxValue + 1;
if (slotCount > MAX_SLOTS) {
LOGW("MultiTouch Device %s reported %d slots but the framework "
"only supports a maximum of %d slots at this time.",
@@ -5364,7 +5441,7 @@
// Collect all axes.
for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
RawAbsoluteAxisInfo rawAxisInfo;
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), abs, &rawAxisInfo);
+ getAbsoluteAxisInfo(abs, &rawAxisInfo);
if (rawAxisInfo.valid) {
// Map axis.
AxisInfo axisInfo;
@@ -5581,9 +5658,10 @@
// TODO: Use the input device configuration to control this behavior more finely.
uint32_t policyFlags = 0;
- getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
1, &pointerProperties, &pointerCoords, 0, 0, 0);
+ getListener()->notifyMotion(&args);
}
bool JoystickInputMapper::filterAxes(bool force) {
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index ee6990b..f5d095d 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -18,8 +18,8 @@
#define _UI_INPUT_READER_H
#include "EventHub.h"
-#include "InputDispatcher.h"
#include "PointerController.h"
+#include "InputListener.h"
#include <ui/Input.h>
#include <ui/DisplayInfo.h>
@@ -164,6 +164,9 @@
*
* The actual implementation is partially supported by callbacks into the DVM
* via JNI. This interface is also mocked in the unit tests.
+ *
+ * These methods must NOT re-enter the input reader since they may be called while
+ * holding the input reader lock.
*/
class InputReaderPolicyInterface : public virtual RefBase {
protected:
@@ -195,7 +198,7 @@
};
-/* Processes raw input events and sends cooked event data to an input dispatcher. */
+/* Processes raw input events and sends cooked event data to an input listener. */
class InputReaderInterface : public virtual RefBase {
protected:
InputReaderInterface() { }
@@ -270,25 +273,27 @@
virtual void requestTimeoutAtTime(nsecs_t when) = 0;
virtual InputReaderPolicyInterface* getPolicy() = 0;
- virtual InputDispatcherInterface* getDispatcher() = 0;
+ virtual InputListenerInterface* getListener() = 0;
virtual EventHubInterface* getEventHub() = 0;
};
/* The input reader reads raw event data from the event hub and processes it into input events
- * that it sends to the input dispatcher. Some functions of the input reader, such as early
+ * that it sends to the input listener. Some functions of the input reader, such as early
* event filtering in low power states, are controlled by a separate policy object.
*
- * IMPORTANT INVARIANT:
- * Because the policy and dispatcher can potentially block or cause re-entrance into
- * the input reader, the input reader never calls into other components while holding
- * an exclusive internal lock whenever re-entrance can happen.
+ * The InputReader owns a collection of InputMappers. Most of the work it does happens
+ * on the input reader thread but the InputReader can receive queries from other system
+ * components running on arbitrary threads. To keep things manageable, the InputReader
+ * uses a single Mutex to guard its state. The Mutex may be held while calling into the
+ * EventHub or the InputReaderPolicy but it is never held while calling into the
+ * InputListener.
*/
-class InputReader : public InputReaderInterface, protected InputReaderContext {
+class InputReader : public InputReaderInterface {
public:
InputReader(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
- const sp<InputDispatcherInterface>& dispatcher);
+ const sp<InputListenerInterface>& listener);
virtual ~InputReader();
virtual void dump(String8& dump);
@@ -313,74 +318,80 @@
virtual void requestRefreshConfiguration(uint32_t changes);
protected:
- // These methods are protected virtual so they can be overridden and instrumented
- // by test cases.
- virtual InputDevice* createDevice(int32_t deviceId, const String8& name, uint32_t classes);
+ // These members are protected so they can be instrumented by test cases.
+ virtual InputDevice* createDeviceLocked(int32_t deviceId,
+ const String8& name, uint32_t classes);
+
+ class ContextImpl : public InputReaderContext {
+ InputReader* mReader;
+
+ public:
+ ContextImpl(InputReader* reader);
+
+ virtual void updateGlobalMetaState();
+ virtual int32_t getGlobalMetaState();
+ virtual void disableVirtualKeysUntil(nsecs_t time);
+ virtual bool shouldDropVirtualKey(nsecs_t now,
+ InputDevice* device, int32_t keyCode, int32_t scanCode);
+ virtual void fadePointer();
+ virtual void requestTimeoutAtTime(nsecs_t when);
+ virtual InputReaderPolicyInterface* getPolicy();
+ virtual InputListenerInterface* getListener();
+ virtual EventHubInterface* getEventHub();
+ } mContext;
+
+ friend class ContextImpl;
private:
+ Mutex mLock;
+
sp<EventHubInterface> mEventHub;
sp<InputReaderPolicyInterface> mPolicy;
- sp<InputDispatcherInterface> mDispatcher;
+ sp<QueuedInputListener> mQueuedListener;
InputReaderConfiguration mConfig;
- virtual InputReaderPolicyInterface* getPolicy() { return mPolicy.get(); }
- virtual InputDispatcherInterface* getDispatcher() { return mDispatcher.get(); }
- virtual EventHubInterface* getEventHub() { return mEventHub.get(); }
-
// The event queue.
static const int EVENT_BUFFER_SIZE = 256;
RawEvent mEventBuffer[EVENT_BUFFER_SIZE];
- // This reader/writer lock guards the list of input devices.
- // The writer lock must be held whenever the list of input devices is modified
- // and then promptly released.
- // The reader lock must be held whenever the list of input devices is traversed or an
- // input device in the list is accessed.
- // This lock only protects the registry and prevents inadvertent deletion of device objects
- // that are in use. Individual devices are responsible for guarding their own internal state
- // as needed for concurrent operation.
- RWLock mDeviceRegistryLock;
KeyedVector<int32_t, InputDevice*> mDevices;
// low-level input event decoding and device management
- void processEvents(const RawEvent* rawEvents, size_t count);
+ void processEventsLocked(const RawEvent* rawEvents, size_t count);
- void addDevice(int32_t deviceId);
- void removeDevice(int32_t deviceId);
- void processEventsForDevice(int32_t deviceId, const RawEvent* rawEvents, size_t count);
- void timeoutExpired(nsecs_t when);
+ void addDeviceLocked(int32_t deviceId);
+ void removeDeviceLocked(int32_t deviceId);
+ void processEventsForDeviceLocked(int32_t deviceId, const RawEvent* rawEvents, size_t count);
+ void timeoutExpiredLocked(nsecs_t when);
- void handleConfigurationChanged(nsecs_t when);
+ void handleConfigurationChangedLocked(nsecs_t when);
- // state management for all devices
- Mutex mStateLock;
+ int32_t mGlobalMetaState;
+ void updateGlobalMetaStateLocked();
+ int32_t getGlobalMetaStateLocked();
- int32_t mGlobalMetaState; // guarded by mStateLock
- virtual void updateGlobalMetaState();
- virtual int32_t getGlobalMetaState();
+ void fadePointerLocked();
- virtual void fadePointer();
+ InputConfiguration mInputConfiguration;
+ void updateInputConfigurationLocked();
- InputConfiguration mInputConfiguration; // guarded by mStateLock
- void updateInputConfiguration();
-
- nsecs_t mDisableVirtualKeysTimeout; // only accessed by reader thread
- virtual void disableVirtualKeysUntil(nsecs_t time);
- virtual bool shouldDropVirtualKey(nsecs_t now,
+ nsecs_t mDisableVirtualKeysTimeout;
+ void disableVirtualKeysUntilLocked(nsecs_t time);
+ bool shouldDropVirtualKeyLocked(nsecs_t now,
InputDevice* device, int32_t keyCode, int32_t scanCode);
- nsecs_t mNextTimeout; // only accessed by reader thread, not guarded
- virtual void requestTimeoutAtTime(nsecs_t when);
+ nsecs_t mNextTimeout;
+ void requestTimeoutAtTimeLocked(nsecs_t when);
- uint32_t mConfigurationChangesToRefresh; // guarded by mStateLock
- void refreshConfiguration(uint32_t changes);
+ uint32_t mConfigurationChangesToRefresh;
+ void refreshConfigurationLocked(uint32_t changes);
// state queries
typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
- int32_t getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
+ int32_t getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
GetStateFunc getStateFunc);
- bool markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
+ bool markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags);
};
@@ -530,6 +541,93 @@
};
+/* Raw axis information from the driver. */
+struct RawPointerAxes {
+ RawAbsoluteAxisInfo x;
+ RawAbsoluteAxisInfo y;
+ RawAbsoluteAxisInfo pressure;
+ RawAbsoluteAxisInfo touchMajor;
+ RawAbsoluteAxisInfo touchMinor;
+ RawAbsoluteAxisInfo toolMajor;
+ RawAbsoluteAxisInfo toolMinor;
+ RawAbsoluteAxisInfo orientation;
+ RawAbsoluteAxisInfo distance;
+ RawAbsoluteAxisInfo trackingId;
+ RawAbsoluteAxisInfo slot;
+
+ RawPointerAxes();
+ void clear();
+};
+
+
+/* Raw data for a collection of pointers including a pointer id mapping table. */
+struct RawPointerData {
+ struct Pointer {
+ uint32_t id;
+ int32_t x;
+ int32_t y;
+ int32_t pressure;
+ int32_t touchMajor;
+ int32_t touchMinor;
+ int32_t toolMajor;
+ int32_t toolMinor;
+ int32_t orientation;
+ int32_t distance;
+ int32_t toolType; // a fully decoded AMOTION_EVENT_TOOL_TYPE constant
+ bool isHovering;
+ };
+
+ uint32_t pointerCount;
+ Pointer pointers[MAX_POINTERS];
+ BitSet32 hoveringIdBits, touchingIdBits;
+ uint32_t idToIndex[MAX_POINTER_ID + 1];
+
+ RawPointerData();
+ void clear();
+ void copyFrom(const RawPointerData& other);
+ void getCentroidOfTouchingPointers(float* outX, float* outY) const;
+
+ inline void markIdBit(uint32_t id, bool isHovering) {
+ if (isHovering) {
+ hoveringIdBits.markBit(id);
+ } else {
+ touchingIdBits.markBit(id);
+ }
+ }
+
+ inline void clearIdBits() {
+ hoveringIdBits.clear();
+ touchingIdBits.clear();
+ }
+
+ inline const Pointer& pointerForId(uint32_t id) const {
+ return pointers[idToIndex[id]];
+ }
+
+ inline bool isHovering(uint32_t pointerIndex) {
+ return pointers[pointerIndex].isHovering;
+ }
+};
+
+
+/* Cooked data for a collection of pointers including a pointer id mapping table. */
+struct CookedPointerData {
+ uint32_t pointerCount;
+ PointerProperties pointerProperties[MAX_POINTERS];
+ PointerCoords pointerCoords[MAX_POINTERS];
+ BitSet32 hoveringIdBits, touchingIdBits;
+ uint32_t idToIndex[MAX_POINTER_ID + 1];
+
+ CookedPointerData();
+ void clear();
+ void copyFrom(const CookedPointerData& other);
+
+ inline bool isHovering(uint32_t pointerIndex) {
+ return hoveringIdBits.hasBit(pointerProperties[pointerIndex].id);
+ }
+};
+
+
/* Keeps track of the state of single-touch protocol. */
class SingleTouchMotionAccumulator {
public:
@@ -590,8 +688,8 @@
int32_t mAbsMTOrientation;
int32_t mAbsMTTrackingId;
int32_t mAbsMTPressure;
- int32_t mAbsMTToolType;
int32_t mAbsMTDistance;
+ int32_t mAbsMTToolType;
Slot();
void clearIfInUse();
@@ -632,7 +730,7 @@
inline const String8 getDeviceName() { return mDevice->getName(); }
inline InputReaderContext* getContext() { return mContext; }
inline InputReaderPolicyInterface* getPolicy() { return mContext->getPolicy(); }
- inline InputDispatcherInterface* getDispatcher() { return mContext->getDispatcher(); }
+ inline InputListenerInterface* getListener() { return mContext->getListener(); }
inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
virtual uint32_t getSources() = 0;
@@ -657,6 +755,8 @@
InputDevice* mDevice;
InputReaderContext* mContext;
+ status_t getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo);
+
static void dumpRawAbsoluteAxisInfo(String8& dump,
const RawAbsoluteAxisInfo& axis, const char* name);
};
@@ -707,27 +807,25 @@
uint32_t mSource;
int32_t mKeyboardType;
+ Vector<KeyDown> mKeyDowns; // keys that are down
+ int32_t mMetaState;
+ nsecs_t mDownTime; // time of most recent key down
+
+ struct LedState {
+ bool avail; // led is available
+ bool on; // we think the led is currently on
+ };
+ LedState mCapsLockLedState;
+ LedState mNumLockLedState;
+ LedState mScrollLockLedState;
+
// Immutable configuration parameters.
struct Parameters {
int32_t associatedDisplayId;
bool orientationAware;
} mParameters;
- struct LockedState {
- Vector<KeyDown> keyDowns; // keys that are down
- int32_t metaState;
- nsecs_t downTime; // time of most recent key down
-
- struct LedState {
- bool avail; // led is available
- bool on; // we think the led is currently on
- };
- LedState capsLockLedState;
- LedState numLockLedState;
- LedState scrollLockLedState;
- } mLocked;
-
- void initializeLocked();
+ void initialize();
void configureParameters();
void dumpParameters(String8& dump);
@@ -737,12 +835,12 @@
void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
uint32_t policyFlags);
- ssize_t findKeyDownLocked(int32_t scanCode);
+ ssize_t findKeyDown(int32_t scanCode);
- void resetLedStateLocked();
- void initializeLedStateLocked(LockedState::LedState& ledState, int32_t led);
- void updateLedStateLocked(bool reset);
- void updateLedStateForModifierLocked(LockedState::LedState& ledState, int32_t led,
+ void resetLedState();
+ void initializeLedState(LedState& ledState, int32_t led);
+ void updateLedState(bool reset);
+ void updateLedStateForModifier(LedState& ledState, int32_t led,
int32_t modifier, bool reset);
};
@@ -767,8 +865,6 @@
// Amount that trackball needs to move in order to generate a key event.
static const int32_t TRACKBALL_MOVEMENT_THRESHOLD = 6;
- Mutex mLock;
-
// Immutable configuration parameters.
struct Parameters {
enum Mode {
@@ -801,12 +897,10 @@
sp<PointerControllerInterface> mPointerController;
- struct LockedState {
- int32_t buttonState;
- nsecs_t downTime;
- } mLocked;
+ int32_t mButtonState;
+ nsecs_t mDownTime;
- void initializeLocked();
+ void initialize();
void configureParameters();
void dumpParameters(String8& dump);
@@ -835,8 +929,6 @@
virtual void timeoutExpired(nsecs_t when);
protected:
- Mutex mLock;
-
struct VirtualKey {
int32_t keyCode;
int32_t scanCode;
@@ -853,82 +945,6 @@
}
};
- // Raw data for a single pointer.
- struct PointerData {
- uint32_t id;
- int32_t x;
- int32_t y;
- int32_t pressure;
- int32_t touchMajor;
- int32_t touchMinor;
- int32_t toolMajor;
- int32_t toolMinor;
- int32_t orientation;
- int32_t distance;
- int32_t toolType; // AMOTION_EVENT_TOOL_TYPE constant
- bool isHovering;
-
- inline bool operator== (const PointerData& other) const {
- return id == other.id
- && x == other.x
- && y == other.y
- && pressure == other.pressure
- && touchMajor == other.touchMajor
- && touchMinor == other.touchMinor
- && toolMajor == other.toolMajor
- && toolMinor == other.toolMinor
- && orientation == other.orientation
- && distance == other.distance
- && toolType == other.toolType
- && isHovering == other.isHovering;
- }
- inline bool operator!= (const PointerData& other) const {
- return !(*this == other);
- }
- };
-
- // Raw data for a collection of pointers including a pointer id mapping table.
- struct TouchData {
- uint32_t pointerCount;
- PointerData pointers[MAX_POINTERS];
- BitSet32 idBits;
- uint32_t idToIndex[MAX_POINTER_ID + 1];
- int32_t buttonState;
-
- void copyFrom(const TouchData& other) {
- pointerCount = other.pointerCount;
- idBits = other.idBits;
- buttonState = other.buttonState;
-
- for (uint32_t i = 0; i < pointerCount; i++) {
- pointers[i] = other.pointers[i];
-
- int id = pointers[i].id;
- idToIndex[id] = other.idToIndex[id];
- }
- }
-
- inline void clear() {
- pointerCount = 0;
- idBits.clear();
- buttonState = 0;
- }
-
- void getCentroid(float* outX, float* outY) {
- float x = 0, y = 0;
- if (pointerCount != 0) {
- for (uint32_t i = 0; i < pointerCount; i++) {
- x += pointers[i].x;
- y += pointers[i].y;
- }
- x /= pointerCount;
- y /= pointerCount;
- }
- *outX = x;
- *outY = y;
- }
- };
-
// Input sources supported by the device.
uint32_t mTouchSource; // sources when reporting touch data
uint32_t mPointerSource; // sources when reporting pointer gestures
@@ -1038,29 +1054,23 @@
float distanceScale;
} mCalibration;
- // Raw axis information from the driver.
- struct RawAxes {
- RawAbsoluteAxisInfo x;
- RawAbsoluteAxisInfo y;
- RawAbsoluteAxisInfo pressure;
- RawAbsoluteAxisInfo touchMajor;
- RawAbsoluteAxisInfo touchMinor;
- RawAbsoluteAxisInfo toolMajor;
- RawAbsoluteAxisInfo toolMinor;
- RawAbsoluteAxisInfo orientation;
- RawAbsoluteAxisInfo distance;
- RawAbsoluteAxisInfo trackingId;
- RawAbsoluteAxisInfo slot;
- } mRawAxes;
+ // Raw pointer axis information from the driver.
+ RawPointerAxes mRawPointerAxes;
- // Current and previous touch sample data.
- TouchData mCurrentTouch;
- PointerProperties mCurrentTouchProperties[MAX_POINTERS];
- PointerCoords mCurrentTouchCoords[MAX_POINTERS];
+ // Raw pointer sample data.
+ RawPointerData mCurrentRawPointerData;
+ RawPointerData mLastRawPointerData;
- TouchData mLastTouch;
- PointerProperties mLastTouchProperties[MAX_POINTERS];
- PointerCoords mLastTouchCoords[MAX_POINTERS];
+ // Cooked pointer sample data.
+ CookedPointerData mCurrentCookedPointerData;
+ CookedPointerData mLastCookedPointerData;
+
+ // Button state.
+ int32_t mCurrentButtonState;
+ int32_t mLastButtonState;
+
+ // True if we sent a HOVER_ENTER event.
+ bool mSentHoverEnter;
// The time the primary pointer last went down.
nsecs_t mDownTime;
@@ -1068,113 +1078,106 @@
// The pointer controller, or null if the device is not a pointer.
sp<PointerControllerInterface> mPointerController;
- struct LockedState {
- Vector<VirtualKey> virtualKeys;
-
- // The surface orientation and width and height set by configureSurfaceLocked().
- int32_t surfaceOrientation;
- int32_t surfaceWidth, surfaceHeight;
-
- // The associated display orientation and width and height set by configureSurfaceLocked().
- int32_t associatedDisplayOrientation;
- int32_t associatedDisplayWidth, associatedDisplayHeight;
-
- // Translation and scaling factors, orientation-independent.
- float xScale;
- float xPrecision;
-
- float yScale;
- float yPrecision;
-
- float geometricScale;
-
- float toolSizeLinearScale;
- float toolSizeLinearBias;
- float toolSizeAreaScale;
- float toolSizeAreaBias;
-
- float pressureScale;
-
- float sizeScale;
-
- float orientationScale;
-
- float distanceScale;
-
- // Oriented motion ranges for input device info.
- struct OrientedRanges {
- InputDeviceInfo::MotionRange x;
- InputDeviceInfo::MotionRange y;
-
- bool havePressure;
- InputDeviceInfo::MotionRange pressure;
-
- bool haveSize;
- InputDeviceInfo::MotionRange size;
-
- bool haveTouchSize;
- InputDeviceInfo::MotionRange touchMajor;
- InputDeviceInfo::MotionRange touchMinor;
-
- bool haveToolSize;
- InputDeviceInfo::MotionRange toolMajor;
- InputDeviceInfo::MotionRange toolMinor;
-
- bool haveOrientation;
- InputDeviceInfo::MotionRange orientation;
-
- bool haveDistance;
- InputDeviceInfo::MotionRange distance;
- } orientedRanges;
-
- // Oriented dimensions and precision.
- float orientedSurfaceWidth, orientedSurfaceHeight;
- float orientedXPrecision, orientedYPrecision;
-
- struct CurrentVirtualKeyState {
- bool down;
- nsecs_t downTime;
- int32_t keyCode;
- int32_t scanCode;
- } currentVirtualKey;
-
- // Scale factor for gesture based pointer movements.
- float pointerGestureXMovementScale;
- float pointerGestureYMovementScale;
-
- // Scale factor for gesture based zooming and other freeform motions.
- float pointerGestureXZoomScale;
- float pointerGestureYZoomScale;
-
- // The maximum swipe width.
- float pointerGestureMaxSwipeWidth;
- } mLocked;
+ Vector<VirtualKey> mVirtualKeys;
virtual void configureParameters();
virtual void dumpParameters(String8& dump);
- virtual void configureRawAxes();
- virtual void dumpRawAxes(String8& dump);
- virtual bool configureSurfaceLocked();
- virtual void dumpSurfaceLocked(String8& dump);
- virtual void configureVirtualKeysLocked();
- virtual void dumpVirtualKeysLocked(String8& dump);
+ virtual void configureRawPointerAxes();
+ virtual void dumpRawPointerAxes(String8& dump);
+ virtual bool configureSurface();
+ virtual void dumpSurface(String8& dump);
+ virtual void configureVirtualKeys();
+ virtual void dumpVirtualKeys(String8& dump);
virtual void parseCalibration();
virtual void resolveCalibration();
virtual void dumpCalibration(String8& dump);
- enum TouchResult {
- // Dispatch the touch normally.
- DISPATCH_TOUCH,
- // Do not dispatch the touch, but keep tracking the current stroke.
- SKIP_TOUCH,
- // Do not dispatch the touch, and drop all information associated with the current stoke
- // so the next movement will appear as a new down.
- DROP_STROKE
- };
-
void syncTouch(nsecs_t when, bool havePointerIds);
private:
+ // The surface orientation and width and height set by configureSurface().
+ int32_t mSurfaceOrientation;
+ int32_t mSurfaceWidth;
+ int32_t mSurfaceHeight;
+
+ // The associated display orientation and width and height set by configureSurface().
+ int32_t mAssociatedDisplayOrientation;
+ int32_t mAssociatedDisplayWidth;
+ int32_t mAssociatedDisplayHeight;
+
+ // Translation and scaling factors, orientation-independent.
+ float mXScale;
+ float mXPrecision;
+
+ float mYScale;
+ float mYPrecision;
+
+ float mGeometricScale;
+
+ float mToolSizeLinearScale;
+ float mToolSizeLinearBias;
+ float mToolSizeAreaScale;
+ float mToolSizeAreaBias;
+
+ float mPressureScale;
+
+ float mSizeScale;
+
+ float mOrientationScale;
+
+ float mDistanceScale;
+
+ // Oriented motion ranges for input device info.
+ struct OrientedRanges {
+ InputDeviceInfo::MotionRange x;
+ InputDeviceInfo::MotionRange y;
+
+ bool havePressure;
+ InputDeviceInfo::MotionRange pressure;
+
+ bool haveSize;
+ InputDeviceInfo::MotionRange size;
+
+ bool haveTouchSize;
+ InputDeviceInfo::MotionRange touchMajor;
+ InputDeviceInfo::MotionRange touchMinor;
+
+ bool haveToolSize;
+ InputDeviceInfo::MotionRange toolMajor;
+ InputDeviceInfo::MotionRange toolMinor;
+
+ bool haveOrientation;
+ InputDeviceInfo::MotionRange orientation;
+
+ bool haveDistance;
+ InputDeviceInfo::MotionRange distance;
+ } mOrientedRanges;
+
+ // Oriented dimensions and precision.
+ float mOrientedSurfaceWidth;
+ float mOrientedSurfaceHeight;
+ float mOrientedXPrecision;
+ float mOrientedYPrecision;
+
+ struct CurrentVirtualKeyState {
+ bool down;
+ bool ignored;
+ nsecs_t downTime;
+ int32_t keyCode;
+ int32_t scanCode;
+ } mCurrentVirtualKey;
+
+ // Scale factor for gesture based pointer movements.
+ float mPointerGestureXMovementScale;
+ float mPointerGestureYMovementScale;
+
+ // Scale factor for gesture based zooming and other freeform motions.
+ float mPointerGestureXZoomScale;
+ float mPointerGestureYZoomScale;
+
+ // The maximum swipe width.
+ float mPointerGestureMaxSwipeWidth;
+
struct PointerDistanceHeapElement {
uint32_t currentPointerIndex : 8;
uint32_t lastPointerIndex : 8;
@@ -1319,11 +1322,17 @@
}
} mPointerGesture;
- void initializeLocked();
+ void initialize();
- TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags);
+ bool consumeRawTouches(nsecs_t when, uint32_t policyFlags);
+ void dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
+ int32_t keyEventAction, int32_t keyEventFlags);
+
void dispatchTouches(nsecs_t when, uint32_t policyFlags);
- void prepareTouches(float* outXPrecision, float* outYPrecision);
+ void dispatchHoverExit(nsecs_t when, uint32_t policyFlags);
+ void dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags);
+ void cookPointerData();
+
void dispatchPointerGestures(nsecs_t when, uint32_t policyFlags, bool isTimeout);
bool preparePointerGestures(nsecs_t when,
bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout);
@@ -1346,12 +1355,10 @@
PointerProperties* outProperties, PointerCoords* outCoords,
const uint32_t* outIdToIndex, BitSet32 idBits) const;
- void suppressSwipeOntoVirtualKeys(nsecs_t when);
+ bool isPointInsideSurface(int32_t x, int32_t y);
+ const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
- bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
- const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
-
- void calculatePointerIds();
+ void assignPointerIds();
};
@@ -1364,7 +1371,7 @@
virtual void process(const RawEvent* rawEvent);
protected:
- virtual void configureRawAxes();
+ virtual void configureRawPointerAxes();
private:
CursorButtonAccumulator mCursorButtonAccumulator;
@@ -1386,7 +1393,7 @@
virtual void process(const RawEvent* rawEvent);
protected:
- virtual void configureRawAxes();
+ virtual void configureRawPointerAxes();
private:
CursorButtonAccumulator mCursorButtonAccumulator;
diff --git a/services/input/PointerController.cpp b/services/input/PointerController.cpp
index 12c7cba..1d1730d 100644
--- a/services/input/PointerController.cpp
+++ b/services/input/PointerController.cpp
@@ -261,9 +261,7 @@
// Add or move spots for fingers that are down.
for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
+ uint32_t id = idBits.clearFirstMarkedBit();
const PointerCoords& c = spotCoords[spotIdToIndex[id]];
const SpriteIcon& icon = c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE) > 0
? mResources.spotTouch : mResources.spotHover;
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 8533743..4a866a8 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -48,13 +48,16 @@
class FakePointerController : public PointerControllerInterface {
bool mHaveBounds;
float mMinX, mMinY, mMaxX, mMaxY;
+ float mX, mY;
+ int32_t mButtonState;
protected:
virtual ~FakePointerController() { }
public:
FakePointerController() :
- mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0) {
+ mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0), mX(0), mY(0),
+ mButtonState(0) {
}
void setBounds(float minX, float minY, float maxX, float maxY) {
@@ -65,6 +68,24 @@
mMaxY = maxY;
}
+ virtual void setPosition(float x, float y) {
+ mX = x;
+ mY = y;
+ }
+
+ virtual void setButtonState(int32_t buttonState) {
+ mButtonState = buttonState;
+ }
+
+ virtual int32_t getButtonState() const {
+ return mButtonState;
+ }
+
+ virtual void getPosition(float* outX, float* outY) const {
+ *outX = mX;
+ *outY = mY;
+ }
+
private:
virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const {
*outMinX = mMinX;
@@ -75,21 +96,12 @@
}
virtual void move(float deltaX, float deltaY) {
- }
-
- virtual void setButtonState(int32_t buttonState) {
- }
-
- virtual int32_t getButtonState() const {
- return 0;
- }
-
- virtual void setPosition(float x, float y) {
- }
-
- virtual void getPosition(float* outX, float* outY) const {
- *outX = 0;
- *outY = 0;
+ mX += deltaX;
+ if (mX < mMinX) mX = mMinX;
+ if (mX > mMaxX) mX = mMaxX;
+ mY += deltaY;
+ if (mY < mMinY) mY = mMinY;
+ if (mY > mMaxY) mY = mMaxY;
}
virtual void fade(Transition transition) {
@@ -186,221 +198,84 @@
};
-// --- FakeInputDispatcher ---
+// --- FakeInputListener ---
-class FakeInputDispatcher : public InputDispatcherInterface {
-public:
- struct NotifyConfigurationChangedArgs {
- NotifyConfigurationChangedArgs() : eventTime(0) { }
-
- nsecs_t eventTime;
- };
-
- struct NotifyKeyArgs {
- nsecs_t eventTime;
- int32_t deviceId;
- uint32_t source;
- uint32_t policyFlags;
- int32_t action;
- int32_t flags;
- int32_t keyCode;
- int32_t scanCode;
- int32_t metaState;
- nsecs_t downTime;
- };
-
- struct NotifyMotionArgs {
- nsecs_t eventTime;
- int32_t deviceId;
- uint32_t source;
- uint32_t policyFlags;
- int32_t action;
- int32_t flags;
- int32_t metaState;
- int32_t buttonState;
- int32_t edgeFlags;
- uint32_t pointerCount;
- Vector<PointerProperties> pointerProperties;
- Vector<PointerCoords> pointerCoords;
- float xPrecision;
- float yPrecision;
- nsecs_t downTime;
- };
-
- struct NotifySwitchArgs {
- nsecs_t when;
- int32_t switchCode;
- int32_t switchValue;
- uint32_t policyFlags;
- };
-
+class FakeInputListener : public InputListenerInterface {
private:
- List<NotifyConfigurationChangedArgs> mNotifyConfigurationChangedArgs;
- List<NotifyKeyArgs> mNotifyKeyArgs;
- List<NotifyMotionArgs> mNotifyMotionArgs;
- List<NotifySwitchArgs> mNotifySwitchArgs;
+ List<NotifyConfigurationChangedArgs> mNotifyConfigurationChangedArgsQueue;
+ List<NotifyKeyArgs> mNotifyKeyArgsQueue;
+ List<NotifyMotionArgs> mNotifyMotionArgsQueue;
+ List<NotifySwitchArgs> mNotifySwitchArgsQueue;
protected:
- virtual ~FakeInputDispatcher() { }
+ virtual ~FakeInputListener() { }
public:
- FakeInputDispatcher() {
+ FakeInputListener() {
}
- void assertNotifyConfigurationChangedWasCalled(NotifyConfigurationChangedArgs* outArgs = NULL) {
- ASSERT_FALSE(mNotifyConfigurationChangedArgs.empty())
+ void assertNotifyConfigurationChangedWasCalled(
+ NotifyConfigurationChangedArgs* outEventArgs = NULL) {
+ ASSERT_FALSE(mNotifyConfigurationChangedArgsQueue.empty())
<< "Expected notifyConfigurationChanged() to have been called.";
- if (outArgs) {
- *outArgs = *mNotifyConfigurationChangedArgs.begin();
+ if (outEventArgs) {
+ *outEventArgs = *mNotifyConfigurationChangedArgsQueue.begin();
}
- mNotifyConfigurationChangedArgs.erase(mNotifyConfigurationChangedArgs.begin());
+ mNotifyConfigurationChangedArgsQueue.erase(mNotifyConfigurationChangedArgsQueue.begin());
}
- void assertNotifyKeyWasCalled(NotifyKeyArgs* outArgs = NULL) {
- ASSERT_FALSE(mNotifyKeyArgs.empty())
+ void assertNotifyKeyWasCalled(NotifyKeyArgs* outEventArgs = NULL) {
+ ASSERT_FALSE(mNotifyKeyArgsQueue.empty())
<< "Expected notifyKey() to have been called.";
- if (outArgs) {
- *outArgs = *mNotifyKeyArgs.begin();
+ if (outEventArgs) {
+ *outEventArgs = *mNotifyKeyArgsQueue.begin();
}
- mNotifyKeyArgs.erase(mNotifyKeyArgs.begin());
+ mNotifyKeyArgsQueue.erase(mNotifyKeyArgsQueue.begin());
}
void assertNotifyKeyWasNotCalled() {
- ASSERT_TRUE(mNotifyKeyArgs.empty())
+ ASSERT_TRUE(mNotifyKeyArgsQueue.empty())
<< "Expected notifyKey() to not have been called.";
}
- void assertNotifyMotionWasCalled(NotifyMotionArgs* outArgs = NULL) {
- ASSERT_FALSE(mNotifyMotionArgs.empty())
+ void assertNotifyMotionWasCalled(NotifyMotionArgs* outEventArgs = NULL) {
+ ASSERT_FALSE(mNotifyMotionArgsQueue.empty())
<< "Expected notifyMotion() to have been called.";
- if (outArgs) {
- *outArgs = *mNotifyMotionArgs.begin();
+ if (outEventArgs) {
+ *outEventArgs = *mNotifyMotionArgsQueue.begin();
}
- mNotifyMotionArgs.erase(mNotifyMotionArgs.begin());
+ mNotifyMotionArgsQueue.erase(mNotifyMotionArgsQueue.begin());
}
void assertNotifyMotionWasNotCalled() {
- ASSERT_TRUE(mNotifyMotionArgs.empty())
+ ASSERT_TRUE(mNotifyMotionArgsQueue.empty())
<< "Expected notifyMotion() to not have been called.";
}
- void assertNotifySwitchWasCalled(NotifySwitchArgs* outArgs = NULL) {
- ASSERT_FALSE(mNotifySwitchArgs.empty())
+ void assertNotifySwitchWasCalled(NotifySwitchArgs* outEventArgs = NULL) {
+ ASSERT_FALSE(mNotifySwitchArgsQueue.empty())
<< "Expected notifySwitch() to have been called.";
- if (outArgs) {
- *outArgs = *mNotifySwitchArgs.begin();
+ if (outEventArgs) {
+ *outEventArgs = *mNotifySwitchArgsQueue.begin();
}
- mNotifySwitchArgs.erase(mNotifySwitchArgs.begin());
+ mNotifySwitchArgsQueue.erase(mNotifySwitchArgsQueue.begin());
}
private:
- virtual void notifyConfigurationChanged(nsecs_t eventTime) {
- NotifyConfigurationChangedArgs args;
- args.eventTime = eventTime;
- mNotifyConfigurationChangedArgs.push_back(args);
+ virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
+ mNotifyConfigurationChangedArgsQueue.push_back(*args);
}
- virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
- int32_t scanCode, int32_t metaState, nsecs_t downTime) {
- NotifyKeyArgs args;
- args.eventTime = eventTime;
- args.deviceId = deviceId;
- args.source = source;
- args.policyFlags = policyFlags;
- args.action = action;
- args.flags = flags;
- args.keyCode = keyCode;
- args.scanCode = scanCode;
- args.metaState = metaState;
- args.downTime = downTime;
- mNotifyKeyArgs.push_back(args);
+ virtual void notifyKey(const NotifyKeyArgs* args) {
+ mNotifyKeyArgsQueue.push_back(*args);
}
- virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t action, int32_t flags,
- int32_t metaState, int32_t buttonState, int32_t edgeFlags,
- uint32_t pointerCount, const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords,
- float xPrecision, float yPrecision, nsecs_t downTime) {
- NotifyMotionArgs args;
- args.eventTime = eventTime;
- args.deviceId = deviceId;
- args.source = source;
- args.policyFlags = policyFlags;
- args.action = action;
- args.flags = flags;
- args.metaState = metaState;
- args.buttonState = buttonState;
- args.edgeFlags = edgeFlags;
- args.pointerCount = pointerCount;
- args.pointerProperties.clear();
- args.pointerProperties.appendArray(pointerProperties, pointerCount);
- args.pointerCoords.clear();
- args.pointerCoords.appendArray(pointerCoords, pointerCount);
- args.xPrecision = xPrecision;
- args.yPrecision = yPrecision;
- args.downTime = downTime;
- mNotifyMotionArgs.push_back(args);
+ virtual void notifyMotion(const NotifyMotionArgs* args) {
+ mNotifyMotionArgsQueue.push_back(*args);
}
- virtual void notifySwitch(nsecs_t when,
- int32_t switchCode, int32_t switchValue, uint32_t policyFlags) {
- NotifySwitchArgs args;
- args.when = when;
- args.switchCode = switchCode;
- args.switchValue = switchValue;
- args.policyFlags = policyFlags;
- mNotifySwitchArgs.push_back(args);
- }
-
- virtual void dump(String8& dump) {
- ADD_FAILURE() << "Should never be called by input reader.";
- }
-
- virtual void dispatchOnce() {
- ADD_FAILURE() << "Should never be called by input reader.";
- }
-
- virtual int32_t injectInputEvent(const InputEvent* event,
- int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
- uint32_t policyFlags) {
- ADD_FAILURE() << "Should never be called by input reader.";
- return INPUT_EVENT_INJECTION_FAILED;
- }
-
- virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) {
- ADD_FAILURE() << "Should never be called by input reader.";
- }
-
- virtual void setFocusedApplication(
- const sp<InputApplicationHandle>& inputApplicationHandle) {
- ADD_FAILURE() << "Should never be called by input reader.";
- }
-
- virtual void setInputDispatchMode(bool enabled, bool frozen) {
- ADD_FAILURE() << "Should never be called by input reader.";
- }
-
- virtual void setInputFilterEnabled(bool enabled) {
- ADD_FAILURE() << "Should never be called by input reader.";
- }
-
- virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
- const sp<InputChannel>& toChannel) {
- ADD_FAILURE() << "Should never be called by input reader.";
- return 0;
- }
-
- virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel,
- const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
- ADD_FAILURE() << "Should never be called by input reader.";
- return 0;
- }
-
- virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) {
- ADD_FAILURE() << "Should never be called by input reader.";
- return 0;
+ virtual void notifySwitch(const NotifySwitchArgs* args) {
+ mNotifySwitchArgsQueue.push_back(*args);
}
};
@@ -551,6 +426,10 @@
event.value = value;
event.flags = flags;
mEvents.push_back(event);
+
+ if (type == EV_ABS) {
+ setAbsoluteAxisValue(deviceId, scanCode, value);
+ }
}
void assertQueueIsEmpty() {
@@ -765,15 +644,15 @@
class FakeInputReaderContext : public InputReaderContext {
sp<EventHubInterface> mEventHub;
sp<InputReaderPolicyInterface> mPolicy;
- sp<InputDispatcherInterface> mDispatcher;
+ sp<InputListenerInterface> mListener;
int32_t mGlobalMetaState;
bool mUpdateGlobalMetaStateWasCalled;
public:
FakeInputReaderContext(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
- const sp<InputDispatcherInterface>& dispatcher) :
- mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
+ const sp<InputListenerInterface>& listener) :
+ mEventHub(eventHub), mPolicy(policy), mListener(listener),
mGlobalMetaState(0) {
}
@@ -806,8 +685,8 @@
return mPolicy.get();
}
- virtual InputDispatcherInterface* getDispatcher() {
- return mDispatcher.get();
+ virtual InputListenerInterface* getListener() {
+ return mListener.get();
}
virtual void disableVirtualKeysUntil(nsecs_t time) {
@@ -969,8 +848,8 @@
public:
InstrumentedInputReader(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
- const sp<InputDispatcherInterface>& dispatcher) :
- InputReader(eventHub, policy, dispatcher),
+ const sp<InputListenerInterface>& listener) :
+ InputReader(eventHub, policy, listener),
mNextDevice(NULL) {
}
@@ -984,14 +863,19 @@
mNextDevice = device;
}
+ InputDevice* newDevice(int32_t deviceId, const String8& name) {
+ return new InputDevice(&mContext, deviceId, name);
+ }
+
protected:
- virtual InputDevice* createDevice(int32_t deviceId, const String8& name, uint32_t classes) {
+ virtual InputDevice* createDeviceLocked(int32_t deviceId,
+ const String8& name, uint32_t classes) {
if (mNextDevice) {
InputDevice* device = mNextDevice;
mNextDevice = NULL;
return device;
}
- return InputReader::createDevice(deviceId, name, classes);
+ return InputReader::createDeviceLocked(deviceId, name, classes);
}
friend class InputReaderTest;
@@ -1002,7 +886,7 @@
class InputReaderTest : public testing::Test {
protected:
- sp<FakeInputDispatcher> mFakeDispatcher;
+ sp<FakeInputListener> mFakeListener;
sp<FakeInputReaderPolicy> mFakePolicy;
sp<FakeEventHub> mFakeEventHub;
sp<InstrumentedInputReader> mReader;
@@ -1010,15 +894,15 @@
virtual void SetUp() {
mFakeEventHub = new FakeEventHub();
mFakePolicy = new FakeInputReaderPolicy();
- mFakeDispatcher = new FakeInputDispatcher();
+ mFakeListener = new FakeInputListener();
- mReader = new InstrumentedInputReader(mFakeEventHub, mFakePolicy, mFakeDispatcher);
+ mReader = new InstrumentedInputReader(mFakeEventHub, mFakePolicy, mFakeListener);
}
virtual void TearDown() {
mReader.clear();
- mFakeDispatcher.clear();
+ mFakeListener.clear();
mFakePolicy.clear();
mFakeEventHub.clear();
}
@@ -1038,7 +922,7 @@
FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId,
const String8& name, uint32_t classes, uint32_t sources,
const PropertyMap* configuration) {
- InputDevice* device = new InputDevice(mReader.get(), deviceId, name);
+ InputDevice* device = mReader->newDevice(deviceId, name);
FakeInputMapper* mapper = new FakeInputMapper(device, sources);
device->addMapper(mapper);
mReader->setNextDevice(device);
@@ -1304,8 +1188,9 @@
TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
addDevice(1, String8("ignored"), INPUT_DEVICE_CLASS_KEYBOARD, NULL);
- FakeInputDispatcher::NotifyConfigurationChangedArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyConfigurationChangedWasCalled(&args));
+ NotifyConfigurationChangedArgs args;
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(&args));
ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
}
@@ -1339,7 +1224,7 @@
sp<FakeEventHub> mFakeEventHub;
sp<FakeInputReaderPolicy> mFakePolicy;
- sp<FakeInputDispatcher> mFakeDispatcher;
+ sp<FakeInputListener> mFakeListener;
FakeInputReaderContext* mFakeContext;
InputDevice* mDevice;
@@ -1347,8 +1232,8 @@
virtual void SetUp() {
mFakeEventHub = new FakeEventHub();
mFakePolicy = new FakeInputReaderPolicy();
- mFakeDispatcher = new FakeInputDispatcher();
- mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeDispatcher);
+ mFakeListener = new FakeInputListener();
+ mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener);
mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME));
@@ -1358,7 +1243,7 @@
delete mDevice;
delete mFakeContext;
- mFakeDispatcher.clear();
+ mFakeListener.clear();
mFakePolicy.clear();
mFakeEventHub.clear();
}
@@ -1509,15 +1394,15 @@
sp<FakeEventHub> mFakeEventHub;
sp<FakeInputReaderPolicy> mFakePolicy;
- sp<FakeInputDispatcher> mFakeDispatcher;
+ sp<FakeInputListener> mFakeListener;
FakeInputReaderContext* mFakeContext;
InputDevice* mDevice;
virtual void SetUp() {
mFakeEventHub = new FakeEventHub();
mFakePolicy = new FakeInputReaderPolicy();
- mFakeDispatcher = new FakeInputDispatcher();
- mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeDispatcher);
+ mFakeListener = new FakeInputListener();
+ mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener);
mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME));
mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
@@ -1526,7 +1411,7 @@
virtual void TearDown() {
delete mDevice;
delete mFakeContext;
- mFakeDispatcher.clear();
+ mFakeListener.clear();
mFakePolicy.clear();
mFakeEventHub.clear();
}
@@ -1570,7 +1455,7 @@
static void assertPointerCoords(const PointerCoords& coords,
float x, float y, float pressure, float size,
float touchMajor, float touchMinor, float toolMajor, float toolMinor,
- float orientation) {
+ float orientation, float distance) {
ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), 1);
ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON);
@@ -1580,6 +1465,14 @@
ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), 1);
ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), 1);
ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON);
+ ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON);
+ }
+
+ static void assertPosition(const sp<FakePointerController>& controller, float x, float y) {
+ float actualX, actualY;
+ controller->getPosition(&actualX, &actualY);
+ ASSERT_NEAR(x, actualX, 1);
+ ASSERT_NEAR(y, actualY, 1);
}
};
@@ -1617,9 +1510,9 @@
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SW, SW_LID, 0, 1, 0);
- FakeInputDispatcher::NotifySwitchArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifySwitchWasCalled(&args));
- ASSERT_EQ(ARBITRARY_TIME, args.when);
+ NotifySwitchArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySwitchWasCalled(&args));
+ ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
ASSERT_EQ(SW_LID, args.switchCode);
ASSERT_EQ(1, args.switchValue);
ASSERT_EQ(uint32_t(0), args.policyFlags);
@@ -1636,16 +1529,16 @@
void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper* mapper,
int32_t originalScanCode, int32_t originalKeyCode, int32_t rotatedKeyCode) {
- FakeInputDispatcher::NotifyKeyArgs args;
+ NotifyKeyArgs args;
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, originalKeyCode, 1, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
ASSERT_EQ(originalScanCode, args.scanCode);
ASSERT_EQ(rotatedKeyCode, args.keyCode);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, originalKeyCode, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
ASSERT_EQ(originalScanCode, args.scanCode);
ASSERT_EQ(rotatedKeyCode, args.keyCode);
@@ -1668,8 +1561,8 @@
// Key down.
process(mapper, ARBITRARY_TIME, DEVICE_ID,
EV_KEY, KEY_HOME, AKEYCODE_HOME, 1, POLICY_FLAG_WAKE);
- FakeInputDispatcher::NotifyKeyArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ NotifyKeyArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
@@ -1684,7 +1577,7 @@
// Key up.
process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
EV_KEY, KEY_HOME, AKEYCODE_HOME, 0, POLICY_FLAG_WAKE);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
@@ -1705,16 +1598,16 @@
// Key down.
process(mapper, ARBITRARY_TIME, DEVICE_ID,
EV_KEY, KEY_HOME, AKEYCODE_HOME, 1, POLICY_FLAG_WAKE);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
// Key up.
process(mapper, ARBITRARY_TIME, DEVICE_ID,
EV_KEY, KEY_HOME, AKEYCODE_HOME, 0, POLICY_FLAG_WAKE);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
// Reset. Since no keys still down, should not synthesize any key ups.
mapper->reset();
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
}
TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreDown_SynthesizesKeyUps) {
@@ -1725,18 +1618,18 @@
// Metakey down.
process(mapper, ARBITRARY_TIME, DEVICE_ID,
EV_KEY, KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT, 1, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
// Key down.
process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
EV_KEY, KEY_A, AKEYCODE_A, 1, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
// Reset. Since two keys are still down, should synthesize two key ups in reverse order.
mapper->reset();
- FakeInputDispatcher::NotifyKeyArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ NotifyKeyArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
@@ -1747,7 +1640,7 @@
ASSERT_EQ(uint32_t(0), args.policyFlags);
ASSERT_EQ(ARBITRARY_TIME + 1, args.downTime);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
@@ -1759,7 +1652,7 @@
ASSERT_EQ(ARBITRARY_TIME + 1, args.downTime);
// And that's it.
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
}
TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
@@ -1773,8 +1666,8 @@
// Metakey down.
process(mapper, ARBITRARY_TIME, DEVICE_ID,
EV_KEY, KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT, 1, 0);
- FakeInputDispatcher::NotifyKeyArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ NotifyKeyArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled());
@@ -1782,21 +1675,21 @@
// Key down.
process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
EV_KEY, KEY_A, AKEYCODE_A, 1, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
// Key up.
process(mapper, ARBITRARY_TIME + 2, DEVICE_ID,
EV_KEY, KEY_A, AKEYCODE_A, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
// Metakey up.
process(mapper, ARBITRARY_TIME + 3, DEVICE_ID,
EV_KEY, KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AMETA_NONE, args.metaState);
ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled());
@@ -1876,13 +1769,13 @@
// Special case: if orientation changes while key is down, we still emit the same keycode
// in the key up as we did in the key down.
- FakeInputDispatcher::NotifyKeyArgs args;
+ NotifyKeyArgs args;
mFakePolicy->setDisplayInfo(DISPLAY_ID,
DISPLAY_WIDTH, DISPLAY_HEIGHT,
DISPLAY_ORIENTATION_270);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, AKEYCODE_DPAD_UP, 1, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
ASSERT_EQ(KEY_UP, args.scanCode);
ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
@@ -1891,7 +1784,7 @@
DISPLAY_WIDTH, DISPLAY_HEIGHT,
DISPLAY_ORIENTATION_180);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, AKEYCODE_DPAD_UP, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
ASSERT_EQ(KEY_UP, args.scanCode);
ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
@@ -2034,17 +1927,17 @@
void CursorInputMapperTest::testMotionRotation(CursorInputMapper* mapper,
int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY) {
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, originalX, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, originalY, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
float(rotatedX) / TRACKBALL_MOVEMENT_THRESHOLD,
float(rotatedY) / TRACKBALL_MOVEMENT_THRESHOLD,
- 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
}
TEST_F(CursorInputMapperTest, WhenModeIsPointer_GetSources_ReturnsMouse) {
@@ -2120,13 +2013,13 @@
mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
// Button press.
// Mostly testing non x/y behavior here so we don't need to check again elsewhere.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
@@ -2140,7 +2033,7 @@
ASSERT_EQ(0, args.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
ASSERT_EQ(ARBITRARY_TIME, args.downTime);
@@ -2148,7 +2041,7 @@
// Button release. Should have same down time.
process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
@@ -2162,7 +2055,7 @@
ASSERT_EQ(0, args.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
ASSERT_EQ(ARBITRARY_TIME, args.downTime);
@@ -2173,23 +2066,23 @@
addConfigurationProperty("cursor.mode", "navigation");
addMapperAndConfigure(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
// Motion in X but not Y.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
// Motion in Y but not X.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, -2, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 0.0f, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
}
TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) {
@@ -2197,23 +2090,23 @@
addConfigurationProperty("cursor.mode", "navigation");
addMapperAndConfigure(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
- // Button press without following sync.
+ // Button press.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
- // Button release without following sync.
+ // Button release.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
}
TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) {
@@ -2221,36 +2114,36 @@
addConfigurationProperty("cursor.mode", "navigation");
addMapperAndConfigure(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
// Combined X, Y and Button.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, -2, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
1.0f / TRACKBALL_MOVEMENT_THRESHOLD, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD,
- 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
// Move X, Y a bit while pressed.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 2, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
- 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
// Release Button.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
}
TEST_F(CursorInputMapperTest, Reset_WhenButtonIsNotDown_ShouldNotSynthesizeButtonUp) {
@@ -2258,22 +2151,24 @@
addConfigurationProperty("cursor.mode", "navigation");
addMapperAndConfigure(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
// Button press.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
// Button release.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
// Reset. Should not synthesize button up since button is not pressed.
mapper->reset();
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(CursorInputMapperTest, Reset_WhenButtonIsDown_ShouldSynthesizeButtonUp) {
@@ -2281,20 +2176,20 @@
addConfigurationProperty("cursor.mode", "navigation");
addMapperAndConfigure(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
// Button press.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
// Reset. Should synthesize button up.
mapper->reset();
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
}
TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateMotions) {
@@ -2366,6 +2261,203 @@
ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, -1));
}
+TEST_F(CursorInputMapperTest, Process_ShouldHandleAllButtons) {
+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+ addConfigurationProperty("cursor.mode", "pointer");
+ addMapperAndConfigure(mapper);
+
+ mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
+ mFakePointerController->setPosition(100, 200);
+ mFakePointerController->setButtonState(0);
+
+ NotifyMotionArgs motionArgs;
+ NotifyKeyArgs keyArgs;
+
+ // press BTN_LEFT, release BTN_LEFT
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_LEFT, 0, 1, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, mFakePointerController->getButtonState());
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_LEFT, 0, 0, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_RIGHT, 0, 1, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MIDDLE, 0, 1, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
+ motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
+ mFakePointerController->getButtonState());
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_RIGHT, 0, 0, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MIDDLE, 0, 0, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ // press BTN_BACK, release BTN_BACK
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_BACK, 0, 1, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_BACK, 0, 0, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+ // press BTN_SIDE, release BTN_SIDE
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_SIDE, 0, 1, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_SIDE, 0, 0, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+ // press BTN_FORWARD, release BTN_FORWARD
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_FORWARD, 0, 1, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_FORWARD, 0, 0, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+
+ // press BTN_EXTRA, release BTN_EXTRA
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_EXTRA, 0, 1, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_EXTRA, 0, 0, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+}
+
+TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerAround) {
+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+ addConfigurationProperty("cursor.mode", "pointer");
+ addMapperAndConfigure(mapper);
+
+ mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
+ mFakePointerController->setPosition(100, 200);
+ mFakePointerController->setButtonState(0);
+
+ NotifyMotionArgs args;
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 10, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, 20, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+ 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
+}
+
// --- TouchInputMapperTest ---
@@ -2383,8 +2475,12 @@
static const int32_t RAW_PRESSURE_MAX;
static const int32_t RAW_ORIENTATION_MIN;
static const int32_t RAW_ORIENTATION_MAX;
+ static const int32_t RAW_DISTANCE_MIN;
+ static const int32_t RAW_DISTANCE_MAX;
static const int32_t RAW_ID_MIN;
static const int32_t RAW_ID_MAX;
+ static const int32_t RAW_SLOT_MIN;
+ static const int32_t RAW_SLOT_MAX;
static const float X_PRECISION;
static const float Y_PRECISION;
@@ -2398,6 +2494,9 @@
ORIENTATION = 1 << 4,
MINOR = 1 << 5,
ID = 1 << 6,
+ DISTANCE = 1 << 7,
+ SLOT = 1 << 8,
+ TOOL_TYPE = 1 << 9,
};
void prepareDisplay(int32_t orientation);
@@ -2420,8 +2519,12 @@
const int32_t TouchInputMapperTest::RAW_PRESSURE_MAX = RAW_TOUCH_MAX;
const int32_t TouchInputMapperTest::RAW_ORIENTATION_MIN = -7;
const int32_t TouchInputMapperTest::RAW_ORIENTATION_MAX = 7;
+const int32_t TouchInputMapperTest::RAW_DISTANCE_MIN = 0;
+const int32_t TouchInputMapperTest::RAW_DISTANCE_MAX = 7;
const int32_t TouchInputMapperTest::RAW_ID_MIN = 0;
const int32_t TouchInputMapperTest::RAW_ID_MAX = 9;
+const int32_t TouchInputMapperTest::RAW_SLOT_MIN = 0;
+const int32_t TouchInputMapperTest::RAW_SLOT_MAX = 9;
const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH;
const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT;
@@ -2470,6 +2573,8 @@
void processUp(SingleTouchInputMapper* mappery);
void processPressure(SingleTouchInputMapper* mapper, int32_t pressure);
void processToolMajor(SingleTouchInputMapper* mapper, int32_t toolMajor);
+ void processDistance(SingleTouchInputMapper* mapper, int32_t distance);
+ void processKey(SingleTouchInputMapper* mapper, int32_t code, int32_t value);
void processSync(SingleTouchInputMapper* mapper);
};
@@ -2492,6 +2597,10 @@
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TOOL_WIDTH,
RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
}
+ if (axes & DISTANCE) {
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_DISTANCE,
+ RAW_DISTANCE_MIN, RAW_DISTANCE_MAX, 0, 0);
+ }
}
void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y) {
@@ -2519,6 +2628,16 @@
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TOOL_WIDTH, 0, toolMajor, 0);
}
+void SingleTouchInputMapperTest::processDistance(
+ SingleTouchInputMapper* mapper, int32_t distance) {
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_DISTANCE, 0, distance, 0);
+}
+
+void SingleTouchInputMapperTest::processKey(
+ SingleTouchInputMapper* mapper, int32_t code, int32_t value) {
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, code, 0, value, 0);
+}
+
void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper* mapper) {
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
}
@@ -2581,14 +2700,14 @@
int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
// Virtual key is up.
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
ASSERT_EQ(AKEY_STATE_UP, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
}
@@ -2610,14 +2729,14 @@
int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
// Virtual key is up.
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
ASSERT_EQ(AKEY_STATE_UP, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
}
@@ -2656,13 +2775,13 @@
int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
// Reset. Since key is down, synthesize key up.
mapper->reset();
- FakeInputDispatcher::NotifyKeyArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ NotifyKeyArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
//ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
@@ -2689,18 +2808,18 @@
int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
// Release virtual key.
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
// Reset. Since no key is down, nothing happens.
mapper->reset();
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
@@ -2714,7 +2833,7 @@
mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
- FakeInputDispatcher::NotifyKeyArgs args;
+ NotifyKeyArgs args;
// Press virtual key.
int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
@@ -2722,7 +2841,7 @@
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
@@ -2738,7 +2857,7 @@
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
@@ -2751,7 +2870,7 @@
ASSERT_EQ(ARBITRARY_TIME, args.downTime);
// Should not have sent any motions.
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
}
TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) {
@@ -2765,7 +2884,7 @@
mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
- FakeInputDispatcher::NotifyKeyArgs keyArgs;
+ NotifyKeyArgs keyArgs;
// Press virtual key.
int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
@@ -2773,7 +2892,7 @@
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
@@ -2791,7 +2910,7 @@
processMove(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
@@ -2804,8 +2923,8 @@
ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
- FakeInputDispatcher::NotifyMotionArgs motionArgs;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ NotifyMotionArgs motionArgs;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -2819,7 +2938,7 @@
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -2829,7 +2948,7 @@
processMove(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -2843,7 +2962,7 @@
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -2852,7 +2971,7 @@
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -2866,14 +2985,14 @@
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
// Should not have sent any more keys or motions.
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) {
@@ -2887,7 +3006,7 @@
mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
- FakeInputDispatcher::NotifyMotionArgs motionArgs;
+ NotifyMotionArgs motionArgs;
// Initially go down out of bounds.
int32_t x = -10;
@@ -2895,7 +3014,7 @@
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
// Move into the display area. Should generate a pointer down.
x = 50;
@@ -2903,7 +3022,7 @@
processMove(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -2917,7 +3036,7 @@
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -2926,7 +3045,7 @@
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -2940,14 +3059,14 @@
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
// Should not have sent any more keys or motions.
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
@@ -2961,7 +3080,7 @@
mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
- FakeInputDispatcher::NotifyMotionArgs motionArgs;
+ NotifyMotionArgs motionArgs;
// Down.
int32_t x = 100;
@@ -2969,7 +3088,7 @@
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -2983,7 +3102,7 @@
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -2994,7 +3113,7 @@
processMove(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3008,7 +3127,7 @@
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -3017,7 +3136,7 @@
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3031,14 +3150,14 @@
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
// Should not have sent any more keys or motions.
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_DoesNotRotateMotions) {
@@ -3049,20 +3168,20 @@
addConfigurationProperty("touch.orientationAware", "0");
addMapperAndConfigure(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
// Rotation 90.
prepareDisplay(DISPLAY_ORIENTATION_90);
processDown(mapper, toRawX(50), toRawY(75));
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
}
TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions) {
@@ -3072,59 +3191,59 @@
prepareAxes(POSITION);
addMapperAndConfigure(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
// Rotation 0.
prepareDisplay(DISPLAY_ORIENTATION_0);
processDown(mapper, toRawX(50), toRawY(75));
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
// Rotation 90.
prepareDisplay(DISPLAY_ORIENTATION_90);
processDown(mapper, RAW_X_MAX - toRawX(75) + RAW_X_MIN, toRawY(50));
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
// Rotation 180.
prepareDisplay(DISPLAY_ORIENTATION_180);
processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
// Rotation 270.
prepareDisplay(DISPLAY_ORIENTATION_270);
processDown(mapper, toRawX(75), RAW_Y_MAX - toRawY(50) + RAW_Y_MIN);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
}
TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
@@ -3132,7 +3251,7 @@
addConfigurationProperty("touch.deviceType", "touchScreen");
prepareDisplay(DISPLAY_ORIENTATION_0);
prepareButtons();
- prepareAxes(POSITION | PRESSURE | TOOL);
+ prepareAxes(POSITION | PRESSURE | TOOL | DISTANCE);
addMapperAndConfigure(mapper);
// These calculations are based on the input device calibration documentation.
@@ -3140,6 +3259,7 @@
int32_t rawY = 200;
int32_t rawPressure = 10;
int32_t rawToolMajor = 12;
+ int32_t rawDistance = 0;
float x = toDisplayX(rawX);
float y = toDisplayY(rawY);
@@ -3147,16 +3267,388 @@
float size = float(rawToolMajor) / RAW_TOOL_MAX;
float tool = min(DISPLAY_WIDTH, DISPLAY_HEIGHT) * size;
float touch = min(tool * pressure, tool);
+ float distance = float(rawDistance);
processDown(mapper, rawX, rawY);
processPressure(mapper, rawPressure);
processToolMajor(mapper, rawToolMajor);
+ processDistance(mapper, rawDistance);
processSync(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ NotifyMotionArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- x, y, pressure, size, touch, touch, tool, tool, 0));
+ x, y, pressure, size, touch, touch, tool, tool, 0, distance));
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) {
+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareButtons();
+ prepareAxes(POSITION);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+ NotifyKeyArgs keyArgs;
+
+ processDown(mapper, 100, 200);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(0, motionArgs.buttonState);
+
+ // press BTN_LEFT, release BTN_LEFT
+ processKey(mapper, BTN_LEFT, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
+
+ processKey(mapper, BTN_LEFT, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
+ processKey(mapper, BTN_RIGHT, 1);
+ processKey(mapper, BTN_MIDDLE, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
+ motionArgs.buttonState);
+
+ processKey(mapper, BTN_RIGHT, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_MIDDLE, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // press BTN_BACK, release BTN_BACK
+ processKey(mapper, BTN_BACK, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_BACK, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+ // press BTN_SIDE, release BTN_SIDE
+ processKey(mapper, BTN_SIDE, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_SIDE, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+ // press BTN_FORWARD, release BTN_FORWARD
+ processKey(mapper, BTN_FORWARD, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_FORWARD, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+
+ // press BTN_EXTRA, release BTN_EXTRA
+ processKey(mapper, BTN_EXTRA, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_EXTRA, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+
+ // press BTN_STYLUS, release BTN_STYLUS
+ processKey(mapper, BTN_STYLUS, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY, motionArgs.buttonState);
+
+ processKey(mapper, BTN_STYLUS, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // press BTN_STYLUS2, release BTN_STYLUS2
+ processKey(mapper, BTN_STYLUS2, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
+
+ processKey(mapper, BTN_STYLUS2, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // release touch
+ processUp(mapper);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_EQ(0, motionArgs.buttonState);
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareButtons();
+ prepareAxes(POSITION);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+
+ // default tool type is finger
+ processDown(mapper, 100, 200);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // eraser
+ processKey(mapper, BTN_TOOL_RUBBER, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+
+ // stylus
+ processKey(mapper, BTN_TOOL_RUBBER, 0);
+ processKey(mapper, BTN_TOOL_PEN, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+ // finger
+ processKey(mapper, BTN_TOOL_PEN, 0);
+ processKey(mapper, BTN_TOOL_FINGER, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // stylus trumps finger
+ processKey(mapper, BTN_TOOL_PEN, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+ // eraser trumps stylus
+ processKey(mapper, BTN_TOOL_RUBBER, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+
+ // back to default tool type
+ processKey(mapper, BTN_TOOL_RUBBER, 0);
+ processKey(mapper, BTN_TOOL_PEN, 0);
+ processKey(mapper, BTN_TOOL_FINGER, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareButtons();
+ prepareAxes(POSITION);
+ mFakeEventHub->addKey(DEVICE_ID, BTN_TOOL_FINGER, AKEYCODE_UNKNOWN, 0);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+
+ // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
+ processKey(mapper, BTN_TOOL_FINGER, 1);
+ processMove(mapper, 100, 200);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ // move a little
+ processMove(mapper, 150, 250);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ // down when BTN_TOUCH is pressed, pressure defaults to 1
+ processKey(mapper, BTN_TOUCH, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // up when BTN_TOUCH is released, hover restored
+ processKey(mapper, BTN_TOUCH, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ // exit hover when pointer goes away
+ processKey(mapper, BTN_TOOL_FINGER, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenAbsDistanceIsPresent_HoversIfItsValueIsGreaterThanZero) {
+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareButtons();
+ prepareAxes(POSITION | DISTANCE);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+
+ // initially hovering because distance is 1, pressure defaults to 0
+ processDown(mapper, 100, 200);
+ processDistance(mapper, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ // move a little
+ processMove(mapper, 150, 250);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ // down when distance goes to 0, pressure defaults to 1
+ processDistance(mapper, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // up when distance goes to 1, hover restored
+ processDistance(mapper, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ // exit hover when pointer goes away
+ processUp(mapper);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
}
@@ -3173,7 +3665,11 @@
void processToolMinor(MultiTouchInputMapper* mapper, int32_t toolMinor);
void processOrientation(MultiTouchInputMapper* mapper, int32_t orientation);
void processPressure(MultiTouchInputMapper* mapper, int32_t pressure);
+ void processDistance(MultiTouchInputMapper* mapper, int32_t distance);
void processId(MultiTouchInputMapper* mapper, int32_t id);
+ void processSlot(MultiTouchInputMapper* mapper, int32_t slot);
+ void processToolType(MultiTouchInputMapper* mapper, int32_t toolType);
+ void processKey(MultiTouchInputMapper* mapper, int32_t code, int32_t value);
void processMTSync(MultiTouchInputMapper* mapper);
void processSync(MultiTouchInputMapper* mapper);
};
@@ -3209,10 +3705,23 @@
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_PRESSURE,
RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
}
+ if (axes & DISTANCE) {
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_DISTANCE,
+ RAW_DISTANCE_MIN, RAW_DISTANCE_MAX, 0, 0);
+ }
if (axes & ID) {
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TRACKING_ID,
RAW_ID_MIN, RAW_ID_MAX, 0, 0);
}
+ if (axes & SLOT) {
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_SLOT,
+ RAW_SLOT_MIN, RAW_SLOT_MAX, 0, 0);
+ mFakeEventHub->setAbsoluteAxisValue(DEVICE_ID, ABS_MT_SLOT, 0);
+ }
+ if (axes & TOOL_TYPE) {
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOOL_TYPE,
+ 0, MT_TOOL_MAX, 0, 0);
+ }
}
void MultiTouchInputMapperTest::processPosition(
@@ -3251,11 +3760,31 @@
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_PRESSURE, 0, pressure, 0);
}
+void MultiTouchInputMapperTest::processDistance(
+ MultiTouchInputMapper* mapper, int32_t distance) {
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_DISTANCE, 0, distance, 0);
+}
+
void MultiTouchInputMapperTest::processId(
MultiTouchInputMapper* mapper, int32_t id) {
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TRACKING_ID, 0, id, 0);
}
+void MultiTouchInputMapperTest::processSlot(
+ MultiTouchInputMapper* mapper, int32_t slot) {
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_SLOT, 0, slot, 0);
+}
+
+void MultiTouchInputMapperTest::processToolType(
+ MultiTouchInputMapper* mapper, int32_t toolType) {
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOOL_TYPE, 0, toolType, 0);
+}
+
+void MultiTouchInputMapperTest::processKey(
+ MultiTouchInputMapper* mapper, int32_t code, int32_t value) {
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, code, 0, value, 0);
+}
+
void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper* mapper) {
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_MT_REPORT, 0, 0, 0);
}
@@ -3275,7 +3804,7 @@
mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
- FakeInputDispatcher::NotifyMotionArgs motionArgs;
+ NotifyMotionArgs motionArgs;
// Two fingers down at once.
int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
@@ -3285,7 +3814,7 @@
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3299,12 +3828,12 @@
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3321,9 +3850,9 @@
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -3336,7 +3865,7 @@
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3352,9 +3881,9 @@
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -3365,7 +3894,7 @@
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3382,14 +3911,14 @@
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3403,7 +3932,7 @@
ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -3414,7 +3943,7 @@
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3428,7 +3957,7 @@
ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -3441,7 +3970,7 @@
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3458,9 +3987,9 @@
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -3471,7 +4000,7 @@
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3488,14 +4017,14 @@
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3509,7 +4038,7 @@
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -3518,7 +4047,7 @@
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3532,14 +4061,14 @@
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
// Should not have sent any more keys or motions.
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
@@ -3552,7 +4081,7 @@
mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
- FakeInputDispatcher::NotifyMotionArgs motionArgs;
+ NotifyMotionArgs motionArgs;
// Two fingers down at once.
int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
@@ -3564,15 +4093,15 @@
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
@@ -3581,9 +4110,9 @@
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
// Move.
x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
@@ -3595,7 +4124,7 @@
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
@@ -3603,9 +4132,9 @@
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
// First finger up.
x2 += 15; y2 -= 20;
@@ -3614,7 +4143,7 @@
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
@@ -3623,17 +4152,17 @@
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
// Move.
x2 += 20; y2 -= 25;
@@ -3642,13 +4171,13 @@
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
// New finger down.
int32_t x3 = 700, y3 = 300;
@@ -3660,7 +4189,7 @@
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
@@ -3669,9 +4198,9 @@
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
// Second finger up.
x3 += 30; y3 -= 20;
@@ -3680,7 +4209,7 @@
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
@@ -3689,40 +4218,211 @@
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
// Last finger up.
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
// Should not have sent any more keys or motions.
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithSlots) {
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareAxes(POSITION | ID | SLOT);
+ prepareVirtualKeys();
+ addMapperAndConfigure(mapper);
+
+ mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+ NotifyMotionArgs motionArgs;
+
+ // Two fingers down at once.
+ int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
+ processPosition(mapper, x1, y1);
+ processId(mapper, 1);
+ processSlot(mapper, 1);
+ processPosition(mapper, x2, y2);
+ processId(mapper, 2);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ motionArgs.action);
+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // Move.
+ x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
+ processSlot(mapper, 0);
+ processPosition(mapper, x1, y1);
+ processSlot(mapper, 1);
+ processPosition(mapper, x2, y2);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // First finger up.
+ x2 += 15; y2 -= 20;
+ processSlot(mapper, 0);
+ processId(mapper, -1);
+ processSlot(mapper, 1);
+ processPosition(mapper, x2, y2);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ motionArgs.action);
+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+ ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // Move.
+ x2 += 20; y2 -= 25;
+ processPosition(mapper, x2, y2);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+ ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // New finger down.
+ int32_t x3 = 700, y3 = 300;
+ processPosition(mapper, x2, y2);
+ processSlot(mapper, 0);
+ processId(mapper, 3);
+ processPosition(mapper, x3, y3);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ motionArgs.action);
+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // Second finger up.
+ x3 += 30; y3 -= 20;
+ processSlot(mapper, 1);
+ processId(mapper, -1);
+ processSlot(mapper, 0);
+ processPosition(mapper, x3, y3);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ motionArgs.action);
+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // Last finger up.
+ processId(mapper, -1);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // Should not have sent any more keys or motions.
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
addConfigurationProperty("touch.deviceType", "touchScreen");
prepareDisplay(DISPLAY_ORIENTATION_0);
- prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR);
+ prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR | DISTANCE);
addMapperAndConfigure(mapper);
// These calculations are based on the input device calibration documentation.
@@ -3733,6 +4433,7 @@
int32_t rawToolMajor = 9;
int32_t rawToolMinor = 8;
int32_t rawPressure = 11;
+ int32_t rawDistance = 0;
int32_t rawOrientation = 3;
int32_t id = 5;
@@ -3745,6 +4446,7 @@
float touchMajor = min(toolMajor * pressure, toolMajor);
float touchMinor = min(toolMinor * pressure, toolMinor);
float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2;
+ float distance = float(rawDistance);
processPosition(mapper, rawX, rawY);
processTouchMajor(mapper, rawTouchMajor);
@@ -3753,15 +4455,16 @@
processToolMinor(mapper, rawToolMinor);
processPressure(mapper, rawPressure);
processOrientation(mapper, rawOrientation);
+ processDistance(mapper, rawDistance);
processId(mapper, id);
processMTSync(mapper);
processSync(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ NotifyMotionArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(0, args.pointerProperties[0].id);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, orientation));
+ x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, orientation, distance));
}
TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) {
@@ -3800,10 +4503,10 @@
processMTSync(mapper);
processSync(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ NotifyMotionArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, 0));
+ x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, 0, 0));
}
TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_SummedLinearCalibration) {
@@ -3850,18 +4553,18 @@
processMTSync(mapper);
processSync(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ NotifyMotionArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
args.action);
ASSERT_EQ(size_t(2), args.pointerCount);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- x, y, pressure, size, touch, touch, tool, tool, 0));
+ x, y, pressure, size, touch, touch, tool, tool, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1],
- x2, y2, pressure, size, touch, touch, tool, tool, 0));
+ x2, y2, pressure, size, touch, touch, tool, tool, 0, 0));
}
TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_AreaCalibration) {
@@ -3899,10 +4602,395 @@
processMTSync(mapper);
processSync(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ NotifyMotionArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- x, y, pressure, size, touch, touch, tool, tool, 0));
+ x, y, pressure, size, touch, touch, tool, tool, 0, 0));
}
+TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllButtons) {
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareAxes(POSITION | ID | SLOT);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+ NotifyKeyArgs keyArgs;
+
+ processId(mapper, 1);
+ processPosition(mapper, 100, 200);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(0, motionArgs.buttonState);
+
+ // press BTN_LEFT, release BTN_LEFT
+ processKey(mapper, BTN_LEFT, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
+
+ processKey(mapper, BTN_LEFT, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
+ processKey(mapper, BTN_RIGHT, 1);
+ processKey(mapper, BTN_MIDDLE, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
+ motionArgs.buttonState);
+
+ processKey(mapper, BTN_RIGHT, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_MIDDLE, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // press BTN_BACK, release BTN_BACK
+ processKey(mapper, BTN_BACK, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_BACK, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+ // press BTN_SIDE, release BTN_SIDE
+ processKey(mapper, BTN_SIDE, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_SIDE, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+ // press BTN_FORWARD, release BTN_FORWARD
+ processKey(mapper, BTN_FORWARD, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_FORWARD, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+
+ // press BTN_EXTRA, release BTN_EXTRA
+ processKey(mapper, BTN_EXTRA, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_EXTRA, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+
+ // press BTN_STYLUS, release BTN_STYLUS
+ processKey(mapper, BTN_STYLUS, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY, motionArgs.buttonState);
+
+ processKey(mapper, BTN_STYLUS, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // press BTN_STYLUS2, release BTN_STYLUS2
+ processKey(mapper, BTN_STYLUS2, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
+
+ processKey(mapper, BTN_STYLUS2, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // release touch
+ processId(mapper, -1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_EQ(0, motionArgs.buttonState);
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+
+ // default tool type is finger
+ processId(mapper, 1);
+ processPosition(mapper, 100, 200);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // eraser
+ processKey(mapper, BTN_TOOL_RUBBER, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+
+ // stylus
+ processKey(mapper, BTN_TOOL_RUBBER, 0);
+ processKey(mapper, BTN_TOOL_PEN, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+ // finger
+ processKey(mapper, BTN_TOOL_PEN, 0);
+ processKey(mapper, BTN_TOOL_FINGER, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // stylus trumps finger
+ processKey(mapper, BTN_TOOL_PEN, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+ // eraser trumps stylus
+ processKey(mapper, BTN_TOOL_RUBBER, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+
+ // MT tool type trumps BTN tool types: MT_TOOL_FINGER
+ processToolType(mapper, MT_TOOL_FINGER); // this is the first time we send MT_TOOL_TYPE
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // MT tool type trumps BTN tool types: MT_TOOL_PEN
+ processToolType(mapper, MT_TOOL_PEN);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+ // back to default tool type
+ processToolType(mapper, -1); // use a deliberately undefined tool type, for testing
+ processKey(mapper, BTN_TOOL_RUBBER, 0);
+ processKey(mapper, BTN_TOOL_PEN, 0);
+ processKey(mapper, BTN_TOOL_FINGER, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareAxes(POSITION | ID | SLOT);
+ mFakeEventHub->addKey(DEVICE_ID, BTN_TOUCH, AKEYCODE_UNKNOWN, 0);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+
+ // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
+ processId(mapper, 1);
+ processPosition(mapper, 100, 200);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ // move a little
+ processPosition(mapper, 150, 250);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ // down when BTN_TOUCH is pressed, pressure defaults to 1
+ processKey(mapper, BTN_TOUCH, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // up when BTN_TOUCH is released, hover restored
+ processKey(mapper, BTN_TOUCH, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ // exit hover when pointer goes away
+ processId(mapper, -1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTDistanceIsPresent_HoversIfItsValueIsGreaterThanZero) {
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareAxes(POSITION | ID | SLOT | DISTANCE);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+
+ // initially hovering because distance is 1, pressure defaults to 0
+ processId(mapper, 1);
+ processPosition(mapper, 100, 200);
+ processDistance(mapper, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ // move a little
+ processPosition(mapper, 150, 250);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ // down when distance goes to 0, pressure defaults to 1
+ processDistance(mapper, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // up when distance goes to 1, hover restored
+ processDistance(mapper, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ // exit hover when pointer goes away
+ processId(mapper, -1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+}
+
+
} // namespace android
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index bdd8938..2e3d6dd 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -129,6 +129,7 @@
class BackupManagerService extends IBackupManager.Stub {
private static final String TAG = "BackupManagerService";
private static final boolean DEBUG = true;
+ private static final boolean MORE_DEBUG = false;
// Name and current contents version of the full-backup manifest file
static final String BACKUP_MANIFEST_FILENAME = "_manifest";
@@ -851,10 +852,10 @@
info = mPackageManager.getPackageInfo(pkg, 0);
mEverStoredApps.add(pkg);
temp.writeUTF(pkg);
- if (DEBUG) Slog.v(TAG, " + " + pkg);
+ if (MORE_DEBUG) Slog.v(TAG, " + " + pkg);
} catch (NameNotFoundException e) {
// nope, this package was uninstalled; don't include it
- if (DEBUG) Slog.v(TAG, " - " + pkg);
+ if (MORE_DEBUG) Slog.v(TAG, " - " + pkg);
}
}
} catch (EOFException e) {
@@ -1246,7 +1247,7 @@
private void addPackageParticipantsLockedInner(String packageName,
List<PackageInfo> targetPkgs) {
- if (DEBUG) {
+ if (MORE_DEBUG) {
Slog.v(TAG, "Adding " + targetPkgs.size() + " backup participants:");
for (PackageInfo p : targetPkgs) {
Slog.v(TAG, " " + p + " agent=" + p.applicationInfo.backupAgentName
@@ -1296,7 +1297,7 @@
private void removePackageParticipantsLockedInner(String packageName,
List<String> allPackageNames) {
- if (DEBUG) {
+ if (MORE_DEBUG) {
Slog.v(TAG, "removePackageParticipantsLockedInner (" + packageName
+ ") removing " + allPackageNames.size() + " entries");
for (String p : allPackageNames) {
@@ -1320,7 +1321,7 @@
// We can't just remove(app) because the instances are different.
for (ApplicationInfo entry: set) {
if (entry.packageName.equals(pkg)) {
- if (DEBUG) Slog.v(TAG, " removing participant " + pkg);
+ if (MORE_DEBUG) Slog.v(TAG, " removing participant " + pkg);
set.remove(entry);
removeEverBackedUp(pkg);
break;
@@ -1403,7 +1404,8 @@
// Remove our awareness of having ever backed up the given package
void removeEverBackedUp(String packageName) {
- if (DEBUG) Slog.v(TAG, "Removing backed-up knowledge of " + packageName + ", new set:");
+ if (DEBUG) Slog.v(TAG, "Removing backed-up knowledge of " + packageName);
+ if (MORE_DEBUG) Slog.v(TAG, "New set:");
synchronized (mEverStoredApps) {
// Rewrite the file and rename to overwrite. If we reboot in the middle,
@@ -1416,7 +1418,7 @@
mEverStoredApps.remove(packageName);
for (String s : mEverStoredApps) {
known.writeUTF(s);
- if (DEBUG) Slog.v(TAG, " " + s);
+ if (MORE_DEBUG) Slog.v(TAG, " " + s);
}
known.close();
known = null;
@@ -1460,7 +1462,7 @@
if (DEBUG) Slog.v(TAG, "Ancestral packages: " + mAncestralPackages.size());
for (String pkgName : mAncestralPackages) {
af.writeUTF(pkgName);
- if (DEBUG) Slog.v(TAG, " " + pkgName);
+ if (MORE_DEBUG) Slog.v(TAG, " " + pkgName);
}
}
af.close();
@@ -1523,7 +1525,7 @@
try {
PackageInfo info = mPackageManager.getPackageInfo(packageName, 0);
if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) == 0) {
- if (DEBUG) Slog.i(TAG, "allowClearUserData=false so not wiping "
+ if (MORE_DEBUG) Slog.i(TAG, "allowClearUserData=false so not wiping "
+ packageName);
return;
}
@@ -1593,13 +1595,13 @@
}
}
mBackupHandler.removeMessages(MSG_TIMEOUT);
- if (DEBUG) Slog.v(TAG, "operation " + Integer.toHexString(token)
+ if (MORE_DEBUG) Slog.v(TAG, "operation " + Integer.toHexString(token)
+ " complete: finalState=" + finalState);
return finalState == OP_ACKNOWLEDGED;
}
void prepareOperationTimeout(int token, long interval) {
- if (DEBUG) Slog.v(TAG, "starting timeout: token=" + Integer.toHexString(token)
+ if (MORE_DEBUG) Slog.v(TAG, "starting timeout: token=" + Integer.toHexString(token)
+ " interval=" + interval);
synchronized (mCurrentOpLock) {
mCurrentOperations.put(token, OP_PENDING);
@@ -1937,7 +1939,7 @@
BackupDataOutput output = new BackupDataOutput(
mPipe.getFileDescriptor());
- if (DEBUG) Slog.d(TAG, "Writing manifest for " + mPackage.packageName);
+ if (MORE_DEBUG) Slog.d(TAG, "Writing manifest for " + mPackage.packageName);
writeAppManifest(mPackage, mManifestFile, mSendApk);
FullBackup.backupToTar(mPackage.packageName, null, null,
mFilesDir.getAbsolutePath(),
@@ -1948,7 +1950,7 @@
writeApkToBackup(mPackage, output);
}
- if (DEBUG) Slog.d(TAG, "Calling doFullBackup()");
+ if (DEBUG) Slog.d(TAG, "Calling doFullBackup() on " + mPackage.packageName);
prepareOperationTimeout(mToken, TIMEOUT_FULL_BACKUP_INTERVAL);
mAgent.doFullBackup(mPipe, mToken, mBackupManagerBinder);
} catch (IOException e) {
@@ -2285,7 +2287,7 @@
// check for .obb and save those too
final File obbDir = Environment.getExternalStorageAppObbDirectory(pkg.packageName);
if (obbDir != null) {
- if (DEBUG) Log.i(TAG, "obb dir: " + obbDir.getAbsolutePath());
+ if (MORE_DEBUG) Log.i(TAG, "obb dir: " + obbDir.getAbsolutePath());
File[] obbFiles = obbDir.listFiles();
if (obbFiles != null) {
final String obbDirName = obbDir.getAbsolutePath();
@@ -2374,10 +2376,10 @@
// The agent was running with a stub Application object, so shut it down.
if (app.uid != Process.SYSTEM_UID
&& app.uid != Process.PHONE_UID) {
- if (DEBUG) Slog.d(TAG, "Backup complete, killing host process");
+ if (MORE_DEBUG) Slog.d(TAG, "Backup complete, killing host process");
mActivityManager.killApplicationProcess(app.processName, app.uid);
} else {
- if (DEBUG) Slog.d(TAG, "Not killing after restore: " + app.processName);
+ if (MORE_DEBUG) Slog.d(TAG, "Not killing after restore: " + app.processName);
}
} catch (RemoteException e) {
Slog.d(TAG, "Lost app trying to shut down");
@@ -2600,7 +2602,7 @@
didRestore = restoreOneFile(in, buffer);
} while (didRestore);
- if (DEBUG) Slog.v(TAG, "Done consuming input tarfile, total bytes=" + mBytes);
+ if (MORE_DEBUG) Slog.v(TAG, "Done consuming input tarfile, total bytes=" + mBytes);
} catch (IOException e) {
Slog.e(TAG, "Unable to read restore input");
} finally {
@@ -2624,7 +2626,7 @@
}
sendEndRestore();
mWakelock.release();
- if (DEBUG) Slog.d(TAG, "Full restore pass complete.");
+ Slog.d(TAG, "Full restore pass complete.");
}
}
@@ -2722,7 +2724,7 @@
try {
info = readTarHeaders(instream);
if (info != null) {
- if (DEBUG) {
+ if (MORE_DEBUG) {
dumpFileMetadata(info);
}
@@ -2910,7 +2912,6 @@
boolean pipeOkay = true;
FileOutputStream pipe = new FileOutputStream(
mPipes[1].getFileDescriptor());
- if (DEBUG) Slog.d(TAG, "Piping data to agent");
while (toCopy > 0) {
int toRead = (toCopy > buffer.length)
? buffer.length : (int)toCopy;
@@ -3629,7 +3630,7 @@
// Allow unsigned apps, but not signed on one device and unsigned on the other
// !!! TODO: is this the right policy?
Signature[] deviceSigs = target.signatures;
- if (DEBUG) Slog.v(TAG, "signaturesMatch(): stored=" + storedSigs
+ if (MORE_DEBUG) Slog.v(TAG, "signaturesMatch(): stored=" + storedSigs
+ " device=" + deviceSigs);
if ((storedSigs == null || storedSigs.length == 0)
&& (deviceSigs == null || deviceSigs.length == 0)) {
@@ -4189,7 +4190,7 @@
// in the set; we want to avoid touching the disk redundantly.
writeToJournalLocked(packageName);
- if (DEBUG) {
+ if (MORE_DEBUG) {
int numKeys = mPendingBackups.size();
Slog.d(TAG, "Now awaiting backup for " + numKeys + " participants:");
for (BackupRequest b : mPendingBackups.values()) {
@@ -4387,7 +4388,7 @@
}
Binder.restoreCallingIdentity(oldId);
}
- if (DEBUG) Slog.d(TAG, "Full backup done; returning to caller");
+ if (MORE_DEBUG) Slog.d(TAG, "Full backup done; returning to caller");
}
public void fullRestore(ParcelFileDescriptor fd) {
@@ -4446,7 +4447,7 @@
}
void startConfirmationTimeout(int token, FullParams params) {
- if (DEBUG) Slog.d(TAG, "Posting conf timeout msg after "
+ if (MORE_DEBUG) Slog.d(TAG, "Posting conf timeout msg after "
+ TIMEOUT_FULL_CONFIRMATION + " millis");
Message msg = mBackupHandler.obtainMessage(MSG_FULL_CONFIRMATION_TIMEOUT,
token, 0, params);
@@ -4625,7 +4626,7 @@
public String getCurrentTransport() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"getCurrentTransport");
- if (DEBUG) Slog.v(TAG, "... getCurrentTransport() returning " + mCurrentTransport);
+ if (MORE_DEBUG) Slog.v(TAG, "... getCurrentTransport() returning " + mCurrentTransport);
return mCurrentTransport;
}
@@ -4682,7 +4683,7 @@
if (transport != null) {
try {
final Intent intent = transport.configurationIntent();
- if (DEBUG) Slog.d(TAG, "getConfigurationIntent() returning config intent "
+ if (MORE_DEBUG) Slog.d(TAG, "getConfigurationIntent() returning config intent "
+ intent);
return intent;
} catch (RemoteException e) {
@@ -4708,7 +4709,7 @@
if (transport != null) {
try {
final String text = transport.currentDestinationString();
- if (DEBUG) Slog.d(TAG, "getDestinationString() returning " + text);
+ if (MORE_DEBUG) Slog.d(TAG, "getDestinationString() returning " + text);
return text;
} catch (RemoteException e) {
/* fall through to return null */
@@ -4853,7 +4854,7 @@
// completed the given outstanding asynchronous backup/restore operation.
public void opComplete(int token) {
synchronized (mCurrentOpLock) {
- if (DEBUG) Slog.v(TAG, "opComplete: " + Integer.toHexString(token));
+ if (MORE_DEBUG) Slog.v(TAG, "opComplete: " + Integer.toHexString(token));
mCurrentOperations.put(token, OP_ACKNOWLEDGED);
mCurrentOpLock.notifyAll();
}
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 2a724d4..bf9e014 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -40,6 +40,7 @@
import android.net.NetworkConfig;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
+import android.net.NetworkQuotaInfo;
import android.net.NetworkState;
import android.net.NetworkStateTracker;
import android.net.NetworkUtils;
@@ -344,7 +345,7 @@
mPolicyManager.registerListener(mPolicyListener);
} catch (RemoteException e) {
// ouch, no rules updates means some processes may never get network
- Slog.e(TAG, "unable to register INetworkPolicyListener", e);
+ loge("unable to register INetworkPolicyListener" + e.toString());
}
final PowerManager powerManager = (PowerManager) context.getSystemService(
@@ -737,6 +738,30 @@
return result.toArray(new NetworkState[result.size()]);
}
+ private NetworkState getNetworkStateUnchecked(int networkType) {
+ if (isNetworkTypeValid(networkType)) {
+ final NetworkStateTracker tracker = mNetTrackers[networkType];
+ if (tracker != null) {
+ return new NetworkState(tracker.getNetworkInfo(), tracker.getLinkProperties(),
+ tracker.getLinkCapabilities());
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
+ enforceAccessPermission();
+ final NetworkState state = getNetworkStateUnchecked(mActiveDefaultNetwork);
+ if (state != null) {
+ try {
+ return mPolicyManager.getNetworkQuotaInfo(state);
+ } catch (RemoteException e) {
+ }
+ }
+ return null;
+ }
+
public boolean setRadios(boolean turnOn) {
boolean result = true;
enforceChangePermission();
@@ -798,9 +823,11 @@
}
public void expire() {
- log("ConnectivityService FeatureUser expire(" +
- mNetworkType + ", " + mFeature + ", " + mBinder +"), created " +
- (System.currentTimeMillis() - mCreateTime) + " mSec ago");
+ if (VDBG) {
+ log("ConnectivityService FeatureUser expire(" +
+ mNetworkType + ", " + mFeature + ", " + mBinder +"), created " +
+ (System.currentTimeMillis() - mCreateTime) + " mSec ago");
+ }
stopUsingNetworkFeature(this, false);
}
@@ -843,7 +870,7 @@
if(networkType == ConnectivityManager.TYPE_MOBILE) {
usedNetworkType = convertFeatureToNetworkType(feature);
if (usedNetworkType < 0) {
- Slog.e(TAG, "Can't match any netTracker!");
+ loge("Can't match any netTracker!");
usedNetworkType = networkType;
}
}
@@ -900,7 +927,7 @@
!network.isTeardownRequested()) {
if (ni.isConnected() == true) {
// add the pid-specific dns
- handleDnsConfigurationChange(networkType);
+ handleDnsConfigurationChange(usedNetworkType);
if (DBG) log("special network already active");
return Phone.APN_ALREADY_ACTIVE;
}
@@ -953,7 +980,7 @@
return stopUsingNetworkFeature(u, true);
} else {
// none found!
- if (DBG) log("ignoring stopUsingNetworkFeature - not a live request");
+ if (VDBG) log("ignoring stopUsingNetworkFeature - not a live request");
return 1;
}
}
@@ -1081,7 +1108,7 @@
if (tracker == null || !tracker.getNetworkInfo().isConnected() ||
tracker.isTeardownRequested()) {
- if (DBG) {
+ if (VDBG) {
log("requestRouteToHostAddress on down network " +
"(" + networkType + ") - dropped");
}
@@ -1152,13 +1179,13 @@
}
}
if (doAdd) {
- if (DBG) log("Adding " + r + " for interface " + ifaceName);
+ if (VDBG) log("Adding " + r + " for interface " + ifaceName);
mAddedRoutes.add(r);
try {
mNetd.addRoute(ifaceName, r);
} catch (Exception e) {
// never crash - catch them all
- loge("Exception trying to add a route: " + e);
+ if (VDBG) loge("Exception trying to add a route: " + e);
return false;
}
} else {
@@ -1166,16 +1193,16 @@
// we can remove it from the table
mAddedRoutes.remove(r);
if (mAddedRoutes.contains(r) == false) {
- if (DBG) log("Removing " + r + " for interface " + ifaceName);
+ if (VDBG) log("Removing " + r + " for interface " + ifaceName);
try {
mNetd.removeRoute(ifaceName, r);
} catch (Exception e) {
// never crash - catch them all
- loge("Exception trying to remove a route: " + e);
+ if (VDBG) loge("Exception trying to remove a route: " + e);
return false;
}
} else {
- if (DBG) log("not removing " + r + " as it's still in use");
+ if (VDBG) log("not removing " + r + " as it's still in use");
}
}
return true;
@@ -1220,7 +1247,7 @@
enforceAccessPermission();
boolean retVal = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.MOBILE_DATA, 1) == 1;
- if (DBG) log("getMobileDataEnabled returning " + retVal);
+ if (VDBG) log("getMobileDataEnabled returning " + retVal);
return retVal;
}
@@ -1247,7 +1274,7 @@
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
if (LOGD_RULES) {
- Slog.d(TAG, "onUidRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")");
+ log("onUidRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")");
}
synchronized (mRulesLock) {
@@ -1268,8 +1295,7 @@
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
if (LOGD_RULES) {
- Slog.d(TAG,
- "onMeteredIfacesChanged(ifaces=" + Arrays.toString(meteredIfaces) + ")");
+ log("onMeteredIfacesChanged(ifaces=" + Arrays.toString(meteredIfaces) + ")");
}
synchronized (mRulesLock) {
@@ -1294,8 +1320,8 @@
private void handleSetMobileData(boolean enabled) {
if (mNetTrackers[ConnectivityManager.TYPE_MOBILE] != null) {
- if (DBG) {
- Slog.d(TAG, mNetTrackers[ConnectivityManager.TYPE_MOBILE].toString() + enabled);
+ if (VDBG) {
+ log(mNetTrackers[ConnectivityManager.TYPE_MOBILE].toString() + enabled);
}
mNetTrackers[ConnectivityManager.TYPE_MOBILE].setDataEnable(enabled);
}
@@ -1587,7 +1613,7 @@
mNetConfigs[type].priority) ||
mNetworkPreference == mActiveDefaultNetwork) {
// don't accept this one
- if (DBG) {
+ if (VDBG) {
log("Not broadcasting CONNECT_ACTION " +
"to torn down network " + info.getTypeName());
}
@@ -1688,9 +1714,11 @@
}
} else {
resetMask = NetworkUtils.RESET_ALL_ADDRESSES;
- log("handleConnectivityChange: interface not not equivalent reset both" +
- " linkProperty[" + netType + "]:" +
- " resetMask=" + resetMask);
+ if (DBG) {
+ log("handleConnectivityChange: interface not not equivalent reset both" +
+ " linkProperty[" + netType + "]:" +
+ " resetMask=" + resetMask);
+ }
}
}
if (mNetConfigs[netType].isDefault()) {
@@ -1798,7 +1826,7 @@
String bufferSizes = SystemProperties.get(key);
if (bufferSizes.length() == 0) {
- loge(key + " not found in system properties. Using defaults");
+ if (VDBG) log(key + " not found in system properties. Using defaults");
// Setting to default values so we won't be stuck to previous values
key = "net.tcp.buffersize.default";
@@ -1807,7 +1835,7 @@
// Set values in kernel
if (bufferSizes.length() != 0) {
- if (DBG) {
+ if (VDBG) {
log("Setting TCP values: [" + bufferSizes
+ "] which comes from [" + key + "]");
}
@@ -1849,7 +1877,7 @@
*/
private void reassessPidDns(int myPid, boolean doBump)
{
- if (DBG) log("reassessPidDns for pid " + myPid);
+ if (VDBG) log("reassessPidDns for pid " + myPid);
for(int i : mPriorityList) {
if (mNetConfigs[i].isDefault()) {
continue;
@@ -1935,7 +1963,7 @@
String value = mDefaultDns.getHostAddress();
if (!value.equals(SystemProperties.get("net.dns1"))) {
if (DBG) {
- log("no dns provided for " + network + " - using " + value);
+ loge("no dns provided for " + network + " - using " + value);
}
changed = true;
SystemProperties.set("net.dns1", value);
@@ -1948,7 +1976,7 @@
if (!changed && value.equals(SystemProperties.get(key))) {
continue;
}
- if (DBG) {
+ if (VDBG) {
log("adding dns " + value + " for " + network);
}
changed = true;
@@ -1957,7 +1985,7 @@
}
for (int i = last + 1; i <= mNumDnsEntries; ++i) {
String key = "net.dns" + i;
- if (DBG) log("erasing " + key);
+ if (VDBG) log("erasing " + key);
changed = true;
SystemProperties.set(key, "");
}
@@ -1968,7 +1996,7 @@
mNetd.setDnsServersForInterface(iface, NetworkUtils.makeStrings(dnses));
mNetd.setDefaultInterfaceForDns(iface);
} catch (Exception e) {
- Slog.e(TAG, "exception setting default dns interface: " + e);
+ loge("exception setting default dns interface: " + e);
}
}
if (!domains.equals(SystemProperties.get("net.dns.search"))) {
@@ -1998,7 +2026,7 @@
mNetd.setDnsServersForInterface(p.getInterfaceName(),
NetworkUtils.makeStrings(dnses));
} catch (Exception e) {
- Slog.e(TAG, "exception setting dns servers: " + e);
+ loge("exception setting dns servers: " + e);
}
// set per-pid dns for attached secondary nets
List pids = mNetRequestersPids[netType];
@@ -2335,7 +2363,7 @@
// 100 percent is full good, 0 is full bad.
public void reportInetCondition(int networkType, int percentage) {
- if (DBG) log("reportNetworkCondition(" + networkType + ", " + percentage + ")");
+ if (VDBG) log("reportNetworkCondition(" + networkType + ", " + percentage + ")");
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.STATUS_BAR,
"ConnectivityService");
@@ -2372,7 +2400,7 @@
mDefaultInetCondition = condition;
int delay;
if (mInetConditionChangeInFlight == false) {
- if (DBG) log("starting a change hold");
+ if (VDBG) log("starting a change hold");
// setup a new hold to debounce this
if (mDefaultInetCondition > 50) {
delay = Settings.Secure.getInt(mContext.getContentResolver(),
@@ -2387,12 +2415,12 @@
} else {
// we've set the new condition, when this hold ends that will get
// picked up
- if (DBG) log("currently in hold - not setting new end evt");
+ if (VDBG) log("currently in hold - not setting new end evt");
}
}
private void handleInetConditionHoldEnd(int netType, int sequence) {
- if (DBG) {
+ if (VDBG) {
log("Inet hold end, net=" + netType +
", condition =" + mDefaultInetCondition +
", published condition =" + mDefaultInetConditionPublished);
@@ -2490,7 +2518,7 @@
mDefaultProxy = null;
}
}
- if (DBG) log("changing default proxy to " + proxy);
+ if (VDBG) log("changing default proxy to " + proxy);
if ((proxy == null && mGlobalProxy == null) || proxy.equals(mGlobalProxy)) return;
if (mGlobalProxy != null) return;
sendProxyBroadcast(proxy);
@@ -2517,7 +2545,7 @@
private void sendProxyBroadcast(ProxyProperties proxy) {
if (proxy == null) proxy = new ProxyProperties("", 0, "");
- log("sending Proxy Broadcast for " + proxy);
+ if (DBG) log("sending Proxy Broadcast for " + proxy);
Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java
index 88d94c2..fed554c 100644
--- a/services/java/com/android/server/NativeDaemonConnector.java
+++ b/services/java/com/android/server/NativeDaemonConnector.java
@@ -19,6 +19,9 @@
import android.net.LocalSocketAddress;
import android.net.LocalSocket;
import android.os.Environment;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.Slog;
@@ -39,7 +42,7 @@
* daemon which uses the libsysutils FrameworkListener
* protocol.
*/
-final class NativeDaemonConnector implements Runnable {
+final class NativeDaemonConnector implements Runnable, Handler.Callback {
private static final boolean LOCAL_LOGD = false;
private BlockingQueue<String> mResponseQueue;
@@ -47,6 +50,7 @@
private String TAG = "NativeDaemonConnector";
private String mSocket;
private INativeDaemonConnectorCallbacks mCallbacks;
+ private Handler mCallbackHandler;
private final int BUFFER_SIZE = 4096;
@@ -76,7 +80,11 @@
mResponseQueue = new LinkedBlockingQueue<String>(responseQueueSize);
}
+ @Override
public void run() {
+ HandlerThread thread = new HandlerThread(TAG + ".CallbackHandler");
+ thread.start();
+ mCallbackHandler = new Handler(thread.getLooper(), this);
while (true) {
try {
@@ -88,6 +96,21 @@
}
}
+ @Override
+ public boolean handleMessage(Message msg) {
+ String event = (String) msg.obj;
+ try {
+ if (!mCallbacks.onEvent(msg.what, event, event.split(" "))) {
+ Slog.w(TAG, String.format(
+ "Unhandled event '%s'", event));
+ }
+ } catch (Exception e) {
+ Slog.e(TAG, String.format(
+ "Error handling '%s'", event), e);
+ }
+ return true;
+ }
+
private void listenToSocket() throws IOException {
LocalSocket socket = null;
@@ -119,20 +142,13 @@
String event = new String(buffer, start, i - start);
if (LOCAL_LOGD) Slog.d(TAG, String.format("RCV <- {%s}", event));
- String[] tokens = event.split(" ");
+ String[] tokens = event.split(" ", 2);
try {
int code = Integer.parseInt(tokens[0]);
if (code >= ResponseCode.UnsolicitedInformational) {
- try {
- if (!mCallbacks.onEvent(code, event, tokens)) {
- Slog.w(TAG, String.format(
- "Unhandled event (%s)", event));
- }
- } catch (Exception ex) {
- Slog.e(TAG, String.format(
- "Error handling '%s'", event), ex);
- }
+ mCallbackHandler.sendMessage(
+ mCallbackHandler.obtainMessage(code, event));
} else {
try {
mResponseQueue.put(event);
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 39d2b1c..30de385 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -21,6 +21,8 @@
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.provider.Settings.Secure.NETSTATS_ENABLED;
+import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
+import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -54,7 +56,6 @@
import java.io.InputStreamReader;
import java.net.Inet4Address;
import java.net.InetAddress;
-import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -89,8 +90,10 @@
private static final String KEY_IFACE = "iface";
private static final String KEY_TAG_HEX = "acct_tag_hex";
private static final String KEY_UID = "uid_tag_int";
- private static final String KEY_RX = "rx_bytes";
- private static final String KEY_TX = "tx_bytes";
+ private static final String KEY_RX_BYTES = "rx_bytes";
+ private static final String KEY_RX_PACKETS = "rx_packets";
+ private static final String KEY_TX_BYTES = "tx_bytes";
+ private static final String KEY_TX_PACKETS = "tx_packets";
class NetdResponseCode {
/* Keep in sync with system/netd/ResponseCode.h */
@@ -203,8 +206,7 @@
Slog.d(TAG, "not enabling bandwidth control");
}
- SystemProperties.set(NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED,
- mBandwidthControlEnabled ? "1" : "0");
+ SystemProperties.set(PROP_QTAGUID_ENABLED, mBandwidthControlEnabled ? "1" : "0");
}
public void registerObserver(INetworkManagementEventObserver obs) {
@@ -1229,6 +1231,13 @@
}
}
+ @Override
+ public boolean isBandwidthControlEnabled() {
+ mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
+ return mBandwidthControlEnabled;
+ }
+
+ @Override
public NetworkStats getNetworkStatsUidDetail(int uid) {
if (Binder.getCallingUid() != uid) {
mContext.enforceCallingOrSelfPermission(
@@ -1249,6 +1258,9 @@
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 24);
final NetworkStats.Entry entry = new NetworkStats.Entry();
+ // TODO: remove knownLines check once 5087722 verified
+ final HashSet<String> knownLines = Sets.newHashSet();
+
final ArrayList<String> keys = Lists.newArrayList();
final ArrayList<String> values = Lists.newArrayList();
final HashMap<String, String> parsed = Maps.newHashMap();
@@ -1266,14 +1278,18 @@
splitLine(line, values);
parseLine(keys, values, parsed);
+ if (!knownLines.add(line)) {
+ throw new IllegalStateException("encountered duplicate proc entry");
+ }
+
try {
- // TODO: add rxPackets/txPackets once kernel exports
entry.iface = parsed.get(KEY_IFACE);
- entry.tag = NetworkManagementSocketTagger.kernelToTag(
- parsed.get(KEY_TAG_HEX));
- entry.uid = Integer.parseInt(parsed.get(KEY_UID));
- entry.rxBytes = Long.parseLong(parsed.get(KEY_RX));
- entry.txBytes = Long.parseLong(parsed.get(KEY_TX));
+ entry.tag = kernelToTag(parsed.get(KEY_TAG_HEX));
+ entry.uid = getParsedInt(parsed, KEY_UID);
+ entry.rxBytes = getParsedLong(parsed, KEY_RX_BYTES);
+ entry.rxPackets = getParsedLong(parsed, KEY_RX_PACKETS);
+ entry.txBytes = getParsedLong(parsed, KEY_TX_BYTES);
+ entry.txPackets = getParsedLong(parsed, KEY_TX_PACKETS);
if (limitUid == UID_ALL || limitUid == entry.uid) {
stats.addValues(entry);
@@ -1291,6 +1307,16 @@
return stats;
}
+ private static int getParsedInt(HashMap<String, String> parsed, String key) {
+ final String value = parsed.get(key);
+ return value != null ? Integer.parseInt(value) : 0;
+ }
+
+ private static long getParsedLong(HashMap<String, String> parsed, String key) {
+ final String value = parsed.get(key);
+ return value != null ? Long.parseLong(value) : 0;
+ }
+
/**
* Build {@link NetworkStats} with detailed UID statistics.
*
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index f15eca6..4a0dcdf 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -27,6 +27,7 @@
import android.content.pm.IPackageManager;
import android.content.res.Configuration;
import android.media.AudioService;
+import android.net.wifi.p2p.WifiP2pService;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -37,7 +38,6 @@
import android.server.BluetoothA2dpService;
import android.server.BluetoothService;
import android.server.search.SearchManagerService;
-import android.server.WifiP2pService;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Slog;
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index 837778e..238b747 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -31,19 +31,17 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Binder;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
-import android.os.SystemClock;
import android.provider.Settings;
-import android.text.TextUtils;
import android.service.textservice.SpellCheckerService;
-import android.util.Log;
+import android.text.TextUtils;
import android.util.Slog;
import android.view.textservice.SpellCheckerInfo;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
public class TextServicesManagerService extends ITextServicesManager.Stub {
@@ -80,7 +78,7 @@
// Set the current spell checker if there is one or more spell checkers
// available. In this case, "sci" is the first one in the available spell
// checkers.
- setCurrentSpellCheckerLocked(sci);
+ setCurrentSpellCheckerLocked(sci.getId());
}
}
}
@@ -95,12 +93,14 @@
if (sci == null) return;
final String packageName = sci.getPackageName();
final int change = isPackageDisappearing(packageName);
- if (change == PACKAGE_PERMANENT_CHANGE || change == PACKAGE_TEMPORARY_CHANGE) {
- // Package disappearing
- setCurrentSpellCheckerLocked(findAvailSpellCheckerLocked(null, packageName));
- } else if (isPackageModified(packageName)) {
- // Package modified
- setCurrentSpellCheckerLocked(findAvailSpellCheckerLocked(null, packageName));
+ if (// Package disappearing
+ change == PACKAGE_PERMANENT_CHANGE || change == PACKAGE_TEMPORARY_CHANGE
+ // Package modified
+ || isPackageModified(packageName)) {
+ sci = findAvailSpellCheckerLocked(null, packageName);
+ if (sci != null) {
+ setCurrentSpellCheckerLocked(sci.getId());
+ }
}
}
}
@@ -177,27 +177,28 @@
}
@Override
- public void getSpellCheckerService(SpellCheckerInfo info, String locale,
- ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener) {
+ public void getSpellCheckerService(String sciId, String locale,
+ ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener,
+ Bundle bundle) {
if (!mSystemReady) {
return;
}
- if (info == null || tsListener == null || scListener == null) {
+ if (TextUtils.isEmpty(sciId) || tsListener == null || scListener == null) {
Slog.e(TAG, "getSpellCheckerService: Invalid input.");
return;
}
- final String sciId = info.getId();
synchronized(mSpellCheckerMap) {
if (!mSpellCheckerMap.containsKey(sciId)) {
return;
}
+ final SpellCheckerInfo sci = mSpellCheckerMap.get(sciId);
final int uid = Binder.getCallingUid();
if (mSpellCheckerBindGroups.containsKey(sciId)) {
final SpellCheckerBindGroup bindGroup = mSpellCheckerBindGroups.get(sciId);
if (bindGroup != null) {
final InternalDeathRecipient recipient =
mSpellCheckerBindGroups.get(sciId).addListener(
- tsListener, locale, scListener, uid);
+ tsListener, locale, scListener, uid, bundle);
if (recipient == null) {
if (DBG) {
Slog.w(TAG, "Didn't create a death recipient.");
@@ -215,7 +216,7 @@
try {
final ISpellCheckerSession session =
bindGroup.mSpellChecker.getISpellCheckerSession(
- recipient.mScLocale, recipient.mScListener);
+ recipient.mScLocale, recipient.mScListener, bundle);
if (session != null) {
tsListener.onServiceConnected(session);
return;
@@ -234,7 +235,8 @@
}
final long ident = Binder.clearCallingIdentity();
try {
- startSpellCheckerServiceInnerLocked(info, locale, tsListener, scListener, uid);
+ startSpellCheckerServiceInnerLocked(
+ sci, locale, tsListener, scListener, uid, bundle);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -244,13 +246,13 @@
private void startSpellCheckerServiceInnerLocked(SpellCheckerInfo info, String locale,
ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener,
- int uid) {
+ int uid, Bundle bundle) {
if (DBG) {
Slog.w(TAG, "Start spell checker session inner locked.");
}
final String sciId = info.getId();
final InternalServiceConnection connection = new InternalServiceConnection(
- sciId, locale, scListener);
+ sciId, locale, scListener, bundle);
final Intent serviceIntent = new Intent(SpellCheckerService.SERVICE_INTERFACE);
serviceIntent.setComponent(info.getComponent());
if (DBG) {
@@ -261,7 +263,7 @@
return;
}
final SpellCheckerBindGroup group = new SpellCheckerBindGroup(
- connection, tsListener, locale, scListener, uid);
+ connection, tsListener, locale, scListener, uid, bundle);
mSpellCheckerBindGroups.put(sciId, group);
}
@@ -290,7 +292,7 @@
}
@Override
- public void setCurrentSpellChecker(SpellCheckerInfo sci) {
+ public void setCurrentSpellChecker(String sciId) {
synchronized(mSpellCheckerMap) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.WRITE_SECURE_SETTINGS)
@@ -299,19 +301,19 @@
"Requires permission "
+ android.Manifest.permission.WRITE_SECURE_SETTINGS);
}
- setCurrentSpellCheckerLocked(sci);
+ setCurrentSpellCheckerLocked(sciId);
}
}
- private void setCurrentSpellCheckerLocked(SpellCheckerInfo sci) {
+ private void setCurrentSpellCheckerLocked(String sciId) {
if (DBG) {
- Slog.w(TAG, "setCurrentSpellChecker: " + sci.getId());
+ Slog.w(TAG, "setCurrentSpellChecker: " + sciId);
}
- if (sci == null || !mSpellCheckerMap.containsKey(sci.getId())) return;
+ if (TextUtils.isEmpty(sciId) || !mSpellCheckerMap.containsKey(sciId)) return;
final long ident = Binder.clearCallingIdentity();
try {
Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.SPELL_CHECKER_SERVICE, sci == null ? "" : sci.getId());
+ Settings.Secure.SPELL_CHECKER_SERVICE, sciId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -330,10 +332,10 @@
public SpellCheckerBindGroup(InternalServiceConnection connection,
ITextServicesSessionListener listener, String locale,
- ISpellCheckerSessionListener scListener, int uid) {
+ ISpellCheckerSessionListener scListener, int uid, Bundle bundle) {
mInternalConnection = connection;
mConnected = false;
- addListener(listener, locale, scListener, uid);
+ addListener(listener, locale, scListener, uid, bundle);
}
public void onServiceConnected(ISpellCheckerService spellChecker) {
@@ -344,7 +346,7 @@
for (InternalDeathRecipient listener : mListeners) {
try {
final ISpellCheckerSession session = spellChecker.getISpellCheckerSession(
- listener.mScLocale, listener.mScListener);
+ listener.mScLocale, listener.mScListener, listener.mBundle);
listener.mTsListener.onServiceConnected(session);
} catch (RemoteException e) {
Slog.e(TAG, "Exception in getting the spell checker session: " + e);
@@ -358,7 +360,7 @@
}
public InternalDeathRecipient addListener(ITextServicesSessionListener tsListener,
- String locale, ISpellCheckerSessionListener scListener, int uid) {
+ String locale, ISpellCheckerSessionListener scListener, int uid, Bundle bundle) {
if (DBG) {
Slog.d(TAG, "addListener: " + locale);
}
@@ -373,7 +375,7 @@
}
}
recipient = new InternalDeathRecipient(
- this, tsListener, locale, scListener, uid);
+ this, tsListener, locale, scListener, uid, bundle);
scListener.asBinder().linkToDeath(recipient, 0);
mListeners.add(recipient);
} catch(RemoteException e) {
@@ -438,11 +440,13 @@
private final ISpellCheckerSessionListener mListener;
private final String mSciId;
private final String mLocale;
+ private final Bundle mBundle;
public InternalServiceConnection(
- String id, String locale, ISpellCheckerSessionListener listener) {
+ String id, String locale, ISpellCheckerSessionListener listener, Bundle bundle) {
mSciId = id;
mLocale = locale;
mListener = listener;
+ mBundle = bundle;
}
@Override
@@ -471,14 +475,16 @@
public final String mScLocale;
private final SpellCheckerBindGroup mGroup;
public final int mUid;
+ public final Bundle mBundle;
public InternalDeathRecipient(SpellCheckerBindGroup group,
ITextServicesSessionListener tsListener, String scLocale,
- ISpellCheckerSessionListener scListener, int uid) {
+ ISpellCheckerSessionListener scListener, int uid, Bundle bundle) {
mTsListener = tsListener;
mScListener = scListener;
mScLocale = scLocale;
mGroup = group;
mUid = uid;
+ mBundle = bundle;
}
public boolean hasSpellCheckerListener(ISpellCheckerSessionListener listener) {
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index c129b97..2460fd6 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -68,7 +68,6 @@
import org.xmlpull.v1.XmlSerializer;
import com.android.internal.content.PackageMonitor;
-import com.android.internal.service.wallpaper.ImageWallpaper;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
@@ -150,8 +149,8 @@
* Name of the component used to display bitmap wallpapers from either the gallery or
* built-in wallpapers.
*/
- ComponentName mImageWallpaperComponent = new ComponentName("android",
- ImageWallpaper.class.getName());
+ ComponentName mImageWallpaperComponent = new ComponentName("com.android.systemui",
+ "com.android.systemui.ImageWallpaper");
WallpaperConnection mWallpaperConnection;
long mLastDiedTime;
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index f9f63b1..242a93d 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -1592,7 +1592,10 @@
for (int i = scanResults.size() - 1; i >= 0; i--) {
ScanResult scanResult = scanResults.get(i);
- if (TextUtils.isEmpty(scanResult.capabilities)) {
+ //A capability of [ESS] represents an open access point
+ //that is available for an STA to connect
+ if (scanResult.capabilities != null &&
+ scanResult.capabilities.equals("[ESS]")) {
numOpenNetworks++;
}
}
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index 0ad58d0..0808d5d 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -313,7 +313,7 @@
if (moveDelta > mTouchExplorationTapSlop) {
mLastTouchExploreEvent = null;
mPerformLongPressDelayed.remove();
- break;
+ break;
}
}
} break;
@@ -388,6 +388,11 @@
mTouchExploreGestureInProgress = false;
mLastTouchExploreEvent = MotionEvent.obtain(event);
sendAccessibilityEvent(TYPE_TOUCH_EXPLORATION_GESTURE_END);
+ final int lastAction = mPointerTracker.getLastInjectedHoverAction();
+ if (lastAction != MotionEvent.ACTION_HOVER_EXIT) {
+ sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT,
+ pointerIdBits, policyFlags);
+ }
break;
}
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index 9cb772e..b69cc31 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -54,7 +54,6 @@
public class Vpn extends INetworkManagementEventObserver.Stub {
private final static String TAG = "Vpn";
- private final static String VPN = android.Manifest.permission.VPN;
private final Context mContext;
private final VpnCallback mCallback;
@@ -69,18 +68,6 @@
}
/**
- * Protect a socket from routing changes by binding it to the given
- * interface. The socket is NOT closed by this method.
- *
- * @param socket The socket to be bound.
- * @param name The name of the interface.
- */
- public void protect(ParcelFileDescriptor socket, String interfaze) {
- mContext.enforceCallingPermission(VPN, "protect");
- jniProtect(socket.getFd(), interfaze);
- }
-
- /**
* Prepare for a VPN application. This method is designed to solve
* race conditions. It first compares the current prepared package
* with {@code oldPackage}. If they are the same, the prepared
@@ -115,13 +102,6 @@
throw new SecurityException("Unauthorized Caller");
}
- // Check the permission of the given package.
- PackageManager pm = mContext.getPackageManager();
- if (!newPackage.equals(VpnConfig.LEGACY_VPN) &&
- pm.checkPermission(VPN, newPackage) != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException(newPackage + " does not have " + VPN);
- }
-
// Reset the interface and hide the notification.
if (mInterface != null) {
jniReset(mInterface);
@@ -130,12 +110,9 @@
mInterface = null;
}
- // Send out the broadcast or stop LegacyVpnRunner.
+ // Revoke the connection or stop LegacyVpnRunner.
if (!mPackage.equals(VpnConfig.LEGACY_VPN)) {
- Intent intent = new Intent(VpnConfig.ACTION_VPN_REVOKED);
- intent.setPackage(mPackage);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- mContext.sendBroadcast(intent);
+ // TODO
} else if (mLegacyVpnRunner != null) {
mLegacyVpnRunner.exit();
mLegacyVpnRunner = null;
@@ -147,6 +124,22 @@
}
/**
+ * Protect a socket from routing changes by binding it to the given
+ * interface. The socket is NOT closed by this method.
+ *
+ * @param socket The socket to be bound.
+ * @param name The name of the interface.
+ */
+ public void protect(ParcelFileDescriptor socket, String interfaze) throws Exception {
+ PackageManager pm = mContext.getPackageManager();
+ ApplicationInfo app = pm.getApplicationInfo(mPackage, 0);
+ if (Binder.getCallingUid() != app.uid) {
+ throw new SecurityException("Unauthorized Caller");
+ }
+ jniProtect(socket.getFd(), interfaze);
+ }
+
+ /**
* Establish a VPN network and return the file descriptor of the VPN
* interface. This methods returns {@code null} if the application is
* revoked or not prepared.
@@ -155,9 +148,6 @@
* @return The file descriptor of the VPN interface.
*/
public synchronized ParcelFileDescriptor establish(VpnConfig config) {
- // Check the permission of the caller.
- mContext.enforceCallingPermission(VPN, "establish");
-
// Check if the caller is already prepared.
PackageManager pm = mContext.getPackageManager();
ApplicationInfo app = null;
@@ -170,6 +160,9 @@
return null;
}
+ // Check if the service is properly declared.
+ // TODO
+
// Load the label.
String label = app.loadLabel(pm).toString();
@@ -183,7 +176,9 @@
android.R.dimen.notification_large_icon_height);
icon.setBounds(0, 0, width, height);
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- icon.draw(new Canvas(bitmap));
+ Canvas c = new Canvas(bitmap);
+ icon.draw(c);
+ c.setBitmap(null);
}
// Configure the interface. Abort if any of these steps fails.
@@ -196,6 +191,7 @@
if (config.routes != null) {
jniSetRoutes(interfaze, config.routes);
}
+ // TODO: bind the service
if (mInterface != null && !mInterface.equals(interfaze)) {
jniReset(mInterface);
}
@@ -209,23 +205,25 @@
throw e;
}
- // Override DNS servers and search domains.
- mCallback.override(config.dnsServers, config.searchDomains);
-
// Fill more values.
- config.packagz = mPackage;
+ config.user = mPackage;
config.interfaze = mInterface;
- // Show the notification!
+ // Override DNS servers and show the notification.
+ long identity = Binder.clearCallingIdentity();
+ mCallback.override(config.dnsServers, config.searchDomains);
showNotification(config, label, bitmap);
+ Binder.restoreCallingIdentity(identity);
return tun;
}
// INetworkManagementEventObserver.Stub
+ @Override
public void interfaceAdded(String interfaze) {
}
// INetworkManagementEventObserver.Stub
+ @Override
public synchronized void interfaceStatusChanged(String interfaze, boolean up) {
if (!up && mLegacyVpnRunner != null) {
mLegacyVpnRunner.check(interfaze);
@@ -233,23 +231,29 @@
}
// INetworkManagementEventObserver.Stub
- public synchronized void interfaceLinkStateChanged(String interfaze, boolean up) {
- if (!up && mLegacyVpnRunner != null) {
- mLegacyVpnRunner.check(interfaze);
+ @Override
+ public void interfaceLinkStateChanged(String interfaze, boolean up) {
+ interfaceStatusChanged(interfaze, up);
+ }
+
+ // INetworkManagementEventObserver.Stub
+ @Override
+ public synchronized void interfaceRemoved(String interfaze) {
+ if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) {
+ long identity = Binder.clearCallingIdentity();
+ mCallback.restore();
+ hideNotification();
+ Binder.restoreCallingIdentity(identity);
+ mInterface = null;
+ // TODO: unbind the service
}
}
// INetworkManagementEventObserver.Stub
- public synchronized void interfaceRemoved(String interfaze) {
- if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) {
- mCallback.restore();
- hideNotification();
- mInterface = null;
- }
+ @Override
+ public void limitReached(String limit, String interfaze) {
}
- public void limitReached(String limitName, String iface) {}
-
private void showNotification(VpnConfig config, String label, Bitmap icon) {
NotificationManager nm = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -261,7 +265,6 @@
mContext.getString(R.string.vpn_text_long, config.session);
config.startTime = SystemClock.elapsedRealtime();
- long identity = Binder.clearCallingIdentity();
Notification notification = new Notification.Builder(mContext)
.setSmallIcon(R.drawable.vpn_connected)
.setLargeIcon(icon)
@@ -272,7 +275,6 @@
.setOngoing(true)
.getNotification();
nm.notify(R.drawable.vpn_connected, notification);
- Binder.restoreCallingIdentity(identity);
}
}
@@ -281,9 +283,7 @@
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
if (nm != null) {
- long identity = Binder.clearCallingIdentity();
nm.cancel(R.drawable.vpn_connected);
- Binder.restoreCallingIdentity(identity);
}
}
@@ -353,8 +353,8 @@
mOuterInterface = mConfig.interfaze;
// Legacy VPN is not a real package, so we use it to carry the key.
- mInfo.key = mConfig.packagz;
- mConfig.packagz = VpnConfig.LEGACY_VPN;
+ mInfo.key = mConfig.user;
+ mConfig.user = VpnConfig.LEGACY_VPN;
}
public void check(String interfaze) {
diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java
index b79e31f..0ce5499 100755
--- a/services/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/java/com/android/server/location/GpsLocationProvider.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.database.Cursor;
import android.location.Criteria;
import android.location.IGpsStatusListener;
import android.location.IGpsStatusProvider;
@@ -32,6 +33,7 @@
import android.location.LocationProvider;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
+import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -45,6 +47,7 @@
import android.os.SystemClock;
import android.os.WorkSource;
import android.provider.Settings;
+import android.provider.Telephony.Carriers;
import android.provider.Telephony.Sms.Intents;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
@@ -489,8 +492,17 @@
}
if (info != null) {
+ boolean dataEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.MOBILE_DATA, 1) == 1;
+ boolean networkAvailable = info.isAvailable() && dataEnabled;
+ String defaultApn = getSelectedApn();
+ if (defaultApn == null) {
+ defaultApn = "dummy-apn";
+ }
+
native_update_network_state(info.isConnected(), info.getType(),
- info.isRoaming(), info.getExtraInfo());
+ info.isRoaming(), networkAvailable,
+ info.getExtraInfo(), defaultApn);
}
if (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE_SUPL
@@ -1597,6 +1609,25 @@
}
}
+ private String getSelectedApn() {
+ Uri uri = Uri.parse("content://telephony/carriers/preferapn");
+ String apn = null;
+
+ Cursor cursor = mContext.getContentResolver().query(uri, new String[] {"apn"},
+ null, null, Carriers.DEFAULT_SORT_ORDER);
+
+ if (null != cursor) {
+ try {
+ if (cursor.moveToFirst()) {
+ apn = cursor.getString(0);
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+ return apn;
+ }
+
// for GPS SV statistics
private static final int MAX_SVS = 32;
private static final int EPHEMERIS_MASK = 0;
@@ -1655,5 +1686,5 @@
private native void native_agps_set_id(int type, String setid);
private native void native_update_network_state(boolean connected, int type,
- boolean roaming, String extraInfo);
+ boolean roaming, boolean available, String extraInfo, String defaultAPN);
}
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 756cd00..a075255 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.net;
+import static android.Manifest.permission.ACCESS_NETWORK_STATE;
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
import static android.Manifest.permission.DUMP;
import static android.Manifest.permission.MANAGE_APP_TOKENS;
@@ -75,9 +76,11 @@
import android.net.INetworkStatsService;
import android.net.NetworkIdentity;
import android.net.NetworkPolicy;
+import android.net.NetworkQuotaInfo;
import android.net.NetworkState;
import android.net.NetworkStats;
import android.net.NetworkTemplate;
+import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
@@ -1054,6 +1057,7 @@
synchronized (mRulesLock) {
mRestrictBackground = restrictBackground;
updateRulesForRestrictBackgroundLocked();
+ writePolicyLocked();
}
}
@@ -1066,6 +1070,68 @@
}
}
+ private NetworkPolicy findPolicyForNetworkLocked(NetworkIdentity ident) {
+ for (NetworkPolicy policy : mNetworkPolicy.values()) {
+ if (policy.template.matches(ident)) {
+ return policy;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) {
+ mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
+
+ // only returns usage summary, so we don't require caller to have
+ // READ_NETWORK_USAGE_HISTORY.
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return getNetworkQuotaInfoUnchecked(state);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ private NetworkQuotaInfo getNetworkQuotaInfoUnchecked(NetworkState state) {
+ final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
+
+ final NetworkPolicy policy;
+ synchronized (mRulesLock) {
+ policy = findPolicyForNetworkLocked(ident);
+ }
+
+ if (policy == null) {
+ // missing policy means we can't derive useful quota info
+ return null;
+ }
+
+ final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
+ : System.currentTimeMillis();
+
+ final long start = computeLastCycleBoundary(currentTime, policy);
+ final long end = currentTime;
+
+ // find total bytes used under policy
+ long totalBytes = 0;
+ try {
+ final NetworkStats stats = mNetworkStats.getSummaryForNetwork(
+ policy.template, start, end);
+ final NetworkStats.Entry entry = stats.getValues(0, null);
+ totalBytes = entry.rxBytes + entry.txBytes;
+ } catch (RemoteException e) {
+ Slog.w(TAG, "problem reading summary for template " + policy.template);
+ }
+
+ // report soft and hard limits under policy
+ final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes
+ : NetworkQuotaInfo.NO_LIMIT;
+ final long hardLimitBytes = policy.limitBytes != LIMIT_DISABLED ? policy.limitBytes
+ : NetworkQuotaInfo.NO_LIMIT;
+
+ return new NetworkQuotaInfo(totalBytes, softLimitBytes, hardLimitBytes);
+ }
+
@Override
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
mContext.enforceCallingOrSelfPermission(DUMP, TAG);
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 6cc01f4..deca7a9 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -16,8 +16,10 @@
package com.android.server.net;
+import static android.Manifest.permission.ACCESS_NETWORK_STATE;
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
import static android.Manifest.permission.DUMP;
+import static android.Manifest.permission.MODIFY_NETWORK_ACCOUNTING;
import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
import static android.content.Intent.ACTION_SHUTDOWN;
import static android.content.Intent.ACTION_UID_REMOVED;
@@ -56,6 +58,7 @@
import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
+import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
@@ -150,9 +153,9 @@
/** Set of currently active ifaces. */
private HashMap<String, NetworkIdentitySet> mActiveIfaces = Maps.newHashMap();
- /** Set of historical stats for known networks. */
+ /** Set of historical network layer stats for known networks. */
private HashMap<NetworkIdentitySet, NetworkStatsHistory> mNetworkStats = Maps.newHashMap();
- /** Set of historical stats for known UIDs. */
+ /** Set of historical network layer stats for known UIDs. */
private HashMap<NetworkIdentitySet, LongSparseArray<NetworkStatsHistory>> mUidStats =
Maps.newHashMap();
@@ -164,6 +167,10 @@
private NetworkStats mLastUidSnapshot;
+ /** Data layer operation counters for splicing into other structures. */
+ private NetworkStats mOperations = new NetworkStats(0L, 10);
+ private NetworkStats mLastOperationsSnapshot;
+
private final HandlerThread mHandlerThread;
private final Handler mHandler;
@@ -274,13 +281,13 @@
}
@Override
- public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template) {
+ public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
synchronized (mStatsLock) {
// combine all interfaces that match template
final NetworkStatsHistory combined = new NetworkStatsHistory(
- mSettings.getNetworkBucketDuration(), estimateNetworkBuckets());
+ mSettings.getNetworkBucketDuration(), estimateNetworkBuckets(), fields);
for (NetworkIdentitySet ident : mNetworkStats.keySet()) {
if (templateMatches(template, ident)) {
final NetworkStatsHistory history = mNetworkStats.get(ident);
@@ -294,7 +301,8 @@
}
@Override
- public NetworkStatsHistory getHistoryForUid(NetworkTemplate template, int uid, int tag) {
+ public NetworkStatsHistory getHistoryForUid(
+ NetworkTemplate template, int uid, int tag, int fields) {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
synchronized (mStatsLock) {
@@ -303,7 +311,7 @@
// combine all interfaces that match template
final NetworkStatsHistory combined = new NetworkStatsHistory(
- mSettings.getUidBucketDuration(), estimateUidBuckets());
+ mSettings.getUidBucketDuration(), estimateUidBuckets(), fields);
for (NetworkIdentitySet ident : mUidStats.keySet()) {
if (templateMatches(template, ident)) {
final NetworkStatsHistory history = mUidStats.get(ident).get(packed);
@@ -381,9 +389,13 @@
entry.uid = uid;
entry.tag = tag;
entry.rxBytes = historyEntry.rxBytes;
+ entry.rxPackets = historyEntry.rxPackets;
entry.txBytes = historyEntry.txBytes;
+ entry.txPackets = historyEntry.txPackets;
+ entry.operations = historyEntry.operations;
- if (entry.rxBytes > 0 || entry.txBytes > 0) {
+ if (entry.rxBytes > 0 || entry.rxPackets > 0 || entry.txBytes > 0
+ || entry.txPackets > 0 || entry.operations > 0) {
stats.combineValues(entry);
}
}
@@ -396,6 +408,41 @@
}
@Override
+ public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
+ if (Binder.getCallingUid() != uid) {
+ mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
+ }
+
+ // TODO: switch to data layer stats once kernel exports
+ // for now, read network layer stats and flatten across all ifaces
+ final NetworkStats networkLayer = mNetworkManager.getNetworkStatsUidDetail(uid);
+ final NetworkStats dataLayer = new NetworkStats(
+ networkLayer.getElapsedRealtime(), networkLayer.size());
+
+ NetworkStats.Entry entry = null;
+ for (int i = 0; i < networkLayer.size(); i++) {
+ entry = networkLayer.getValues(i, entry);
+ entry.iface = IFACE_ALL;
+ dataLayer.combineValues(entry);
+ }
+
+ // splice in operation counts
+ dataLayer.spliceOperationsFrom(mOperations);
+ return dataLayer;
+ }
+
+ @Override
+ public void incrementOperationCount(int uid, int tag, int operationCount) {
+ if (Binder.getCallingUid() != uid) {
+ mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
+ }
+
+ synchronized (mStatsLock) {
+ mOperations.combineValues(IFACE_ALL, uid, tag, 0L, 0L, 0L, 0L, operationCount);
+ }
+ }
+
+ @Override
public void forceUpdate() {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
@@ -533,7 +580,7 @@
final NetworkStats uidSnapshot;
try {
networkSnapshot = mNetworkManager.getNetworkStatsSummary();
- uidSnapshot = detailedPoll ? mNetworkManager.getNetworkStatsDetail() : null;
+ uidSnapshot = detailedPoll ? mNetworkManager.getNetworkStatsUidDetail(UID_ALL) : null;
} catch (IllegalStateException e) {
Slog.w(TAG, "problem reading network stats: " + e);
return;
@@ -549,7 +596,7 @@
// decide if enough has changed to trigger persist
final NetworkStats persistDelta = computeStatsDelta(
- mLastPersistNetworkSnapshot, networkSnapshot);
+ mLastPersistNetworkSnapshot, networkSnapshot, true);
final long persistThreshold = mSettings.getPersistThreshold();
NetworkStats.Entry entry = null;
@@ -579,7 +626,7 @@
private void performNetworkPollLocked(NetworkStats networkSnapshot, long currentTime) {
final HashSet<String> unknownIface = Sets.newHashSet();
- final NetworkStats delta = computeStatsDelta(mLastNetworkSnapshot, networkSnapshot);
+ final NetworkStats delta = computeStatsDelta(mLastNetworkSnapshot, networkSnapshot, false);
final long timeStart = currentTime - delta.getElapsedRealtime();
NetworkStats.Entry entry = null;
@@ -592,7 +639,7 @@
}
final NetworkStatsHistory history = findOrCreateNetworkStatsLocked(ident);
- history.recordData(timeStart, currentTime, entry.rxBytes, entry.txBytes);
+ history.recordData(timeStart, currentTime, entry);
}
// trim any history beyond max
@@ -614,10 +661,13 @@
private void performUidPollLocked(NetworkStats uidSnapshot, long currentTime) {
ensureUidStatsLoadedLocked();
- final NetworkStats delta = computeStatsDelta(mLastUidSnapshot, uidSnapshot);
+ final NetworkStats delta = computeStatsDelta(mLastUidSnapshot, uidSnapshot, false);
+ final NetworkStats operationsDelta = computeStatsDelta(
+ mLastOperationsSnapshot, mOperations, false);
final long timeStart = currentTime - delta.getElapsedRealtime();
NetworkStats.Entry entry = null;
+ NetworkStats.Entry operationsEntry = null;
for (int i = 0; i < delta.size(); i++) {
entry = delta.getValues(i, entry);
final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface);
@@ -625,9 +675,16 @@
continue;
}
+ // splice in operation counts since last poll
+ final int j = operationsDelta.findIndex(IFACE_ALL, entry.uid, entry.tag);
+ if (j != -1) {
+ operationsEntry = operationsDelta.getValues(j, operationsEntry);
+ entry.operations = operationsEntry.operations;
+ }
+
final NetworkStatsHistory history = findOrCreateUidStatsLocked(
ident, entry.uid, entry.tag);
- history.recordData(timeStart, currentTime, entry.rxBytes, entry.txBytes);
+ history.recordData(timeStart, currentTime, entry);
}
// trim any history beyond max
@@ -648,6 +705,8 @@
}
mLastUidSnapshot = uidSnapshot;
+ mLastOperationsSnapshot = mOperations;
+ mOperations = new NetworkStats(0L, 10);
}
/**
@@ -873,6 +932,7 @@
out.flush();
mNetworkFile.finishWrite(fos);
} catch (IOException e) {
+ Slog.w(TAG, "problem writing stats: ", e);
if (fos != null) {
mNetworkFile.failWrite(fos);
}
@@ -919,6 +979,7 @@
out.flush();
mUidFile.finishWrite(fos);
} catch (IOException e) {
+ Slog.w(TAG, "problem writing stats: ", e);
if (fos != null) {
mUidFile.failWrite(fos);
}
@@ -980,7 +1041,7 @@
final int tag = unpackTag(packed);
final NetworkStatsHistory history = uidStats.valueAt(i);
pw.print(" UID="); pw.print(uid);
- pw.print(" tag="); pw.println(tag);
+ pw.print(" tag=0x"); pw.println(Integer.toHexString(tag));
history.dump(" ", pw, fullHistory);
}
}
@@ -993,15 +1054,20 @@
*/
@Deprecated
private void generateRandomLocked() {
- long networkEnd = System.currentTimeMillis();
- long networkStart = networkEnd - mSettings.getNetworkMaxHistory();
- long networkRx = 3 * GB_IN_BYTES;
- long networkTx = 2 * GB_IN_BYTES;
+ final long NET_END = System.currentTimeMillis();
+ final long NET_START = NET_END - mSettings.getNetworkMaxHistory();
+ final long NET_RX_BYTES = 3 * GB_IN_BYTES;
+ final long NET_RX_PACKETS = NET_RX_BYTES / 1024;
+ final long NET_TX_BYTES = 2 * GB_IN_BYTES;
+ final long NET_TX_PACKETS = NET_TX_BYTES / 1024;
- long uidEnd = System.currentTimeMillis();
- long uidStart = uidEnd - mSettings.getUidMaxHistory();
- long uidRx = 500 * MB_IN_BYTES;
- long uidTx = 100 * MB_IN_BYTES;
+ final long UID_END = System.currentTimeMillis();
+ final long UID_START = UID_END - mSettings.getUidMaxHistory();
+ final long UID_RX_BYTES = 500 * MB_IN_BYTES;
+ final long UID_RX_PACKETS = UID_RX_BYTES / 1024;
+ final long UID_TX_BYTES = 100 * MB_IN_BYTES;
+ final long UID_TX_PACKETS = UID_TX_BYTES / 1024;
+ final long UID_OPERATIONS = UID_RX_BYTES / 2048;
final List<ApplicationInfo> installedApps = mContext
.getPackageManager().getInstalledApplications(0);
@@ -1009,13 +1075,13 @@
mNetworkStats.clear();
mUidStats.clear();
for (NetworkIdentitySet ident : mActiveIfaces.values()) {
- findOrCreateNetworkStatsLocked(ident).generateRandom(
- networkStart, networkEnd, networkRx, networkTx);
+ findOrCreateNetworkStatsLocked(ident).generateRandom(NET_START, NET_END, NET_RX_BYTES,
+ NET_RX_PACKETS, NET_TX_BYTES, NET_TX_PACKETS, 0L);
for (ApplicationInfo info : installedApps) {
final int uid = info.uid;
- findOrCreateUidStatsLocked(ident, uid, TAG_NONE).generateRandom(
- uidStart, uidEnd, uidRx, uidTx);
+ findOrCreateUidStatsLocked(ident, uid, TAG_NONE).generateRandom(UID_START, UID_END,
+ UID_RX_BYTES, UID_RX_PACKETS, UID_TX_BYTES, UID_TX_PACKETS, UID_OPERATIONS);
}
}
}
@@ -1024,11 +1090,17 @@
* Return the delta between two {@link NetworkStats} snapshots, where {@code
* before} can be {@code null}.
*/
- private static NetworkStats computeStatsDelta(NetworkStats before, NetworkStats current) {
+ private static NetworkStats computeStatsDelta(
+ NetworkStats before, NetworkStats current, boolean collectStale) {
if (before != null) {
return current.subtractClamped(before);
- } else {
+ } else if (collectStale) {
+ // caller is okay collecting stale stats for first call.
return current;
+ } else {
+ // this is first snapshot; to prevent from double-counting we only
+ // observe traffic occuring between known snapshots.
+ return new NetworkStats(0L, 10);
}
}
@@ -1114,5 +1186,4 @@
return DAY_IN_MILLIS;
}
}
-
}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 88e0fa8..36371a57 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -3326,7 +3326,7 @@
if (pkg.applicationInfo.nativeLibraryDir != null) {
try {
final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
- final String dataPathString = dataPath.getCanonicalFile().getPath();
+ final String dataPathString = dataPath.getCanonicalPath();
if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
/*
@@ -3340,7 +3340,7 @@
Log.i(TAG, "removed obsolete native libraries for system package "
+ path);
}
- } else if (nativeLibraryDir.getCanonicalFile().getParent()
+ } else if (nativeLibraryDir.getParentFile().getCanonicalPath()
.equals(dataPathString)) {
/*
* Make sure the native library dir isn't a symlink to
@@ -5025,16 +5025,18 @@
}
int loc = pkgLite.recommendedInstallLocation;
- if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION){
+ if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
- } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS){
+ } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
- } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE){
+ } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
} else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
ret = PackageManager.INSTALL_FAILED_INVALID_APK;
+ } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
+ ret = PackageManager.INSTALL_FAILED_INVALID_URI;
} else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
- ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
+ ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
} else {
// Override with defaults if needed.
loc = installLocationPolicy(pkgLite, flags);
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index dcf040a..91c5e33 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -382,19 +382,18 @@
mAdbEnabled = enable;
// Due to the persist.sys.usb.config property trigger, changing adb state requires
// switching to default function
- setEnabledFunctions(mDefaultFunctions, false);
+ setEnabledFunctions(mDefaultFunctions, true);
updateAdbNotification();
}
}
private void setEnabledFunctions(String functions, boolean makeDefault) {
- if (mAdbEnabled) {
- functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB);
- } else {
- functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB);
- }
-
if (functions != null && makeDefault) {
+ if (mAdbEnabled) {
+ functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB);
+ } else {
+ functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB);
+ }
if (!mDefaultFunctions.equals(functions)) {
if (!setUsbConfig("none")) {
Slog.e(TAG, "Failed to disable USB");
@@ -418,6 +417,11 @@
if (functions == null) {
functions = mDefaultFunctions;
}
+ if (mAdbEnabled) {
+ functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB);
+ } else {
+ functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB);
+ }
if (!mCurrentFunctions.equals(functions)) {
if (!setUsbConfig("none")) {
Slog.e(TAG, "Failed to disable USB");
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index f8059f5..e0b5e17 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -4919,6 +4919,7 @@
matrix.postTranslate(-(int)(frame.left*scale), -(int)(frame.top*scale));
Canvas canvas = new Canvas(bm);
canvas.drawBitmap(rawss, matrix, null);
+ canvas.setBitmap(null);
rawss.recycle();
return bm;
diff --git a/services/jni/com_android_server_location_GpsLocationProvider.cpp b/services/jni/com_android_server_location_GpsLocationProvider.cpp
index c29be3a..c823da5 100755
--- a/services/jni/com_android_server_location_GpsLocationProvider.cpp
+++ b/services/jni/com_android_server_location_GpsLocationProvider.cpp
@@ -543,7 +543,7 @@
}
static void android_location_GpsLocationProvider_update_network_state(JNIEnv* env, jobject obj,
- jboolean connected, int type, jboolean roaming, jstring extraInfo)
+ jboolean connected, int type, jboolean roaming, jboolean available, jstring extraInfo, jstring apn)
{
if (sAGpsRilInterface && sAGpsRilInterface->update_network_state) {
@@ -554,6 +554,14 @@
} else {
sAGpsRilInterface->update_network_state(connected, type, roaming, NULL);
}
+
+ // update_network_availability callback was not included in original AGpsRilInterface
+ if (sAGpsRilInterface->size >= sizeof(AGpsRilInterface)
+ && sAGpsRilInterface->update_network_availability) {
+ const char *c_apn = env->GetStringUTFChars(apn, NULL);
+ sAGpsRilInterface->update_network_availability(available, c_apn);
+ env->ReleaseStringUTFChars(apn, c_apn);
+ }
}
}
@@ -582,7 +590,7 @@
{"native_send_ni_response", "(II)V", (void*)android_location_GpsLocationProvider_send_ni_response},
{"native_agps_ni_message", "([BI)V", (void *)android_location_GpsLocationProvider_agps_send_ni_message},
{"native_get_internal_state", "()Ljava/lang/String;", (void*)android_location_GpsLocationProvider_get_internal_state},
- {"native_update_network_state", "(ZIZLjava/lang/String;)V", (void*)android_location_GpsLocationProvider_update_network_state },
+ {"native_update_network_state", "(ZIZZLjava/lang/String;Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_update_network_state },
};
int register_android_server_location_GpsLocationProvider(JNIEnv* env)
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 7bf3e0a..f4be168 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -40,6 +40,7 @@
#include "GLExtensions.h"
#include "HWComposer.h"
+#include "SurfaceFlinger.h"
using namespace android;
@@ -75,7 +76,7 @@
const sp<SurfaceFlinger>& flinger,
uint32_t dpy)
: DisplayHardwareBase(flinger, dpy),
- mFlags(0), mHwc(0)
+ mFlinger(flinger), mFlags(0), mHwc(0)
{
init(dpy);
}
@@ -310,7 +311,7 @@
// initialize the H/W composer
- mHwc = new HWComposer();
+ mHwc = new HWComposer(mFlinger);
if (mHwc->initCheck() == NO_ERROR) {
mHwc->setFrameBuffer(mDisplay, mSurface);
}
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
index cdf89fd..40a6f1e 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -95,6 +95,7 @@
void init(uint32_t displayIndex) __attribute__((noinline));
void fini() __attribute__((noinline));
+ sp<SurfaceFlinger> mFlinger;
EGLDisplay mDisplay;
EGLSurface mSurface;
EGLContext mContext;
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
index 30eb258..3ebc7b6 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
@@ -37,7 +37,7 @@
~DisplayHardwareBase();
- // console managment
+ // console management
void releaseScreen() const;
void acquireScreen() const;
bool isScreenAcquired() const;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 4a3b20d..7d1bdf0 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -30,12 +30,14 @@
#include <EGL/egl.h>
#include "HWComposer.h"
+#include "SurfaceFlinger.h"
namespace android {
// ---------------------------------------------------------------------------
-HWComposer::HWComposer()
- : mModule(0), mHwc(0), mList(0), mCapacity(0),
+HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger)
+ : mFlinger(flinger),
+ mModule(0), mHwc(0), mList(0), mCapacity(0),
mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE)
{
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
@@ -44,6 +46,13 @@
err = hwc_open(mModule, &mHwc);
LOGE_IF(err, "%s device failed to initialize (%s)",
HWC_HARDWARE_COMPOSER, strerror(-err));
+ if (err == 0) {
+ if (mHwc->registerProcs) {
+ mCBContext.hwc = this;
+ mCBContext.procs.invalidate = &hook_invalidate;
+ mHwc->registerProcs(mHwc, &mCBContext.procs);
+ }
+ }
}
}
@@ -58,6 +67,14 @@
return mHwc ? NO_ERROR : NO_INIT;
}
+void HWComposer::hook_invalidate(struct hwc_procs* procs) {
+ reinterpret_cast<cb_context *>(procs)->hwc->invalidate();
+}
+
+void HWComposer::invalidate() {
+ mFlinger->signalEvent();
+}
+
void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) {
mDpy = (hwc_display_t)dpy;
mSur = (hwc_surface_t)sur;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 5a9e9eb..983898a 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -24,16 +24,19 @@
#include <hardware/hwcomposer.h>
+#include <utils/StrongPointer.h>
+
namespace android {
// ---------------------------------------------------------------------------
class String8;
+class SurfaceFlinger;
class HWComposer
{
public:
- HWComposer();
+ HWComposer(const sp<SurfaceFlinger>& flinger);
~HWComposer();
status_t initCheck() const;
@@ -60,12 +63,21 @@
void dump(String8& out, char* scratch, size_t SIZE) const;
private:
+ struct cb_context {
+ hwc_procs_t procs;
+ HWComposer* hwc;
+ };
+ static void hook_invalidate(struct hwc_procs* procs);
+ void invalidate();
+
+ sp<SurfaceFlinger> mFlinger;
hw_module_t const* mModule;
hwc_composer_device_t* mHwc;
hwc_layer_list_t* mList;
size_t mCapacity;
hwc_display_t mDpy;
hwc_surface_t mSur;
+ cb_context mCBContext;
};
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 886bb2a..383c045 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -172,17 +172,14 @@
void Layer::setGeometry(hwc_layer_t* hwcl)
{
- hwcl->compositionType = HWC_FRAMEBUFFER;
- hwcl->hints = 0;
- hwcl->flags = 0;
- hwcl->transform = 0;
- hwcl->blending = HWC_BLENDING_NONE;
+ LayerBaseClient::setGeometry(hwcl);
+
+ hwcl->flags &= ~HWC_SKIP_LAYER;
// we can't do alpha-fade with the hwc HAL
const State& s(drawingState());
if (s.alpha < 0xFF) {
hwcl->flags = HWC_SKIP_LAYER;
- return;
}
/*
@@ -205,26 +202,9 @@
// we can only handle simple transformation
if (finalTransform & Transform::ROT_INVALID) {
hwcl->flags = HWC_SKIP_LAYER;
- return;
+ } else {
+ hwcl->transform = finalTransform;
}
-
- hwcl->transform = finalTransform;
-
- if (!isOpaque()) {
- hwcl->blending = mPremultipliedAlpha ?
- HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
- }
-
- // scaling is already applied in mTransformedBounds
- hwcl->displayFrame.left = mTransformedBounds.left;
- hwcl->displayFrame.top = mTransformedBounds.top;
- hwcl->displayFrame.right = mTransformedBounds.right;
- hwcl->displayFrame.bottom = mTransformedBounds.bottom;
-
- hwcl->visibleRegionScreen.rects =
- reinterpret_cast<hwc_rect_t const *>(
- visibleRegionScreen.getArray(
- &hwcl->visibleRegionScreen.numRects));
}
void Layer::setPerFrameData(hwc_layer_t* hwcl) {
@@ -235,9 +215,9 @@
// HWC handle it.
hwcl->flags |= HWC_SKIP_LAYER;
hwcl->handle = NULL;
- return;
+ } else {
+ hwcl->handle = buffer->handle;
}
- hwcl->handle = buffer->handle;
if (isCropped()) {
hwcl->sourceCrop.left = mCurrentCrop.left;
@@ -247,8 +227,13 @@
} else {
hwcl->sourceCrop.left = 0;
hwcl->sourceCrop.top = 0;
- hwcl->sourceCrop.right = buffer->width;
- hwcl->sourceCrop.bottom = buffer->height;
+ if (buffer != NULL) {
+ hwcl->sourceCrop.right = buffer->width;
+ hwcl->sourceCrop.bottom = buffer->height;
+ } else {
+ hwcl->sourceCrop.right = mTransformedBounds.width();
+ hwcl->sourceCrop.bottom = mTransformedBounds.height();
+ }
}
}
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index c86c659..e04c533 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -302,13 +302,47 @@
}
}
-void LayerBase::setGeometry(hwc_layer_t* hwcl) {
- hwcl->flags |= HWC_SKIP_LAYER;
+void LayerBase::setGeometry(hwc_layer_t* hwcl)
+{
+ hwcl->compositionType = HWC_FRAMEBUFFER;
+ hwcl->hints = 0;
+ hwcl->flags = HWC_SKIP_LAYER;
+ hwcl->transform = 0;
+ hwcl->blending = HWC_BLENDING_NONE;
+
+ // this gives us only the "orientation" component of the transform
+ const State& s(drawingState());
+ const uint32_t finalTransform = s.transform.getOrientation();
+ // we can only handle simple transformation
+ if (finalTransform & Transform::ROT_INVALID) {
+ hwcl->flags = HWC_SKIP_LAYER;
+ } else {
+ hwcl->transform = finalTransform;
+ }
+
+ if (!isOpaque()) {
+ hwcl->blending = mPremultipliedAlpha ?
+ HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
+ }
+
+ // scaling is already applied in mTransformedBounds
+ hwcl->displayFrame.left = mTransformedBounds.left;
+ hwcl->displayFrame.top = mTransformedBounds.top;
+ hwcl->displayFrame.right = mTransformedBounds.right;
+ hwcl->displayFrame.bottom = mTransformedBounds.bottom;
+ hwcl->visibleRegionScreen.rects =
+ reinterpret_cast<hwc_rect_t const *>(
+ visibleRegionScreen.getArray(
+ &hwcl->visibleRegionScreen.numRects));
}
void LayerBase::setPerFrameData(hwc_layer_t* hwcl) {
hwcl->compositionType = HWC_FRAMEBUFFER;
hwcl->handle = NULL;
+ hwcl->sourceCrop.left = 0;
+ hwcl->sourceCrop.top = 0;
+ hwcl->sourceCrop.right = mTransformedBounds.width();
+ hwcl->sourceCrop.bottom = mTransformedBounds.height();
}
void LayerBase::setFiltering(bool filtering)
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 1620405..60be35a 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -26,10 +26,12 @@
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
<uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+
<uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
<uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
+ <uses-permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING" />
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
- <uses-permission android:name="android.permission.WAKE_LOCK" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
index 56ef995a..f628977 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
@@ -50,10 +50,9 @@
public void setUp() throws Exception {
super.setUp();
- final File canonicalFilesDir = getContext().getFilesDir().getCanonicalFile();
- mTestProc = new File(canonicalFilesDir, "proc");
+ mTestProc = new File(getContext().getFilesDir(), "proc");
if (mTestProc.exists()) {
- Files.deleteRecursively(mTestProc);
+ IoUtils.deleteContents(mTestProc);
}
mService = NetworkManagementService.createForTest(mContext, mTestProc, true);
@@ -64,7 +63,7 @@
mService = null;
if (mTestProc.exists()) {
- Files.deleteRecursively(mTestProc);
+ IoUtils.deleteContents(mTestProc);
}
super.tearDown();
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index aab09ca..09f8ff3 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -20,14 +20,18 @@
import static android.content.Intent.EXTRA_UID;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.TYPE_WIFI;
+import static android.net.NetworkPolicy.LIMIT_DISABLED;
import static android.net.NetworkPolicy.SNOOZE_NEVER;
+import static android.net.NetworkPolicy.WARNING_DISABLED;
import static android.net.NetworkPolicyManager.POLICY_NONE;
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
+import static android.net.NetworkPolicyManager.computeNextCycleBoundary;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
+import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT;
import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED;
@@ -79,6 +83,7 @@
import org.easymock.IAnswer;
import java.io.File;
+import java.util.LinkedHashSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@@ -197,9 +202,6 @@
expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce();
expectTime(System.currentTimeMillis());
- // default behavior is background data enabled
- expect(mConnManager.getBackgroundDataSetting()).andReturn(true);
-
replay();
mService.systemReady();
verifyAndReset();
@@ -405,7 +407,7 @@
final NetworkPolicy policy = new NetworkPolicy(
sTemplateWifi, 5, 1024L, 1024L, SNOOZE_NEVER);
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
- assertEquals(expectedCycle, actualCycle);
+ assertTimeEquals(expectedCycle, actualCycle);
}
public void testLastCycleBoundaryLastMonth() throws Exception {
@@ -416,7 +418,7 @@
final NetworkPolicy policy = new NetworkPolicy(
sTemplateWifi, 20, 1024L, 1024L, SNOOZE_NEVER);
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
- assertEquals(expectedCycle, actualCycle);
+ assertTimeEquals(expectedCycle, actualCycle);
}
public void testLastCycleBoundaryThisMonthFebruary() throws Exception {
@@ -427,18 +429,48 @@
final NetworkPolicy policy = new NetworkPolicy(
sTemplateWifi, 30, 1024L, 1024L, SNOOZE_NEVER);
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
- assertEquals(expectedCycle, actualCycle);
+ assertTimeEquals(expectedCycle, actualCycle);
}
public void testLastCycleBoundaryLastMonthFebruary() throws Exception {
// assume cycle day of "30th" in february, which should clamp
final long currentTime = parseTime("2007-03-14T00:00:00.000Z");
- final long expectedCycle = parseTime("2007-03-01T00:00:00.000Z");
+ final long expectedCycle = parseTime("2007-02-28T23:59:59.000Z");
final NetworkPolicy policy = new NetworkPolicy(
sTemplateWifi, 30, 1024L, 1024L, SNOOZE_NEVER);
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
- assertEquals(expectedCycle, actualCycle);
+ assertTimeEquals(expectedCycle, actualCycle);
+ }
+
+ public void testNextCycleSane() throws Exception {
+ final NetworkPolicy policy = new NetworkPolicy(
+ sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER);
+ final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();
+
+ // walk forwards, ensuring that cycle boundaries don't get stuck
+ long currentCycle = computeNextCycleBoundary(parseTime("2011-08-01T00:00:00.000Z"), policy);
+ for (int i = 0; i < 128; i++) {
+ long nextCycle = computeNextCycleBoundary(currentCycle, policy);
+ assertEqualsFuzzy(DAY_IN_MILLIS * 30, nextCycle - currentCycle, DAY_IN_MILLIS * 3);
+ assertUnique(seen, nextCycle);
+ currentCycle = nextCycle;
+ }
+ }
+
+ public void testLastCycleSane() throws Exception {
+ final NetworkPolicy policy = new NetworkPolicy(
+ sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER);
+ final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();
+
+ // walk backwards, ensuring that cycle boundaries look sane
+ long currentCycle = computeLastCycleBoundary(parseTime("2011-08-04T00:00:00.000Z"), policy);
+ for (int i = 0; i < 128; i++) {
+ long lastCycle = computeLastCycleBoundary(currentCycle, policy);
+ assertEqualsFuzzy(DAY_IN_MILLIS * 30, currentCycle - lastCycle, DAY_IN_MILLIS * 3);
+ assertUnique(seen, lastCycle);
+ currentCycle = lastCycle;
+ }
}
public void testNetworkPolicyAppliedCycleLastMonth() throws Exception {
@@ -471,7 +503,7 @@
// pretend that 512 bytes total have happened
stats = new NetworkStats(elapsedRealtime, 1)
- .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 256L, 2L, 256L, 2L);
+ .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 256L, 2L, 256L, 2L, 11);
expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, TIME_MAR_10))
.andReturn(stats).atLeastOnce();
@@ -547,7 +579,7 @@
elapsedRealtime += MINUTE_IN_MILLIS;
currentTime = TIME_MAR_10 + elapsedRealtime;
stats = new NetworkStats(elapsedRealtime, 1)
- .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L);
+ .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0);
state = new NetworkState[] { buildWifi() };
{
@@ -574,7 +606,7 @@
elapsedRealtime += MINUTE_IN_MILLIS;
currentTime = TIME_MAR_10 + elapsedRealtime;
stats = new NetworkStats(elapsedRealtime, 1)
- .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 1536L, 15L, 0L, 0L);
+ .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 1536L, 15L, 0L, 0L, 11);
{
expectTime(currentTime);
@@ -595,7 +627,7 @@
elapsedRealtime += MINUTE_IN_MILLIS;
currentTime = TIME_MAR_10 + elapsedRealtime;
stats = new NetworkStats(elapsedRealtime, 1)
- .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 5120L, 512L, 0L, 0L);
+ .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 5120L, 512L, 0L, 0L, 22);
{
expectTime(currentTime);
@@ -737,6 +769,32 @@
}
}
+ private static void assertTimeEquals(long expected, long actual) {
+ if (expected != actual) {
+ fail("expected " + formatTime(expected) + " but was actually " + formatTime(actual));
+ }
+ }
+
+ private static String formatTime(long millis) {
+ final Time time = new Time(Time.TIMEZONE_UTC);
+ time.set(millis);
+ return time.format3339(false);
+ }
+
+ private static void assertEqualsFuzzy(long expected, long actual, long fuzzy) {
+ final long low = expected - fuzzy;
+ final long high = expected + fuzzy;
+ if (actual < low || actual > high) {
+ fail("value " + actual + " is outside [" + low + "," + high + "]");
+ }
+ }
+
+ private static void assertUnique(LinkedHashSet<Long> seen, Long value) {
+ if (!seen.add(value)) {
+ fail("found duplicate time " + value + " in series " + seen.toString());
+ }
+ }
+
private static void assertNotificationType(int expected, String actualTag) {
assertEquals(
Integer.toString(expected), actualTag.substring(actualTag.lastIndexOf(':') + 1));
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index bd80af9..8eb9cc3 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -25,6 +25,7 @@
import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
+import static android.net.NetworkStatsHistory.FIELD_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.NetworkTemplate.buildTemplateWifi;
import static android.net.TrafficStats.UID_REMOVED;
@@ -160,22 +161,25 @@
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
// verify service has empty history for wifi
- assertNetworkTotal(sTemplateWifi, 0L, 0L);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
verifyAndReset();
+ // bootstrap with full polling event to prime stats
+ performBootstrapPoll(TEST_START, elapsedRealtime);
+
// modify some number on wifi, and trigger poll event
elapsedRealtime += HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 1L, 2048L, 2L));
- expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
+ assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
verifyAndReset();
// and bump forward again, with counters going higher. this is
@@ -185,13 +189,13 @@
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_ALL, TAG_NONE, 4096L, 4L, 8192L, 8L));
- expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertNetworkTotal(sTemplateWifi, 4096L, 8192L);
+ assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0);
verifyAndReset();
}
@@ -211,26 +215,32 @@
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
// verify service has empty history for wifi
- assertNetworkTotal(sTemplateWifi, 0L, 0L);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
verifyAndReset();
+ // bootstrap with full polling event to prime stats
+ performBootstrapPoll(TEST_START, elapsedRealtime);
+
// modify some number on wifi, and trigger poll event
elapsedRealtime += HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 8L, 2048L, 16L));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 2)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 2)
.addValues(TEST_IFACE, UID_RED, TAG_NONE, 512L, 4L, 256L, 2L)
.addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 128L, 1L, 128L, 1L));
+ mService.incrementOperationCount(UID_RED, TAG_NONE, 20);
+ mService.incrementOperationCount(UID_BLUE, TAG_NONE, 10);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
- assertUidTotal(sTemplateWifi, UID_RED, 512L, 256L);
- assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 128L);
+ assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
+ assertUidTotal(sTemplateWifi, UID_RED, 512L, 4L, 256L, 2L, 20);
+ assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 10);
verifyAndReset();
// graceful shutdown system, which should trigger persist of stats, and
@@ -241,7 +251,7 @@
// we persisted them to file.
expectDefaultSettings();
replay();
- assertNetworkTotal(sTemplateWifi, 0L, 0L);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
verifyAndReset();
assertStatsFilesExist(true);
@@ -254,9 +264,9 @@
mService.systemReady();
// after systemReady(), we should have historical stats loaded again
- assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
- assertUidTotal(sTemplateWifi, UID_RED, 512L, 256L);
- assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 128L);
+ assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
+ assertUidTotal(sTemplateWifi, UID_RED, 512L, 4L, 256L, 2L, 20);
+ assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 10);
verifyAndReset();
}
@@ -278,20 +288,23 @@
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
verifyAndReset();
+ // bootstrap with full polling event to prime stats
+ performBootstrapPoll(TEST_START, elapsedRealtime);
+
// modify some number on wifi, and trigger poll event
elapsedRealtime += 2 * HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_ALL, TAG_NONE, 512L, 4L, 512L, 4L));
- expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- history = mService.getHistoryForNetwork(sTemplateWifi);
- assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 512L);
+ history = mService.getHistoryForNetwork(sTemplateWifi, FIELD_ALL);
+ assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
assertEquals(HOUR_IN_MILLIS, history.getBucketDuration());
assertEquals(2, history.size());
verifyAndReset();
@@ -301,14 +314,14 @@
expectTime(TEST_START + elapsedRealtime);
expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
- expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify identical stats, but spread across 4 buckets now
- history = mService.getHistoryForNetwork(sTemplateWifi);
- assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 512L);
+ history = mService.getHistoryForNetwork(sTemplateWifi, FIELD_ALL);
+ assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
assertEquals(30 * MINUTE_IN_MILLIS, history.getBucketDuration());
assertEquals(4, history.size());
verifyAndReset();
@@ -328,25 +341,32 @@
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
verifyAndReset();
+ // bootstrap with full polling event to prime stats
+ performBootstrapPoll(TEST_START, elapsedRealtime);
+
// create some traffic on first network
elapsedRealtime += HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_ALL, TAG_NONE, 2048L, 16L, 512L, 4L));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 3)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 3)
.addValues(TEST_IFACE, UID_RED, TAG_NONE, 1536L, 12L, 512L, 4L)
.addValues(TEST_IFACE, UID_RED, 0xF00D, 512L, 4L, 512L, 4L)
.addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 512L, 4L, 0L, 0L));
+ mService.incrementOperationCount(UID_RED, TAG_NONE, 15);
+ mService.incrementOperationCount(UID_RED, 0xF00D, 10);
+ mService.incrementOperationCount(UID_BLUE, TAG_NONE, 5);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertNetworkTotal(sTemplateImsi1, 2048L, 512L);
- assertNetworkTotal(sTemplateWifi, 0L, 0L);
- assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 512L);
- assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 0L);
+ assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
+ assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 15);
+ assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 5);
verifyAndReset();
// now switch networks; this also tests that we're okay with interfaces
@@ -356,7 +376,7 @@
expectDefaultSettings();
expectNetworkState(buildMobile3gState(IMSI_2));
expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
- expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
@@ -369,22 +389,24 @@
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_ALL, TAG_NONE, 128L, 1L, 1024L, 8L));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 128L, 1L, 1024L, 8L));
+ mService.incrementOperationCount(UID_BLUE, TAG_NONE, 10);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify original history still intact
- assertNetworkTotal(sTemplateImsi1, 2048L, 512L);
- assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 512L);
- assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 0L);
+ assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
+ assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 15);
+ assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 5);
// and verify new history also recorded under different template, which
// verifies that we didn't cross the streams.
- assertNetworkTotal(sTemplateImsi2, 128L, 1024L);
- assertNetworkTotal(sTemplateWifi, 0L, 0L);
- assertUidTotal(sTemplateImsi2, UID_BLUE, 128L, 1024L);
+ assertNetworkTotal(sTemplateImsi2, 128L, 1L, 1024L, 8L, 0);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
+ assertUidTotal(sTemplateImsi2, UID_BLUE, 128L, 1L, 1024L, 8L, 10);
verifyAndReset();
}
@@ -402,25 +424,32 @@
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
verifyAndReset();
+ // bootstrap with full polling event to prime stats
+ performBootstrapPoll(TEST_START, elapsedRealtime);
+
// create some traffic
elapsedRealtime += HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_ALL, TAG_NONE, 4128L, 258L, 544L, 34L));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_RED, TAG_NONE, 16L, 1L, 16L, 1L)
.addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 4096L, 258L, 512L, 32L)
.addValues(TEST_IFACE, UID_GREEN, TAG_NONE, 16L, 1L, 16L, 1L));
+ mService.incrementOperationCount(UID_RED, TAG_NONE, 10);
+ mService.incrementOperationCount(UID_BLUE, TAG_NONE, 15);
+ mService.incrementOperationCount(UID_GREEN, TAG_NONE, 5);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertNetworkTotal(sTemplateWifi, 4128L, 544L);
- assertUidTotal(sTemplateWifi, UID_RED, 16L, 16L);
- assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 512L);
- assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 16L);
+ assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
+ assertUidTotal(sTemplateWifi, UID_RED, 16L, 1L, 16L, 1L, 10);
+ assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 15);
+ assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 5);
verifyAndReset();
// now pretend two UIDs are uninstalled, which should migrate stats to
@@ -435,11 +464,11 @@
// existing uid and total should remain unchanged; but removed UID
// should be gone completely.
- assertNetworkTotal(sTemplateWifi, 4128L, 544L);
- assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L);
- assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L);
- assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 16L);
- assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 528L);
+ assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
+ assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L, 0L, 0L, 0);
+ assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L, 0L, 0L, 0);
+ assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 5);
+ assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 259L, 528L, 33L, 25);
verifyAndReset();
}
@@ -457,20 +486,26 @@
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
verifyAndReset();
+ // bootstrap with full polling event to prime stats
+ performBootstrapPoll(TEST_START, elapsedRealtime);
+
// create some traffic
elapsedRealtime += HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_RED, TAG_NONE, 1024L, 8L, 1024L, 8L)
.addValues(TEST_IFACE, UID_RED, 0xF00D, 512L, 4L, 512L, 4L));
+ mService.incrementOperationCount(UID_RED, TAG_NONE, 10);
+ mService.incrementOperationCount(UID_RED, 0xF00D, 5);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 1024L);
+ assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 8L, 1024L, 8L, 10);
verifyAndReset();
// now switch over to 4g network
@@ -479,7 +514,7 @@
expectDefaultSettings();
expectNetworkState(buildMobile4gState());
expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
- expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
@@ -491,14 +526,16 @@
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_RED, TAG_NONE, 512L, 4L, 256L, 2L));
+ mService.incrementOperationCount(UID_RED, TAG_NONE, 5);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify that ALL_MOBILE template combines both
- assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 1280L);
+ assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 1280L, 10L, 15);
verifyAndReset();
@@ -537,32 +574,41 @@
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
verifyAndReset();
+ // bootstrap with full polling event to prime stats
+ performBootstrapPoll(TEST_START, elapsedRealtime);
+
// create some traffic for two apps
elapsedRealtime += HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_RED, TAG_NONE, 50L, 5L, 50L, 5L)
.addValues(TEST_IFACE, UID_RED, 0xF00D, 10L, 1L, 10L, 1L)
.addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 1024L, 8L, 512L, 4L));
+ mService.incrementOperationCount(UID_RED, TAG_NONE, 5);
+ mService.incrementOperationCount(UID_RED, 0xF00D, 1);
+ mService.incrementOperationCount(UID_BLUE, TAG_NONE, 10);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertUidTotal(sTemplateWifi, UID_RED, 50L, 50L);
- assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 512L);
+ assertUidTotal(sTemplateWifi, UID_RED, 50L, 5L, 50L, 5L, 5);
+ assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 8L, 512L, 4L, 10);
verifyAndReset();
-
+
// now create more traffic in next hour, but only for one app
elapsedRealtime += HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 2048L, 16L, 1024L, 8L));
+ mService.incrementOperationCount(UID_BLUE, TAG_NONE, 15);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
@@ -570,28 +616,33 @@
NetworkStats stats = mService.getSummaryForAllUid(
sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
assertEquals(3, stats.size());
- assertValues(stats, 0, IFACE_ALL, UID_RED, TAG_NONE, 50L, 5L, 50L, 5L);
- assertValues(stats, 1, IFACE_ALL, UID_RED, 0xF00D, 10L, 1L, 10L, 1L);
- assertValues(stats, 2, IFACE_ALL, UID_BLUE, TAG_NONE, 2048L, 16L, 1024L, 8L);
+ assertValues(stats, 0, IFACE_ALL, UID_RED, TAG_NONE, 50L, 5L, 50L, 5L, 5);
+ assertValues(stats, 1, IFACE_ALL, UID_RED, 0xF00D, 10L, 1L, 10L, 1L, 1);
+ assertValues(stats, 2, IFACE_ALL, UID_BLUE, TAG_NONE, 2048L, 16L, 1024L, 8L, 15);
// now verify that recent history only contains one uid
final long currentTime = TEST_START + elapsedRealtime;
stats = mService.getSummaryForAllUid(
sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true);
assertEquals(1, stats.size());
- assertValues(stats, 0, IFACE_ALL, UID_BLUE, TAG_NONE, 1024L, 8L, 512L, 4L);
+ assertValues(stats, 0, IFACE_ALL, UID_BLUE, TAG_NONE, 1024L, 8L, 512L, 4L, 5);
verifyAndReset();
}
- private void assertNetworkTotal(NetworkTemplate template, long rxBytes, long txBytes) {
- final NetworkStatsHistory history = mService.getHistoryForNetwork(template);
- assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, txBytes);
+ private void assertNetworkTotal(NetworkTemplate template, long rxBytes, long rxPackets,
+ long txBytes, long txPackets, int operations) {
+ final NetworkStatsHistory history = mService.getHistoryForNetwork(template, FIELD_ALL);
+ assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
+ txPackets, operations);
}
- private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long txBytes) {
- final NetworkStatsHistory history = mService.getHistoryForUid(template, uid, TAG_NONE);
- assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, txBytes);
+ private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long rxPackets,
+ long txBytes, long txPackets, int operations) {
+ final NetworkStatsHistory history = mService.getHistoryForUid(
+ template, uid, TAG_NONE, FIELD_ALL);
+ assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
+ txPackets, operations);
}
private void expectSystemReady() throws Exception {
@@ -611,8 +662,8 @@
expect(mNetManager.getNetworkStatsSummary()).andReturn(summary).atLeastOnce();
}
- private void expectNetworkStatsDetail(NetworkStats detail) throws Exception {
- expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce();
+ private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
+ expect(mNetManager.getNetworkStatsUidDetail(eq(UID_ALL))).andReturn(detail).atLeastOnce();
}
private void expectDefaultSettings() throws Exception {
@@ -639,6 +690,17 @@
expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
}
+ private void performBootstrapPoll(long testStart, long elapsedRealtime) throws Exception {
+ expectTime(testStart + elapsedRealtime);
+ expectDefaultSettings();
+ expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
+
+ replay();
+ mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
+ verifyAndReset();
+ }
+
private void assertStatsFilesExist(boolean exist) {
final File networkFile = new File(mStatsDir, "netstats.bin");
final File uidFile = new File(mStatsDir, "netstats_uid.bin");
@@ -652,23 +714,26 @@
}
private static void assertValues(NetworkStats stats, int i, String iface, int uid, int tag,
- long rxBytes, long rxPackets, long txBytes, long txPackets) {
+ long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) {
final NetworkStats.Entry entry = stats.getValues(i, null);
- assertEquals(iface, entry.iface);
- assertEquals(uid, entry.uid);
- assertEquals(tag, entry.tag);
- assertEquals(rxBytes, entry.rxBytes);
- // TODO: enable testing packet counts once stored in history
-// assertEquals(rxPackets, entry.rxPackets);
- assertEquals(txBytes, entry.txBytes);
-// assertEquals(txPackets, entry.txPackets);
+ assertEquals("unexpected iface", iface, entry.iface);
+ assertEquals("unexpected uid", uid, entry.uid);
+ assertEquals("unexpected tag", tag, entry.tag);
+ assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
+ assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
+ assertEquals("unexpected txBytes", txBytes, entry.txBytes);
+ assertEquals("unexpected txPackets", txPackets, entry.txPackets);
+ assertEquals("unexpected operations", operations, entry.operations);
}
- private static void assertValues(
- NetworkStatsHistory stats, long start, long end, long rxBytes, long txBytes) {
+ private static void assertValues(NetworkStatsHistory stats, long start, long end, long rxBytes,
+ long rxPackets, long txBytes, long txPackets, int operations) {
final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
+ assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
assertEquals("unexpected txBytes", txBytes, entry.txBytes);
+ assertEquals("unexpected txPackets", txPackets, entry.txPackets);
+ assertEquals("unexpected operations", operations, entry.operations);
}
private static NetworkState buildWifiState() {
diff --git a/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java b/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
index 50c18f0..c0870c7 100644
--- a/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
@@ -289,7 +289,7 @@
public void expectGetInterfaceCounter(long rx, long tx) throws Exception {
// TODO: provide elapsedRealtime mock to match TimeAuthority
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
- stats.addValues(TEST_IFACE, NetworkStats.UID_ALL, NetworkStats.TAG_NONE, rx, 0L, tx, 0L);
+ stats.addValues(TEST_IFACE, NetworkStats.UID_ALL, NetworkStats.TAG_NONE, rx, 0L, tx, 0L, 0);
expect(mMockNMService.getNetworkStatsSummary()).andReturn(stats).atLeastOnce();
}
diff --git a/tests/GridLayoutTest/res/layout/grid3.xml b/tests/GridLayoutTest/res/layout/grid3.xml
index 2eca384..0e53613 100644
--- a/tests/GridLayoutTest/res/layout/grid3.xml
+++ b/tests/GridLayoutTest/res/layout/grid3.xml
@@ -22,6 +22,7 @@
android:useDefaultMargins="true"
android:alignmentMode="alignBounds"
+ android:rowOrderPreserved="false"
android:columnCount="4"
>
@@ -49,7 +50,7 @@
/>
<EditText
- android:layout_width="64dip"
+ android:ems="10"
/>
<TextView
@@ -60,13 +61,13 @@
/>
<EditText
- android:layout_width="32dip"
+ android:ems="8"
/>
<Space
- android:layout_row="4"
+ android:layout_row="2"
+ android:layout_rowSpan="3"
android:layout_column="2"
- android:layout_margin="0dip"
android:layout_gravity="fill"
/>
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
index e1871ac..8974f37 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
@@ -34,15 +34,16 @@
public class Activity2 extends Activity {
public static View create(Context context) {
- GridLayout vg = new GridLayout(context);
- vg.setUseDefaultMargins(true);
- vg.setAlignmentMode(ALIGN_BOUNDS);
+ GridLayout p = new GridLayout(context);
+ p.setUseDefaultMargins(true);
+ p.setAlignmentMode(ALIGN_BOUNDS);
+ p.setRowOrderPreserved(false);
Spec row1 = spec(0);
Spec row2 = spec(1);
Spec row3 = spec(2, BASELINE);
Spec row4 = spec(3, BASELINE);
- Spec row5 = spec(4, FILL);
+ Spec row5 = spec(2, 3, FILL); // allow the last two rows to overlap the middle two
Spec row6 = spec(5);
Spec row7 = spec(6);
@@ -55,63 +56,56 @@
Spec col4b = spec(3, FILL);
{
- TextView v = new TextView(context);
- v.setTextSize(32);
- v.setText("Email setup");
- vg.addView(v, new LayoutParams(row1, col1a));
+ TextView c = new TextView(context);
+ c.setTextSize(32);
+ c.setText("Email setup");
+ p.addView(c, new LayoutParams(row1, col1a));
}
{
- TextView v = new TextView(context);
- v.setTextSize(16);
- v.setText("You can configure email in just a few steps:");
- vg.addView(v, new LayoutParams(row2, col1b));
+ TextView c = new TextView(context);
+ c.setTextSize(16);
+ c.setText("You can configure email in just a few steps:");
+ p.addView(c, new LayoutParams(row2, col1b));
}
{
- TextView v = new TextView(context);
- v.setText("Email address:");
- vg.addView(v, new LayoutParams(row3, col1c));
+ TextView c = new TextView(context);
+ c.setText("Email address:");
+ p.addView(c, new LayoutParams(row3, col1c));
}
{
- EditText v = new EditText(context);
- v.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
- {
- LayoutParams lp = new LayoutParams(row3, col2);
- lp.width = (int) v.getPaint().measureText("Frederick.W.Flintstone");
- vg.addView(v, lp);
- }
+ EditText c = new EditText(context);
+ c.setEms(10);
+ c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
+ p.addView(c, new LayoutParams(row3, col2));
}
{
- TextView v = new TextView(context);
- v.setText("Password:");
- vg.addView(v, new LayoutParams(row4, col1c));
+ TextView c = new TextView(context);
+ c.setText("Password:");
+ p.addView(c, new LayoutParams(row4, col1c));
}
{
- TextView v = new EditText(context);
- v.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD);
- {
- LayoutParams lp = new LayoutParams(row4, col2);
- lp.width = (int) v.getPaint().measureText("************");
- vg.addView(v, lp);
- }
+ TextView c = new EditText(context);
+ c.setEms(8);
+ c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD);
+ p.addView(c, new LayoutParams(row4, col2));
}
{
- Space v = new Space(context);
+ Space c = new Space(context);
LayoutParams lp = new LayoutParams(row5, col3);
- lp.setMargins(0, 0, 0, 0);
- vg.addView(v, lp);
+ p.addView(c, lp);
}
{
- Button v = new Button(context);
- v.setText("Manual setup");
- vg.addView(v, new LayoutParams(row6, col4a));
+ Button c = new Button(context);
+ c.setText("Manual setup");
+ p.addView(c, new LayoutParams(row6, col4a));
}
{
- Button v = new Button(context);
- v.setText("Next");
- vg.addView(v, new LayoutParams(row7, col4b));
+ Button c = new Button(context);
+ c.setText("Next");
+ p.addView(c, new LayoutParams(row7, col4b));
}
- return vg;
+ return p;
}
protected void onCreate(Bundle savedInstanceState) {
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/PathsActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsActivity.java
index 833b61c..c241a62 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/PathsActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsActivity.java
@@ -101,6 +101,7 @@
Canvas canvas = new Canvas(mBitmap);
canvas.translate(-mPathBounds.left + mOffset * 1.5f, -mPathBounds.top + mOffset * 1.5f);
canvas.drawPath(mPath, mMediumPaint);
+ canvas.setBitmap(null);
}
@Override
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java
index 7bf25cf..4037a69 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java
@@ -77,13 +77,23 @@
super.onDraw(canvas);
canvas.drawRGB(255, 255, 255);
+ mMediumPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+ mMediumPaint.setStrokeWidth(2.0f);
canvas.drawText("Hello OpenGL renderer!", 100, 20, mMediumPaint);
+
+ mMediumPaint.setStyle(Paint.Style.FILL);
mMediumPaint.setTextAlign(Paint.Align.CENTER);
canvas.drawText("Hello OpenGL renderer!", 100, 40, mMediumPaint);
+
+ mMediumPaint.setStyle(Paint.Style.STROKE);
+ mMediumPaint.setStrokeWidth(2.0f);
mMediumPaint.setTextAlign(Paint.Align.RIGHT);
canvas.drawText("Hello OpenGL renderer!", 100, 60, mMediumPaint);
+
+ mMediumPaint.setStyle(Paint.Style.FILL);
mMediumPaint.setTextAlign(Paint.Align.LEFT);
canvas.drawText("Hello OpenGL renderer!", 100, 100, mMediumPaint);
+
mMediumPaint.setShadowLayer(2.5f, 0.0f, 0.0f, 0xff000000);
canvas.drawText("Hello OpenGL renderer!", 100, 150, mMediumPaint);
mMediumPaint.clearShadowLayer();
diff --git a/tests/TileBenchmark/res/values/strings.xml b/tests/TileBenchmark/res/values/strings.xml
index 66972ac..c4fd189 100644
--- a/tests/TileBenchmark/res/values/strings.xml
+++ b/tests/TileBenchmark/res/values/strings.xml
@@ -71,8 +71,16 @@
<string name="frames_per_second">Frames/sec</string>
<!-- Portion of viewport covered by good tiles [CHAR LIMIT=15] -->
<string name="viewport_coverage">Coverage</string>
+ <!-- Milliseconds taken to inval, and re-render the page [CHAR LIMIT=15] -->
+ <string name="render_millis">RenderMillis</string>
<!-- Format string for stat value overlay [CHAR LIMIT=15] -->
<string name="format_stat">%4.4f</string>
+
+ <!-- Format string for viewport position value overlay [CHAR LIMIT=25] -->
+ <string name="format_view_pos">View:(%1$d,%2$d)-(%3$d,%4$d)</string>
+ <!-- Format string for viewport position value overlay [CHAR LIMIT=25] -->
+ <string name="format_inval_pos">Inval:(%1$d,%2$d)-(%3$d,%4$d)</string>
+
<!-- Format string for displaying aggregate stats+values (nr of valid tiles,
etc.) [CHAR LIMIT=20] -->
<string name="format_stat_name">%1$-20s %2$3d</string>
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackActivity.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackActivity.java
index 36694a7..1eb1c00 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackActivity.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackActivity.java
@@ -83,14 +83,14 @@
}
};
- private class LoadFileTask extends AsyncTask<String, Void, TileData[][]> {
+ private class LoadFileTask extends AsyncTask<String, Void, RunData> {
@Override
- protected TileData[][] doInBackground(String... params) {
- TileData[][] data = null;
+ protected RunData doInBackground(String... params) {
+ RunData data = null;
try {
FileInputStream fis = openFileInput(params[0]);
ObjectInputStream in = new ObjectInputStream(fis);
- data = (TileData[][]) in.readObject();
+ data = (RunData) in.readObject();
in.close();
} catch (IOException ex) {
ex.printStackTrace();
@@ -101,7 +101,7 @@
}
@Override
- protected void onPostExecute(TileData data[][]) {
+ protected void onPostExecute(RunData data) {
if (data == null) {
Toast.makeText(getApplicationContext(),
getResources().getString(R.string.error_no_data),
@@ -110,7 +110,7 @@
}
mPlaybackView.setData(data);
- mFrameMax = data.length - 1;
+ mFrameMax = data.frames.length - 1;
mSeekBar.setMax(mFrameMax);
setFrame(null, 0);
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
index 35b1563..9ea90f8 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
@@ -22,10 +22,12 @@
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.ShapeDrawable;
-import android.os.Bundle;
+
+import com.test.tilebenchmark.RunData.TileData;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
public class PlaybackGraphs {
private static final int BAR_WIDTH = PlaybackView.TILE_SCALE * 3;
@@ -44,7 +46,7 @@
return 0.0f;
}
- private interface MetricGen {
+ protected interface MetricGen {
public double getValue(TileData[] frame);
public double getMax();
@@ -52,7 +54,7 @@
public int getLabelId();
};
- private static MetricGen[] Metrics = new MetricGen[] {
+ protected static MetricGen[] Metrics = new MetricGen[] {
new MetricGen() {
// framerate graph
@Override
@@ -99,7 +101,7 @@
}
};
- private interface StatGen {
+ protected interface StatGen {
public double getValue(double sortedValues[]);
public int getLabelId();
@@ -116,7 +118,7 @@
+ sortedValues[intIndex + 1] * (alpha);
}
- private static StatGen[] Stats = new StatGen[] {
+ protected static StatGen[] Stats = new StatGen[] {
new StatGen() {
@Override
public double getValue(double[] sortedValues) {
@@ -157,21 +159,22 @@
}
private ArrayList<ShapeDrawable> mShapes = new ArrayList<ShapeDrawable>();
- private double[][] mStats = new double[Metrics.length][Stats.length];
+ protected double[][] mStats = new double[Metrics.length][Stats.length];
+ protected HashMap<String, Double> mSingleStats;
- public void setData(TileData[][] tileProfilingData) {
+ public void setData(RunData data) {
mShapes.clear();
- double metricValues[] = new double[tileProfilingData.length];
+ double metricValues[] = new double[data.frames.length];
- if (tileProfilingData.length == 0) {
+ if (data.frames.length == 0) {
return;
}
for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) {
// create graph out of rectangles, one per frame
int lastBar = 0;
- for (int frameIndex = 0; frameIndex < tileProfilingData.length; frameIndex++) {
- TileData frame[] = tileProfilingData[frameIndex];
+ for (int frameIndex = 0; frameIndex < data.frames.length; frameIndex++) {
+ TileData frame[] = data.frames[frameIndex];
int newBar = (frame[0].top + frame[0].bottom) / 2;
MetricGen s = Metrics[metricIndex];
@@ -194,9 +197,11 @@
// store aggregate statistics per metric (median, and similar)
Arrays.sort(metricValues);
for (int statIndex = 0; statIndex < Stats.length; statIndex++) {
- mStats[metricIndex][statIndex] = Stats[statIndex]
- .getValue(metricValues);
+ mStats[metricIndex][statIndex] =
+ Stats[statIndex].getValue(metricValues);
}
+
+ mSingleStats = data.singleStats;
}
}
@@ -215,7 +220,7 @@
}
public void draw(Canvas canvas, ArrayList<ShapeDrawable> shapes,
- String[] strings, Resources resources) {
+ ArrayList<String> strings, Resources resources) {
canvas.scale(CANVAS_SCALE, CANVAS_SCALE);
canvas.translate(BAR_WIDTH * Metrics.length, 0);
@@ -231,33 +236,18 @@
int yPos = LABELOFFSET;
canvas.drawText(label, xPos, yPos, whiteLabels);
for (int statIndex = 0; statIndex < Stats.length; statIndex++) {
- label = resources.getString(R.string.format_stat,
- mStats[metricIndex][statIndex]);
+ String statLabel = resources.getString(
+ Stats[statIndex].getLabelId()).substring(0,3);
+ label = statLabel + " " + resources.getString(
+ R.string.format_stat, mStats[metricIndex][statIndex]);
yPos = LABELOFFSET + (1 + statIndex) * PlaybackView.TILE_SCALE
/ 2;
canvas.drawText(label, xPos, yPos, whiteLabels);
}
}
- for (int stringIndex = 0; stringIndex < strings.length; stringIndex++) {
+ for (int stringIndex = 0; stringIndex < strings.size(); stringIndex++) {
int yPos = LABELOFFSET + stringIndex * PlaybackView.TILE_SCALE / 2;
- canvas.drawText(strings[stringIndex], 0, yPos, whiteLabels);
+ canvas.drawText(strings.get(stringIndex), 0, yPos, whiteLabels);
}
}
-
- public Bundle getStatBundle(Resources resources) {
- Bundle b = new Bundle();
-
- for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) {
- for (int statIndex = 0; statIndex < Stats.length; statIndex++) {
- String metricLabel = resources.getString(
- Metrics[metricIndex].getLabelId());
- String statLabel = resources.getString(
- Stats[statIndex].getLabelId());
- double value = mStats[metricIndex][statIndex];
- b.putDouble(metricLabel + " " + statLabel, value);
- }
- }
-
- return b;
- }
}
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackView.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackView.java
index edc8643..5459c1f 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackView.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackView.java
@@ -30,10 +30,12 @@
import android.view.MotionEvent;
import android.view.View;
+import com.test.tilebenchmark.RunData.TileData;
+
import java.util.ArrayList;
public class PlaybackView extends View {
- public static final int TILE_SCALE = 300;
+ public static final int TILE_SCALE = 256;
private static final int INVAL_FLAG = -2;
private static final int INVAL_CYCLE = 250;
@@ -41,9 +43,9 @@
private PlaybackGraphs mGraphs;
private ArrayList<ShapeDrawable> mTempShapes = new ArrayList<ShapeDrawable>();
- private TileData mProfData[][] = null;
+ private RunData mProfData = null;
private GestureDetector mGestureDetector = null;
- private String mRenderStrings[] = new String[4];
+ private ArrayList<String> mRenderStrings = new ArrayList<String>();
private class TileDrawable extends ShapeDrawable {
TileData tile;
@@ -135,17 +137,30 @@
invalidate(); // may have animations, force redraw
}
+ private String statString(int labelId, int value) {
+ return getResources().getString(R.string.format_stat_name,
+ getResources().getString(labelId), value);
+ }
+ private String tileString(int formatStringId, TileData t) {
+ return getResources().getString(formatStringId,
+ t.left, t.top, t.right, t.bottom);
+ }
+
public int setFrame(int frame) {
- if (mProfData == null || mProfData.length == 0) {
+ if (mProfData == null || mProfData.frames.length == 0) {
return 0;
}
int readyTiles = 0, unreadyTiles = 0, unplacedTiles = 0, numInvals = 0;
mTempShapes.clear();
+ mRenderStrings.clear();
// create tile shapes (as they're drawn on bottom)
- for (TileData t : mProfData[frame]) {
- if (t.level != INVAL_FLAG && t != mProfData[frame][0]) {
+ for (TileData t : mProfData.frames[frame]) {
+ if (t == mProfData.frames[frame][0]){
+ // viewport 'tile', add coords to render strings
+ mRenderStrings.add(tileString(R.string.format_view_pos, t));
+ } else if (t.level != INVAL_FLAG) {
int colorId;
if (t.isReady) {
readyTiles++;
@@ -159,14 +174,16 @@
}
mTempShapes.add(new TileDrawable(t, colorId));
} else {
+ // inval 'tile', count and add coords to render strings
numInvals++;
+ mRenderStrings.add(tileString(R.string.format_inval_pos, t));
}
}
// create invalidate shapes (drawn above tiles)
int invalId = 0;
- for (TileData t : mProfData[frame]) {
- if (t.level == INVAL_FLAG && t != mProfData[frame][0]) {
+ for (TileData t : mProfData.frames[frame]) {
+ if (t.level == INVAL_FLAG && t != mProfData.frames[frame][0]) {
TileDrawable invalShape = new TileDrawable(t,
R.color.inval_region_start);
ValueAnimator tileAnimator = ObjectAnimator.ofInt(invalShape,
@@ -186,26 +203,20 @@
}
}
- mRenderStrings[0] = getResources().getString(R.string.format_stat_name,
- getResources().getString(R.string.ready_tiles), readyTiles);
- mRenderStrings[1] = getResources().getString(R.string.format_stat_name,
- getResources().getString(R.string.unready_tiles), unreadyTiles);
- mRenderStrings[2] = getResources().getString(R.string.format_stat_name,
- getResources().getString(R.string.unplaced_tiles),
- unplacedTiles);
- mRenderStrings[3] = getResources().getString(R.string.format_stat_name,
- getResources().getString(R.string.number_invalidates),
- numInvals);
+ mRenderStrings.add(statString(R.string.ready_tiles, readyTiles));
+ mRenderStrings.add(statString(R.string.unready_tiles, unreadyTiles));
+ mRenderStrings.add(statString(R.string.unplaced_tiles, unplacedTiles));
+ mRenderStrings.add(statString(R.string.number_invalidates, numInvals));
// draw view rect (using first TileData object, on top)
- TileDrawable viewShape = new TileDrawable(mProfData[frame][0],
+ TileDrawable viewShape = new TileDrawable(mProfData.frames[frame][0],
R.color.view);
mTempShapes.add(viewShape);
this.invalidate();
return frame;
}
- public void setData(TileData[][] tileProfilingData) {
+ public void setData(RunData tileProfilingData) {
mProfData = tileProfilingData;
mGraphs.setData(mProfData);
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java
index 1521807..82a7e82 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java
@@ -51,11 +51,11 @@
public class ProfileActivity extends Activity {
public interface ProfileCallback {
- public void profileCallback(TileData data[][]);
+ public void profileCallback(RunData data);
}
public static final String TEMP_FILENAME = "profile.tiles";
- private static final int LOAD_TEST_DELAY = 2000; // nr of millis after load,
+ private static final int LOAD_TEST_DELAY = 1000; // nr of millis after load,
// before test
Button mInspectButton;
@@ -135,6 +135,7 @@
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
view.requestFocus();
+
new CountDownTimer(LOAD_TEST_DELAY, LOAD_TEST_DELAY) {
@Override
public void onTick(long millisUntilFinished) {
@@ -155,10 +156,10 @@
}
private class StoreFileTask extends
- AsyncTask<Pair<String, TileData[][]>, Void, Void> {
+ AsyncTask<Pair<String, RunData>, Void, Void> {
@Override
- protected Void doInBackground(Pair<String, TileData[][]>... params) {
+ protected Void doInBackground(Pair<String, RunData>... params) {
try {
FileOutputStream fos = openFileOutput(params[0].first,
Context.MODE_PRIVATE);
@@ -205,10 +206,8 @@
/** auto - automatically scroll. */
private void startViewProfiling(boolean auto) {
- if (!auto) {
- // manual, toggle capture button to indicate capture state to user
- mCaptureButton.setChecked(true);
- }
+ // toggle capture button to indicate capture state to user
+ mCaptureButton.setChecked(true);
mWeb.startScrollTest(mCallback, auto);
setTestingState(TestingState.START_TESTING);
}
@@ -224,16 +223,16 @@
mMovementSpinner = (Spinner) findViewById(R.id.movement);
mUrl = (EditText) findViewById(R.id.url);
mWeb = (ProfiledWebView) findViewById(R.id.web);
- mCallback = new ProfileCallback() {
+ setCallback(new ProfileCallback() {
@SuppressWarnings("unchecked")
@Override
- public void profileCallback(TileData[][] data) {
- new StoreFileTask().execute(new Pair<String, TileData[][]>(
+ public void profileCallback(RunData data) {
+ new StoreFileTask().execute(new Pair<String, RunData>(
TEMP_FILENAME, data));
mCaptureButton.setChecked(false);
setTestingState(TestingState.STOP_TESTING);
}
- };
+ });
// Inspect button (opens PlaybackActivity)
mInspectButton.setOnClickListener(new OnClickListener() {
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
index d3941be..3fc4665 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
@@ -18,15 +18,19 @@
import android.content.Context;
import android.util.AttributeSet;
+import android.util.Log;
import android.webkit.WebView;
import com.test.tilebenchmark.ProfileActivity.ProfileCallback;
+import com.test.tilebenchmark.RunData.TileData;
public class ProfiledWebView extends WebView {
private int mSpeed;
+ private boolean isTesting = false;
private boolean isScrolling = false;
private ProfileCallback mCallback;
+ private long mContentInvalMillis;
public ProfiledWebView(Context context) {
super(context);
@@ -47,7 +51,7 @@
@Override
protected void onDraw(android.graphics.Canvas canvas) {
- if (isScrolling) {
+ if (isTesting && isScrolling) {
if (canScrollVertically(1)) {
scrollBy(0, mSpeed);
} else {
@@ -60,31 +64,53 @@
/*
* Called once the page is loaded to start scrolling for evaluating tiles.
- * If autoScrolling isn't set, stop must be called manually.
+ * If autoScrolling isn't set, stop must be called manually. Before
+ * scrolling, invalidate all content and redraw it, measuring time taken.
*/
public void startScrollTest(ProfileCallback callback, boolean autoScrolling) {
isScrolling = autoScrolling;
mCallback = callback;
- tileProfilingStart();
+ isTesting = false;
+ mContentInvalMillis = System.currentTimeMillis();
+ registerPageSwapCallback();
+ contentInvalidateAll();
invalidate();
}
/*
+ * Called after the manual contentInvalidateAll, after the tiles have all
+ * been redrawn.
+ */
+ @Override
+ protected void pageSwapCallback() {
+ mContentInvalMillis = System.currentTimeMillis() - mContentInvalMillis;
+ super.pageSwapCallback();
+ Log.d("ProfiledWebView", "REDRAW TOOK " + mContentInvalMillis
+ + "millis");
+ isTesting = true;
+ invalidate(); // ensure a redraw so that auto-scrolling can occur
+ tileProfilingStart();
+ }
+
+ /*
* Called once the page has stopped scrolling
*/
public void stopScrollTest() {
- super.tileProfilingStop();
+ tileProfilingStop();
+ isTesting = false;
if (mCallback == null) {
tileProfilingClear();
return;
}
- TileData data[][] = new TileData[super.tileProfilingNumFrames()][];
- for (int frame = 0; frame < data.length; frame++) {
- data[frame] = new TileData[
+ RunData data = new RunData(super.tileProfilingNumFrames());
+ data.singleStats.put(getResources().getString(R.string.render_millis),
+ (double)mContentInvalMillis);
+ for (int frame = 0; frame < data.frames.length; frame++) {
+ data.frames[frame] = new TileData[
tileProfilingNumTilesInFrame(frame)];
- for (int tile = 0; tile < data[frame].length; tile++) {
+ for (int tile = 0; tile < data.frames[frame].length; tile++) {
int left = tileProfilingGetInt(frame, tile, "left");
int top = tileProfilingGetInt(frame, tile, "top");
int right = tileProfilingGetInt(frame, tile, "right");
@@ -96,18 +122,18 @@
float scale = tileProfilingGetFloat(frame, tile, "scale");
- data[frame][tile] = new TileData(left, top, right, bottom,
+ data.frames[frame][tile] = data.new TileData(left, top, right, bottom,
isReady, level, scale);
}
}
- super.tileProfilingClear();
+ tileProfilingClear();
mCallback.profileCallback(data);
}
@Override
public void loadUrl(String url) {
- if (!url.startsWith("http://")) {
+ if (!url.startsWith("http://") && !url.startsWith("file://")) {
url = "http://" + url;
}
super.loadUrl(url);
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java b/tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java
new file mode 100644
index 0000000..2da61cc
--- /dev/null
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.test.tilebenchmark;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+public class RunData implements Serializable {
+ public TileData[][] frames;
+ public HashMap<String, Double> singleStats = new HashMap<String, Double>();
+
+ public RunData(int frames) {
+ this.frames = new TileData[frames][];
+ }
+
+ public class TileData implements Serializable {
+ public int left, top, right, bottom;
+ public boolean isReady;
+ public int level;
+ public float scale;
+
+ public TileData(int left, int top, int right, int bottom,
+ boolean isReady, int level, float scale) {
+ this.left = left;
+ this.right = right;
+ this.top = top;
+ this.bottom = bottom;
+ this.isReady = isReady;
+ this.level = level;
+ this.scale = scale;
+ }
+
+ public String toString() {
+ return "Tile (" + left + "," + top + ")->("
+ + right + "," + bottom + ")";
+ }
+ }
+
+}
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/TileData.java b/tests/TileBenchmark/src/com/test/tilebenchmark/TileData.java
deleted file mode 100644
index 3e729a6..0000000
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/TileData.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.test.tilebenchmark;
-
-import java.io.Serializable;
-
-public class TileData implements Serializable {
- int left, top, right, bottom;
- public boolean isReady;
- public int level;
- public float scale;
-
- public TileData(int left, int top, int right, int bottom, boolean isReady,
- int level, float scale) {
- this.left = left;
- this.right = right;
- this.top = top;
- this.bottom = bottom;
- this.isReady = isReady;
- this.level = level;
- this.scale = scale;
- }
-
- public String toString() {
- return "Tile (" + left + "," + top + ")->("
- + right + "," + bottom + ")";
- }
-}
diff --git a/tests/TileBenchmark/tests/Android.mk b/tests/TileBenchmark/tests/Android.mk
new file mode 100644
index 0000000..8b235ec
--- /dev/null
+++ b/tests/TileBenchmark/tests/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := TileBenchmarkTests
+
+LOCAL_INSTRUMENTATION_FOR := TileBenchmark
+
+include $(BUILD_PACKAGE)
diff --git a/tests/TileBenchmark/tests/AndroidManifest.xml b/tests/TileBenchmark/tests/AndroidManifest.xml
new file mode 100644
index 0000000..703b152
--- /dev/null
+++ b/tests/TileBenchmark/tests/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.test.tilebenchmark.tests">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.test.tilebenchmark"
+ android:label="Tests for WebView Tiles."/>
+</manifest>
diff --git a/tests/TileBenchmark/tests/src/com/test/tilebenchmark/PerformanceTest.java b/tests/TileBenchmark/tests/src/com/test/tilebenchmark/PerformanceTest.java
new file mode 100644
index 0000000..0f02239
--- /dev/null
+++ b/tests/TileBenchmark/tests/src/com/test/tilebenchmark/PerformanceTest.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.test.tilebenchmark;
+
+import com.test.tilebenchmark.ProfileActivity.ProfileCallback;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.Environment;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+public class PerformanceTest extends
+ ActivityInstrumentationTestCase2<ProfileActivity> {
+
+ private class StatAggregator extends PlaybackGraphs {
+ private HashMap<String, Double> mDataMap = new HashMap<String, Double>();
+ private int mCount = 0;
+
+ public void aggregate() {
+ mCount++;
+ Resources resources = mView.getResources();
+ for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) {
+ for (int statIndex = 0; statIndex < Stats.length; statIndex++) {
+ String metricLabel = resources.getString(
+ Metrics[metricIndex].getLabelId());
+ String statLabel = resources.getString(
+ Stats[statIndex].getLabelId());
+
+ String label = metricLabel + " " + statLabel;
+ double aggVal = mDataMap.containsKey(label) ? mDataMap
+ .get(label) : 0;
+
+ aggVal += mStats[metricIndex][statIndex];
+ mDataMap.put(label, aggVal);
+ }
+ }
+ for (Map.Entry<String, Double> e : mSingleStats.entrySet()) {
+ double aggVal = mDataMap.containsKey(e.getKey())
+ ? mDataMap.get(e.getKey()) : 0;
+ mDataMap.put(e.getKey(), aggVal + e.getValue());
+ }
+ }
+
+ public Bundle getBundle() {
+ Bundle b = new Bundle();
+ int count = 0 == mCount ? Integer.MAX_VALUE : mCount;
+ for (Map.Entry<String, Double> e : mDataMap.entrySet()) {
+ b.putDouble(e.getKey(), e.getValue() / count);
+ }
+ return b;
+ }
+ }
+
+ ProfileActivity mActivity;
+ ProfiledWebView mView;
+ StatAggregator mStats = new StatAggregator();
+
+ private static final String LOGTAG = "PerformanceTest";
+ private static final String TEST_LOCATION = "webkit/page_cycler";
+ private static final String URL_PREFIX = "file://";
+ private static final String URL_POSTFIX = "/index.html?skip=true";
+ private static final int MAX_ITERATIONS = 4;
+ private static final String TEST_DIRS[] = {
+ "alexa_us"//, "android", "dom", "intl1", "intl2", "moz", "moz2"
+ };
+
+ public PerformanceTest() {
+ super(ProfileActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ mView = (ProfiledWebView) mActivity.findViewById(R.id.web);
+ }
+
+ private boolean loadUrl(final String url) {
+ try {
+ Log.d(LOGTAG, "test starting for url " + url);
+ mActivity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mView.loadUrl(url);
+ }
+ });
+ synchronized (mStats) {
+ mStats.wait();
+ }
+ mStats.aggregate();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ private boolean runIteration() {
+ File sdFile = Environment.getExternalStorageDirectory();
+ for (String testDirName : TEST_DIRS) {
+ File testDir = new File(sdFile, TEST_LOCATION + "/" + testDirName);
+ Log.d(LOGTAG, "Testing dir: '" + testDir.getAbsolutePath()
+ + "', exists=" + testDir.exists());
+ for (File siteDir : testDir.listFiles()) {
+ if (!siteDir.isDirectory())
+ continue;
+
+ if (!loadUrl(URL_PREFIX + siteDir.getAbsolutePath()
+ + URL_POSTFIX)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public void testMetrics() {
+ String state = Environment.getExternalStorageState();
+
+ if (!Environment.MEDIA_MOUNTED.equals(state)
+ && !Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ Log.d(LOGTAG, "ARG Can't access sd card!");
+ // Can't read the SD card, fail and die!
+ getInstrumentation().sendStatus(1, null);
+ return;
+ }
+
+ // use mGraphs as a condition variable between the UI thread and
+ // this(the testing) thread
+ mActivity.setCallback(new ProfileCallback() {
+ @Override
+ public void profileCallback(RunData data) {
+ Log.d(LOGTAG, "test completion callback");
+ mStats.setData(data);
+ synchronized (mStats) {
+ mStats.notify();
+ }
+ }
+ });
+
+ for (int i = 0; i < MAX_ITERATIONS; i++)
+ if (!runIteration()) {
+ getInstrumentation().sendStatus(1, null);
+ return;
+ }
+ getInstrumentation().sendStatus(0, mStats.getBundle());
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
similarity index 95%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
rename to tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
index 1756496..0928ec5 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
@@ -14,13 +14,15 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge.android;
+package android.content.res;
import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.layoutlib.bridge.impl.ResourceHelper;
import com.android.ninepatch.NinePatch;
@@ -30,13 +32,6 @@
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
-import android.content.res.AssetFileDescriptor;
-import android.content.res.AssetManager;
-import android.content.res.ColorStateList;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -94,7 +89,7 @@
* <p/>
* {@link Bridge} calls this method after setting up a new bridge.
*/
- /*package*/ static Resources initSystem(BridgeContext context,
+ public static Resources initSystem(BridgeContext context,
AssetManager assets,
DisplayMetrics metrics,
Configuration config,
@@ -110,7 +105,7 @@
* Disposes the static {@link Resources#mSystem} to make sure we don't leave objects
* around that would prevent us from unloading the library.
*/
- /*package*/ static void disposeSystem() {
+ public static void disposeSystem() {
if (Resources.mSystem instanceof BridgeResources) {
((BridgeResources)(Resources.mSystem)).mContext = null;
((BridgeResources)(Resources.mSystem)).mProjectCallback = null;
@@ -336,7 +331,7 @@
if (ResourceHelper.parseFloatAttribute(
value.getFirst(), v, mTmpValue, true /*requireUnit*/) &&
mTmpValue.type == TypedValue.TYPE_DIMENSION) {
- return mTmpValue.getDimension(mMetrics);
+ return mTmpValue.getDimension(getDisplayMetrics());
}
}
}
@@ -359,7 +354,8 @@
if (ResourceHelper.parseFloatAttribute(
value.getFirst(), v, mTmpValue, true /*requireUnit*/) &&
mTmpValue.type == TypedValue.TYPE_DIMENSION) {
- return TypedValue.complexToDimensionPixelOffset(mTmpValue.data, mMetrics);
+ return TypedValue.complexToDimensionPixelOffset(mTmpValue.data,
+ getDisplayMetrics());
}
}
}
@@ -382,7 +378,8 @@
if (ResourceHelper.parseFloatAttribute(
value.getFirst(), v, mTmpValue, true /*requireUnit*/) &&
mTmpValue.type == TypedValue.TYPE_DIMENSION) {
- return TypedValue.complexToDimensionPixelSize(mTmpValue.data, mMetrics);
+ return TypedValue.complexToDimensionPixelSize(mTmpValue.data,
+ getDisplayMetrics());
}
}
}
@@ -420,6 +417,22 @@
}
@Override
+ public boolean getBoolean(int id) throws NotFoundException {
+ Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
+
+ if (value != null && value.getSecond().getValue() != null) {
+ String v = value.getSecond().getValue();
+ return Boolean.parseBoolean(v);
+ }
+
+ // id was not found or not resolved. Throw a NotFoundException.
+ throwException(id);
+
+ // this is not used since the method above always throws
+ return false;
+ }
+
+ @Override
public String getResourceEntryName(int resid) throws NotFoundException {
throw new UnsupportedOperationException();
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
similarity index 98%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
rename to tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index fc2f2f8..9deed32 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge.android;
+package android.content.res;
import com.android.ide.common.rendering.api.DeclareStyleableResourceValue;
import com.android.ide.common.rendering.api.LayoutLog;
@@ -24,6 +24,8 @@
import com.android.internal.util.XmlUtils;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.layoutlib.bridge.impl.ResourceHelper;
import com.android.resources.ResourceType;
@@ -445,7 +447,7 @@
}
if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true /*requireUnit*/)) {
- return mValue.getDimension(mBridgeResources.mMetrics);
+ return mValue.getDimension(mBridgeResources.getDisplayMetrics());
}
// looks like we were unable to resolve the dimension value
@@ -572,7 +574,7 @@
}
if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true /*requireUnit*/)) {
- float f = mValue.getDimension(mBridgeResources.mMetrics);
+ float f = mValue.getDimension(mBridgeResources.getDisplayMetrics());
final int res = (int)(f+0.5f);
if (res != 0) return res;
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
index 080b85f..945b3cd7 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
@@ -17,12 +17,12 @@
package android.graphics;
import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeResources.NinePatchInputStream;
import com.android.layoutlib.bridge.impl.DelegateManager;
import com.android.ninepatch.NinePatchChunk;
import com.android.resources.Density;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+import android.content.res.BridgeResources.NinePatchInputStream;
import android.graphics.BitmapFactory.Options;
import java.io.FileDescriptor;
diff --git a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
index 3ef3288..64efa7e 100644
--- a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
@@ -38,11 +38,15 @@
*/
public class LayoutInflater_Delegate {
+ private static final String TAG_MERGE = "merge";
+
public static boolean sIsInInclude = false;
/**
* Recursive method used to descend down the xml hierarchy and instantiate
* views, instantiate their children, and then call onFinishInflate().
+ *
+ * This implementation just records the merge status before calling the default implementation.
*/
@LayoutlibDelegate
/*package*/ static void rInflate(LayoutInflater thisInflater,
@@ -58,37 +62,7 @@
// ---- START DEFAULT IMPLEMENTATION.
- final int depth = parser.getDepth();
- int type;
-
- while (((type = parser.next()) != XmlPullParser.END_TAG ||
- parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
-
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
-
- final String name = parser.getName();
-
- if (LayoutInflater.TAG_REQUEST_FOCUS.equals(name)) {
- thisInflater.parseRequestFocus(parser, parent);
- } else if (LayoutInflater.TAG_INCLUDE.equals(name)) {
- if (parser.getDepth() == 0) {
- throw new InflateException("<include /> cannot be the root element");
- }
- thisInflater.parseInclude(parser, parent, attrs);
- } else if (LayoutInflater.TAG_MERGE.equals(name)) {
- throw new InflateException("<merge /> must be the root element");
- } else {
- final View view = thisInflater.createViewFromTag(parent, name, attrs);
- final ViewGroup viewGroup = (ViewGroup) parent;
- final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
- thisInflater.rInflate(parser, view, attrs, true);
- viewGroup.addView(view, params);
- }
- }
-
- if (finishInflate) parent.onFinishInflate();
+ thisInflater.rInflate_Original(parser, parent, attrs, finishInflate);
// ---- END DEFAULT IMPLEMENTATION.
@@ -138,7 +112,7 @@
final String childName = childParser.getName();
- if (LayoutInflater.TAG_MERGE.equals(childName)) {
+ if (TAG_MERGE.equals(childName)) {
// Inflate all children.
thisInflater.rInflate(childParser, parent, childAttrs, false);
} else {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 69e0de9..b38b3b8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -47,6 +47,8 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
+import android.content.res.BridgeResources;
+import android.content.res.BridgeTypedArray;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -813,7 +815,7 @@
return null;
}
- int getDynamicIdByStyle(StyleResourceValue resValue) {
+ public int getDynamicIdByStyle(StyleResourceValue resValue) {
if (mDynamicIdToStyleMap == null) {
// create the maps.
mDynamicIdToStyleMap = new HashMap<Integer, StyleResourceValue>();
@@ -843,7 +845,7 @@
return null;
}
- int getFrameworkResourceValue(ResourceType resType, String resName, int defValue) {
+ public int getFrameworkResourceValue(ResourceType resType, String resName, int defValue) {
Integer value = Bridge.getResourceId(resType, resName);
if (value != null) {
return value.intValue();
@@ -852,7 +854,7 @@
return defValue;
}
- int getProjectResourceValue(ResourceType resType, String resName, int defValue) {
+ public int getProjectResourceValue(ResourceType resType, String resName, int defValue) {
if (mProjectCallback != null) {
Integer value = mProjectCallback.getResourceId(resType, resName);
if (value != null) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index df701d5..72ed351 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -230,7 +230,7 @@
if (ResourceHelper.parseFloatAttribute("textSize", textSize.getValue(), out,
true /*requireUnit*/)) {
textView.setTextSize(
- out.getDimension(bridgeContext.getResources().mMetrics));
+ out.getDimension(bridgeContext.getResources().getDisplayMetrics()));
}
}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
index 9bf52c7..b027b6a 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
@@ -167,5 +167,4 @@
return true;
}
-
}
diff --git a/voip/java/android/net/sip/SipManager.java b/voip/java/android/net/sip/SipManager.java
index dce46fe..cd0b5c4 100644
--- a/voip/java/android/net/sip/SipManager.java
+++ b/voip/java/android/net/sip/SipManager.java
@@ -471,6 +471,10 @@
try {
ISipSession session = mSipService.createSession(localProfile,
createRelay(listener, localProfile.getUriString()));
+ if (session == null) {
+ throw new SipException(
+ "SipService.createSession() returns null");
+ }
session.register(expiryTime);
} catch (RemoteException e) {
throw new SipException("register()", e);
@@ -492,6 +496,10 @@
try {
ISipSession session = mSipService.createSession(localProfile,
createRelay(listener, localProfile.getUriString()));
+ if (session == null) {
+ throw new SipException(
+ "SipService.createSession() returns null");
+ }
session.unregister();
} catch (RemoteException e) {
throw new SipException("unregister()", e);
@@ -513,7 +521,7 @@
try {
String callId = getCallId(incomingCallIntent);
ISipSession s = mSipService.getPendingSession(callId);
- return new SipSession(s);
+ return ((s == null) ? null : new SipSession(s));
} catch (RemoteException e) {
throw new SipException("getSessionFor()", e);
}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index de49eb4..331d5c0 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -57,6 +57,7 @@
import android.net.NetworkUtils;
import android.net.wifi.WpsResult.Status;
import android.net.wifi.p2p.WifiP2pManager;
+import android.net.wifi.p2p.WifiP2pService;
import android.net.wifi.StateChangeResult;
import android.os.Binder;
import android.os.IBinder;
@@ -69,7 +70,6 @@
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.WorkSource;
-import android.server.WifiP2pService;
import android.provider.Settings;
import android.util.EventLog;
import android.util.Log;
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index be9dfcf..168c68b 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -44,9 +44,11 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
+import java.net.InetAddress;
import java.net.URL;
import java.util.HashSet;
import java.util.List;
+import java.util.Set;
/**
* {@link WifiWatchdogStateMachine} monitors the initial connection to a Wi-Fi
@@ -82,7 +84,6 @@
private static final int DEFAULT_MAX_SSID_BLACKLISTS = 7;
private static final int DEFAULT_NUM_DNS_PINGS = 5;
private static final int DEFAULT_MIN_DNS_RESPONSES = 3;
- private static final long DNS_PING_INTERVAL_MS = 100;
private static final int DEFAULT_DNS_PING_TIMEOUT_MS = 2000;
@@ -92,6 +93,7 @@
private static final String DEFAULT_WALLED_GARDEN_URL =
"http://clients3.google.com/generate_204";
private static final int WALLED_GARDEN_SOCKET_TIMEOUT_MS = 10000;
+ private static final int DNS_INTRATEST_PING_INTERVAL = 20;
private static final int BASE = Protocol.BASE_WIFI_WATCHDOG;
@@ -114,9 +116,8 @@
private static final int EVENT_WIFI_RADIO_STATE_CHANGE = BASE + 5;
private static final int EVENT_WATCHDOG_SETTINGS_CHANGE = BASE + 6;
- private static final int MESSAGE_CHECK_STEP = BASE + 100;
- private static final int MESSAGE_HANDLE_WALLED_GARDEN = BASE + 101;
- private static final int MESSAGE_HANDLE_BAD_AP = BASE + 102;
+ private static final int MESSAGE_HANDLE_WALLED_GARDEN = BASE + 100;
+ private static final int MESSAGE_HANDLE_BAD_AP = BASE + 101;
/**
* arg1 == mOnlineWatchState.checkCount
*/
@@ -189,8 +190,9 @@
mContext = context;
mContentResolver = context.getContentResolver();
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
- mDnsPinger = new DnsPinger("WifiWatchdogServer.DnsPinger", context,
- ConnectivityManager.TYPE_WIFI);
+ mDnsPinger = new DnsPinger(mContext, "WifiWatchdogStateMachine.DnsPinger",
+ this.getHandler().getLooper(), this.getHandler(),
+ ConnectivityManager.TYPE_WIFI);
setupNetworkReceiver();
@@ -637,36 +639,43 @@
}
class DnsCheckingState extends State {
- int dnsCheckTries = 0;
int dnsCheckSuccesses = 0;
+ int dnsCheckTries = 0;
String dnsCheckLogStr = "";
+ Set<Integer> ids = new HashSet<Integer>();
@Override
public void enter() {
dnsCheckSuccesses = 0;
dnsCheckTries = 0;
+ ids.clear();
+ InetAddress dns = mDnsPinger.getDns();
if (DBG) {
Slog.d(WWSM_TAG, "Starting DNS pings at " + SystemClock.elapsedRealtime());
dnsCheckLogStr = String.format("Pinging %s on ssid [%s]: ",
- mDnsPinger.getDns(), mInitialConnInfo.getSSID());
+ dns, mInitialConnInfo.getSSID());
}
- sendCheckStepMessage(0);
+ for (int i=0; i < mNumDnsPings; i++) {
+ ids.add(mDnsPinger.pingDnsAsync(dns, mDnsPingTimeoutMs,
+ DNS_INTRATEST_PING_INTERVAL * i));
+ }
}
@Override
public boolean processMessage(Message msg) {
- if (msg.what != MESSAGE_CHECK_STEP) {
+ if (msg.what != DnsPinger.DNS_PING_RESULT) {
return NOT_HANDLED;
}
- if (msg.arg1 != mNetEventCounter) {
- Slog.d(WWSM_TAG, "Check step out of sync, ignoring...");
+
+ int pingID = msg.arg1;
+ int pingResponseTime = msg.arg2;
+
+ if (!ids.contains(pingID)) {
+ Slog.w(WWSM_TAG, "Received a Dns response with unknown ID!");
return HANDLED;
}
-
- long pingResponseTime = mDnsPinger.pingDns(mDnsPinger.getDns(),
- mDnsPingTimeoutMs);
-
+ ids.remove(pingID);
dnsCheckTries++;
if (pingResponseTime >= 0)
dnsCheckSuccesses++;
@@ -730,11 +739,15 @@
return HANDLED;
}
- // Still in dns check step
- sendCheckStepMessage(DNS_PING_INTERVAL_MS);
return HANDLED;
}
+ @Override
+ public void exit() {
+ mDnsPinger.cancelPings();
+ }
+
+
private boolean shouldCheckWalledGarden() {
if (!mWalledGardenTestEnabled) {
if (VDBG)
@@ -752,11 +765,6 @@
}
return true;
}
-
- private void sendCheckStepMessage(long delay) {
- sendMessageDelayed(obtainMessage(MESSAGE_CHECK_STEP, mNetEventCounter, 0), delay);
- }
-
}
class OnlineWatchState extends State {
@@ -779,12 +787,15 @@
int checkGuard = 0;
Long lastCheckTime = null;
+ int curPingID = 0;
+
@Override
public void enter() {
lastCheckTime = SystemClock.elapsedRealtime();
signalUnstable = false;
checkGuard++;
unstableSignalChecks = false;
+ curPingID = 0;
triggerSingleDnsCheck();
}
@@ -820,8 +831,18 @@
return HANDLED;
}
lastCheckTime = SystemClock.elapsedRealtime();
- long responseTime = mDnsPinger.pingDns(mDnsPinger.getDns(),
- mDnsPingTimeoutMs);
+ curPingID = mDnsPinger.pingDnsAsync(mDnsPinger.getDns(),
+ mDnsPingTimeoutMs, 0);
+ return HANDLED;
+ case DnsPinger.DNS_PING_RESULT:
+ if ((short) msg.arg1 != curPingID) {
+ if (VDBG) {
+ Slog.v(WWSM_TAG, "Received non-matching DnsPing w/ id: " +
+ msg.arg1);
+ }
+ return HANDLED;
+ }
+ int responseTime = msg.arg2;
if (responseTime >= 0) {
if (VDBG) {
Slog.v(WWSM_TAG, "Ran a single DNS ping. Response time: "
@@ -842,6 +863,11 @@
return NOT_HANDLED;
}
+ @Override
+ public void exit() {
+ mDnsPinger.cancelPings();
+ }
+
/**
* Times a dns check with an interval based on {@link #signalUnstable}
*/
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 4988f0b..28afd44 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.server;
+package android.net.wifi.p2p;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
@@ -31,20 +31,13 @@
import android.net.wifi.WifiStateMachine;
import android.net.wifi.WpsConfiguration;
import android.net.wifi.WpsConfiguration.Setup;
-import android.net.wifi.p2p.IWifiP2pManager;
-import android.net.wifi.p2p.WifiP2pConfig;
-import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDevice.Status;
-import android.net.wifi.p2p.WifiP2pDeviceList;
-import android.net.wifi.p2p.WifiP2pGroup;
-import android.net.wifi.p2p.WifiP2pManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.Handler;
-import android.os.Messenger;
import android.os.HandlerThread;
-import android.os.IBinder;
import android.os.Message;
+import android.os.Messenger;
import android.util.Slog;
import android.view.LayoutInflater;
import android.view.View;
@@ -55,9 +48,9 @@
import java.io.PrintWriter;
import java.util.Collection;
+import com.android.internal.R;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
-import com.android.internal.R;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;